MultiTech / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers internal.c Source File

internal.c

00001 /* internal.c
00002  *
00003  * Copyright (C) 2006-2014 wolfSSL Inc.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL 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  * CyaSSL 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-1301, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <cyassl/ctaocrypt/settings.h>
00028 
00029 #include <cyassl/internal.h>
00030 #include <cyassl/error-ssl.h>
00031 #include <cyassl/ctaocrypt/asn.h>
00032 
00033 #ifdef HAVE_LIBZ
00034     #include "zlib.h"
00035 #endif
00036 
00037 #ifdef HAVE_NTRU
00038     #include "ntru_crypto.h"
00039 #endif
00040 
00041 #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
00042     #ifdef FREESCALE_MQX
00043         #include <fio.h>
00044     #else
00045         #include <stdio.h>
00046     #endif
00047 #endif
00048 
00049 #ifdef __sun
00050     #include <sys/filio.h>
00051 #endif
00052 
00053 #ifndef TRUE
00054     #define TRUE  1
00055 #endif
00056 #ifndef FALSE
00057     #define FALSE 0
00058 #endif
00059 
00060 
00061 #if defined(CYASSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
00062     #error \
00063 CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
00064 #endif
00065 
00066 #if defined(HAVE_SECURE_RENEGOTIATION) && defined(HAVE_RENEGOTIATION_INDICATION)
00067     #error Cannot use both secure-renegotiation and renegotiation-indication
00068 #endif
00069 
00070 static int BuildMessage(CYASSL* ssl, byte* output, int outSz,
00071                         const byte* input, int inSz, int type);
00072 
00073 #ifndef NO_CYASSL_CLIENT
00074     static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*,
00075                                                                         word32);
00076     static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
00077     static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*,
00078                                                                         word32);
00079     #ifndef NO_CERTS
00080         static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*,
00081                                                                         word32);
00082     #endif
00083     #ifdef HAVE_SESSION_TICKET
00084         static int DoSessionTicket(CYASSL* ssl, const byte* input, word32*,
00085                                                                         word32);
00086     #endif
00087 #endif
00088 
00089 
00090 #ifndef NO_CYASSL_SERVER
00091     static int DoClientHello(CYASSL* ssl, const byte* input, word32*, word32);
00092     static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32*, word32);
00093     #if !defined(NO_RSA) || defined(HAVE_ECC)
00094         static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32);
00095     #endif
00096 #endif
00097 
00098 
00099 #ifdef CYASSL_DTLS
00100     static INLINE int DtlsCheckWindow(DtlsState* state);
00101     static INLINE int DtlsUpdateWindow(DtlsState* state);
00102 #endif
00103 
00104 
00105 typedef enum {
00106     doProcessInit = 0,
00107 #ifndef NO_CYASSL_SERVER
00108     runProcessOldClientHello,
00109 #endif
00110     getRecordLayerHeader,
00111     getData,
00112     runProcessingOneMessage
00113 } processReply;
00114 
00115 #ifndef NO_OLD_TLS
00116 static int SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
00117                     int content, int verify);
00118 
00119 #endif
00120 
00121 #ifndef NO_CERTS
00122 static int BuildCertHashes(CYASSL* ssl, Hashes* hashes);
00123 #endif
00124 
00125 static void PickHashSigAlgo(CYASSL* ssl,
00126                                 const byte* hashSigAlgo, word32 hashSigAlgoSz);
00127 
00128 #ifndef min
00129 
00130     static INLINE word32 min(word32 a, word32 b)
00131     {
00132         return a > b ? b : a;
00133     }
00134 
00135 #endif /* min */
00136 
00137 
00138 int IsTLS(const CYASSL* ssl)
00139 {
00140     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
00141         return 1;
00142 
00143     return 0;
00144 }
00145 
00146 
00147 int IsAtLeastTLSv1_2(const CYASSL* ssl)
00148 {
00149     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
00150         return 1;
00151     if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
00152         return 1;
00153 
00154     return 0;
00155 }
00156 
00157 
00158 #ifdef HAVE_NTRU
00159 
00160 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
00161 {
00162     /* TODO: add locking? */
00163     static RNG rng;
00164 
00165     if (cmd == INIT)
00166         return (InitRng(&rng) == 0) ? 1 : 0;
00167 
00168     if (out == NULL)
00169         return 0;
00170 
00171     if (cmd == GET_BYTE_OF_ENTROPY)
00172         return (RNG_GenerateBlock(&rng, out, 1) == 0) ? 1 : 0;
00173 
00174     if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
00175         *out = 1;
00176         return 1;
00177     }
00178 
00179     return 0;
00180 }
00181 
00182 #endif /* HAVE_NTRU */
00183 
00184 /* used by ssl.c too */
00185 void c32to24(word32 in, word24 out)
00186 {
00187     out[0] = (in >> 16) & 0xff;
00188     out[1] = (in >>  8) & 0xff;
00189     out[2] =  in & 0xff;
00190 }
00191 
00192 
00193 #ifdef CYASSL_DTLS
00194 
00195 static INLINE void c32to48(word32 in, byte out[6])
00196 {
00197     out[0] = 0;
00198     out[1] = 0;
00199     out[2] = (in >> 24) & 0xff;
00200     out[3] = (in >> 16) & 0xff;
00201     out[4] = (in >>  8) & 0xff;
00202     out[5] =  in & 0xff;
00203 }
00204 
00205 #endif /* CYASSL_DTLS */
00206 
00207 
00208 /* convert 16 bit integer to opaque */
00209 static INLINE void c16toa(word16 u16, byte* c)
00210 {
00211     c[0] = (u16 >> 8) & 0xff;
00212     c[1] =  u16 & 0xff;
00213 }
00214 
00215 
00216 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
00217     || defined(HAVE_AESGCM)
00218 /* convert 32 bit integer to opaque */
00219 static INLINE void c32toa(word32 u32, byte* c)
00220 {
00221     c[0] = (u32 >> 24) & 0xff;
00222     c[1] = (u32 >> 16) & 0xff;
00223     c[2] = (u32 >>  8) & 0xff;
00224     c[3] =  u32 & 0xff;
00225 }
00226 #endif
00227 
00228 
00229 /* convert a 24 bit integer into a 32 bit one */
00230 static INLINE void c24to32(const word24 u24, word32* u32)
00231 {
00232     *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
00233 }
00234 
00235 
00236 /* convert opaque to 16 bit integer */
00237 static INLINE void ato16(const byte* c, word16* u16)
00238 {
00239     *u16 = (word16) ((c[0] << 8) | (c[1]));
00240 }
00241 
00242 
00243 #if defined(CYASSL_DTLS) || defined(HAVE_SESSION_TICKET)
00244 
00245 /* convert opaque to 32 bit integer */
00246 static INLINE void ato32(const byte* c, word32* u32)
00247 {
00248     *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
00249 }
00250 
00251 #endif /* CYASSL_DTLS */
00252 
00253 
00254 #ifdef HAVE_LIBZ
00255 
00256     /* alloc user allocs to work with zlib */
00257     static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
00258     {
00259         (void)opaque;
00260         return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
00261     }
00262 
00263 
00264     static void myFree(void* opaque, void* memory)
00265     {
00266         (void)opaque;
00267         XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
00268     }
00269 
00270 
00271     /* init zlib comp/decomp streams, 0 on success */
00272     static int InitStreams(CYASSL* ssl)
00273     {
00274         ssl->c_stream.zalloc = (alloc_func)myAlloc;
00275         ssl->c_stream.zfree  = (free_func)myFree;
00276         ssl->c_stream.opaque = (voidpf)ssl->heap;
00277 
00278         if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
00279             return ZLIB_INIT_ERROR;
00280 
00281         ssl->didStreamInit = 1;
00282 
00283         ssl->d_stream.zalloc = (alloc_func)myAlloc;
00284         ssl->d_stream.zfree  = (free_func)myFree;
00285         ssl->d_stream.opaque = (voidpf)ssl->heap;
00286 
00287         if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
00288 
00289         return 0;
00290     }
00291 
00292 
00293     static void FreeStreams(CYASSL* ssl)
00294     {
00295         if (ssl->didStreamInit) {
00296             deflateEnd(&ssl->c_stream);
00297             inflateEnd(&ssl->d_stream);
00298         }
00299     }
00300 
00301 
00302     /* compress in to out, return out size or error */
00303     static int myCompress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
00304     {
00305         int    err;
00306         int    currTotal = (int)ssl->c_stream.total_out;
00307 
00308         ssl->c_stream.next_in   = in;
00309         ssl->c_stream.avail_in  = inSz;
00310         ssl->c_stream.next_out  = out;
00311         ssl->c_stream.avail_out = outSz;
00312 
00313         err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
00314         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
00315 
00316         return (int)ssl->c_stream.total_out - currTotal;
00317     }
00318 
00319 
00320     /* decompress in to out, returnn out size or error */
00321     static int myDeCompress(CYASSL* ssl, byte* in,int inSz, byte* out,int outSz)
00322     {
00323         int    err;
00324         int    currTotal = (int)ssl->d_stream.total_out;
00325 
00326         ssl->d_stream.next_in   = in;
00327         ssl->d_stream.avail_in  = inSz;
00328         ssl->d_stream.next_out  = out;
00329         ssl->d_stream.avail_out = outSz;
00330 
00331         err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
00332         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
00333 
00334         return (int)ssl->d_stream.total_out - currTotal;
00335     }
00336 
00337 #endif /* HAVE_LIBZ */
00338 
00339 
00340 void InitSSL_Method(CYASSL_METHOD* method, ProtocolVersion pv)
00341 {
00342     method->version    = pv;
00343     method->side       = CYASSL_CLIENT_END;
00344     method->downgrade  = 0;
00345 }
00346 
00347 
00348 /* Initialze SSL context, return 0 on success */
00349 int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
00350 {
00351     ctx->method = method;
00352     ctx->refCount = 1;          /* so either CTX_free or SSL_free can release */
00353 #ifndef NO_CERTS
00354     ctx->certificate.buffer = 0;
00355     ctx->certChain.buffer   = 0;
00356     ctx->privateKey.buffer  = 0;
00357     ctx->serverDH_P.buffer  = 0;
00358     ctx->serverDH_G.buffer  = 0;
00359 #endif
00360     ctx->haveDH             = 0;
00361     ctx->haveNTRU           = 0;    /* start off */
00362     ctx->haveECDSAsig       = 0;    /* start off */
00363     ctx->haveStaticECC      = 0;    /* start off */
00364     ctx->heap               = ctx;  /* defaults to self */
00365 #ifndef NO_PSK
00366     ctx->havePSK            = 0;
00367     ctx->server_hint[0]     = 0;
00368     ctx->client_psk_cb      = 0;
00369     ctx->server_psk_cb      = 0;
00370 #endif /* NO_PSK */
00371 #ifdef HAVE_ANON
00372     ctx->haveAnon           = 0;
00373 #endif /* HAVE_ANON */
00374 #ifdef HAVE_ECC
00375     ctx->eccTempKeySz       = ECDHE_SIZE;
00376 #endif
00377 
00378 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
00379     ctx->passwd_cb   = 0;
00380     ctx->userdata    = 0;
00381 #endif /* OPENSSL_EXTRA */
00382 
00383     ctx->timeout = CYASSL_SESSION_TIMEOUT;
00384 
00385 #ifndef CYASSL_USER_IO
00386     ctx->CBIORecv = EmbedReceive;
00387     ctx->CBIOSend = EmbedSend;
00388     #ifdef CYASSL_DTLS
00389         if (method->version.major == DTLS_MAJOR) {
00390             ctx->CBIORecv   = EmbedReceiveFrom;
00391             ctx->CBIOSend   = EmbedSendTo;
00392             ctx->CBIOCookie = EmbedGenerateCookie;
00393         }
00394     #endif
00395 #else
00396     /* user will set */
00397     ctx->CBIORecv   = NULL;
00398     ctx->CBIOSend   = NULL;
00399     #ifdef CYASSL_DTLS
00400         ctx->CBIOCookie = NULL;
00401     #endif
00402 #endif /* CYASSL_USER_IO */
00403 #ifdef HAVE_NETX
00404     ctx->CBIORecv = NetX_Receive;
00405     ctx->CBIOSend = NetX_Send;
00406 #endif
00407     ctx->partialWrite   = 0;
00408     ctx->verifyCallback = 0;
00409 
00410 #ifndef NO_CERTS
00411     ctx->cm = CyaSSL_CertManagerNew();
00412 #endif
00413 #ifdef HAVE_NTRU
00414     if (method->side == CYASSL_CLIENT_END)
00415         ctx->haveNTRU = 1;           /* always on cliet side */
00416                                      /* server can turn on by loading key */
00417 #endif
00418 #ifdef HAVE_ECC
00419     if (method->side == CYASSL_CLIENT_END) {
00420         ctx->haveECDSAsig  = 1;        /* always on cliet side */
00421         ctx->haveStaticECC = 1;        /* server can turn on by loading key */
00422     }
00423 #endif
00424     ctx->suites.setSuites = 0;  /* user hasn't set yet */
00425     /* remove DH later if server didn't set, add psk later */
00426     InitSuites(&ctx->suites, method->version, TRUE, FALSE, TRUE, ctx->haveNTRU,
00427                ctx->haveECDSAsig, ctx->haveStaticECC, method->side);
00428     ctx->verifyPeer = 0;
00429     ctx->verifyNone = 0;
00430     ctx->failNoCert = 0;
00431     ctx->sessionCacheOff      = 0;  /* initially on */
00432     ctx->sessionCacheFlushOff = 0;  /* initially on */
00433     ctx->sendVerify = 0;
00434     ctx->quietShutdown = 0;
00435     ctx->groupMessages = 0;
00436 #ifdef HAVE_CAVIUM
00437     ctx->devId = NO_CAVIUM_DEVICE;
00438 #endif
00439 #ifdef HAVE_TLS_EXTENSIONS
00440     ctx->extensions = NULL;
00441 #endif
00442 #ifdef ATOMIC_USER
00443     ctx->MacEncryptCb    = NULL;
00444     ctx->DecryptVerifyCb = NULL;
00445 #endif
00446 #ifdef HAVE_PK_CALLBACKS
00447     #ifdef HAVE_ECC
00448         ctx->EccSignCb   = NULL;
00449         ctx->EccVerifyCb = NULL;
00450     #endif /* HAVE_ECC */
00451     #ifndef NO_RSA
00452         ctx->RsaSignCb   = NULL;
00453         ctx->RsaVerifyCb = NULL;
00454         ctx->RsaEncCb    = NULL;
00455         ctx->RsaDecCb    = NULL;
00456     #endif /* NO_RSA */
00457 #endif /* HAVE_PK_CALLBACKS */
00458 
00459     if (InitMutex(&ctx->countMutex) < 0) {
00460         CYASSL_MSG("Mutex error on CTX init");
00461         return BAD_MUTEX_E;
00462     }
00463 #ifndef NO_CERTS
00464     if (ctx->cm == NULL) {
00465         CYASSL_MSG("Bad Cert Manager New");
00466         return BAD_CERT_MANAGER_ERROR;
00467     }
00468 #endif
00469     return 0;
00470 }
00471 
00472 
00473 /* In case contexts are held in array and don't want to free actual ctx */
00474 void SSL_CtxResourceFree(CYASSL_CTX* ctx)
00475 {
00476     XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
00477 
00478 #ifndef NO_CERTS
00479     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00480     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00481     XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
00482     XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
00483     XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
00484     CyaSSL_CertManagerFree(ctx->cm);
00485 #endif
00486 #ifdef HAVE_TLS_EXTENSIONS
00487     TLSX_FreeAll(ctx->extensions);
00488 #endif
00489 }
00490 
00491 
00492 void FreeSSL_Ctx(CYASSL_CTX* ctx)
00493 {
00494     int doFree = 0;
00495 
00496     if (LockMutex(&ctx->countMutex) != 0) {
00497         CYASSL_MSG("Couldn't lock count mutex");
00498         return;
00499     }
00500     ctx->refCount--;
00501     if (ctx->refCount == 0)
00502         doFree = 1;
00503     UnLockMutex(&ctx->countMutex);
00504 
00505     if (doFree) {
00506         CYASSL_MSG("CTX ref count down to 0, doing full free");
00507         SSL_CtxResourceFree(ctx);
00508         FreeMutex(&ctx->countMutex);
00509         XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
00510     }
00511     else {
00512         (void)ctx;
00513         CYASSL_MSG("CTX ref count not 0 yet, no free");
00514     }
00515 }
00516 
00517 
00518 /* Set cipher pointers to null */
00519 void InitCiphers(CYASSL* ssl)
00520 {
00521 #ifdef BUILD_ARC4
00522     ssl->encrypt.arc4 = NULL;
00523     ssl->decrypt.arc4 = NULL;
00524 #endif
00525 #ifdef BUILD_DES3
00526     ssl->encrypt.des3 = NULL;
00527     ssl->decrypt.des3 = NULL;
00528 #endif
00529 #ifdef BUILD_AES
00530     ssl->encrypt.aes = NULL;
00531     ssl->decrypt.aes = NULL;
00532 #endif
00533 #ifdef HAVE_CAMELLIA
00534     ssl->encrypt.cam = NULL;
00535     ssl->decrypt.cam = NULL;
00536 #endif
00537 #ifdef HAVE_HC128
00538     ssl->encrypt.hc128 = NULL;
00539     ssl->decrypt.hc128 = NULL;
00540 #endif
00541 #ifdef BUILD_RABBIT
00542     ssl->encrypt.rabbit = NULL;
00543     ssl->decrypt.rabbit = NULL;
00544 #endif
00545 #ifdef HAVE_CHACHA
00546     ssl->encrypt.chacha = NULL;
00547     ssl->decrypt.chacha = NULL;
00548 #endif
00549 #ifdef HAVE_POLY1305
00550     ssl->auth.poly1305 = NULL;
00551 #endif
00552     ssl->encrypt.setup = 0;
00553     ssl->decrypt.setup = 0;
00554 #ifdef HAVE_ONE_TIME_AUTH
00555     ssl->auth.setup    = 0;
00556 #endif
00557 }
00558 
00559 
00560 /* Free ciphers */
00561 void FreeCiphers(CYASSL* ssl)
00562 {
00563     (void)ssl;
00564 #ifdef BUILD_ARC4
00565     #ifdef HAVE_CAVIUM
00566     if (ssl->devId != NO_CAVIUM_DEVICE) {
00567         Arc4FreeCavium(ssl->encrypt.arc4);
00568         Arc4FreeCavium(ssl->decrypt.arc4);
00569     }
00570     #endif
00571     XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
00572     XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
00573 #endif
00574 #ifdef BUILD_DES3
00575     #ifdef HAVE_CAVIUM
00576     if (ssl->devId != NO_CAVIUM_DEVICE) {
00577         Des3_FreeCavium(ssl->encrypt.des3);
00578         Des3_FreeCavium(ssl->decrypt.des3);
00579     }
00580     #endif
00581     XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
00582     XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
00583 #endif
00584 #ifdef BUILD_AES
00585     #ifdef HAVE_CAVIUM
00586     if (ssl->devId != NO_CAVIUM_DEVICE) {
00587         AesFreeCavium(ssl->encrypt.aes);
00588         AesFreeCavium(ssl->decrypt.aes);
00589     }
00590     #endif
00591     XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
00592     XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
00593 #endif
00594 #ifdef HAVE_CAMELLIA
00595     XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
00596     XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
00597 #endif
00598 #ifdef HAVE_HC128
00599     XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
00600     XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
00601 #endif
00602 #ifdef BUILD_RABBIT
00603     XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
00604     XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
00605 #endif
00606 #ifdef HAVE_CHACHA
00607     XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
00608     XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
00609 #endif
00610 #ifdef HAVE_POLY1305
00611     XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
00612 #endif
00613 }
00614 
00615 
00616 void InitCipherSpecs(CipherSpecs* cs)
00617 {
00618     cs->bulk_cipher_algorithm = INVALID_BYTE;
00619     cs->cipher_type           = INVALID_BYTE;
00620     cs->mac_algorithm         = INVALID_BYTE;
00621     cs->kea                   = INVALID_BYTE;
00622     cs->sig_algo              = INVALID_BYTE;
00623 
00624     cs->hash_size   = 0;
00625     cs->static_ecdh = 0;
00626     cs->key_size    = 0;
00627     cs->iv_size     = 0;
00628     cs->block_size  = 0;
00629 }
00630 
00631 static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
00632                                                   int haveRSAsig, int haveAnon)
00633 {
00634     int idx = 0;
00635 
00636     if (haveECDSAsig) {
00637         #ifdef CYASSL_SHA384
00638             suites->hashSigAlgo[idx++] = sha384_mac;
00639             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
00640         #endif
00641         #ifndef NO_SHA256
00642             suites->hashSigAlgo[idx++] = sha256_mac;
00643             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
00644         #endif
00645         #ifndef NO_SHA
00646             suites->hashSigAlgo[idx++] = sha_mac;
00647             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
00648         #endif
00649     }
00650 
00651     if (haveRSAsig) {
00652         #ifdef CYASSL_SHA384
00653             suites->hashSigAlgo[idx++] = sha384_mac;
00654             suites->hashSigAlgo[idx++] = rsa_sa_algo;
00655         #endif
00656         #ifndef NO_SHA256
00657             suites->hashSigAlgo[idx++] = sha256_mac;
00658             suites->hashSigAlgo[idx++] = rsa_sa_algo;
00659         #endif
00660         #ifndef NO_SHA
00661             suites->hashSigAlgo[idx++] = sha_mac;
00662             suites->hashSigAlgo[idx++] = rsa_sa_algo;
00663         #endif
00664     }
00665 
00666     if (haveAnon) {
00667         #ifdef HAVE_ANON
00668             suites->hashSigAlgo[idx++] = sha_mac;
00669             suites->hashSigAlgo[idx++] = anonymous_sa_algo;
00670         #endif
00671     }
00672 
00673     suites->hashSigAlgoSz = (word16)idx;
00674 }
00675 
00676 void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK,
00677                 byte haveDH, byte haveNTRU, byte haveECDSAsig,
00678                 byte haveStaticECC, int side)
00679 {
00680     word16 idx = 0;
00681     int    tls    = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
00682     int    tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
00683     int    haveRSAsig = 1;
00684 
00685     (void)tls;  /* shut up compiler */
00686     (void)tls1_2;
00687     (void)haveDH;
00688     (void)havePSK;
00689     (void)haveNTRU;
00690     (void)haveStaticECC;
00691 
00692     if (suites == NULL) {
00693         CYASSL_MSG("InitSuites pointer error");
00694         return;
00695     }
00696 
00697     if (suites->setSuites)
00698         return;      /* trust user settings, don't override */
00699 
00700     if (side == CYASSL_SERVER_END && haveStaticECC) {
00701         haveRSA = 0;   /* can't do RSA with ECDSA key */
00702         (void)haveRSA; /* some builds won't read */
00703     }
00704 
00705     if (side == CYASSL_SERVER_END && haveECDSAsig) {
00706         haveRSAsig = 0;     /* can't have RSA sig if signed by ECDSA */
00707         (void)haveRSAsig;   /* non ecc builds won't read */
00708     }
00709 
00710 #ifdef CYASSL_DTLS
00711     if (pv.major == DTLS_MAJOR) {
00712         tls    = 1;
00713         tls1_2 = pv.minor <= DTLSv1_2_MINOR;
00714     }
00715 #endif
00716 
00717 #ifdef HAVE_RENEGOTIATION_INDICATION
00718     if (side == CYASSL_CLIENT_END) {
00719         suites->suites[idx++] = 0;
00720         suites->suites[idx++] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
00721     }
00722 #endif
00723 
00724 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
00725     if (tls && haveNTRU && haveRSA) {
00726         suites->suites[idx++] = 0;
00727         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
00728     }
00729 #endif
00730 
00731 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
00732     if (tls && haveNTRU && haveRSA) {
00733         suites->suites[idx++] = 0;
00734         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
00735     }
00736 #endif
00737 
00738 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
00739     if (tls && haveNTRU && haveRSA) {
00740         suites->suites[idx++] = 0;
00741         suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
00742     }
00743 #endif
00744 
00745 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
00746     if (tls && haveNTRU && haveRSA) {
00747         suites->suites[idx++] = 0;
00748         suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
00749     }
00750 #endif
00751 
00752 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
00753     if (tls1_2 && haveRSAsig) {
00754         suites->suites[idx++] = ECC_BYTE;
00755         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
00756     }
00757 #endif
00758 
00759 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
00760     if (tls1_2 && haveECDSAsig) {
00761         suites->suites[idx++] = ECC_BYTE;
00762         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
00763     }
00764 #endif
00765 
00766 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
00767     if (tls1_2 && haveRSAsig && haveStaticECC) {
00768         suites->suites[idx++] = ECC_BYTE;
00769         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
00770     }
00771 #endif
00772 
00773 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
00774     if (tls1_2 && haveECDSAsig && haveStaticECC) {
00775         suites->suites[idx++] = ECC_BYTE;
00776         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
00777     }
00778 #endif
00779 
00780 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
00781     if (tls1_2 && haveRSAsig) {
00782         suites->suites[idx++] = ECC_BYTE;
00783         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
00784     }
00785 #endif
00786 
00787 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
00788     if (tls1_2 && haveECDSAsig) {
00789         suites->suites[idx++] = ECC_BYTE;
00790         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
00791     }
00792 #endif
00793 
00794 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
00795     if (tls1_2 && haveRSAsig && haveStaticECC) {
00796         suites->suites[idx++] = ECC_BYTE;
00797         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
00798     }
00799 #endif
00800 
00801 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
00802     if (tls1_2 && haveECDSAsig && haveStaticECC) {
00803         suites->suites[idx++] = ECC_BYTE;
00804         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
00805     }
00806 #endif
00807 
00808 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
00809     if (tls1_2 && haveECDSAsig) {
00810         suites->suites[idx++] = ECC_BYTE;
00811         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
00812     }
00813 #endif
00814 
00815 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
00816     if (tls && haveECDSAsig) {
00817         suites->suites[idx++] = ECC_BYTE;
00818         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
00819     }
00820 #endif
00821 
00822 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
00823     if (tls1_2 && haveECDSAsig && haveStaticECC) {
00824         suites->suites[idx++] = ECC_BYTE;
00825         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
00826     }
00827 #endif
00828 
00829 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
00830     if (tls && haveECDSAsig && haveStaticECC) {
00831         suites->suites[idx++] = ECC_BYTE;
00832         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
00833     }
00834 #endif
00835 
00836 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
00837     if (tls1_2 && haveECDSAsig) {
00838         suites->suites[idx++] = ECC_BYTE;
00839         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
00840     }
00841 #endif
00842 
00843 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
00844     if (tls && haveECDSAsig) {
00845         suites->suites[idx++] = ECC_BYTE;
00846         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
00847     }
00848 #endif
00849 
00850 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
00851     if (tls1_2 && haveECDSAsig && haveStaticECC) {
00852         suites->suites[idx++] = ECC_BYTE;
00853         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
00854     }
00855 #endif
00856 
00857 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
00858     if (tls && haveECDSAsig && haveStaticECC) {
00859         suites->suites[idx++] = ECC_BYTE;
00860         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
00861     }
00862 #endif
00863 
00864 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
00865     if (tls && haveECDSAsig) {
00866         suites->suites[idx++] = ECC_BYTE;
00867         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
00868     }
00869 #endif
00870 
00871 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
00872     if (tls && haveECDSAsig && haveStaticECC) {
00873         suites->suites[idx++] = ECC_BYTE;
00874         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
00875     }
00876 #endif
00877 
00878 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
00879     if (tls && haveECDSAsig) {
00880         suites->suites[idx++] = ECC_BYTE;
00881         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
00882     }
00883 #endif
00884 
00885 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
00886     if (tls && haveECDSAsig && haveStaticECC) {
00887         suites->suites[idx++] = ECC_BYTE;
00888         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
00889     }
00890 #endif
00891 
00892 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
00893     if (tls1_2 && haveRSA) {
00894         suites->suites[idx++] = ECC_BYTE;
00895         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
00896     }
00897 #endif
00898 
00899 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
00900     if (tls && haveRSA) {
00901         suites->suites[idx++] = ECC_BYTE;
00902         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
00903     }
00904 #endif
00905 
00906 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
00907     if (tls1_2 && haveRSAsig && haveStaticECC) {
00908         suites->suites[idx++] = ECC_BYTE;
00909         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
00910     }
00911 #endif
00912 
00913 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
00914     if (tls && haveRSAsig && haveStaticECC) {
00915         suites->suites[idx++] = ECC_BYTE;
00916         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
00917     }
00918 #endif
00919 
00920 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
00921     if (tls1_2 && haveRSA) {
00922         suites->suites[idx++] = ECC_BYTE;
00923         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
00924     }
00925 #endif
00926 
00927 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
00928     if (tls && haveRSA) {
00929         suites->suites[idx++] = ECC_BYTE;
00930         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
00931     }
00932 #endif
00933 
00934 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
00935     if (tls1_2 && haveRSAsig && haveStaticECC) {
00936         suites->suites[idx++] = ECC_BYTE;
00937         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
00938     }
00939 #endif
00940 
00941 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
00942     if (tls && haveRSAsig && haveStaticECC) {
00943         suites->suites[idx++] = ECC_BYTE;
00944         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
00945     }
00946 #endif
00947 
00948 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
00949     if (tls && haveRSA) {
00950         suites->suites[idx++] = ECC_BYTE;
00951         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
00952     }
00953 #endif
00954 
00955 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
00956     if (tls && haveRSAsig && haveStaticECC) {
00957         suites->suites[idx++] = ECC_BYTE;
00958         suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
00959     }
00960 #endif
00961 
00962 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
00963     if (tls && haveRSA) {
00964         suites->suites[idx++] = ECC_BYTE;
00965         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
00966     }
00967 #endif
00968 
00969 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
00970     if (tls && haveRSA) {
00971         suites->suites[idx++] = CHACHA_BYTE;
00972         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
00973     }
00974 #endif
00975 
00976 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
00977     if (tls1_2 && haveECDSAsig) {
00978         suites->suites[idx++] = CHACHA_BYTE;
00979         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
00980     }
00981 #endif
00982 
00983 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
00984     if (tls && haveRSA) {
00985         suites->suites[idx++] = CHACHA_BYTE;
00986         suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
00987     }
00988 #endif
00989 
00990 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
00991     if (tls && haveRSAsig && haveStaticECC) {
00992         suites->suites[idx++] = ECC_BYTE;
00993         suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
00994     }
00995 #endif
00996 
00997 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
00998     if (tls1_2 && haveDH && haveRSA) {
00999         suites->suites[idx++] = 0;
01000         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
01001     }
01002 #endif
01003 
01004 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
01005     if (tls1_2 && haveECDSAsig) {
01006         suites->suites[idx++] = ECC_BYTE;
01007         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
01008     }
01009 #endif
01010 
01011 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
01012     if (tls1_2 && haveECDSAsig) {
01013         suites->suites[idx++] = ECC_BYTE;
01014         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
01015     }
01016 #endif
01017 
01018 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
01019     if (tls1_2 && haveRSA) {
01020         suites->suites[idx++] = ECC_BYTE;
01021         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
01022     }
01023 #endif
01024 
01025 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
01026     if (tls1_2 && haveRSA) {
01027         suites->suites[idx++] = ECC_BYTE;
01028         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
01029     }
01030 #endif
01031 
01032 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
01033     if (tls1_2 && haveDH && haveRSA) {
01034         suites->suites[idx++] = 0;
01035         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
01036     }
01037 #endif
01038 
01039 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
01040     if (tls1_2 && haveDH && haveRSA) {
01041         suites->suites[idx++] = 0;
01042         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
01043     }
01044 #endif
01045 
01046 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
01047     if (tls1_2 && haveDH && haveRSA) {
01048         suites->suites[idx++] = 0;
01049         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
01050     }
01051 #endif
01052 
01053 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
01054     if (tls && haveDH && haveRSA) {
01055         suites->suites[idx++] = 0;
01056         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
01057     }
01058 #endif
01059 
01060 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
01061     if (tls && haveDH && haveRSA) {
01062         suites->suites[idx++] = 0;
01063         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
01064     }
01065 #endif
01066 
01067 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
01068     if (tls1_2 && haveRSA) {
01069         suites->suites[idx++] = 0;
01070         suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
01071     }
01072 #endif
01073 
01074 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
01075     if (tls1_2 && haveRSA) {
01076         suites->suites[idx++] = 0;
01077         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
01078     }
01079 #endif
01080 
01081 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
01082     if (tls1_2 && haveRSA) {
01083         suites->suites[idx++] = 0;
01084         suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
01085     }
01086 #endif
01087 
01088 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
01089     if (tls1_2 && haveRSA) {
01090         suites->suites[idx++] = 0;
01091         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
01092     }
01093 #endif
01094 
01095 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
01096     if (tls && haveRSA) {
01097         suites->suites[idx++] = 0;
01098         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
01099     }
01100 #endif
01101 
01102 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
01103     if (tls && haveRSA) {
01104         suites->suites[idx++] = 0;
01105         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
01106     }
01107 #endif
01108 
01109 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
01110     if (tls && haveRSA) {
01111         suites->suites[idx++] = 0;
01112         suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
01113     }
01114 #endif
01115 
01116 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
01117     if (tls && haveRSA) {
01118         suites->suites[idx++] = 0;
01119         suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
01120     }
01121 #endif
01122 
01123 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
01124     if (tls1_2 && haveDH && havePSK) {
01125         suites->suites[idx++] = 0;
01126         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
01127     }
01128 #endif
01129 
01130 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
01131     if (tls1_2 && havePSK) {
01132         suites->suites[idx++] = 0;
01133         suites->suites[idx++] = TLS_PSK_WITH_AES_256_GCM_SHA384;
01134     }
01135 #endif
01136 
01137 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
01138     if (tls && havePSK) {
01139         suites->suites[idx++] = 0;
01140         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
01141     }
01142 #endif
01143 
01144 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
01145     if (tls && haveDH && havePSK) {
01146         suites->suites[idx++] = 0;
01147         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384;
01148     }
01149 #endif
01150 
01151 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
01152     if (tls && havePSK) {
01153         suites->suites[idx++] = 0;
01154         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384;
01155     }
01156 #endif
01157 
01158 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
01159     if (tls1_2 && haveDH && havePSK) {
01160         suites->suites[idx++] = 0;
01161         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
01162     }
01163 #endif
01164 
01165 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
01166     if (tls1_2 && havePSK) {
01167         suites->suites[idx++] = 0;
01168         suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256;
01169     }
01170 #endif
01171 
01172 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
01173     if (tls && haveDH && havePSK) {
01174         suites->suites[idx++] = 0;
01175         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256;
01176     }
01177 #endif
01178 
01179 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
01180     if (tls && havePSK) {
01181         suites->suites[idx++] = 0;
01182         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
01183     }
01184 #endif
01185 
01186 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
01187     if (tls && havePSK) {
01188         suites->suites[idx++] = 0;
01189         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
01190     }
01191 #endif
01192 
01193 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
01194     if (tls && haveDH && havePSK) {
01195         suites->suites[idx++] = ECC_BYTE;
01196         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM;
01197     }
01198 #endif
01199 
01200 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
01201     if (tls && haveDH && havePSK) {
01202         suites->suites[idx++] = ECC_BYTE;
01203         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CCM;
01204     }
01205 #endif
01206 
01207 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
01208     if (tls && havePSK) {
01209         suites->suites[idx++] = ECC_BYTE;
01210         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM;
01211     }
01212 #endif
01213 
01214 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
01215     if (tls && havePSK) {
01216         suites->suites[idx++] = ECC_BYTE;
01217         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM;
01218     }
01219 #endif
01220 
01221 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
01222     if (tls && havePSK) {
01223         suites->suites[idx++] = ECC_BYTE;
01224         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
01225     }
01226 #endif
01227 
01228 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
01229     if (tls && havePSK) {
01230         suites->suites[idx++] = ECC_BYTE;
01231         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
01232     }
01233 #endif
01234 
01235 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
01236     if (tls && haveDH && havePSK) {
01237         suites->suites[idx++] = 0;
01238         suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384;
01239     }
01240 #endif
01241 
01242 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
01243     if (tls && havePSK) {
01244         suites->suites[idx++] = 0;
01245         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384;
01246     }
01247 #endif
01248 
01249 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
01250     if (tls && haveDH && havePSK) {
01251         suites->suites[idx++] = 0;
01252         suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256;
01253     }
01254 #endif
01255 
01256 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
01257     if (tls && havePSK) {
01258         suites->suites[idx++] = 0;
01259         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
01260     }
01261 #endif
01262 
01263 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
01264     if (tls && havePSK) {
01265         suites->suites[idx++] = 0;
01266         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
01267     }
01268 #endif
01269 
01270 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
01271     if (haveRSA ) {
01272         suites->suites[idx++] = 0;
01273         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
01274     }
01275 #endif
01276 
01277 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
01278     if (haveRSA ) {
01279         suites->suites[idx++] = 0;
01280         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
01281     }
01282 #endif
01283 
01284 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
01285     if (haveRSA ) {
01286         suites->suites[idx++] = 0;
01287         suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
01288     }
01289 #endif
01290 
01291 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
01292     if (tls && haveRSA) {
01293         suites->suites[idx++] = 0;
01294         suites->suites[idx++] = TLS_RSA_WITH_HC_128_MD5;
01295     }
01296 #endif
01297 
01298 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
01299     if (tls && haveRSA) {
01300         suites->suites[idx++] = 0;
01301         suites->suites[idx++] = TLS_RSA_WITH_HC_128_SHA;
01302     }
01303 #endif
01304 
01305 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
01306     if (tls && haveRSA) {
01307         suites->suites[idx++] = 0;
01308         suites->suites[idx++] = TLS_RSA_WITH_HC_128_B2B256;
01309     }
01310 #endif
01311 
01312 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
01313     if (tls && haveRSA) {
01314         suites->suites[idx++] = 0;
01315         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_B2B256;
01316     }
01317 #endif
01318 
01319 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
01320     if (tls && haveRSA) {
01321         suites->suites[idx++] = 0;
01322         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_B2B256;
01323     }
01324 #endif
01325 
01326 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
01327     if (tls && haveRSA) {
01328         suites->suites[idx++] = 0;
01329         suites->suites[idx++] = TLS_RSA_WITH_RABBIT_SHA;
01330     }
01331 #endif
01332 
01333 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
01334     if (tls && haveRSA) {
01335         suites->suites[idx++] = 0;
01336         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
01337     }
01338 #endif
01339 
01340 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
01341     if (tls && haveDH && haveRSA) {
01342         suites->suites[idx++] = 0;
01343         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
01344     }
01345 #endif
01346 
01347 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
01348     if (tls && haveRSA) {
01349         suites->suites[idx++] = 0;
01350         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
01351     }
01352 #endif
01353 
01354 #ifdef BUILD_TLS_DHE_WITH_RSA_CAMELLIA_256_CBC_SHA
01355     if (tls && haveDH && haveRSA) {
01356         suites->suites[idx++] = 0;
01357         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
01358     }
01359 #endif
01360 
01361 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
01362     if (tls && haveRSA) {
01363         suites->suites[idx++] = 0;
01364         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
01365     }
01366 #endif
01367 
01368 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
01369     if (tls && haveDH && haveRSA) {
01370         suites->suites[idx++] = 0;
01371         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
01372     }
01373 #endif
01374 
01375 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
01376     if (tls && haveRSA) {
01377         suites->suites[idx++] = 0;
01378         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
01379     }
01380 #endif
01381 
01382 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
01383     if (tls && haveDH && haveRSA) {
01384         suites->suites[idx++] = 0;
01385         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
01386     }
01387 #endif
01388 
01389     suites->suiteSz = idx;
01390 
01391     InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0);
01392 }
01393 
01394 
01395 #ifndef NO_CERTS
01396 
01397 
01398 void InitX509Name(CYASSL_X509_NAME* name, int dynamicFlag)
01399 {
01400     (void)dynamicFlag;
01401 
01402     if (name != NULL) {
01403         name->name        = name->staticName;
01404         name->dynamicName = 0;
01405 #ifdef OPENSSL_EXTRA
01406         XMEMSET(&name->fullName, 0, sizeof(DecodedName));
01407 #endif /* OPENSSL_EXTRA */
01408     }
01409 }
01410 
01411 
01412 void FreeX509Name(CYASSL_X509_NAME* name)
01413 {
01414     if (name != NULL) {
01415         if (name->dynamicName)
01416             XFREE(name->name, NULL, DYNAMIC_TYPE_SUBJECT_CN);
01417 #ifdef OPENSSL_EXTRA
01418         if (name->fullName.fullName != NULL)
01419             XFREE(name->fullName.fullName, NULL, DYNAMIC_TYPE_X509);
01420 #endif /* OPENSSL_EXTRA */
01421     }
01422 }
01423 
01424 
01425 /* Initialize CyaSSL X509 type */
01426 void InitX509(CYASSL_X509* x509, int dynamicFlag)
01427 {
01428     InitX509Name(&x509->issuer, 0);
01429     InitX509Name(&x509->subject, 0);
01430     x509->version        = 0;
01431     x509->pubKey.buffer  = NULL;
01432     x509->sig.buffer     = NULL;
01433     x509->derCert.buffer = NULL;
01434     x509->altNames       = NULL;
01435     x509->altNamesNext   = NULL;
01436     x509->dynamicMemory  = (byte)dynamicFlag;
01437     x509->isCa           = 0;
01438 #ifdef HAVE_ECC
01439     x509->pkCurveOID = 0;
01440 #endif /* HAVE_ECC */
01441 #ifdef OPENSSL_EXTRA
01442     x509->pathLength     = 0;
01443     x509->basicConstSet  = 0;
01444     x509->basicConstCrit = 0;
01445     x509->basicConstPlSet = 0;
01446     x509->subjAltNameSet = 0;
01447     x509->subjAltNameCrit = 0;
01448     x509->authKeyIdSet   = 0;
01449     x509->authKeyIdCrit  = 0;
01450     x509->authKeyId      = NULL;
01451     x509->authKeyIdSz    = 0;
01452     x509->subjKeyIdSet   = 0;
01453     x509->subjKeyIdCrit  = 0;
01454     x509->subjKeyId      = NULL;
01455     x509->subjKeyIdSz    = 0;
01456     x509->keyUsageSet    = 0;
01457     x509->keyUsageCrit   = 0;
01458     x509->keyUsage       = 0;
01459     #ifdef CYASSL_SEP
01460         x509->certPolicySet  = 0;
01461         x509->certPolicyCrit = 0;
01462     #endif /* CYASSL_SEP */
01463 #endif /* OPENSSL_EXTRA */
01464 }
01465 
01466 
01467 /* Free CyaSSL X509 type */
01468 void FreeX509(CYASSL_X509* x509)
01469 {
01470     if (x509 == NULL)
01471         return;
01472 
01473     FreeX509Name(&x509->issuer);
01474     FreeX509Name(&x509->subject);
01475     if (x509->pubKey.buffer)
01476         XFREE(x509->pubKey.buffer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
01477     XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_SUBJECT_CN);
01478     XFREE(x509->sig.buffer, NULL, DYNAMIC_TYPE_SIGNATURE);
01479     #ifdef OPENSSL_EXTRA
01480         XFREE(x509->authKeyId, NULL, 0);
01481         XFREE(x509->subjKeyId, NULL, 0);
01482     #endif /* OPENSSL_EXTRA */
01483     if (x509->altNames)
01484         FreeAltNames(x509->altNames, NULL);
01485     if (x509->dynamicMemory)
01486         XFREE(x509, NULL, DYNAMIC_TYPE_X509);
01487 }
01488 
01489 #endif /* NO_CERTS */
01490 
01491 
01492 /* init everything to 0, NULL, default values before calling anything that may
01493    fail so that desctructor has a "good" state to cleanup */
01494 int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
01495 {
01496     int  ret;
01497     byte haveRSA = 0;
01498     byte havePSK = 0;
01499     byte haveAnon = 0;
01500 
01501     ssl->ctx     = ctx; /* only for passing to calls, options could change */
01502     ssl->version = ctx->method->version;
01503     ssl->suites  = NULL;
01504 
01505 #ifdef HAVE_LIBZ
01506     ssl->didStreamInit = 0;
01507 #endif
01508 #ifndef NO_RSA
01509     haveRSA = 1;
01510 #endif
01511 
01512 #ifndef NO_CERTS
01513     ssl->buffers.certificate.buffer   = 0;
01514     ssl->buffers.key.buffer           = 0;
01515     ssl->buffers.certChain.buffer     = 0;
01516 #endif
01517     ssl->buffers.inputBuffer.length   = 0;
01518     ssl->buffers.inputBuffer.idx      = 0;
01519     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
01520     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
01521     ssl->buffers.inputBuffer.dynamicFlag = 0;
01522     ssl->buffers.inputBuffer.offset   = 0;
01523     ssl->buffers.outputBuffer.length  = 0;
01524     ssl->buffers.outputBuffer.idx     = 0;
01525     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
01526     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
01527     ssl->buffers.outputBuffer.dynamicFlag = 0;
01528     ssl->buffers.outputBuffer.offset      = 0;
01529     ssl->buffers.domainName.buffer    = 0;
01530 #ifndef NO_CERTS
01531     ssl->buffers.serverDH_P.buffer    = 0;
01532     ssl->buffers.serverDH_G.buffer    = 0;
01533     ssl->buffers.serverDH_Pub.buffer  = 0;
01534     ssl->buffers.serverDH_Priv.buffer = 0;
01535 #endif
01536     ssl->buffers.clearOutputBuffer.buffer  = 0;
01537     ssl->buffers.clearOutputBuffer.length  = 0;
01538     ssl->buffers.prevSent                  = 0;
01539     ssl->buffers.plainSz                   = 0;
01540 #ifdef HAVE_PK_CALLBACKS
01541     #ifdef HAVE_ECC
01542         ssl->buffers.peerEccDsaKey.buffer = 0;
01543         ssl->buffers.peerEccDsaKey.length = 0;
01544     #endif /* HAVE_ECC */
01545     #ifndef NO_RSA
01546         ssl->buffers.peerRsaKey.buffer = 0;
01547         ssl->buffers.peerRsaKey.length = 0;
01548     #endif /* NO_RSA */
01549 #endif /* HAVE_PK_CALLBACKS */
01550 
01551 #ifdef KEEP_PEER_CERT
01552     InitX509(&ssl->peerCert, 0);
01553 #endif
01554 
01555 #ifdef HAVE_ECC
01556     ssl->eccTempKeySz = ctx->eccTempKeySz;
01557     ssl->pkCurveOID = ctx->pkCurveOID;
01558     ssl->peerEccKeyPresent = 0;
01559     ssl->peerEccDsaKeyPresent = 0;
01560     ssl->eccDsaKeyPresent = 0;
01561     ssl->eccTempKeyPresent = 0;
01562     ssl->peerEccKey = NULL;
01563     ssl->peerEccDsaKey = NULL;
01564     ssl->eccDsaKey = NULL;
01565     ssl->eccTempKey = NULL;
01566 #endif
01567 
01568     ssl->timeout = ctx->timeout;
01569     ssl->rfd = -1;   /* set to invalid descriptor */
01570     ssl->wfd = -1;
01571     ssl->rflags = 0;    /* no user flags yet */
01572     ssl->wflags = 0;    /* no user flags yet */
01573     ssl->biord = 0;
01574     ssl->biowr = 0;
01575 
01576     ssl->IOCB_ReadCtx  = &ssl->rfd;  /* prevent invalid pointer access if not */
01577     ssl->IOCB_WriteCtx = &ssl->wfd;  /* correctly set */
01578 #ifdef HAVE_NETX
01579     ssl->nxCtx.nxSocket = NULL;
01580     ssl->nxCtx.nxPacket = NULL;
01581     ssl->nxCtx.nxOffset = 0;
01582     ssl->nxCtx.nxWait   = 0;
01583     ssl->IOCB_ReadCtx  = &ssl->nxCtx;  /* default NetX IO ctx, same for read */
01584     ssl->IOCB_WriteCtx = &ssl->nxCtx;  /* and write */
01585 #endif
01586 #ifdef CYASSL_DTLS
01587     ssl->IOCB_CookieCtx = NULL;      /* we don't use for default cb */
01588     ssl->dtls_expected_rx = MAX_MTU;
01589     ssl->keys.dtls_state.window = 0;
01590     ssl->keys.dtls_state.nextEpoch = 0;
01591     ssl->keys.dtls_state.nextSeq = 0;
01592 #endif
01593 
01594     XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
01595 
01596 #ifndef NO_RSA
01597     ssl->peerRsaKey = NULL;
01598     ssl->peerRsaKeyPresent = 0;
01599 #endif
01600     ssl->verifyCallback    = ctx->verifyCallback;
01601     ssl->verifyCbCtx       = NULL;
01602     ssl->options.side      = ctx->method->side;
01603     ssl->options.downgrade    = ctx->method->downgrade;
01604     ssl->options.minDowngrade = TLSv1_MINOR;     /* current default */
01605     ssl->error = 0;
01606     ssl->options.connReset = 0;
01607     ssl->options.isClosed  = 0;
01608     ssl->options.closeNotify  = 0;
01609     ssl->options.sentNotify   = 0;
01610     ssl->options.usingCompression = 0;
01611     if (ssl->options.side == CYASSL_SERVER_END)
01612         ssl->options.haveDH = ctx->haveDH;
01613     else
01614         ssl->options.haveDH = 0;
01615     ssl->options.haveNTRU      = ctx->haveNTRU;
01616     ssl->options.haveECDSAsig  = ctx->haveECDSAsig;
01617     ssl->options.haveStaticECC = ctx->haveStaticECC;
01618     ssl->options.havePeerCert    = 0;
01619     ssl->options.havePeerVerify  = 0;
01620     ssl->options.usingPSK_cipher = 0;
01621     ssl->options.usingAnon_cipher = 0;
01622     ssl->options.sendAlertState = 0;
01623 #ifndef NO_PSK
01624     havePSK = ctx->havePSK;
01625     ssl->options.havePSK   = ctx->havePSK;
01626     ssl->options.client_psk_cb = ctx->client_psk_cb;
01627     ssl->options.server_psk_cb = ctx->server_psk_cb;
01628 #endif /* NO_PSK */
01629 #ifdef HAVE_ANON
01630     haveAnon = ctx->haveAnon;
01631     ssl->options.haveAnon = ctx->haveAnon;
01632 #endif
01633 
01634     ssl->options.serverState = NULL_STATE;
01635     ssl->options.clientState = NULL_STATE;
01636     ssl->options.connectState = CONNECT_BEGIN;
01637     ssl->options.acceptState  = ACCEPT_BEGIN;
01638     ssl->options.handShakeState  = NULL_STATE;
01639     ssl->options.handShakeDone   = 0;
01640     ssl->options.processReply = doProcessInit;
01641 
01642 #ifdef CYASSL_DTLS
01643     ssl->keys.dtls_sequence_number      = 0;
01644     ssl->keys.dtls_state.curSeq         = 0;
01645     ssl->keys.dtls_state.nextSeq        = 0;
01646     ssl->keys.dtls_handshake_number     = 0;
01647     ssl->keys.dtls_expected_peer_handshake_number = 0;
01648     ssl->keys.dtls_epoch                = 0;
01649     ssl->keys.dtls_state.curEpoch       = 0;
01650     ssl->keys.dtls_state.nextEpoch      = 0;
01651     ssl->dtls_timeout_init              = DTLS_TIMEOUT_INIT;
01652     ssl->dtls_timeout_max               = DTLS_TIMEOUT_MAX;
01653     ssl->dtls_timeout                   = ssl->dtls_timeout_init;
01654     ssl->dtls_pool                      = NULL;
01655     ssl->dtls_msg_list                  = NULL;
01656 #endif
01657     ssl->keys.encryptSz    = 0;
01658     ssl->keys.padSz        = 0;
01659     ssl->keys.encryptionOn = 0;     /* initially off */
01660     ssl->keys.decryptedCur = 0;     /* initially off */
01661     ssl->options.sessionCacheOff      = ctx->sessionCacheOff;
01662     ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
01663 
01664     ssl->options.verifyPeer = ctx->verifyPeer;
01665     ssl->options.verifyNone = ctx->verifyNone;
01666     ssl->options.failNoCert = ctx->failNoCert;
01667     ssl->options.sendVerify = ctx->sendVerify;
01668 
01669     ssl->options.resuming = 0;
01670     ssl->options.haveSessionId = 0;
01671     #ifndef NO_OLD_TLS
01672         ssl->hmac = SSL_hmac; /* default to SSLv3 */
01673     #else
01674         ssl->hmac = TLS_hmac;
01675     #endif
01676     ssl->heap = ctx->heap;    /* defaults to self */
01677     ssl->options.tls    = 0;
01678     ssl->options.tls1_1 = 0;
01679     ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
01680     ssl->options.partialWrite  = ctx->partialWrite;
01681     ssl->options.quietShutdown = ctx->quietShutdown;
01682     ssl->options.certOnly = 0;
01683     ssl->options.groupMessages = ctx->groupMessages;
01684     ssl->options.usingNonblock = 0;
01685     ssl->options.saveArrays = 0;
01686 #ifdef HAVE_POLY1305
01687     ssl->options.oldPoly = 0;
01688 #endif
01689 
01690 #ifndef NO_CERTS
01691     /* ctx still owns certificate, certChain, key, dh, and cm */
01692     ssl->buffers.certificate = ctx->certificate;
01693     ssl->buffers.certChain = ctx->certChain;
01694     ssl->buffers.key = ctx->privateKey;
01695     if (ssl->options.side == CYASSL_SERVER_END) {
01696         ssl->buffers.serverDH_P = ctx->serverDH_P;
01697         ssl->buffers.serverDH_G = ctx->serverDH_G;
01698     }
01699 #endif
01700     ssl->buffers.weOwnCert      = 0;
01701     ssl->buffers.weOwnCertChain = 0;
01702     ssl->buffers.weOwnKey       = 0;
01703     ssl->buffers.weOwnDH        = 0;
01704 
01705 #ifdef CYASSL_DTLS
01706     ssl->buffers.dtlsCtx.fd = -1;
01707     ssl->buffers.dtlsCtx.peer.sa = NULL;
01708     ssl->buffers.dtlsCtx.peer.sz = 0;
01709 #endif
01710 
01711 #ifdef KEEP_PEER_CERT
01712     ssl->peerCert.issuer.sz    = 0;
01713     ssl->peerCert.subject.sz   = 0;
01714 #endif
01715 
01716 #ifdef SESSION_CERTS
01717     ssl->session.chain.count = 0;
01718 #endif
01719 
01720 #ifndef NO_CLIENT_CACHE
01721     ssl->session.idLen = 0;
01722 #endif
01723 
01724 #ifdef HAVE_SESSION_TICKET
01725     ssl->session.ticketLen = 0;
01726 #endif
01727 
01728     ssl->cipher.ssl = ssl;
01729 
01730 #ifdef FORTRESS
01731     ssl->ex_data[0] = 0;
01732     ssl->ex_data[1] = 0;
01733     ssl->ex_data[2] = 0;
01734 #endif
01735 
01736 #ifdef CYASSL_CALLBACKS
01737     ssl->hsInfoOn = 0;
01738     ssl->toInfoOn = 0;
01739 #endif
01740 
01741 #ifdef HAVE_CAVIUM
01742     ssl->devId = ctx->devId;
01743 #endif
01744 
01745 #ifdef HAVE_TLS_EXTENSIONS
01746     ssl->extensions = NULL;
01747 #ifdef HAVE_MAX_FRAGMENT
01748     ssl->max_fragment = MAX_RECORD_SIZE;
01749 #endif
01750 #ifdef HAVE_TRUNCATED_HMAC
01751     ssl->truncated_hmac = 0;
01752 #endif
01753 #ifdef HAVE_SECURE_RENEGOTIATION
01754     ssl->secure_renegotiation = NULL;
01755 #endif
01756 #if !defined(NO_CYASSL_CLIENT) && defined(HAVE_SESSION_TICKET)
01757     ssl->session_ticket_cb = NULL;
01758     ssl->session_ticket_ctx = NULL;
01759     ssl->expect_session_ticket = 0;
01760 #endif
01761 #endif
01762 
01763     ssl->rng    = NULL;
01764     ssl->arrays = NULL;
01765 
01766     /* default alert state (none) */
01767     ssl->alert_history.last_rx.code  = -1;
01768     ssl->alert_history.last_rx.level = -1;
01769     ssl->alert_history.last_tx.code  = -1;
01770     ssl->alert_history.last_tx.level = -1;
01771 
01772     InitCiphers(ssl);
01773     InitCipherSpecs(&ssl->specs);
01774 #ifdef ATOMIC_USER
01775     ssl->MacEncryptCtx    = NULL;
01776     ssl->DecryptVerifyCtx = NULL;
01777 #endif
01778 #ifdef HAVE_FUZZER
01779     ssl->fuzzerCb         = NULL;
01780     ssl->fuzzerCtx        = NULL;
01781 #endif
01782 #ifdef HAVE_PK_CALLBACKS
01783     #ifdef HAVE_ECC
01784         ssl->EccSignCtx   = NULL;
01785         ssl->EccVerifyCtx = NULL;
01786     #endif /* HAVE_ECC */
01787     #ifndef NO_RSA
01788         ssl->RsaSignCtx   = NULL;
01789         ssl->RsaVerifyCtx = NULL;
01790         ssl->RsaEncCtx    = NULL;
01791         ssl->RsaDecCtx    = NULL;
01792     #endif /* NO_RSA */
01793 #endif /* HAVE_PK_CALLBACKS */
01794 
01795     /* all done with init, now can return errors, call other stuff */
01796 
01797 #ifndef NO_OLD_TLS
01798 #ifndef NO_MD5
01799     InitMd5(&ssl->hashMd5);
01800 #endif
01801 #ifndef NO_SHA
01802     ret = InitSha(&ssl->hashSha);
01803     if (ret != 0) {
01804         return ret;
01805     }
01806 #endif
01807 #endif
01808 #ifndef NO_SHA256
01809     ret = InitSha256(&ssl->hashSha256);
01810     if (ret != 0) {
01811         return ret;
01812     }
01813 #endif
01814 #ifdef CYASSL_SHA384
01815     ret = InitSha384(&ssl->hashSha384);
01816     if (ret != 0) {
01817         return ret;
01818     }
01819 #endif
01820 
01821     /* increment CTX reference count */
01822     if (LockMutex(&ctx->countMutex) != 0) {
01823         CYASSL_MSG("Couldn't lock CTX count mutex");
01824         return BAD_MUTEX_E;
01825     }
01826     ctx->refCount++;
01827     UnLockMutex(&ctx->countMutex);
01828 
01829     /* arrays */
01830     ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
01831                                                            DYNAMIC_TYPE_ARRAYS);
01832     if (ssl->arrays == NULL) {
01833         CYASSL_MSG("Arrays Memory error");
01834         return MEMORY_E;
01835     }
01836     XMEMSET(ssl->arrays, 0, sizeof(Arrays));
01837 
01838 #ifndef NO_PSK
01839     ssl->arrays->client_identity[0] = 0;
01840     if (ctx->server_hint[0]) {   /* set in CTX */
01841         XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
01842         ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
01843     }
01844     else
01845         ssl->arrays->server_hint[0] = 0;
01846 #endif /* NO_PSK */
01847 
01848 #ifdef CYASSL_DTLS
01849     ssl->arrays->cookieSz = 0;
01850 #endif
01851 
01852     /* RNG */
01853     ssl->rng = (RNG*)XMALLOC(sizeof(RNG), ssl->heap, DYNAMIC_TYPE_RNG);
01854     if (ssl->rng == NULL) {
01855         CYASSL_MSG("RNG Memory error");
01856         return MEMORY_E;
01857     }
01858 
01859     if ( (ret = InitRng(ssl->rng)) != 0) {
01860         CYASSL_MSG("RNG Init error");
01861         return ret;
01862     }
01863 
01864     /* suites */
01865     ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
01866                                    DYNAMIC_TYPE_SUITES);
01867     if (ssl->suites == NULL) {
01868         CYASSL_MSG("Suites Memory error");
01869         return MEMORY_E;
01870     }
01871     *ssl->suites = ctx->suites;
01872 
01873     /* peer key */
01874 #ifndef NO_RSA
01875     ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey), ssl->heap,
01876                                        DYNAMIC_TYPE_RSA);
01877     if (ssl->peerRsaKey == NULL) {
01878         CYASSL_MSG("PeerRsaKey Memory error");
01879         return MEMORY_E;
01880     }
01881     ret = InitRsaKey(ssl->peerRsaKey, ctx->heap);
01882     if (ret != 0) return ret;
01883 #endif
01884 #ifndef NO_CERTS
01885     /* make sure server has cert and key unless using PSK or Anon */
01886     if (ssl->options.side == CYASSL_SERVER_END && !havePSK && !haveAnon)
01887         if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
01888             CYASSL_MSG("Server missing certificate and/or private key");
01889             return NO_PRIVATE_KEY;
01890         }
01891 #endif
01892 #ifdef HAVE_ECC
01893     ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
01894                                                    ctx->heap, DYNAMIC_TYPE_ECC);
01895     if (ssl->peerEccKey == NULL) {
01896         CYASSL_MSG("PeerEccKey Memory error");
01897         return MEMORY_E;
01898     }
01899     ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
01900                                                    ctx->heap, DYNAMIC_TYPE_ECC);
01901     if (ssl->peerEccDsaKey == NULL) {
01902         CYASSL_MSG("PeerEccDsaKey Memory error");
01903         return MEMORY_E;
01904     }
01905     ssl->eccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
01906                                                    ctx->heap, DYNAMIC_TYPE_ECC);
01907     if (ssl->eccDsaKey == NULL) {
01908         CYASSL_MSG("EccDsaKey Memory error");
01909         return MEMORY_E;
01910     }
01911     ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
01912                                                    ctx->heap, DYNAMIC_TYPE_ECC);
01913     if (ssl->eccTempKey == NULL) {
01914         CYASSL_MSG("EccTempKey Memory error");
01915         return MEMORY_E;
01916     }
01917     ecc_init(ssl->peerEccKey);
01918     ecc_init(ssl->peerEccDsaKey);
01919     ecc_init(ssl->eccDsaKey);
01920     ecc_init(ssl->eccTempKey);
01921 #endif
01922 #ifdef HAVE_SECRET_CALLBACK
01923     ssl->sessionSecretCb  = NULL;
01924     ssl->sessionSecretCtx = NULL;
01925 #endif
01926 
01927     /* make sure server has DH parms, and add PSK if there, add NTRU too */
01928     if (ssl->options.side == CYASSL_SERVER_END)
01929         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
01930                    ssl->options.haveDH, ssl->options.haveNTRU,
01931                    ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
01932                    ssl->options.side);
01933     else
01934         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
01935                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
01936                    ssl->options.haveStaticECC, ssl->options.side);
01937 
01938     return 0;
01939 }
01940 
01941 
01942 /* free use of temporary arrays */
01943 void FreeArrays(CYASSL* ssl, int keep)
01944 {
01945     if (ssl->arrays && keep) {
01946         /* keeps session id for user retrieval */
01947         XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
01948         ssl->session.sessionIDSz = ssl->arrays->sessionIDSz;
01949     }
01950     XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
01951     ssl->arrays = NULL;
01952 }
01953 
01954 
01955 /* In case holding SSL object in array and don't want to free actual ssl */
01956 void SSL_ResourceFree(CYASSL* ssl)
01957 {
01958     /* Note: any resources used during the handshake should be released in the
01959      * function FreeHandshakeResources(). Be careful with the special cases
01960      * like the RNG which may optionally be kept for the whole session. (For
01961      * example with the RNG, it isn't used beyond the handshake except when
01962      * using stream ciphers where it is retained. */
01963 
01964     FreeCiphers(ssl);
01965     FreeArrays(ssl, 0);
01966 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
01967     FreeRng(ssl->rng);
01968 #endif
01969     XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
01970     XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
01971     XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
01972 
01973 #ifndef NO_CERTS
01974     XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
01975     XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
01976     /* parameters (p,g) may be owned by ctx */
01977     if (ssl->buffers.weOwnDH || ssl->options.side == CYASSL_CLIENT_END) {
01978         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
01979         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
01980     }
01981 
01982     if (ssl->buffers.weOwnCert)
01983         XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
01984     if (ssl->buffers.weOwnCertChain)
01985         XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
01986     if (ssl->buffers.weOwnKey)
01987         XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
01988 #endif
01989 #ifndef NO_RSA
01990     if (ssl->peerRsaKey) {
01991         FreeRsaKey(ssl->peerRsaKey);
01992         XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
01993     }
01994 #endif
01995     if (ssl->buffers.inputBuffer.dynamicFlag)
01996         ShrinkInputBuffer(ssl, FORCED_FREE);
01997     if (ssl->buffers.outputBuffer.dynamicFlag)
01998         ShrinkOutputBuffer(ssl);
01999 #ifdef CYASSL_DTLS
02000     if (ssl->dtls_pool != NULL) {
02001         DtlsPoolReset(ssl);
02002         XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
02003     }
02004     if (ssl->dtls_msg_list != NULL) {
02005         DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
02006         ssl->dtls_msg_list = NULL;
02007     }
02008     XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
02009     ssl->buffers.dtlsCtx.peer.sa = NULL;
02010 #endif
02011 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
02012     FreeX509(&ssl->peerCert);
02013 #endif
02014 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
02015     CyaSSL_BIO_free(ssl->biord);
02016     if (ssl->biord != ssl->biowr)        /* in case same as write */
02017         CyaSSL_BIO_free(ssl->biowr);
02018 #endif
02019 #ifdef HAVE_LIBZ
02020     FreeStreams(ssl);
02021 #endif
02022 #ifdef HAVE_ECC
02023     if (ssl->peerEccKey) {
02024         if (ssl->peerEccKeyPresent)
02025             ecc_free(ssl->peerEccKey);
02026         XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
02027     }
02028     if (ssl->peerEccDsaKey) {
02029         if (ssl->peerEccDsaKeyPresent)
02030             ecc_free(ssl->peerEccDsaKey);
02031         XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
02032     }
02033     if (ssl->eccTempKey) {
02034         if (ssl->eccTempKeyPresent)
02035             ecc_free(ssl->eccTempKey);
02036         XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
02037     }
02038     if (ssl->eccDsaKey) {
02039         if (ssl->eccDsaKeyPresent)
02040             ecc_free(ssl->eccDsaKey);
02041         XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
02042     }
02043 #endif
02044 #ifdef HAVE_PK_CALLBACKS
02045     #ifdef HAVE_ECC
02046         XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
02047     #endif /* HAVE_ECC */
02048     #ifndef NO_RSA
02049         XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
02050     #endif /* NO_RSA */
02051 #endif /* HAVE_PK_CALLBACKS */
02052 #ifdef HAVE_TLS_EXTENSIONS
02053     TLSX_FreeAll(ssl->extensions);
02054 #endif
02055 #ifdef HAVE_NETX
02056     if (ssl->nxCtx.nxPacket)
02057         nx_packet_release(ssl->nxCtx.nxPacket);
02058 #endif
02059 }
02060 
02061 
02062 /* Free any handshake resources no longer needed */
02063 void FreeHandshakeResources(CYASSL* ssl)
02064 {
02065 
02066 #ifdef HAVE_SECURE_RENEGOTIATION
02067     if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
02068         CYASSL_MSG("Secure Renegotiation needs to retain handshake resources");
02069         return;
02070     }
02071 #endif
02072 
02073     /* input buffer */
02074     if (ssl->buffers.inputBuffer.dynamicFlag)
02075         ShrinkInputBuffer(ssl, NO_FORCED_FREE);
02076 
02077     /* suites */
02078     XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
02079     ssl->suites = NULL;
02080 
02081     /* RNG */
02082     if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
02083 #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
02084         FreeRng(ssl->rng);
02085 #endif
02086         XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
02087         ssl->rng = NULL;
02088     }
02089 
02090 #ifdef CYASSL_DTLS
02091     /* DTLS_POOL */
02092     if (ssl->options.dtls && ssl->dtls_pool != NULL) {
02093         DtlsPoolReset(ssl);
02094         XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
02095         ssl->dtls_pool = NULL;
02096     }
02097 #endif
02098 
02099     /* arrays */
02100     if (ssl->options.saveArrays)
02101         FreeArrays(ssl, 1);
02102 
02103 #ifndef NO_RSA
02104     /* peerRsaKey */
02105     if (ssl->peerRsaKey) {
02106         FreeRsaKey(ssl->peerRsaKey);
02107         XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
02108         ssl->peerRsaKey = NULL;
02109     }
02110 #endif
02111 
02112 #ifdef HAVE_ECC
02113     if (ssl->peerEccKey)
02114     {
02115         if (ssl->peerEccKeyPresent) {
02116             ecc_free(ssl->peerEccKey);
02117             ssl->peerEccKeyPresent = 0;
02118         }
02119         XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
02120         ssl->peerEccKey = NULL;
02121     }
02122     if (ssl->peerEccDsaKey)
02123     {
02124         if (ssl->peerEccDsaKeyPresent) {
02125             ecc_free(ssl->peerEccDsaKey);
02126             ssl->peerEccDsaKeyPresent = 0;
02127         }
02128         XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
02129         ssl->peerEccDsaKey = NULL;
02130     }
02131     if (ssl->eccTempKey)
02132     {
02133         if (ssl->eccTempKeyPresent) {
02134             ecc_free(ssl->eccTempKey);
02135             ssl->eccTempKeyPresent = 0;
02136         }
02137         XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
02138         ssl->eccTempKey = NULL;
02139     }
02140     if (ssl->eccDsaKey)
02141     {
02142         if (ssl->eccDsaKeyPresent) {
02143             ecc_free(ssl->eccDsaKey);
02144             ssl->eccDsaKeyPresent = 0;
02145         }
02146         XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
02147         ssl->eccDsaKey = NULL;
02148     }
02149 #endif
02150 #ifdef HAVE_PK_CALLBACKS
02151     #ifdef HAVE_ECC
02152         XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
02153         ssl->buffers.peerEccDsaKey.buffer = NULL;
02154     #endif /* HAVE_ECC */
02155     #ifndef NO_RSA
02156         XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
02157         ssl->buffers.peerRsaKey.buffer = NULL;
02158     #endif /* NO_RSA */
02159 #endif /* HAVE_PK_CALLBACKS */
02160 }
02161 
02162 
02163 void FreeSSL(CYASSL* ssl)
02164 {
02165     FreeSSL_Ctx(ssl->ctx);  /* will decrement and free underyling CTX if 0 */
02166     SSL_ResourceFree(ssl);
02167     XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
02168 }
02169 
02170 
02171 #ifdef CYASSL_DTLS
02172 
02173 int DtlsPoolInit(CYASSL* ssl)
02174 {
02175     if (ssl->dtls_pool == NULL) {
02176         DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
02177                                              ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
02178         if (pool == NULL) {
02179             CYASSL_MSG("DTLS Buffer Pool Memory error");
02180             return MEMORY_E;
02181         }
02182         else {
02183             int i;
02184 
02185             for (i = 0; i < DTLS_POOL_SZ; i++) {
02186                 pool->buf[i].length = 0;
02187                 pool->buf[i].buffer = NULL;
02188             }
02189             pool->used = 0;
02190             ssl->dtls_pool = pool;
02191         }
02192     }
02193     return 0;
02194 }
02195 
02196 
02197 int DtlsPoolSave(CYASSL* ssl, const byte *src, int sz)
02198 {
02199     DtlsPool *pool = ssl->dtls_pool;
02200     if (pool != NULL && pool->used < DTLS_POOL_SZ) {
02201         buffer *pBuf = &pool->buf[pool->used];
02202         pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
02203         if (pBuf->buffer == NULL) {
02204             CYASSL_MSG("DTLS Buffer Memory error");
02205             return MEMORY_ERROR;
02206         }
02207         XMEMCPY(pBuf->buffer, src, sz);
02208         pBuf->length = (word32)sz;
02209         pool->used++;
02210     }
02211     return 0;
02212 }
02213 
02214 
02215 void DtlsPoolReset(CYASSL* ssl)
02216 {
02217     DtlsPool *pool = ssl->dtls_pool;
02218     if (pool != NULL) {
02219         buffer *pBuf;
02220         int i, used;
02221 
02222         used = pool->used;
02223         for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) {
02224             XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
02225             pBuf->buffer = NULL;
02226             pBuf->length = 0;
02227         }
02228         pool->used = 0;
02229     }
02230     ssl->dtls_timeout = ssl->dtls_timeout_init;
02231 }
02232 
02233 
02234 int DtlsPoolTimeout(CYASSL* ssl)
02235 {
02236     int result = -1;
02237     if (ssl->dtls_timeout <  ssl->dtls_timeout_max) {
02238         ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
02239         result = 0;
02240     }
02241     return result;
02242 }
02243 
02244 
02245 int DtlsPoolSend(CYASSL* ssl)
02246 {
02247     int ret;
02248     DtlsPool *pool = ssl->dtls_pool;
02249 
02250     if (pool != NULL && pool->used > 0) {
02251         int i;
02252         for (i = 0; i < pool->used; i++) {
02253             int sendResult;
02254             buffer* buf = &pool->buf[i];
02255 
02256             DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
02257 
02258             word16 message_epoch;
02259             ato16(dtls->epoch, &message_epoch);
02260             if (message_epoch == ssl->keys.dtls_epoch) {
02261                 /* Increment record sequence number on retransmitted handshake
02262                  * messages */
02263                 c32to48(ssl->keys.dtls_sequence_number, dtls->sequence_number);
02264                 ssl->keys.dtls_sequence_number++;
02265             }
02266             else {
02267                 /* The Finished message is sent with the next epoch, keep its
02268                  * sequence number */
02269             }
02270 
02271             if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
02272                 return ret;
02273 
02274             XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
02275             ssl->buffers.outputBuffer.idx = 0;
02276             ssl->buffers.outputBuffer.length = buf->length;
02277 
02278             sendResult = SendBuffered(ssl);
02279             if (sendResult < 0) {
02280                 return sendResult;
02281             }
02282         }
02283     }
02284     return 0;
02285 }
02286 
02287 
02288 /* functions for managing DTLS datagram reordering */
02289 
02290 /* Need to allocate space for the handshake message header. The hashing
02291  * routines assume the message pointer is still within the buffer that
02292  * has the headers, and will include those headers in the hash. The store
02293  * routines need to take that into account as well. New will allocate
02294  * extra space for the headers. */
02295 DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
02296 {
02297     DtlsMsg* msg = NULL;
02298 
02299     msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
02300 
02301     if (msg != NULL) {
02302         msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
02303                                                      heap, DYNAMIC_TYPE_NONE);
02304         if (msg->buf != NULL) {
02305             msg->next = NULL;
02306             msg->seq = 0;
02307             msg->sz = sz;
02308             msg->fragSz = 0;
02309             msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
02310         }
02311         else {
02312             XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
02313             msg = NULL;
02314         }
02315     }
02316 
02317     return msg;
02318 }
02319 
02320 void DtlsMsgDelete(DtlsMsg* item, void* heap)
02321 {
02322     (void)heap;
02323 
02324     if (item != NULL) {
02325         if (item->buf != NULL)
02326             XFREE(item->buf, heap, DYNAMIC_TYPE_NONE);
02327         XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
02328     }
02329 }
02330 
02331 
02332 void DtlsMsgListDelete(DtlsMsg* head, void* heap)
02333 {
02334     DtlsMsg* next;
02335     while (head) {
02336         next = head->next;
02337         DtlsMsgDelete(head, heap);
02338         head = next;
02339     }
02340 }
02341 
02342 
02343 void DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
02344                                               word32 fragOffset, word32 fragSz)
02345 {
02346     if (msg != NULL && data != NULL && msg->fragSz <= msg->sz &&
02347                      fragOffset < msg->sz && (fragOffset + fragSz) <= msg->sz) {
02348 
02349         msg->seq = seq;
02350         msg->type = type;
02351         msg->fragSz += fragSz;
02352         /* If fragOffset is zero, this is either a full message that is out
02353          * of order, or the first fragment of a fragmented message. Copy the
02354          * handshake message header as well as the message data. */
02355         if (fragOffset == 0)
02356             XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
02357                                             fragSz + DTLS_HANDSHAKE_HEADER_SZ);
02358         else {
02359             /* If fragOffet is non-zero, this is an additional fragment that
02360              * needs to be copied to its location in the message buffer. Also
02361              * copy the total size of the message over the fragment size. The
02362              * hash routines look at a defragmented message if it had actually
02363              * come across as a single handshake message. */
02364             XMEMCPY(msg->msg + fragOffset, data, fragSz);
02365             c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
02366         }
02367     }
02368 }
02369 
02370 
02371 DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
02372 {
02373     while (head != NULL && head->seq != seq) {
02374         head = head->next;
02375     }
02376     return head;
02377 }
02378 
02379 
02380 DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
02381         word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
02382 {
02383 
02384     /* See if seq exists in the list. If it isn't in the list, make
02385      * a new item of size dataSz, copy fragSz bytes from data to msg->msg
02386      * starting at offset fragOffset, and add fragSz to msg->fragSz. If
02387      * the seq is in the list and it isn't full, copy fragSz bytes from
02388      * data to msg->msg starting at offset fragOffset, and add fragSz to
02389      * msg->fragSz. The new item should be inserted into the list in its
02390      * proper position.
02391      *
02392      * 1. Find seq in list, or where seq should go in list. If seq not in
02393      *    list, create new item and insert into list. Either case, keep
02394      *    pointer to item.
02395      * 2. If msg->fragSz + fragSz < sz, copy data to msg->msg at offset
02396      *    fragOffset. Add fragSz to msg->fragSz.
02397      */
02398 
02399     if (head != NULL) {
02400         DtlsMsg* cur = DtlsMsgFind(head, seq);
02401         if (cur == NULL) {
02402             cur = DtlsMsgNew(dataSz, heap);
02403             if (cur != NULL) {
02404                 DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
02405                 head = DtlsMsgInsert(head, cur);
02406             }
02407         }
02408         else {
02409             DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
02410         }
02411     }
02412     else {
02413         head = DtlsMsgNew(dataSz, heap);
02414         DtlsMsgSet(head, seq, data, type, fragOffset, fragSz);
02415     }
02416 
02417     return head;
02418 }
02419 
02420 
02421 /* DtlsMsgInsert() is an in-order insert. */
02422 DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
02423 {
02424     if (head == NULL || item->seq < head->seq) {
02425         item->next = head;
02426         head = item;
02427     }
02428     else if (head->next == NULL) {
02429         head->next = item;
02430     }
02431     else {
02432         DtlsMsg* cur = head->next;
02433         DtlsMsg* prev = head;
02434         while (cur) {
02435             if (item->seq < cur->seq) {
02436                 item->next = cur;
02437                 prev->next = item;
02438                 break;
02439             }
02440             prev = cur;
02441             cur = cur->next;
02442         }
02443         if (cur == NULL) {
02444             prev->next = item;
02445         }
02446     }
02447 
02448     return head;
02449 }
02450 
02451 #endif /* CYASSL_DTLS */
02452 
02453 #ifndef NO_OLD_TLS
02454 
02455 ProtocolVersion MakeSSLv3(void)
02456 {
02457     ProtocolVersion pv;
02458     pv.major = SSLv3_MAJOR;
02459     pv.minor = SSLv3_MINOR;
02460 
02461     return pv;
02462 }
02463 
02464 #endif /* NO_OLD_TLS */
02465 
02466 
02467 #ifdef CYASSL_DTLS
02468 
02469 ProtocolVersion MakeDTLSv1(void)
02470 {
02471     ProtocolVersion pv;
02472     pv.major = DTLS_MAJOR;
02473     pv.minor = DTLS_MINOR;
02474 
02475     return pv;
02476 }
02477 
02478 ProtocolVersion MakeDTLSv1_2(void)
02479 {
02480     ProtocolVersion pv;
02481     pv.major = DTLS_MAJOR;
02482     pv.minor = DTLSv1_2_MINOR;
02483 
02484     return pv;
02485 }
02486 
02487 #endif /* CYASSL_DTLS */
02488 
02489 
02490 
02491 
02492 #ifdef USE_WINDOWS_API
02493 
02494     word32 LowResTimer(void)
02495     {
02496         static int           init = 0;
02497         static LARGE_INTEGER freq;
02498         LARGE_INTEGER        count;
02499 
02500         if (!init) {
02501             QueryPerformanceFrequency(&freq);
02502             init = 1;
02503         }
02504 
02505         QueryPerformanceCounter(&count);
02506 
02507         return (word32)(count.QuadPart / freq.QuadPart);
02508     }
02509 
02510 #elif defined(HAVE_RTP_SYS)
02511 
02512     #include "rtptime.h"
02513 
02514     word32 LowResTimer(void)
02515     {
02516         return (word32)rtp_get_system_sec();
02517     }
02518 
02519 
02520 #elif defined(MICRIUM)
02521 
02522     word32 LowResTimer(void)
02523     {
02524         NET_SECURE_OS_TICK  clk;
02525 
02526         #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
02527             clk = NetSecure_OS_TimeGet();
02528         #endif
02529         return (word32)clk;
02530     }
02531 
02532 
02533 #elif defined(MICROCHIP_TCPIP_V5)
02534 
02535     word32 LowResTimer(void)
02536     {
02537         return (word32) TickGet();
02538     }
02539 
02540 
02541 #elif defined(MICROCHIP_TCPIP)
02542 
02543     #if defined(MICROCHIP_MPLAB_HARMONY)
02544 
02545         #include <system/tmr/sys_tmr.h>
02546 
02547         word32 LowResTimer(void)
02548         {
02549             return (word32) SYS_TMR_TickCountGet();
02550         }
02551 
02552     #else
02553 
02554         word32 LowResTimer(void)
02555         {
02556             return (word32) SYS_TICK_Get();
02557         }
02558 
02559     #endif
02560 
02561 #elif defined(FREESCALE_MQX)
02562 
02563     word32 LowResTimer(void)
02564     {
02565         TIME_STRUCT mqxTime;
02566 
02567         _time_get_elapsed(&mqxTime);
02568 
02569         return (word32) mqxTime.SECONDS;
02570     }
02571 
02572 #elif defined(CYASSL_TIRTOS)
02573 
02574     word32 LowResTimer(void)
02575     {
02576         return (word32) MYTIME_gettime();
02577     }
02578 
02579 #elif defined(USER_TICKS)
02580 #if 0
02581     word32 LowResTimer(void)
02582     {
02583         /*
02584         write your own clock tick function if don't want time(0)
02585         needs second accuracy but doesn't have to correlated to EPOCH
02586         */
02587     }
02588 #endif
02589 #else /* !USE_WINDOWS_API && !HAVE_RTP_SYS && !MICRIUM && !USER_TICKS */
02590 
02591     #include <time.h>
02592 
02593     word32 LowResTimer(void)
02594     {
02595         return (word32)time(0);
02596     }
02597 
02598 
02599 #endif /* USE_WINDOWS_API */
02600 
02601 
02602 /* add output to md5 and sha handshake hashes, exclude record header */
02603 static int HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
02604 {
02605     const byte* adj = output + RECORD_HEADER_SZ + ivSz;
02606     sz -= RECORD_HEADER_SZ;
02607 
02608 #ifdef HAVE_FUZZER
02609     if (ssl->fuzzerCb)
02610         ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
02611 #endif
02612 #ifdef CYASSL_DTLS
02613     if (ssl->options.dtls) {
02614         adj += DTLS_RECORD_EXTRA;
02615         sz  -= DTLS_RECORD_EXTRA;
02616     }
02617 #endif
02618 #ifndef NO_OLD_TLS
02619 #ifndef NO_SHA
02620     ShaUpdate(&ssl->hashSha, adj, sz);
02621 #endif
02622 #ifndef NO_MD5
02623     Md5Update(&ssl->hashMd5, adj, sz);
02624 #endif
02625 #endif
02626 
02627     if (IsAtLeastTLSv1_2(ssl)) {
02628         int ret;
02629 
02630 #ifndef NO_SHA256
02631         ret = Sha256Update(&ssl->hashSha256, adj, sz);
02632         if (ret != 0)
02633             return ret;
02634 #endif
02635 #ifdef CYASSL_SHA384
02636         ret = Sha384Update(&ssl->hashSha384, adj, sz);
02637         if (ret != 0)
02638             return ret;
02639 #endif
02640     }
02641 
02642     return 0;
02643 }
02644 
02645 
02646 /* add input to md5 and sha handshake hashes, include handshake header */
02647 static int HashInput(CYASSL* ssl, const byte* input, int sz)
02648 {
02649     const byte* adj = input - HANDSHAKE_HEADER_SZ;
02650     sz += HANDSHAKE_HEADER_SZ;
02651 
02652 #ifdef CYASSL_DTLS
02653     if (ssl->options.dtls) {
02654         adj -= DTLS_HANDSHAKE_EXTRA;
02655         sz  += DTLS_HANDSHAKE_EXTRA;
02656     }
02657 #endif
02658 
02659 #ifndef NO_OLD_TLS
02660 #ifndef NO_SHA
02661     ShaUpdate(&ssl->hashSha, adj, sz);
02662 #endif
02663 #ifndef NO_MD5
02664     Md5Update(&ssl->hashMd5, adj, sz);
02665 #endif
02666 #endif
02667 
02668     if (IsAtLeastTLSv1_2(ssl)) {
02669         int ret;
02670 
02671 #ifndef NO_SHA256
02672         ret = Sha256Update(&ssl->hashSha256, adj, sz);
02673         if (ret != 0)
02674             return ret;
02675 #endif
02676 #ifdef CYASSL_SHA384
02677         ret = Sha384Update(&ssl->hashSha384, adj, sz);
02678         if (ret != 0)
02679             return ret;
02680 #endif
02681     }
02682 
02683     return 0;
02684 }
02685 
02686 
02687 /* add record layer header for message */
02688 static void AddRecordHeader(byte* output, word32 length, byte type, CYASSL* ssl)
02689 {
02690     RecordLayerHeader* rl;
02691 
02692     /* record layer header */
02693     rl = (RecordLayerHeader*)output;
02694     rl->type    = type;
02695     rl->pvMajor = ssl->version.major;       /* type and version same in each */
02696     rl->pvMinor = ssl->version.minor;
02697 
02698     if (!ssl->options.dtls)
02699         c16toa((word16)length, rl->length);
02700     else {
02701 #ifdef CYASSL_DTLS
02702         DtlsRecordLayerHeader* dtls;
02703 
02704         /* dtls record layer header extensions */
02705         dtls = (DtlsRecordLayerHeader*)output;
02706         c16toa(ssl->keys.dtls_epoch, dtls->epoch);
02707         c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
02708         c16toa((word16)length, dtls->length);
02709 #endif
02710     }
02711 }
02712 
02713 
02714 /* add handshake header for message */
02715 static void AddHandShakeHeader(byte* output, word32 length, byte type,
02716                                CYASSL* ssl)
02717 {
02718     HandShakeHeader* hs;
02719     (void)ssl;
02720 
02721     /* handshake header */
02722     hs = (HandShakeHeader*)output;
02723     hs->type = type;
02724     c32to24(length, hs->length);         /* type and length same for each */
02725 #ifdef CYASSL_DTLS
02726     if (ssl->options.dtls) {
02727         DtlsHandShakeHeader* dtls;
02728 
02729         /* dtls handshake header extensions */
02730         dtls = (DtlsHandShakeHeader*)output;
02731         c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
02732         c32to24(0, dtls->fragment_offset);
02733         c32to24(length, dtls->fragment_length);
02734     }
02735 #endif
02736 }
02737 
02738 
02739 /* add both headers for handshake message */
02740 static void AddHeaders(byte* output, word32 length, byte type, CYASSL* ssl)
02741 {
02742     if (!ssl->options.dtls) {
02743         AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
02744         AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
02745     }
02746 #ifdef CYASSL_DTLS
02747     else  {
02748         AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
02749         AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
02750     }
02751 #endif
02752 }
02753 
02754 
02755 /* return bytes received, -1 on error */
02756 static int Receive(CYASSL* ssl, byte* buf, word32 sz)
02757 {
02758     int recvd;
02759 
02760     if (ssl->ctx->CBIORecv == NULL) {
02761         CYASSL_MSG("Your IO Recv callback is null, please set");
02762         return -1;
02763     }
02764 
02765 retry:
02766     recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
02767     if (recvd < 0)
02768         switch (recvd) {
02769             case CYASSL_CBIO_ERR_GENERAL:        /* general/unknown error */
02770                 return -1;
02771 
02772             case CYASSL_CBIO_ERR_WANT_READ:      /* want read, would block */
02773                 return WANT_READ;
02774 
02775             case CYASSL_CBIO_ERR_CONN_RST:       /* connection reset */
02776                 #ifdef USE_WINDOWS_API
02777                 if (ssl->options.dtls) {
02778                     goto retry;
02779                 }
02780                 #endif
02781                 ssl->options.connReset = 1;
02782                 return -1;
02783 
02784             case CYASSL_CBIO_ERR_ISR:            /* interrupt */
02785                 /* see if we got our timeout */
02786                 #ifdef CYASSL_CALLBACKS
02787                     if (ssl->toInfoOn) {
02788                         struct itimerval timeout;
02789                         getitimer(ITIMER_REAL, &timeout);
02790                         if (timeout.it_value.tv_sec == 0 &&
02791                                                 timeout.it_value.tv_usec == 0) {
02792                             XSTRNCPY(ssl->timeoutInfo.timeoutName,
02793                                     "recv() timeout", MAX_TIMEOUT_NAME_SZ);
02794                             CYASSL_MSG("Got our timeout");
02795                             return WANT_READ;
02796                         }
02797                     }
02798                 #endif
02799                 goto retry;
02800 
02801             case CYASSL_CBIO_ERR_CONN_CLOSE:     /* peer closed connection */
02802                 ssl->options.isClosed = 1;
02803                 return -1;
02804 
02805             case CYASSL_CBIO_ERR_TIMEOUT:
02806 #ifdef CYASSL_DTLS
02807                 if (DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0)
02808                     goto retry;
02809                 else
02810 #endif
02811                     return -1;
02812 
02813             default:
02814                 return recvd;
02815         }
02816 
02817     return recvd;
02818 }
02819 
02820 
02821 /* Switch dynamic output buffer back to static, buffer is assumed clear */
02822 void ShrinkOutputBuffer(CYASSL* ssl)
02823 {
02824     CYASSL_MSG("Shrinking output buffer\n");
02825     XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
02826           ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
02827     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
02828     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
02829     ssl->buffers.outputBuffer.dynamicFlag = 0;
02830     ssl->buffers.outputBuffer.offset      = 0;
02831 }
02832 
02833 
02834 /* Switch dynamic input buffer back to static, keep any remaining input */
02835 /* forced free means cleaning up */
02836 void ShrinkInputBuffer(CYASSL* ssl, int forcedFree)
02837 {
02838     int usedLength = ssl->buffers.inputBuffer.length -
02839                      ssl->buffers.inputBuffer.idx;
02840     if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
02841         return;
02842 
02843     CYASSL_MSG("Shrinking input buffer\n");
02844 
02845     if (!forcedFree && usedLength)
02846         XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
02847                ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
02848                usedLength);
02849 
02850     XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
02851           ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
02852     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
02853     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
02854     ssl->buffers.inputBuffer.dynamicFlag = 0;
02855     ssl->buffers.inputBuffer.offset      = 0;
02856     ssl->buffers.inputBuffer.idx = 0;
02857     ssl->buffers.inputBuffer.length = usedLength;
02858 }
02859 
02860 
02861 int SendBuffered(CYASSL* ssl)
02862 {
02863     if (ssl->ctx->CBIOSend == NULL) {
02864         CYASSL_MSG("Your IO Send callback is null, please set");
02865         return SOCKET_ERROR_E;
02866     }
02867 
02868     while (ssl->buffers.outputBuffer.length > 0) {
02869         int sent = ssl->ctx->CBIOSend(ssl,
02870                                       (char*)ssl->buffers.outputBuffer.buffer +
02871                                       ssl->buffers.outputBuffer.idx,
02872                                       (int)ssl->buffers.outputBuffer.length,
02873                                       ssl->IOCB_WriteCtx);
02874         if (sent < 0) {
02875             switch (sent) {
02876 
02877                 case CYASSL_CBIO_ERR_WANT_WRITE:        /* would block */
02878                     return WANT_WRITE;
02879 
02880                 case CYASSL_CBIO_ERR_CONN_RST:          /* connection reset */
02881                     ssl->options.connReset = 1;
02882                     break;
02883 
02884                 case CYASSL_CBIO_ERR_ISR:               /* interrupt */
02885                     /* see if we got our timeout */
02886                     #ifdef CYASSL_CALLBACKS
02887                         if (ssl->toInfoOn) {
02888                             struct itimerval timeout;
02889                             getitimer(ITIMER_REAL, &timeout);
02890                             if (timeout.it_value.tv_sec == 0 &&
02891                                                 timeout.it_value.tv_usec == 0) {
02892                                 XSTRNCPY(ssl->timeoutInfo.timeoutName,
02893                                         "send() timeout", MAX_TIMEOUT_NAME_SZ);
02894                                 CYASSL_MSG("Got our timeout");
02895                                 return WANT_WRITE;
02896                             }
02897                         }
02898                     #endif
02899                     continue;
02900 
02901                 case CYASSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
02902                     ssl->options.connReset = 1;  /* treat same as reset */
02903                     break;
02904 
02905                 default:
02906                     return SOCKET_ERROR_E;
02907             }
02908 
02909             return SOCKET_ERROR_E;
02910         }
02911 
02912         if (sent > (int)ssl->buffers.outputBuffer.length) {
02913             CYASSL_MSG("SendBuffered() out of bounds read");
02914             return SEND_OOB_READ_E;
02915         }
02916 
02917         ssl->buffers.outputBuffer.idx += sent;
02918         ssl->buffers.outputBuffer.length -= sent;
02919     }
02920 
02921     ssl->buffers.outputBuffer.idx = 0;
02922 
02923     if (ssl->buffers.outputBuffer.dynamicFlag)
02924         ShrinkOutputBuffer(ssl);
02925 
02926     return 0;
02927 }
02928 
02929 
02930 /* Grow the output buffer */
02931 static INLINE int GrowOutputBuffer(CYASSL* ssl, int size)
02932 {
02933     byte* tmp;
02934     byte  hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
02935                                       RECORD_HEADER_SZ;
02936     byte  align = CYASSL_GENERAL_ALIGNMENT;
02937     /* the encrypted data will be offset from the front of the buffer by
02938        the header, if the user wants encrypted alignment they need
02939        to define their alignment requirement */
02940 
02941     if (align) {
02942        while (align < hdrSz)
02943            align *= 2;
02944     }
02945 
02946     tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length + align,
02947                           ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
02948     CYASSL_MSG("growing output buffer\n");
02949 
02950     if (!tmp) return MEMORY_E;
02951     if (align)
02952         tmp += align - hdrSz;
02953 
02954     if (ssl->buffers.outputBuffer.length)
02955         XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
02956                ssl->buffers.outputBuffer.length);
02957 
02958     if (ssl->buffers.outputBuffer.dynamicFlag)
02959         XFREE(ssl->buffers.outputBuffer.buffer -
02960               ssl->buffers.outputBuffer.offset, ssl->heap,
02961               DYNAMIC_TYPE_OUT_BUFFER);
02962     ssl->buffers.outputBuffer.dynamicFlag = 1;
02963     if (align)
02964         ssl->buffers.outputBuffer.offset = align - hdrSz;
02965     else
02966         ssl->buffers.outputBuffer.offset = 0;
02967     ssl->buffers.outputBuffer.buffer = tmp;
02968     ssl->buffers.outputBuffer.bufferSize = size +
02969                                            ssl->buffers.outputBuffer.length;
02970     return 0;
02971 }
02972 
02973 
02974 /* Grow the input buffer, should only be to read cert or big app data */
02975 int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
02976 {
02977     byte* tmp;
02978     byte  hdrSz = DTLS_RECORD_HEADER_SZ;
02979     byte  align = ssl->options.dtls ? CYASSL_GENERAL_ALIGNMENT : 0;
02980     /* the encrypted data will be offset from the front of the buffer by
02981        the dtls record header, if the user wants encrypted alignment they need
02982        to define their alignment requirement. in tls we read record header
02983        to get size of record and put actual data back at front, so don't need */
02984 
02985     if (align) {
02986        while (align < hdrSz)
02987            align *= 2;
02988     }
02989     tmp = (byte*) XMALLOC(size + usedLength + align, ssl->heap,
02990                           DYNAMIC_TYPE_IN_BUFFER);
02991     CYASSL_MSG("growing input buffer\n");
02992 
02993     if (!tmp) return MEMORY_E;
02994     if (align)
02995         tmp += align - hdrSz;
02996 
02997     if (usedLength)
02998         XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
02999                     ssl->buffers.inputBuffer.idx, usedLength);
03000 
03001     if (ssl->buffers.inputBuffer.dynamicFlag)
03002         XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
03003               ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
03004 
03005     ssl->buffers.inputBuffer.dynamicFlag = 1;
03006     if (align)
03007         ssl->buffers.inputBuffer.offset = align - hdrSz;
03008     else
03009         ssl->buffers.inputBuffer.offset = 0;
03010     ssl->buffers.inputBuffer.buffer = tmp;
03011     ssl->buffers.inputBuffer.bufferSize = size + usedLength;
03012     ssl->buffers.inputBuffer.idx    = 0;
03013     ssl->buffers.inputBuffer.length = usedLength;
03014 
03015     return 0;
03016 }
03017 
03018 
03019 /* check available size into output buffer, make room if needed */
03020 int CheckAvailableSize(CYASSL *ssl, int size)
03021 {
03022 
03023     if (size < 0) {
03024         CYASSL_MSG("CheckAvailableSize() called with negative number");
03025         return BAD_FUNC_ARG;
03026     }
03027 
03028     if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
03029                                              < (word32)size) {
03030         if (GrowOutputBuffer(ssl, size) < 0)
03031             return MEMORY_E;
03032     }
03033 
03034     return 0;
03035 }
03036 
03037 
03038 /* do all verify and sanity checks on record header */
03039 static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
03040                            RecordLayerHeader* rh, word16 *size)
03041 {
03042     if (!ssl->options.dtls) {
03043 #ifdef HAVE_FUZZER
03044         if (ssl->fuzzerCb)
03045             ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
03046                     ssl->fuzzerCtx);
03047 #endif
03048         XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
03049         *inOutIdx += RECORD_HEADER_SZ;
03050         ato16(rh->length, size);
03051     }
03052     else {
03053 #ifdef CYASSL_DTLS
03054         /* type and version in same sport */
03055         XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
03056         *inOutIdx += ENUM_LEN + VERSION_SZ;
03057         ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch);
03058         *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
03059         ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq);
03060         *inOutIdx += 4;  /* advance past rest of seq */
03061         ato16(input + *inOutIdx, size);
03062         *inOutIdx += LENGTH_SZ;
03063 #ifdef HAVE_FUZZER
03064         if (ssl->fuzzerCb)
03065             ssl->fuzzerCb(ssl, input + *inOutIdx - LENGTH_SZ - 8 - ENUM_LEN -
03066                            VERSION_SZ, ENUM_LEN + VERSION_SZ + 8 + LENGTH_SZ,
03067                            FUZZ_HEAD, ssl->fuzzerCtx);
03068 #endif
03069 #endif
03070     }
03071 
03072     /* catch version mismatch */
03073     if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
03074         if (ssl->options.side == CYASSL_SERVER_END &&
03075             ssl->options.acceptState == ACCEPT_BEGIN)
03076             CYASSL_MSG("Client attempting to connect with different version");
03077         else if (ssl->options.side == CYASSL_CLIENT_END &&
03078                                  ssl->options.downgrade &&
03079                                  ssl->options.connectState < FIRST_REPLY_DONE)
03080             CYASSL_MSG("Server attempting to accept with different version");
03081         else {
03082             CYASSL_MSG("SSL version error");
03083             return VERSION_ERROR;              /* only use requested version */
03084         }
03085     }
03086 
03087 #ifdef CYASSL_DTLS
03088     if (ssl->options.dtls) {
03089         if (DtlsCheckWindow(&ssl->keys.dtls_state) != 1)
03090             return SEQUENCE_ERROR;
03091     }
03092 #endif
03093 
03094     /* record layer length check */
03095 #ifdef HAVE_MAX_FRAGMENT
03096     if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
03097         SendAlert(ssl, alert_fatal, record_overflow);
03098         return LENGTH_ERROR;
03099     }
03100 #else
03101     if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
03102         return LENGTH_ERROR;
03103 #endif
03104 
03105     /* verify record type here as well */
03106     switch (rh->type) {
03107         case handshake:
03108         case change_cipher_spec:
03109         case application_data:
03110         case alert:
03111             break;
03112         case no_type:
03113         default:
03114             CYASSL_MSG("Unknown Record Type");
03115             return UNKNOWN_RECORD_TYPE;
03116     }
03117 
03118     /* haven't decrypted this record yet */
03119     ssl->keys.decryptedCur = 0;
03120 
03121     return 0;
03122 }
03123 
03124 
03125 static int GetHandShakeHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
03126                               byte *type, word32 *size, word32 totalSz)
03127 {
03128     const byte *ptr = input + *inOutIdx;
03129     (void)ssl;
03130 
03131     *inOutIdx += HANDSHAKE_HEADER_SZ;
03132     if (*inOutIdx > totalSz)
03133         return BUFFER_E;
03134 
03135     *type = ptr[0];
03136     c24to32(&ptr[1], size);
03137 
03138     return 0;
03139 }
03140 
03141 
03142 #ifdef CYASSL_DTLS
03143 static int GetDtlsHandShakeHeader(CYASSL* ssl, const byte* input,
03144                                   word32* inOutIdx, byte *type, word32 *size,
03145                                   word32 *fragOffset, word32 *fragSz,
03146                                   word32 totalSz)
03147 {
03148     word32 idx = *inOutIdx;
03149 
03150     *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
03151     if (*inOutIdx > totalSz)
03152         return BUFFER_E;
03153 
03154     *type = input[idx++];
03155     c24to32(input + idx, size);
03156     idx += BYTE3_LEN;
03157 
03158     ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
03159     idx += DTLS_HANDSHAKE_SEQ_SZ;
03160 
03161     c24to32(input + idx, fragOffset);
03162     idx += DTLS_HANDSHAKE_FRAG_SZ;
03163     c24to32(input + idx, fragSz);
03164 
03165     return 0;
03166 }
03167 #endif
03168 
03169 
03170 #ifndef NO_OLD_TLS
03171 /* fill with MD5 pad size since biggest required */
03172 static const byte PAD1[PAD_MD5] =
03173                               { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03174                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03175                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03176                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03177                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03178                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
03179                               };
03180 static const byte PAD2[PAD_MD5] =
03181                               { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03182                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03183                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03184                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03185                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03186                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
03187                               };
03188 
03189 /* calculate MD5 hash for finished */
03190 static void BuildMD5(CYASSL* ssl, Hashes* hashes, const byte* sender)
03191 {
03192     byte md5_result[MD5_DIGEST_SIZE];
03193 
03194     /* make md5 inner */
03195     Md5Update(&ssl->hashMd5, sender, SIZEOF_SENDER);
03196     Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
03197     Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
03198     Md5Final(&ssl->hashMd5, md5_result);
03199 
03200     /* make md5 outer */
03201     Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
03202     Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
03203     Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
03204 
03205     Md5Final(&ssl->hashMd5, hashes->md5);
03206 }
03207 
03208 
03209 /* calculate SHA hash for finished */
03210 static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender)
03211 {
03212     byte sha_result[SHA_DIGEST_SIZE];
03213 
03214     /* make sha inner */
03215     ShaUpdate(&ssl->hashSha, sender, SIZEOF_SENDER);
03216     ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
03217     ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
03218     ShaFinal(&ssl->hashSha, sha_result);
03219 
03220     /* make sha outer */
03221     ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
03222     ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
03223     ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
03224 
03225     ShaFinal(&ssl->hashSha, hashes->sha);
03226 }
03227 #endif
03228 
03229 
03230 static int BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
03231 {
03232     int ret = 0;
03233 #ifdef CYASSL_SMALL_STACK
03234     #ifndef NO_OLD_TLS
03235     #ifndef NO_MD5
03236         Md5* md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
03237     #endif
03238     #ifndef NO_SHA
03239         Sha* sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
03240     #endif
03241     #endif
03242     #ifndef NO_SHA256
03243         Sha256* sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
03244                                                        DYNAMIC_TYPE_TMP_BUFFER);
03245     #endif
03246     #ifdef CYASSL_SHA384
03247         Sha384* sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,                                                                        DYNAMIC_TYPE_TMP_BUFFER);
03248     #endif
03249 #else
03250     #ifndef NO_OLD_TLS
03251     #ifndef NO_MD5
03252         Md5 md5[1];
03253     #endif
03254     #ifndef NO_SHA
03255         Sha sha[1];
03256     #endif
03257     #endif
03258     #ifndef NO_SHA256
03259         Sha256 sha256[1];
03260     #endif
03261     #ifdef CYASSL_SHA384
03262         Sha384 sha384[1];
03263     #endif
03264 #endif
03265 
03266 #ifdef CYASSL_SMALL_STACK
03267     if (ssl == NULL
03268     #ifndef NO_OLD_TLS
03269     #ifndef NO_MD5
03270         || md5 == NULL
03271     #endif
03272     #ifndef NO_SHA
03273         || sha == NULL
03274     #endif
03275     #endif
03276     #ifndef NO_SHA256
03277         || sha256 == NULL
03278     #endif
03279     #ifdef CYASSL_SHA384
03280         || sha384 == NULL
03281     #endif
03282         ) {
03283     #ifndef NO_OLD_TLS
03284     #ifndef NO_MD5
03285         XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03286     #endif
03287     #ifndef NO_SHA
03288         XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03289     #endif
03290     #endif
03291     #ifndef NO_SHA256
03292         XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03293     #endif
03294     #ifdef CYASSL_SHA384
03295         XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03296     #endif
03297         return MEMORY_E;
03298     }
03299 #endif
03300 
03301     /* store current states, building requires get_digest which resets state */
03302 #ifndef NO_OLD_TLS
03303 #ifndef NO_MD5
03304     md5[0] = ssl->hashMd5;
03305 #endif
03306 #ifndef NO_SHA
03307     sha[0] = ssl->hashSha;
03308     #endif
03309 #endif
03310 #ifndef NO_SHA256
03311     sha256[0] = ssl->hashSha256;
03312 #endif
03313 #ifdef CYASSL_SHA384
03314     sha384[0] = ssl->hashSha384;
03315 #endif
03316 
03317 #ifndef NO_TLS
03318     if (ssl->options.tls) {
03319         ret = BuildTlsFinished(ssl, hashes, sender);
03320     }
03321 #endif
03322 #ifndef NO_OLD_TLS
03323     if (!ssl->options.tls) {
03324         BuildMD5(ssl, hashes, sender);
03325         BuildSHA(ssl, hashes, sender);
03326     }
03327 #endif
03328 
03329     /* restore */
03330 #ifndef NO_OLD_TLS
03331     #ifndef NO_MD5
03332         ssl->hashMd5 = md5[0];
03333     #endif
03334     #ifndef NO_SHA
03335     ssl->hashSha = sha[0];
03336     #endif
03337 #endif
03338     if (IsAtLeastTLSv1_2(ssl)) {
03339     #ifndef NO_SHA256
03340         ssl->hashSha256 = sha256[0];
03341     #endif
03342     #ifdef CYASSL_SHA384
03343         ssl->hashSha384 = sha384[0];
03344     #endif
03345     }
03346 
03347 #ifdef CYASSL_SMALL_STACK
03348 #ifndef NO_OLD_TLS
03349 #ifndef NO_MD5
03350     XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03351 #endif
03352 #ifndef NO_SHA
03353     XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03354 #endif
03355 #endif
03356 #ifndef NO_SHA256
03357     XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03358 #endif
03359 #ifdef CYASSL_SHA384
03360     XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03361 #endif
03362 #endif
03363 
03364     return ret;
03365 }
03366 
03367 
03368     /* cipher requirements */
03369     enum {
03370         REQUIRES_RSA,
03371         REQUIRES_DHE,
03372         REQUIRES_ECC_DSA,
03373         REQUIRES_ECC_STATIC,
03374         REQUIRES_PSK,
03375         REQUIRES_NTRU,
03376         REQUIRES_RSA_SIG
03377     };
03378 
03379 
03380 
03381     /* Does this cipher suite (first, second) have the requirement
03382        an ephemeral key exchange will still require the key for signing
03383        the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
03384     static int CipherRequires(byte first, byte second, int requirement)
03385     {
03386 
03387         if (first == CHACHA_BYTE) {
03388 
03389         switch (second) {
03390 
03391         case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
03392             if (requirement == REQUIRES_RSA)
03393                 return 1;
03394             break;
03395 
03396         case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
03397             if (requirement == REQUIRES_ECC_DSA)
03398                 return 1;
03399             break;
03400 
03401         case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
03402             if (requirement == REQUIRES_RSA)
03403                 return 1;
03404             if (requirement == REQUIRES_DHE)
03405                 return 1;
03406             break;
03407             }
03408         }
03409 
03410         /* ECC extensions */
03411         if (first == ECC_BYTE) {
03412 
03413         switch (second) {
03414 
03415 #ifndef NO_RSA
03416         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
03417             if (requirement == REQUIRES_RSA)
03418                 return 1;
03419             break;
03420 
03421         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
03422             if (requirement == REQUIRES_ECC_STATIC)
03423                 return 1;
03424             if (requirement == REQUIRES_RSA_SIG)
03425                 return 1;
03426             break;
03427 
03428 #ifndef NO_DES3
03429         case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
03430             if (requirement == REQUIRES_RSA)
03431                 return 1;
03432             break;
03433 
03434         case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
03435             if (requirement == REQUIRES_ECC_STATIC)
03436                 return 1;
03437             if (requirement == REQUIRES_RSA_SIG)
03438                 return 1;
03439             break;
03440 #endif
03441 
03442 #ifndef NO_RC4
03443         case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
03444             if (requirement == REQUIRES_RSA)
03445                 return 1;
03446             break;
03447 
03448         case TLS_ECDH_RSA_WITH_RC4_128_SHA :
03449             if (requirement == REQUIRES_ECC_STATIC)
03450                 return 1;
03451             if (requirement == REQUIRES_RSA_SIG)
03452                 return 1;
03453             break;
03454 #endif
03455 #endif /* NO_RSA */
03456 
03457 #ifndef NO_DES3
03458         case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
03459             if (requirement == REQUIRES_ECC_DSA)
03460                 return 1;
03461             break;
03462 
03463         case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
03464             if (requirement == REQUIRES_ECC_STATIC)
03465                 return 1;
03466             break;
03467 #endif
03468 #ifndef NO_RC4
03469         case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
03470             if (requirement == REQUIRES_ECC_DSA)
03471                 return 1;
03472             break;
03473 
03474         case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
03475             if (requirement == REQUIRES_ECC_STATIC)
03476                 return 1;
03477             break;
03478 #endif
03479 #ifndef NO_RSA
03480         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
03481             if (requirement == REQUIRES_RSA)
03482                 return 1;
03483             break;
03484 
03485         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
03486             if (requirement == REQUIRES_ECC_STATIC)
03487                 return 1;
03488             if (requirement == REQUIRES_RSA_SIG)
03489                 return 1;
03490             break;
03491 #endif
03492 
03493         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
03494             if (requirement == REQUIRES_ECC_DSA)
03495                 return 1;
03496             break;
03497 
03498         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
03499             if (requirement == REQUIRES_ECC_STATIC)
03500                 return 1;
03501             break;
03502 
03503         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
03504             if (requirement == REQUIRES_ECC_DSA)
03505                 return 1;
03506             break;
03507 
03508         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
03509             if (requirement == REQUIRES_ECC_STATIC)
03510                 return 1;
03511             break;
03512 
03513         case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
03514             if (requirement == REQUIRES_ECC_DSA)
03515                 return 1;
03516             break;
03517 
03518         case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
03519             if (requirement == REQUIRES_ECC_DSA)
03520                 return 1;
03521             break;
03522 
03523         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
03524             if (requirement == REQUIRES_ECC_STATIC)
03525                 return 1;
03526             break;
03527 
03528         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
03529             if (requirement == REQUIRES_ECC_STATIC)
03530                 return 1;
03531             break;
03532 
03533 #ifndef NO_RSA
03534         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
03535             if (requirement == REQUIRES_RSA)
03536                 return 1;
03537             break;
03538 
03539         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
03540             if (requirement == REQUIRES_RSA)
03541                 return 1;
03542             break;
03543 
03544         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
03545             if (requirement == REQUIRES_ECC_STATIC)
03546                 return 1;
03547             if (requirement == REQUIRES_RSA_SIG)
03548                 return 1;
03549             break;
03550 
03551         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
03552             if (requirement == REQUIRES_ECC_STATIC)
03553                 return 1;
03554             if (requirement == REQUIRES_RSA_SIG)
03555                 return 1;
03556             break;
03557 
03558         case TLS_RSA_WITH_AES_128_CCM_8 :
03559         case TLS_RSA_WITH_AES_256_CCM_8 :
03560             if (requirement == REQUIRES_RSA)
03561                 return 1;
03562             if (requirement == REQUIRES_RSA_SIG)
03563                 return 1;
03564             break;
03565 
03566         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
03567         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
03568             if (requirement == REQUIRES_RSA)
03569                 return 1;
03570             if (requirement == REQUIRES_RSA_SIG)
03571                 return 1;
03572             break;
03573 
03574         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
03575         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
03576             if (requirement == REQUIRES_RSA_SIG)
03577                 return 1;
03578             if (requirement == REQUIRES_ECC_STATIC)
03579                 return 1;
03580             break;
03581 #endif
03582 
03583         case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
03584         case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
03585             if (requirement == REQUIRES_ECC_DSA)
03586                 return 1;
03587             break;
03588 
03589         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
03590         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
03591             if (requirement == REQUIRES_ECC_DSA)
03592                 return 1;
03593             break;
03594 
03595         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
03596         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
03597             if (requirement == REQUIRES_ECC_DSA)
03598                 return 1;
03599             if (requirement == REQUIRES_ECC_STATIC)
03600                 return 1;
03601             break;
03602 
03603         case TLS_PSK_WITH_AES_128_CCM:
03604         case TLS_PSK_WITH_AES_256_CCM:
03605         case TLS_PSK_WITH_AES_128_CCM_8:
03606         case TLS_PSK_WITH_AES_256_CCM_8:
03607             if (requirement == REQUIRES_PSK)
03608                 return 1;
03609             break;
03610 
03611         case TLS_DHE_PSK_WITH_AES_128_CCM:
03612         case TLS_DHE_PSK_WITH_AES_256_CCM:
03613             if (requirement == REQUIRES_PSK)
03614                 return 1;
03615             if (requirement == REQUIRES_DHE)
03616                 return 1;
03617             break;
03618 
03619         default:
03620             CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
03621             return 0;
03622         }   /* switch */
03623         }   /* if     */
03624         if (first != ECC_BYTE) {   /* normal suites */
03625         switch (second) {
03626 
03627 #ifndef NO_RSA
03628         case SSL_RSA_WITH_RC4_128_SHA :
03629             if (requirement == REQUIRES_RSA)
03630                 return 1;
03631             break;
03632 
03633         case TLS_NTRU_RSA_WITH_RC4_128_SHA :
03634             if (requirement == REQUIRES_NTRU)
03635                 return 1;
03636             break;
03637 
03638         case SSL_RSA_WITH_RC4_128_MD5 :
03639             if (requirement == REQUIRES_RSA)
03640                 return 1;
03641             break;
03642 
03643         case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
03644             if (requirement == REQUIRES_RSA)
03645                 return 1;
03646             break;
03647 
03648         case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
03649             if (requirement == REQUIRES_NTRU)
03650                 return 1;
03651             break;
03652 
03653         case TLS_RSA_WITH_AES_128_CBC_SHA :
03654             if (requirement == REQUIRES_RSA)
03655                 return 1;
03656             break;
03657 
03658         case TLS_RSA_WITH_AES_128_CBC_SHA256 :
03659             if (requirement == REQUIRES_RSA)
03660                 return 1;
03661             break;
03662 
03663         case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
03664             if (requirement == REQUIRES_NTRU)
03665                 return 1;
03666             break;
03667 
03668         case TLS_RSA_WITH_AES_256_CBC_SHA :
03669             if (requirement == REQUIRES_RSA)
03670                 return 1;
03671             break;
03672 
03673         case TLS_RSA_WITH_AES_256_CBC_SHA256 :
03674             if (requirement == REQUIRES_RSA)
03675                 return 1;
03676             break;
03677 
03678         case TLS_RSA_WITH_NULL_SHA :
03679         case TLS_RSA_WITH_NULL_SHA256 :
03680             if (requirement == REQUIRES_RSA)
03681                 return 1;
03682             break;
03683 
03684         case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
03685             if (requirement == REQUIRES_NTRU)
03686                 return 1;
03687             break;
03688 #endif
03689 
03690         case TLS_PSK_WITH_AES_128_GCM_SHA256 :
03691         case TLS_PSK_WITH_AES_256_GCM_SHA384 :
03692         case TLS_PSK_WITH_AES_128_CBC_SHA256 :
03693         case TLS_PSK_WITH_AES_256_CBC_SHA384 :
03694         case TLS_PSK_WITH_AES_128_CBC_SHA :
03695         case TLS_PSK_WITH_AES_256_CBC_SHA :
03696         case TLS_PSK_WITH_NULL_SHA384 :
03697         case TLS_PSK_WITH_NULL_SHA256 :
03698         case TLS_PSK_WITH_NULL_SHA :
03699             if (requirement == REQUIRES_PSK)
03700                 return 1;
03701             break;
03702 
03703         case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
03704         case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
03705         case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
03706         case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
03707         case TLS_DHE_PSK_WITH_NULL_SHA384 :
03708         case TLS_DHE_PSK_WITH_NULL_SHA256 :
03709             if (requirement == REQUIRES_DHE)
03710                 return 1;
03711             if (requirement == REQUIRES_PSK)
03712                 return 1;
03713             break;
03714 
03715 #ifndef NO_RSA
03716         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
03717             if (requirement == REQUIRES_RSA)
03718                 return 1;
03719             if (requirement == REQUIRES_DHE)
03720                 return 1;
03721             break;
03722 
03723         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
03724             if (requirement == REQUIRES_RSA)
03725                 return 1;
03726             if (requirement == REQUIRES_DHE)
03727                 return 1;
03728             break;
03729 
03730         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
03731             if (requirement == REQUIRES_RSA)
03732                 return 1;
03733             if (requirement == REQUIRES_DHE)
03734                 return 1;
03735             break;
03736 
03737         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
03738             if (requirement == REQUIRES_RSA)
03739                 return 1;
03740             if (requirement == REQUIRES_DHE)
03741                 return 1;
03742             break;
03743 
03744         case TLS_RSA_WITH_HC_128_MD5 :
03745             if (requirement == REQUIRES_RSA)
03746                 return 1;
03747             break;
03748 
03749         case TLS_RSA_WITH_HC_128_SHA :
03750             if (requirement == REQUIRES_RSA)
03751                 return 1;
03752             break;
03753 
03754         case TLS_RSA_WITH_HC_128_B2B256:
03755             if (requirement == REQUIRES_RSA)
03756                 return 1;
03757             break;
03758 
03759         case TLS_RSA_WITH_AES_128_CBC_B2B256:
03760         case TLS_RSA_WITH_AES_256_CBC_B2B256:
03761             if (requirement == REQUIRES_RSA)
03762                 return 1;
03763             break;
03764 
03765         case TLS_RSA_WITH_RABBIT_SHA :
03766             if (requirement == REQUIRES_RSA)
03767                 return 1;
03768             break;
03769 
03770         case TLS_RSA_WITH_AES_128_GCM_SHA256 :
03771         case TLS_RSA_WITH_AES_256_GCM_SHA384 :
03772             if (requirement == REQUIRES_RSA)
03773                 return 1;
03774             break;
03775 
03776         case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
03777         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
03778             if (requirement == REQUIRES_RSA)
03779                 return 1;
03780             if (requirement == REQUIRES_DHE)
03781                 return 1;
03782             break;
03783 
03784         case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
03785         case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
03786         case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
03787         case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
03788             if (requirement == REQUIRES_RSA)
03789                 return 1;
03790             break;
03791 
03792         case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
03793         case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
03794         case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
03795         case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
03796             if (requirement == REQUIRES_RSA)
03797                 return 1;
03798             if (requirement == REQUIRES_RSA_SIG)
03799                 return 1;
03800             if (requirement == REQUIRES_DHE)
03801                 return 1;
03802             break;
03803 #endif
03804 #ifdef HAVE_ANON
03805         case TLS_DH_anon_WITH_AES_128_CBC_SHA :
03806             if (requirement == REQUIRES_DHE)
03807                 return 1;
03808             break;
03809 #endif
03810 
03811         default:
03812             CYASSL_MSG("Unsupported cipher suite, CipherRequires");
03813             return 0;
03814         }  /* switch */
03815         }  /* if ECC / Normal suites else */
03816 
03817         return 0;
03818     }
03819 
03820 
03821 #ifndef NO_CERTS
03822 
03823 
03824 /* Match names with wildcards, each wildcard can represent a single name
03825    component or fragment but not mulitple names, i.e.,
03826    *.z.com matches y.z.com but not x.y.z.com
03827 
03828    return 1 on success */
03829 static int MatchDomainName(const char* pattern, int len, const char* str)
03830 {
03831     char p, s;
03832 
03833     if (pattern == NULL || str == NULL || len <= 0)
03834         return 0;
03835 
03836     while (len > 0) {
03837 
03838         p = (char)XTOLOWER(*pattern++);
03839         if (p == 0)
03840             break;
03841 
03842         if (p == '*') {
03843             while (--len > 0 && (p = (char)XTOLOWER(*pattern++)) == '*')
03844                 ;
03845 
03846             if (len == 0)
03847                 p = '\0';
03848 
03849             while ( (s = (char)XTOLOWER(*str)) != '\0') {
03850                 if (s == p)
03851                     break;
03852                 if (s == '.')
03853                     return 0;
03854                 str++;
03855             }
03856         }
03857         else {
03858             if (p != (char)XTOLOWER(*str))
03859                 return 0;
03860         }
03861 
03862         if (*str != '\0')
03863             str++;
03864 
03865         if (len > 0)
03866             len--;
03867     }
03868 
03869     return *str == '\0';
03870 }
03871 
03872 
03873 /* try to find an altName match to domain, return 1 on success */
03874 static int CheckAltNames(DecodedCert* dCert, char* domain)
03875 {
03876     int        match = 0;
03877     DNS_entry* altName = NULL;
03878 
03879     CYASSL_MSG("Checking AltNames");
03880 
03881     if (dCert)
03882         altName = dCert->altNames;
03883 
03884     while (altName) {
03885         CYASSL_MSG("    individual AltName check");
03886 
03887         if (MatchDomainName(altName->name,(int)XSTRLEN(altName->name), domain)){
03888             match = 1;
03889             break;
03890         }
03891 
03892         altName = altName->next;
03893     }
03894 
03895     return match;
03896 }
03897 
03898 
03899 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
03900 
03901 /* Copy parts X509 needs from Decoded cert, 0 on success */
03902 int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert)
03903 {
03904     int ret = 0;
03905 
03906     if (x509 == NULL || dCert == NULL)
03907         return BAD_FUNC_ARG;
03908 
03909     x509->version = dCert->version + 1;
03910 
03911     XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
03912     x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
03913     x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
03914 #ifdef OPENSSL_EXTRA
03915     if (dCert->issuerName.fullName != NULL) {
03916         XMEMCPY(&x509->issuer.fullName,
03917                                        &dCert->issuerName, sizeof(DecodedName));
03918         x509->issuer.fullName.fullName = (char*)XMALLOC(
03919                         dCert->issuerName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
03920         if (x509->issuer.fullName.fullName != NULL)
03921             XMEMCPY(x509->issuer.fullName.fullName,
03922                      dCert->issuerName.fullName, dCert->issuerName.fullNameLen);
03923     }
03924 #endif /* OPENSSL_EXTRA */
03925 
03926     XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
03927     x509->subject.name[ASN_NAME_MAX - 1] = '\0';
03928     x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
03929 #ifdef OPENSSL_EXTRA
03930     if (dCert->subjectName.fullName != NULL) {
03931         XMEMCPY(&x509->subject.fullName,
03932                                       &dCert->subjectName, sizeof(DecodedName));
03933         x509->subject.fullName.fullName = (char*)XMALLOC(
03934                        dCert->subjectName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
03935         if (x509->subject.fullName.fullName != NULL)
03936             XMEMCPY(x509->subject.fullName.fullName,
03937                    dCert->subjectName.fullName, dCert->subjectName.fullNameLen);
03938     }
03939 #endif /* OPENSSL_EXTRA */
03940 
03941     XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
03942     x509->serialSz = dCert->serialSz;
03943     if (dCert->subjectCNLen < ASN_NAME_MAX) {
03944         XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
03945         x509->subjectCN[dCert->subjectCNLen] = '\0';
03946     }
03947     else
03948         x509->subjectCN[0] = '\0';
03949 
03950 #ifdef CYASSL_SEP
03951     {
03952         int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE);
03953         if (minSz > 0) {
03954             x509->deviceTypeSz = minSz;
03955             XMEMCPY(x509->deviceType, dCert->deviceType, minSz);
03956         }
03957         else
03958             x509->deviceTypeSz = 0;
03959         minSz = min(dCert->hwTypeSz, EXTERNAL_SERIAL_SIZE);
03960         if (minSz != 0) {
03961             x509->hwTypeSz = minSz;
03962             XMEMCPY(x509->hwType, dCert->hwType, minSz);
03963         }
03964         else
03965             x509->hwTypeSz = 0;
03966         minSz = min(dCert->hwSerialNumSz, EXTERNAL_SERIAL_SIZE);
03967         if (minSz != 0) {
03968             x509->hwSerialNumSz = minSz;
03969             XMEMCPY(x509->hwSerialNum, dCert->hwSerialNum, minSz);
03970         }
03971         else
03972             x509->hwSerialNumSz = 0;
03973     }
03974 #endif /* CYASSL_SEP */
03975     {
03976         int minSz = min(dCert->beforeDateLen, MAX_DATE_SZ);
03977         if (minSz != 0) {
03978             x509->notBeforeSz = minSz;
03979             XMEMCPY(x509->notBefore, dCert->beforeDate, minSz);
03980         }
03981         else
03982             x509->notBeforeSz = 0;
03983         minSz = min(dCert->afterDateLen, MAX_DATE_SZ);
03984         if (minSz != 0) {
03985             x509->notAfterSz = minSz;
03986             XMEMCPY(x509->notAfter, dCert->afterDate, minSz);
03987         }
03988         else
03989             x509->notAfterSz = 0;
03990     }
03991 
03992     if (dCert->publicKey != NULL && dCert->pubKeySize != 0) {
03993         x509->pubKey.buffer = (byte*)XMALLOC(
03994                               dCert->pubKeySize, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
03995         if (x509->pubKey.buffer != NULL) {
03996             x509->pubKeyOID = dCert->keyOID;
03997             x509->pubKey.length = dCert->pubKeySize;
03998             XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize);
03999         }
04000         else
04001             ret = MEMORY_E;
04002     }
04003 
04004     if (dCert->signature != NULL && dCert->sigLength != 0) {
04005         x509->sig.buffer = (byte*)XMALLOC(
04006                                 dCert->sigLength, NULL, DYNAMIC_TYPE_SIGNATURE);
04007         if (x509->sig.buffer == NULL) {
04008             ret = MEMORY_E;
04009         }
04010         else {
04011             XMEMCPY(x509->sig.buffer, dCert->signature, dCert->sigLength);
04012             x509->sig.length = dCert->sigLength;
04013             x509->sigOID = dCert->signatureOID;
04014         }
04015     }
04016 
04017     /* store cert for potential retrieval */
04018     x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL,
04019                                           DYNAMIC_TYPE_CERT);
04020     if (x509->derCert.buffer == NULL) {
04021         ret = MEMORY_E;
04022     }
04023     else {
04024         XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
04025         x509->derCert.length = dCert->maxIdx;
04026     }
04027 
04028     x509->altNames     = dCert->altNames;
04029     dCert->altNames    = NULL;     /* takes ownership */
04030     x509->altNamesNext = x509->altNames;  /* index hint */
04031 
04032     x509->isCa = dCert->isCA;
04033 #ifdef OPENSSL_EXTRA
04034     x509->pathLength = dCert->pathLength;
04035     x509->keyUsage = dCert->extKeyUsage;
04036 
04037     x509->basicConstSet = dCert->extBasicConstSet;
04038     x509->basicConstCrit = dCert->extBasicConstCrit;
04039     x509->basicConstPlSet = dCert->extBasicConstPlSet;
04040     x509->subjAltNameSet = dCert->extSubjAltNameSet;
04041     x509->subjAltNameCrit = dCert->extSubjAltNameCrit;
04042     x509->authKeyIdSet = dCert->extAuthKeyIdSet;
04043     x509->authKeyIdCrit = dCert->extAuthKeyIdCrit;
04044     if (dCert->extAuthKeyIdSrc != NULL && dCert->extAuthKeyIdSz != 0) {
04045         x509->authKeyId = (byte*)XMALLOC(dCert->extAuthKeyIdSz, NULL, 0);
04046         if (x509->authKeyId != NULL) {
04047             XMEMCPY(x509->authKeyId,
04048                                  dCert->extAuthKeyIdSrc, dCert->extAuthKeyIdSz);
04049             x509->authKeyIdSz = dCert->extAuthKeyIdSz;
04050         }
04051         else
04052             ret = MEMORY_E;
04053     }
04054     x509->subjKeyIdSet = dCert->extSubjKeyIdSet;
04055     x509->subjKeyIdCrit = dCert->extSubjKeyIdCrit;
04056     if (dCert->extSubjKeyIdSrc != NULL && dCert->extSubjKeyIdSz != 0) {
04057         x509->subjKeyId = (byte*)XMALLOC(dCert->extSubjKeyIdSz, NULL, 0);
04058         if (x509->subjKeyId != NULL) {
04059             XMEMCPY(x509->subjKeyId,
04060                                  dCert->extSubjKeyIdSrc, dCert->extSubjKeyIdSz);
04061             x509->subjKeyIdSz = dCert->extSubjKeyIdSz;
04062         }
04063         else
04064             ret = MEMORY_E;
04065     }
04066     x509->keyUsageSet = dCert->extKeyUsageSet;
04067     x509->keyUsageCrit = dCert->extKeyUsageCrit;
04068     #ifdef CYASSL_SEP
04069         x509->certPolicySet = dCert->extCertPolicySet;
04070         x509->certPolicyCrit = dCert->extCertPolicyCrit;
04071     #endif /* CYASSL_SEP */
04072 #endif /* OPENSSL_EXTRA */
04073 #ifdef HAVE_ECC
04074     x509->pkCurveOID = dCert->pkCurveOID;
04075 #endif /* HAVE_ECC */
04076 
04077     return ret;
04078 }
04079 
04080 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
04081 
04082 
04083 static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx,
04084                                                                     word32 size)
04085 {
04086     word32 listSz;
04087     word32 begin = *inOutIdx;
04088     int    ret = 0;
04089     int    anyError = 0;
04090     int    totalCerts = 0;    /* number of certs in certs buffer */
04091     int    count;
04092     buffer certs[MAX_CHAIN_DEPTH];
04093 
04094 #ifdef CYASSL_SMALL_STACK
04095     char*                  domain = NULL;
04096     DecodedCert*           dCert  = NULL;
04097     CYASSL_X509_STORE_CTX* store  = NULL;
04098 #else
04099     char                   domain[ASN_NAME_MAX];
04100     DecodedCert            dCert[1];
04101     CYASSL_X509_STORE_CTX  store[1];
04102 #endif
04103 
04104     #ifdef CYASSL_CALLBACKS
04105         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
04106         if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
04107     #endif
04108 
04109     if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
04110         return BUFFER_ERROR;
04111 
04112     c24to32(input + *inOutIdx, &listSz);
04113     *inOutIdx += OPAQUE24_LEN;
04114 
04115 #ifdef HAVE_MAX_FRAGMENT
04116     if (listSz > ssl->max_fragment) {
04117         SendAlert(ssl, alert_fatal, record_overflow);
04118         return BUFFER_E;
04119     }
04120 #else
04121     if (listSz > MAX_RECORD_SIZE)
04122         return BUFFER_E;
04123 #endif
04124 
04125     if ((*inOutIdx - begin) + listSz != size)
04126         return BUFFER_ERROR;
04127 
04128     CYASSL_MSG("Loading peer's cert chain");
04129     /* first put cert chain into buffer so can verify top down
04130        we're sent bottom up */
04131     while (listSz) {
04132         word32 certSz;
04133 
04134         if (totalCerts >= MAX_CHAIN_DEPTH)
04135             return MAX_CHAIN_ERROR;
04136 
04137         if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
04138             return BUFFER_ERROR;
04139 
04140         c24to32(input + *inOutIdx, &certSz);
04141         *inOutIdx += OPAQUE24_LEN;
04142 
04143         if ((*inOutIdx - begin) + certSz > size)
04144             return BUFFER_ERROR;
04145 
04146         certs[totalCerts].length = certSz;
04147         certs[totalCerts].buffer = input + *inOutIdx;
04148 
04149 #ifdef SESSION_CERTS
04150         if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
04151                                        certSz < MAX_X509_SIZE) {
04152             ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
04153             XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
04154                     input + *inOutIdx, certSz);
04155             ssl->session.chain.count++;
04156         } else {
04157             CYASSL_MSG("Couldn't store chain cert for session");
04158         }
04159 #endif
04160 
04161         *inOutIdx += certSz;
04162         listSz -= certSz + CERT_HEADER_SZ;
04163 
04164         totalCerts++;
04165         CYASSL_MSG("    Put another cert into chain");
04166     }
04167 
04168     count = totalCerts;
04169 
04170 #ifdef CYASSL_SMALL_STACK
04171     dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
04172                                                        DYNAMIC_TYPE_TMP_BUFFER);
04173     if (dCert == NULL)
04174         return MEMORY_E;
04175 #endif
04176 
04177     /* verify up to peer's first */
04178     while (count > 1) {
04179         buffer myCert = certs[count - 1];
04180         byte* subjectHash;
04181 
04182         InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
04183         ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
04184                                 ssl->ctx->cm);
04185         #ifndef NO_SKID
04186             subjectHash = dCert->extSubjKeyId;
04187         #else
04188             subjectHash = dCert->subjectHash;
04189         #endif
04190 
04191         if (ret == 0 && dCert->isCA == 0) {
04192             CYASSL_MSG("Chain cert is not a CA, not adding as one");
04193         }
04194         else if (ret == 0 && ssl->options.verifyNone) {
04195             CYASSL_MSG("Chain cert not verified by option, not adding as CA");
04196         }
04197         else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
04198             buffer add;
04199             add.length = myCert.length;
04200             add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
04201                                         DYNAMIC_TYPE_CA);
04202             CYASSL_MSG("Adding CA from chain");
04203 
04204             if (add.buffer == NULL)
04205                 return MEMORY_E;
04206             XMEMCPY(add.buffer, myCert.buffer, myCert.length);
04207 
04208             ret = AddCA(ssl->ctx->cm, add, CYASSL_CHAIN_CA,
04209                         ssl->ctx->verifyPeer);
04210             if (ret == 1) ret = 0;   /* SSL_SUCCESS for external */
04211         }
04212         else if (ret != 0) {
04213             CYASSL_MSG("Failed to verify CA from chain");
04214         }
04215         else {
04216             CYASSL_MSG("Verified CA from chain and already had it");
04217         }
04218 
04219 #ifdef HAVE_CRL
04220         if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) {
04221             CYASSL_MSG("Doing Non Leaf CRL check");
04222             ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
04223 
04224             if (ret != 0) {
04225                 CYASSL_MSG("\tCRL check not ok");
04226             }
04227         }
04228 #endif /* HAVE_CRL */
04229 
04230         if (ret != 0 && anyError == 0)
04231             anyError = ret;   /* save error from last time */
04232 
04233         FreeDecodedCert(dCert);
04234         count--;
04235     }
04236 
04237     /* peer's, may not have one if blank client cert sent by TLSv1.2 */
04238     if (count) {
04239         buffer myCert = certs[0];
04240         int    fatal  = 0;
04241 
04242         CYASSL_MSG("Verifying Peer's cert");
04243 
04244         InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
04245         ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
04246                                 ssl->ctx->cm);
04247         if (ret == 0) {
04248             CYASSL_MSG("Verified Peer's cert");
04249             fatal = 0;
04250         }
04251         else if (ret == ASN_PARSE_E) {
04252             CYASSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
04253             fatal = 1;
04254         }
04255         else {
04256             CYASSL_MSG("Failed to verify Peer's cert");
04257             if (ssl->verifyCallback) {
04258                 CYASSL_MSG("\tCallback override available, will continue");
04259                 fatal = 0;
04260             }
04261             else {
04262                 CYASSL_MSG("\tNo callback override available, fatal");
04263                 fatal = 1;
04264             }
04265         }
04266 
04267 #ifdef HAVE_SECURE_RENEGOTIATION
04268         if (fatal == 0 && ssl->secure_renegotiation
04269                        && ssl->secure_renegotiation->enabled) {
04270 
04271             if (ssl->keys.encryptionOn) {
04272                 /* compare against previous time */
04273                 if (XMEMCMP(dCert->subjectHash,
04274                             ssl->secure_renegotiation->subject_hash,
04275                             SHA_DIGEST_SIZE) != 0) {
04276                     CYASSL_MSG("Peer sent different cert during scr, fatal");
04277                     fatal = 1;
04278                     ret   = SCR_DIFFERENT_CERT_E;
04279                 }
04280             }
04281 
04282             /* cache peer's hash */
04283             if (fatal == 0) {
04284                 XMEMCPY(ssl->secure_renegotiation->subject_hash,
04285                         dCert->subjectHash, SHA_DIGEST_SIZE);
04286             }
04287         }
04288 #endif
04289 
04290 #ifdef HAVE_OCSP
04291         if (fatal == 0 && ssl->ctx->cm->ocspEnabled) {
04292             ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert);
04293             if (ret != 0) {
04294                 CYASSL_MSG("\tOCSP Lookup not ok");
04295                 fatal = 0;
04296             }
04297         }
04298 #endif
04299 
04300 #ifdef HAVE_CRL
04301         if (fatal == 0 && ssl->ctx->cm->crlEnabled) {
04302             int doCrlLookup = 1;
04303 
04304             #ifdef HAVE_OCSP
04305             if (ssl->ctx->cm->ocspEnabled) {
04306                 doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
04307             }
04308             #endif /* HAVE_OCSP */
04309 
04310             if (doCrlLookup) {
04311                 CYASSL_MSG("Doing Leaf CRL check");
04312                 ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
04313 
04314                 if (ret != 0) {
04315                     CYASSL_MSG("\tCRL check not ok");
04316                     fatal = 0;
04317                 }
04318             }
04319         }
04320 
04321 #endif /* HAVE_CRL */
04322 
04323 #ifdef KEEP_PEER_CERT
04324         {
04325         /* set X509 format for peer cert even if fatal */
04326         int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert);
04327         if (copyRet == MEMORY_E)
04328             fatal = 1;
04329         }
04330 #endif
04331 
04332 #ifndef IGNORE_KEY_EXTENSIONS
04333         if (dCert->extKeyUsageSet) {
04334             if ((ssl->specs.kea == rsa_kea) &&
04335                 (dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) {
04336                 ret = KEYUSE_ENCIPHER_E;
04337             }
04338             if ((ssl->specs.sig_algo == rsa_sa_algo ||
04339                     (ssl->specs.sig_algo == ecc_dsa_sa_algo &&
04340                          !ssl->specs.static_ecdh)) &&
04341                 (dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) {
04342                 CYASSL_MSG("KeyUse Digital Sig not set");
04343                 ret = KEYUSE_SIGNATURE_E;
04344             }
04345         }
04346 
04347         if (dCert->extExtKeyUsageSet) {
04348             if (ssl->options.side == CYASSL_CLIENT_END) {
04349                 if ((dCert->extExtKeyUsage &
04350                         (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) {
04351                     CYASSL_MSG("ExtKeyUse Server Auth not set");
04352                     ret = EXTKEYUSE_AUTH_E;
04353                 }
04354             }
04355             else {
04356                 if ((dCert->extExtKeyUsage &
04357                         (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) {
04358                     CYASSL_MSG("ExtKeyUse Client Auth not set");
04359                     ret = EXTKEYUSE_AUTH_E;
04360                 }
04361             }
04362         }
04363 #endif /* IGNORE_KEY_EXTENSIONS */
04364 
04365         if (fatal) {
04366             FreeDecodedCert(dCert);
04367         #ifdef CYASSL_SMALL_STACK
04368             XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04369         #endif
04370             ssl->error = ret;
04371             return ret;
04372         }
04373         ssl->options.havePeerCert = 1;
04374 
04375 #ifdef CYASSL_SMALL_STACK
04376         domain = (char*)XMALLOC(ASN_NAME_MAX, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04377         if (domain == NULL) {
04378             FreeDecodedCert(dCert);
04379             XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04380             return MEMORY_E;
04381         }
04382 #endif
04383         /* store for callback use */
04384         if (dCert->subjectCNLen < ASN_NAME_MAX) {
04385             XMEMCPY(domain, dCert->subjectCN, dCert->subjectCNLen);
04386             domain[dCert->subjectCNLen] = '\0';
04387         }
04388         else
04389             domain[0] = '\0';
04390 
04391         if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
04392             if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
04393                                 (char*)ssl->buffers.domainName.buffer) == 0) {
04394                 CYASSL_MSG("DomainName match on common name failed");
04395                 if (CheckAltNames(dCert,
04396                                  (char*)ssl->buffers.domainName.buffer) == 0 ) {
04397                     CYASSL_MSG("DomainName match on alt names failed too");
04398                     ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
04399                 }
04400             }
04401         }
04402 
04403         /* decode peer key */
04404         switch (dCert->keyOID) {
04405         #ifndef NO_RSA
04406             case RSAk:
04407                 {
04408                     word32 idx = 0;
04409                     int    keyRet = 0;
04410 
04411                     if (ssl->peerRsaKeyPresent) {  /* don't leak on reuse */
04412                         FreeRsaKey(ssl->peerRsaKey);
04413                         ssl->peerRsaKeyPresent = 0;
04414                         keyRet = InitRsaKey(ssl->peerRsaKey, ssl->heap);
04415                     }
04416 
04417                     if (keyRet != 0 || RsaPublicKeyDecode(dCert->publicKey,
04418                                &idx, ssl->peerRsaKey, dCert->pubKeySize) != 0) {
04419                         ret = PEER_KEY_ERROR;
04420                     }
04421                     else {
04422                         ssl->peerRsaKeyPresent = 1;
04423                         #ifdef HAVE_PK_CALLBACKS
04424                             #ifndef NO_RSA
04425                                 ssl->buffers.peerRsaKey.buffer =
04426                                        (byte*)XMALLOC(dCert->pubKeySize,
04427                                                ssl->heap, DYNAMIC_TYPE_RSA);
04428                                 if (ssl->buffers.peerRsaKey.buffer == NULL)
04429                                     ret = MEMORY_ERROR;
04430                                 else {
04431                                     XMEMCPY(ssl->buffers.peerRsaKey.buffer,
04432                                            dCert->publicKey, dCert->pubKeySize);
04433                                     ssl->buffers.peerRsaKey.length =
04434                                             dCert->pubKeySize;
04435                                 }
04436                             #endif /* NO_RSA */
04437                         #endif /*HAVE_PK_CALLBACKS */
04438                     }
04439                 }
04440                 break;
04441         #endif /* NO_RSA */
04442         #ifdef HAVE_NTRU
04443             case NTRUk:
04444                 {
04445                     if (dCert->pubKeySize > sizeof(ssl->peerNtruKey)) {
04446                         ret = PEER_KEY_ERROR;
04447                     }
04448                     else {
04449                         XMEMCPY(ssl->peerNtruKey, dCert->publicKey,
04450                                                              dCert->pubKeySize);
04451                         ssl->peerNtruKeyLen = (word16)dCert->pubKeySize;
04452                         ssl->peerNtruKeyPresent = 1;
04453                     }
04454                 }
04455                 break;
04456         #endif /* HAVE_NTRU */
04457         #ifdef HAVE_ECC
04458             case ECDSAk:
04459                 {
04460                     if (ssl->peerEccDsaKeyPresent) {  /* don't leak on reuse */
04461                         ecc_free(ssl->peerEccDsaKey);
04462                         ssl->peerEccDsaKeyPresent = 0;
04463                         ecc_init(ssl->peerEccDsaKey);
04464                     }
04465                     if (ecc_import_x963(dCert->publicKey, dCert->pubKeySize,
04466                                         ssl->peerEccDsaKey) != 0) {
04467                         ret = PEER_KEY_ERROR;
04468                     }
04469                     else {
04470                         ssl->peerEccDsaKeyPresent = 1;
04471                         #ifdef HAVE_PK_CALLBACKS
04472                             #ifdef HAVE_ECC
04473                                 ssl->buffers.peerEccDsaKey.buffer =
04474                                        (byte*)XMALLOC(dCert->pubKeySize,
04475                                                ssl->heap, DYNAMIC_TYPE_ECC);
04476                                 if (ssl->buffers.peerEccDsaKey.buffer == NULL)
04477                                     ret = MEMORY_ERROR;
04478                                 else {
04479                                     XMEMCPY(ssl->buffers.peerEccDsaKey.buffer,
04480                                            dCert->publicKey, dCert->pubKeySize);
04481                                     ssl->buffers.peerEccDsaKey.length =
04482                                             dCert->pubKeySize;
04483                                 }
04484                             #endif /* HAVE_ECC */
04485                         #endif /*HAVE_PK_CALLBACKS */
04486                     }
04487                 }
04488                 break;
04489         #endif /* HAVE_ECC */
04490             default:
04491                 break;
04492         }
04493 
04494         FreeDecodedCert(dCert);
04495     }
04496 
04497 #ifdef CYASSL_SMALL_STACK
04498     XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04499 
04500     store = (CYASSL_X509_STORE_CTX*)XMALLOC(sizeof(CYASSL_X509_STORE_CTX),
04501                                                  NULL, DYNAMIC_TYPE_TMP_BUFFER);
04502     if (store == NULL) {
04503         XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04504         return MEMORY_E;
04505     }
04506 #endif
04507 
04508     if (anyError != 0 && ret == 0)
04509         ret = anyError;
04510 
04511     if (ret != 0) {
04512         if (!ssl->options.verifyNone) {
04513             int why = bad_certificate;
04514 
04515             if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
04516                 why = certificate_expired;
04517             if (ssl->verifyCallback) {
04518                 int ok;
04519 
04520                 store->error = ret;
04521                 store->error_depth = totalCerts;
04522                 store->discardSessionCerts = 0;
04523                 store->domain = domain;
04524                 store->userCtx = ssl->verifyCbCtx;
04525 #ifdef KEEP_PEER_CERT
04526                 store->current_cert = &ssl->peerCert;
04527 #else
04528                 store->current_cert = NULL;
04529 #endif
04530 #ifdef FORTRESS
04531                 store->ex_data = ssl;
04532 #endif
04533                 ok = ssl->verifyCallback(0, store);
04534                 if (ok) {
04535                     CYASSL_MSG("Verify callback overriding error!");
04536                     ret = 0;
04537                 }
04538                 #ifdef SESSION_CERTS
04539                 if (store->discardSessionCerts) {
04540                     CYASSL_MSG("Verify callback requested discard sess certs");
04541                     ssl->session.chain.count = 0;
04542                 }
04543                 #endif
04544             }
04545             if (ret != 0) {
04546                 SendAlert(ssl, alert_fatal, why);   /* try to send */
04547                 ssl->options.isClosed = 1;
04548             }
04549         }
04550         ssl->error = ret;
04551     }
04552 #ifdef CYASSL_ALWAYS_VERIFY_CB
04553     else {
04554         if (ssl->verifyCallback) {
04555             int ok;
04556 
04557             store->error = ret;
04558             store->error_depth = totalCerts;
04559             store->discardSessionCerts = 0;
04560             store->domain = domain;
04561             store->userCtx = ssl->verifyCbCtx;
04562 #ifdef KEEP_PEER_CERT
04563             store->current_cert = &ssl->peerCert;
04564 #endif
04565             store->ex_data = ssl;
04566 
04567             ok = ssl->verifyCallback(1, store);
04568             if (!ok) {
04569                 CYASSL_MSG("Verify callback overriding valid certificate!");
04570                 ret = -1;
04571                 SendAlert(ssl, alert_fatal, bad_certificate);
04572                 ssl->options.isClosed = 1;
04573             }
04574             #ifdef SESSION_CERTS
04575             if (store->discardSessionCerts) {
04576                 CYASSL_MSG("Verify callback requested discard sess certs");
04577                 ssl->session.chain.count = 0;
04578             }
04579             #endif
04580         }
04581     }
04582 #endif
04583 
04584     if (ssl->options.verifyNone &&
04585                               (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) {
04586         CYASSL_MSG("Ignoring CRL problem based on verify setting");
04587         ret = ssl->error = 0;
04588     }
04589 
04590     if (ret == 0 && ssl->options.side == CYASSL_CLIENT_END)
04591         ssl->options.serverState = SERVER_CERT_COMPLETE;
04592 
04593     if (ssl->keys.encryptionOn) {
04594         *inOutIdx += ssl->keys.padSz;
04595     }
04596 
04597 #ifdef CYASSL_SMALL_STACK
04598     XFREE(store,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
04599     XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04600 #endif
04601 
04602     return ret;
04603 }
04604 
04605 #endif /* !NO_CERTS */
04606 
04607 
04608 static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx,
04609                                                     word32 size, word32 totalSz)
04610 {
04611     (void)input;
04612 
04613     if (size) /* must be 0 */
04614         return BUFFER_ERROR;
04615 
04616     if (ssl->keys.encryptionOn) {
04617         /* access beyond input + size should be checked against totalSz */
04618         if (*inOutIdx + ssl->keys.padSz > totalSz)
04619             return BUFFER_E;
04620 
04621         *inOutIdx += ssl->keys.padSz;
04622     }
04623 
04624     if (ssl->options.side == CYASSL_SERVER_END) {
04625         SendAlert(ssl, alert_fatal, unexpected_message); /* try */
04626         return FATAL_ERROR;
04627     }
04628 #ifdef HAVE_SECURE_RENEGOTIATION
04629     else if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
04630         ssl->secure_renegotiation->startScr = 1;
04631         return 0;
04632     }
04633 #endif
04634     else {
04635         return SendAlert(ssl, alert_warning, no_renegotiation);
04636     }
04637 }
04638 
04639 
04640 int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, word32 size,
04641                                                       word32 totalSz, int sniff)
04642 {
04643     word32 finishedSz = (ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ);
04644 
04645     if (finishedSz != size)
04646         return BUFFER_ERROR;
04647 
04648     /* check against totalSz */
04649     if (*inOutIdx + size + ssl->keys.padSz > totalSz)
04650         return BUFFER_E;
04651 
04652     #ifdef CYASSL_CALLBACKS
04653         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
04654         if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
04655     #endif
04656 
04657     if (sniff == NO_SNIFF) {
04658         if (XMEMCMP(input + *inOutIdx, &ssl->verifyHashes, size) != 0) {
04659             CYASSL_MSG("Verify finished error on hashes");
04660             return VERIFY_FINISHED_ERROR;
04661         }
04662     }
04663 
04664 #ifdef HAVE_SECURE_RENEGOTIATION
04665     if (ssl->secure_renegotiation) {
04666         /* save peer's state */
04667         if (ssl->options.side == CYASSL_CLIENT_END)
04668             XMEMCPY(ssl->secure_renegotiation->server_verify_data,
04669                     input + *inOutIdx, TLS_FINISHED_SZ);
04670         else
04671             XMEMCPY(ssl->secure_renegotiation->client_verify_data,
04672                     input + *inOutIdx, TLS_FINISHED_SZ);
04673     }
04674 #endif
04675 
04676     /* force input exhaustion at ProcessReply consuming padSz */
04677     *inOutIdx += size + ssl->keys.padSz;
04678 
04679     if (ssl->options.side == CYASSL_CLIENT_END) {
04680         ssl->options.serverState = SERVER_FINISHED_COMPLETE;
04681         if (!ssl->options.resuming) {
04682             ssl->options.handShakeState = HANDSHAKE_DONE;
04683             ssl->options.handShakeDone  = 1;
04684 
04685 #ifdef CYASSL_DTLS
04686             if (ssl->options.dtls) {
04687                 /* Other side has received our Finished, go to next epoch */
04688                 ssl->keys.dtls_epoch++;
04689                 ssl->keys.dtls_sequence_number = 1;
04690             }
04691 #endif
04692         }
04693     }
04694     else {
04695         ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
04696         if (ssl->options.resuming) {
04697             ssl->options.handShakeState = HANDSHAKE_DONE;
04698             ssl->options.handShakeDone  = 1;
04699 
04700 #ifdef CYASSL_DTLS
04701             if (ssl->options.dtls) {
04702                 /* Other side has received our Finished, go to next epoch */
04703                 ssl->keys.dtls_epoch++;
04704                 ssl->keys.dtls_sequence_number = 1;
04705             }
04706 #endif
04707         }
04708     }
04709 
04710     return 0;
04711 }
04712 
04713 
04714 /* Make sure no duplicates, no fast forward, or other problems; 0 on success */
04715 static int SanityCheckMsgReceived(CYASSL* ssl, byte type)
04716 {
04717     /* verify not a duplicate, mark received, check state */
04718     switch (type) {
04719 
04720 #ifndef NO_CYASSL_CLIENT
04721         case hello_request:
04722             if (ssl->msgsReceived.got_hello_request) {
04723                 CYASSL_MSG("Duplicate HelloRequest received");
04724                 return DUPLICATE_MSG_E;
04725             }
04726             ssl->msgsReceived.got_hello_request = 1;
04727 
04728             break;
04729 #endif
04730 
04731 #ifndef NO_CYASSL_SERVER
04732         case client_hello:
04733             if (ssl->msgsReceived.got_client_hello) {
04734                 CYASSL_MSG("Duplicate ClientHello received");
04735                 return DUPLICATE_MSG_E;
04736             }
04737             ssl->msgsReceived.got_client_hello = 1;
04738 
04739             break;
04740 #endif
04741 
04742 #ifndef NO_CYASSL_CLIENT
04743         case server_hello:
04744             if (ssl->msgsReceived.got_server_hello) {
04745                 CYASSL_MSG("Duplicate ServerHello received");
04746                 return DUPLICATE_MSG_E;
04747             }
04748             ssl->msgsReceived.got_server_hello = 1;
04749 
04750             break;
04751 #endif
04752 
04753 #ifndef NO_CYASSL_CLIENT
04754         case hello_verify_request:
04755             if (ssl->msgsReceived.got_hello_verify_request) {
04756                 CYASSL_MSG("Duplicate HelloVerifyRequest received");
04757                 return DUPLICATE_MSG_E;
04758             }
04759             ssl->msgsReceived.got_hello_verify_request = 1;
04760 
04761             break;
04762 #endif
04763 
04764 #ifndef NO_CYASSL_CLIENT
04765         case session_ticket:
04766             if (ssl->msgsReceived.got_session_ticket) {
04767                 CYASSL_MSG("Duplicate SessionTicket received");
04768                 return DUPLICATE_MSG_E;
04769             }
04770             ssl->msgsReceived.got_session_ticket = 1;
04771 
04772             break;
04773 #endif
04774 
04775         case certificate:
04776             if (ssl->msgsReceived.got_certificate) {
04777                 CYASSL_MSG("Duplicate Certificate received");
04778                 return DUPLICATE_MSG_E;
04779             }
04780             ssl->msgsReceived.got_certificate = 1;
04781 
04782 #ifndef NO_CYASSL_CLIENT
04783             if (ssl->options.side == CYASSL_CLIENT_END) {
04784                 if ( ssl->msgsReceived.got_server_hello == 0) {
04785                     CYASSL_MSG("No ServerHello before Cert");
04786                     return OUT_OF_ORDER_E;
04787                 }
04788             }
04789 #endif
04790 #ifndef NO_CYASSL_SERVER
04791             if (ssl->options.side == CYASSL_SERVER_END) {
04792                 if ( ssl->msgsReceived.got_client_hello == 0) {
04793                     CYASSL_MSG("No ClientHello before Cert");
04794                     return OUT_OF_ORDER_E;
04795                 }
04796             }
04797 #endif
04798             break;
04799 
04800 #ifndef NO_CYASSL_CLIENT
04801         case server_key_exchange:
04802             if (ssl->msgsReceived.got_server_key_exchange) {
04803                 CYASSL_MSG("Duplicate ServerKeyExchange received");
04804                 return DUPLICATE_MSG_E;
04805             }
04806             ssl->msgsReceived.got_server_key_exchange = 1;
04807 
04808             if ( ssl->msgsReceived.got_server_hello == 0) {
04809                 CYASSL_MSG("No ServerHello before Cert");
04810                 return OUT_OF_ORDER_E;
04811             }
04812 
04813             break;
04814 #endif
04815 
04816 #ifndef NO_CYASSL_CLIENT
04817         case certificate_request:
04818             if (ssl->msgsReceived.got_certificate_request) {
04819                 CYASSL_MSG("Duplicate CertificateRequest received");
04820                 return DUPLICATE_MSG_E;
04821             }
04822             ssl->msgsReceived.got_certificate_request = 1;
04823 
04824             break;
04825 #endif
04826 
04827 #ifndef NO_CYASSL_CLIENT
04828         case server_hello_done:
04829             if (ssl->msgsReceived.got_server_hello_done) {
04830                 CYASSL_MSG("Duplicate ServerHelloDone received");
04831                 return DUPLICATE_MSG_E;
04832             }
04833             ssl->msgsReceived.got_server_hello_done = 1;
04834 
04835             if (ssl->msgsReceived.got_certificate == 0) {
04836                 if (ssl->specs.kea == psk_kea ||
04837                     ssl->specs.kea == dhe_psk_kea ||
04838                     ssl->options.usingAnon_cipher) {
04839                     CYASSL_MSG("No Cert required");
04840                 } else {
04841                     CYASSL_MSG("No Certificate before ServerHelloDone");
04842                     return OUT_OF_ORDER_E;
04843                 }
04844             }
04845             if (ssl->msgsReceived.got_server_key_exchange == 0) {
04846                 if (ssl->specs.static_ecdh == 1 ||
04847                     ssl->specs.kea == rsa_kea ||
04848                     ssl->specs.kea == ntru_kea) {
04849                     CYASSL_MSG("No KeyExchange required");
04850                 } else {
04851                     CYASSL_MSG("No ServerKeyExchange before ServerDone");
04852                     return OUT_OF_ORDER_E;
04853                 }
04854             }
04855             break;
04856 #endif
04857 
04858 #ifndef NO_CYASSL_SERVER
04859         case certificate_verify:
04860             if (ssl->msgsReceived.got_certificate_verify) {
04861                 CYASSL_MSG("Duplicate CertificateVerify received");
04862                 return DUPLICATE_MSG_E;
04863             }
04864             ssl->msgsReceived.got_certificate_verify = 1;
04865 
04866             if ( ssl->msgsReceived.got_certificate == 0) {
04867                 CYASSL_MSG("No Cert before CertVerify");
04868                 return OUT_OF_ORDER_E;
04869             }
04870             break;
04871 #endif
04872 
04873 #ifndef NO_CYASSL_SERVER
04874         case client_key_exchange:
04875             if (ssl->msgsReceived.got_client_key_exchange) {
04876                 CYASSL_MSG("Duplicate ClientKeyExchange received");
04877                 return DUPLICATE_MSG_E;
04878             }
04879             ssl->msgsReceived.got_client_key_exchange = 1;
04880 
04881             if (ssl->msgsReceived.got_client_hello == 0) {
04882                 CYASSL_MSG("No ClientHello before ClientKeyExchange");
04883                 return OUT_OF_ORDER_E;
04884             }
04885             break;
04886 #endif
04887 
04888         case finished:
04889             if (ssl->msgsReceived.got_finished) {
04890                 CYASSL_MSG("Duplicate Finished received");
04891                 return DUPLICATE_MSG_E;
04892             }
04893             ssl->msgsReceived.got_finished = 1;
04894 
04895             if (ssl->msgsReceived.got_change_cipher == 0) {
04896                 CYASSL_MSG("Finished received before ChangeCipher");
04897                 return NO_CHANGE_CIPHER_E;
04898             }
04899 
04900             break;
04901 
04902         case change_cipher_hs:
04903             if (ssl->msgsReceived.got_change_cipher) {
04904                 CYASSL_MSG("Duplicate ChangeCipher received");
04905                 return DUPLICATE_MSG_E;
04906             }
04907             ssl->msgsReceived.got_change_cipher = 1;
04908 
04909 #ifndef NO_CYASSL_CLIENT
04910             if (ssl->options.side == CYASSL_CLIENT_END) {
04911                 if (!ssl->options.resuming &&
04912                                  ssl->msgsReceived.got_server_hello_done == 0) {
04913                     CYASSL_MSG("No ServerHelloDone before ChangeCipher");
04914                     return OUT_OF_ORDER_E;
04915                 }
04916             }
04917 #endif
04918 #ifndef NO_CYASSL_SERVER
04919             if (ssl->options.side == CYASSL_SERVER_END) {
04920                 if (!ssl->options.resuming &&
04921                                ssl->msgsReceived.got_client_key_exchange == 0) {
04922                     CYASSL_MSG("No ClientKeyExchange before ChangeCipher");
04923                     return OUT_OF_ORDER_E;
04924                 }
04925             }
04926 #endif
04927 
04928             break;
04929 
04930         default:
04931             CYASSL_MSG("Unknown message type");
04932             return SANITY_MSG_E;
04933     }
04934 
04935     return 0;
04936 }
04937 
04938 
04939 static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
04940                           byte type, word32 size, word32 totalSz)
04941 {
04942     int ret = 0;
04943     (void)totalSz;
04944 
04945     CYASSL_ENTER("DoHandShakeMsgType");
04946 
04947     /* make sure can read the message */
04948     if (*inOutIdx + size > totalSz)
04949         return INCOMPLETE_DATA;
04950 
04951     /* sanity check msg received */
04952     if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) {
04953         CYASSL_MSG("Sanity Check on handshake message type received failed");
04954         return ret;
04955     }
04956 
04957     /* hello_request not hashed */
04958     if (type != hello_request) {
04959         ret = HashInput(ssl, input + *inOutIdx, size);
04960         if (ret != 0) return ret;
04961     }
04962 
04963 #ifdef CYASSL_CALLBACKS
04964     /* add name later, add on record and handshake header part back on */
04965     if (ssl->toInfoOn) {
04966         int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
04967         AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
04968                       size + add, ssl->heap);
04969         AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
04970     }
04971 #endif
04972 
04973     if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
04974         CYASSL_MSG("HandShake message after handshake complete");
04975         SendAlert(ssl, alert_fatal, unexpected_message);
04976         return OUT_OF_ORDER_E;
04977     }
04978 
04979     if (ssl->options.side == CYASSL_CLIENT_END && ssl->options.dtls == 0 &&
04980                ssl->options.serverState == NULL_STATE && type != server_hello) {
04981         CYASSL_MSG("First server message not server hello");
04982         SendAlert(ssl, alert_fatal, unexpected_message);
04983         return OUT_OF_ORDER_E;
04984     }
04985 
04986     if (ssl->options.side == CYASSL_CLIENT_END && ssl->options.dtls &&
04987             type == server_hello_done &&
04988             ssl->options.serverState < SERVER_HELLO_COMPLETE) {
04989         CYASSL_MSG("Server hello done received before server hello in DTLS");
04990         SendAlert(ssl, alert_fatal, unexpected_message);
04991         return OUT_OF_ORDER_E;
04992     }
04993 
04994     if (ssl->options.side == CYASSL_SERVER_END &&
04995                ssl->options.clientState == NULL_STATE && type != client_hello) {
04996         CYASSL_MSG("First client message not client hello");
04997         SendAlert(ssl, alert_fatal, unexpected_message);
04998         return OUT_OF_ORDER_E;
04999     }
05000 
05001 
05002     switch (type) {
05003 
05004     case hello_request:
05005         CYASSL_MSG("processing hello request");
05006         ret = DoHelloRequest(ssl, input, inOutIdx, size, totalSz);
05007         break;
05008 
05009 #ifndef NO_CYASSL_CLIENT
05010     case hello_verify_request:
05011         CYASSL_MSG("processing hello verify request");
05012         ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size);
05013         break;
05014 
05015     case server_hello:
05016         CYASSL_MSG("processing server hello");
05017         ret = DoServerHello(ssl, input, inOutIdx, size);
05018         break;
05019 
05020 #ifndef NO_CERTS
05021     case certificate_request:
05022         CYASSL_MSG("processing certificate request");
05023         ret = DoCertificateRequest(ssl, input, inOutIdx, size);
05024         break;
05025 #endif
05026 
05027     case server_key_exchange:
05028         CYASSL_MSG("processing server key exchange");
05029         ret = DoServerKeyExchange(ssl, input, inOutIdx, size);
05030         break;
05031 
05032 #ifdef HAVE_SESSION_TICKET
05033     case session_ticket:
05034         CYASSL_MSG("processing session ticket");
05035         ret = DoSessionTicket(ssl, input, inOutIdx, size);
05036         break;
05037 #endif /* HAVE_SESSION_TICKET */
05038 #endif
05039 
05040 #ifndef NO_CERTS
05041     case certificate:
05042         CYASSL_MSG("processing certificate");
05043         ret =  DoCertificate(ssl, input, inOutIdx, size);
05044         break;
05045 #endif
05046 
05047     case server_hello_done:
05048         CYASSL_MSG("processing server hello done");
05049         #ifdef CYASSL_CALLBACKS
05050             if (ssl->hsInfoOn)
05051                 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
05052             if (ssl->toInfoOn)
05053                 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
05054         #endif
05055         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
05056         if (ssl->keys.encryptionOn) {
05057             *inOutIdx += ssl->keys.padSz;
05058         }
05059         break;
05060 
05061     case finished:
05062         CYASSL_MSG("processing finished");
05063         ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
05064         break;
05065 
05066 #ifndef NO_CYASSL_SERVER
05067     case client_hello:
05068         CYASSL_MSG("processing client hello");
05069         ret = DoClientHello(ssl, input, inOutIdx, size);
05070         break;
05071 
05072     case client_key_exchange:
05073         CYASSL_MSG("processing client key exchange");
05074         ret = DoClientKeyExchange(ssl, input, inOutIdx, size);
05075         break;
05076 
05077 #if !defined(NO_RSA) || defined(HAVE_ECC)
05078     case certificate_verify:
05079         CYASSL_MSG("processing certificate verify");
05080         ret = DoCertificateVerify(ssl, input, inOutIdx, size);
05081         break;
05082 #endif /* !NO_RSA || HAVE_ECC */
05083 
05084 #endif /* !NO_CYASSL_SERVER */
05085 
05086     default:
05087         CYASSL_MSG("Unknown handshake message type");
05088         ret = UNKNOWN_HANDSHAKE_TYPE;
05089         break;
05090     }
05091 
05092     CYASSL_LEAVE("DoHandShakeMsgType()", ret);
05093     return ret;
05094 }
05095 
05096 
05097 static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
05098                           word32 totalSz)
05099 {
05100     byte   type;
05101     word32 size;
05102     int    ret = 0;
05103 
05104     CYASSL_ENTER("DoHandShakeMsg()");
05105 
05106     if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size, totalSz) != 0)
05107         return PARSE_ERROR;
05108 
05109     ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
05110 
05111     CYASSL_LEAVE("DoHandShakeMsg()", ret);
05112     return ret;
05113 }
05114 
05115 
05116 #ifdef CYASSL_DTLS
05117 
05118 static INLINE int DtlsCheckWindow(DtlsState* state)
05119 {
05120     word32 cur;
05121     word32 next;
05122     DtlsSeq window;
05123 
05124     if (state->curEpoch == state->nextEpoch) {
05125         next = state->nextSeq;
05126         window = state->window;
05127     }
05128     else if (state->curEpoch < state->nextEpoch) {
05129         next = state->prevSeq;
05130         window = state->prevWindow;
05131     }
05132     else {
05133         return 0;
05134     }
05135 
05136     cur = state->curSeq;
05137 
05138     if ((next > DTLS_SEQ_BITS) && (cur < next - DTLS_SEQ_BITS)) {
05139         return 0;
05140     }
05141     else if ((cur < next) && (window & ((DtlsSeq)1 << (next - cur - 1)))) {
05142         return 0;
05143     }
05144 
05145     return 1;
05146 }
05147 
05148 
05149 static INLINE int DtlsUpdateWindow(DtlsState* state)
05150 {
05151     word32 cur;
05152     word32* next;
05153     DtlsSeq* window;
05154 
05155     if (state->curEpoch == state->nextEpoch) {
05156         next = &state->nextSeq;
05157         window = &state->window;
05158     }
05159     else {
05160         next = &state->prevSeq;
05161         window = &state->prevWindow;
05162     }
05163 
05164     cur = state->curSeq;
05165 
05166     if (cur < *next) {
05167         *window |= ((DtlsSeq)1 << (*next - cur - 1));
05168     }
05169     else {
05170         *window <<= (1 + cur - *next);
05171         *window |= 1;
05172         *next = cur + 1;
05173     }
05174 
05175     return 1;
05176 }
05177 
05178 
05179 static int DtlsMsgDrain(CYASSL* ssl)
05180 {
05181     DtlsMsg* item = ssl->dtls_msg_list;
05182     int ret = 0;
05183 
05184     /* While there is an item in the store list, and it is the expected
05185      * message, and it is complete, and there hasn't been an error in the
05186      * last messge... */
05187     while (item != NULL &&
05188             ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
05189             item->fragSz == item->sz &&
05190             ret == 0) {
05191         word32 idx = 0;
05192         ssl->keys.dtls_expected_peer_handshake_number++;
05193         ret = DoHandShakeMsgType(ssl, item->msg,
05194                                  &idx, item->type, item->sz, item->sz);
05195         ssl->dtls_msg_list = item->next;
05196         DtlsMsgDelete(item, ssl->heap);
05197         item = ssl->dtls_msg_list;
05198     }
05199 
05200     return ret;
05201 }
05202 
05203 
05204 static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
05205                           word32 totalSz)
05206 {
05207     byte type;
05208     word32 size;
05209     word32 fragOffset, fragSz;
05210     int ret = 0;
05211 
05212     CYASSL_ENTER("DoDtlsHandShakeMsg()");
05213     if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
05214                                &size, &fragOffset, &fragSz, totalSz) != 0)
05215         return PARSE_ERROR;
05216 
05217     if (*inOutIdx + fragSz > totalSz)
05218         return INCOMPLETE_DATA;
05219 
05220     /* Check the handshake sequence number first. If out of order,
05221      * add the current message to the list. If the message is in order,
05222      * but it is a fragment, add the current message to the list, then
05223      * check the head of the list to see if it is complete, if so, pop
05224      * it out as the current message. If the message is complete and in
05225      * order, process it. Check the head of the list to see if it is in
05226      * order, if so, process it. (Repeat until list exhausted.) If the
05227      * head is out of order, return for more processing.
05228      */
05229     if (ssl->keys.dtls_peer_handshake_number >
05230                                 ssl->keys.dtls_expected_peer_handshake_number) {
05231         /* Current message is out of order. It will get stored in the list.
05232          * Storing also takes care of defragmentation. */
05233         ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
05234                         ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
05235                         size, type, fragOffset, fragSz, ssl->heap);
05236         *inOutIdx += fragSz;
05237         ret = 0;
05238     }
05239     else if (ssl->keys.dtls_peer_handshake_number <
05240                                 ssl->keys.dtls_expected_peer_handshake_number) {
05241         /* Already saw this message and processed it. It can be ignored. */
05242         *inOutIdx += fragSz;
05243         ret = 0;
05244     }
05245     else if (fragSz < size) {
05246         /* Since this branch is in order, but fragmented, dtls_msg_list will be
05247          * pointing to the message with this fragment in it. Check it to see
05248          * if it is completed. */
05249         ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
05250                         ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
05251                         size, type, fragOffset, fragSz, ssl->heap);
05252         *inOutIdx += fragSz;
05253         ret = 0;
05254         if (ssl->dtls_msg_list != NULL &&
05255             ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz)
05256             ret = DtlsMsgDrain(ssl);
05257     }
05258     else {
05259         /* This branch is in order next, and a complete message. */
05260         ssl->keys.dtls_expected_peer_handshake_number++;
05261         ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
05262         if (ret == 0 && ssl->dtls_msg_list != NULL)
05263             ret = DtlsMsgDrain(ssl);
05264     }
05265 
05266     CYASSL_LEAVE("DoDtlsHandShakeMsg()", ret);
05267     return ret;
05268 }
05269 #endif
05270 
05271 
05272 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
05273     || defined(HAVE_AESGCM)
05274 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
05275 {
05276 #ifdef CYASSL_DTLS
05277     if (ssl->options.dtls) {
05278         if (verify)
05279             return ssl->keys.dtls_state.curSeq; /* explicit from peer */
05280         else
05281             return ssl->keys.dtls_sequence_number - 1; /* already incremented */
05282     }
05283 #endif
05284     if (verify)
05285         return ssl->keys.peer_sequence_number++;
05286     else
05287         return ssl->keys.sequence_number++;
05288 }
05289 #endif
05290 
05291 
05292 #ifdef HAVE_AEAD
05293 static INLINE void AeadIncrementExpIV(CYASSL* ssl)
05294 {
05295     int i;
05296     for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) {
05297         if (++ssl->keys.aead_exp_IV[i]) return;
05298     }
05299 }
05300 
05301 
05302 #ifdef HAVE_POLY1305
05303 /*more recent rfc's concatonate input for poly1305 differently*/
05304 static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out,
05305                        byte* cipher, word16 sz, byte* tag)
05306 {
05307     int ret       = 0;
05308     int paddingSz = 0;
05309     int msglen    = (sz - ssl->specs.aead_mac_size);
05310     word32 keySz  = 32;
05311     byte padding[16];
05312 
05313     if (msglen < 0)
05314         return INPUT_CASE_ERROR;
05315 
05316     XMEMSET(padding, 0, sizeof(padding));
05317 
05318     if ((ret = Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
05319         return ret;
05320 
05321     /* additional input to poly1305 */
05322     if ((ret = Poly1305Update(ssl->auth.poly1305, additional,
05323                    CHACHA20_BLOCK_SIZE)) != 0)
05324         return ret;
05325 
05326     /* cipher input */
05327     if ((ret = Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
05328         return ret;
05329 
05330     /* handle padding for cipher input to make it 16 bytes long */
05331     if (msglen % 16 != 0) {
05332           paddingSz = (16 - (sz - ssl->specs.aead_mac_size) % 16);
05333           if (paddingSz < 0)
05334               return INPUT_CASE_ERROR;
05335 
05336           if ((ret = Poly1305Update(ssl->auth.poly1305, padding, paddingSz))
05337                  != 0)
05338               return ret;
05339     }
05340 
05341     /* add size of AD and size of cipher to poly input */
05342     XMEMSET(padding, 0, sizeof(padding));
05343     padding[0] = CHACHA20_BLOCK_SIZE;
05344 
05345     /* 32 bit size of cipher to 64 bit endian */
05346     padding[8]  =  msglen       & 0xff;
05347     padding[9]  = (msglen >> 8) & 0xff;
05348     padding[10] = (msglen >>16) & 0xff;
05349     padding[11] = (msglen >>24) & 0xff;
05350     if ((ret = Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
05351                 != 0)
05352         return ret;
05353 
05354     /* generate tag */
05355     if ((ret = Poly1305Final(ssl->auth.poly1305, tag)) != 0)
05356         return ret;
05357 
05358     return ret;
05359 }
05360 
05361 
05362 /* Used for the older version of creating AEAD tags with Poly1305 */
05363 static int Poly1305TagOld(CYASSL* ssl, byte* additional, const byte* out,
05364                        byte* cipher, word16 sz, byte* tag)
05365 {
05366     int ret       = 0;
05367     int msglen    = (sz - ssl->specs.aead_mac_size);
05368     word32 keySz  = 32;
05369     byte padding[8]; /* used to temporarly store lengths */
05370 
05371 #ifdef CHACHA_AEAD_TEST
05372       printf("Using old version of poly1305 input.\n");
05373 #endif
05374 
05375     if (msglen < 0)
05376         return INPUT_CASE_ERROR;
05377 
05378     if ((ret = Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
05379         return ret;
05380 
05381     /* add TLS compressed length and additional input to poly1305 */
05382     additional[AEAD_AUTH_DATA_SZ - 2] = (msglen >> 8) & 0xff;
05383     additional[AEAD_AUTH_DATA_SZ - 1] =  msglen       & 0xff;
05384     if ((ret = Poly1305Update(ssl->auth.poly1305, additional,
05385                    AEAD_AUTH_DATA_SZ)) != 0)
05386         return ret;
05387 
05388     /* length of additional input plus padding */
05389     XMEMSET(padding, 0, sizeof(padding));
05390     padding[0] = AEAD_AUTH_DATA_SZ;
05391     if ((ret = Poly1305Update(ssl->auth.poly1305, padding,
05392                     sizeof(padding))) != 0)
05393         return ret;
05394 
05395 
05396     /* add cipher info and then its length */
05397     XMEMSET(padding, 0, sizeof(padding));
05398     if ((ret = Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
05399         return ret;
05400 
05401     /* 32 bit size of cipher to 64 bit endian */
05402     padding[0] =  msglen        & 0xff;
05403     padding[1] = (msglen >>  8) & 0xff;
05404     padding[2] = (msglen >> 16) & 0xff;
05405     padding[3] = (msglen >> 24) & 0xff;
05406     if ((ret = Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
05407         != 0)
05408         return ret;
05409 
05410     /* generate tag */
05411     if ((ret = Poly1305Final(ssl->auth.poly1305, tag)) != 0)
05412         return ret;
05413 
05414     return ret;
05415 }
05416 #endif /*HAVE_POLY1305*/
05417 
05418 
05419 #ifdef HAVE_CHACHA
05420 static int  ChachaAEADEncrypt(CYASSL* ssl, byte* out, const byte* input,
05421                               word16 sz)
05422 {
05423     const byte* additionalSrc = input - RECORD_HEADER_SZ;
05424     int ret = 0;
05425     byte tag[POLY1305_AUTH_SZ];
05426     byte additional[CHACHA20_BLOCK_SIZE];
05427     byte nonce[AEAD_NONCE_SZ];
05428     byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
05429     #ifdef CHACHA_AEAD_TEST
05430         int i;
05431     #endif
05432 
05433     XMEMSET(tag, 0, sizeof(tag));
05434     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05435     XMEMSET(cipher, 0, sizeof(cipher));
05436     XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
05437     
05438     /* get nonce */
05439     c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ
05440            + AEAD_SEQ_OFFSET);
05441     
05442     /* opaque SEQ number stored for AD */
05443     c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET);
05444     
05445     /* Store the type, version. Unfortunately, they are in
05446      * the input buffer ahead of the plaintext. */
05447     #ifdef CYASSL_DTLS
05448         if (ssl->options.dtls) {
05449             c16toa(ssl->keys.dtls_epoch, additional);
05450             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
05451         }
05452     #endif
05453     
05454     XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
05455     
05456     #ifdef CHACHA_AEAD_TEST
05457         printf("Encrypt Additional : ");
05458         for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
05459             printf("%02x", additional[i]);
05460         }
05461         printf("\n\n");
05462         printf("input before encryption :\n");
05463         for (i = 0; i < sz; i++) {
05464             printf("%02x", input[i]);
05465             if ((i + 1) % 16 == 0)
05466                 printf("\n");
05467         }
05468         printf("\n");
05469     #endif
05470     
05471     /* set the nonce for chacha and get poly1305 key */
05472     if ((ret = Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0)
05473         return ret;
05474     
05475         if ((ret = Chacha_Process(ssl->encrypt.chacha, cipher,
05476                     cipher, sizeof(cipher))) != 0)
05477         return ret;
05478     
05479     /* encrypt the plain text */
05480     if ((ret = Chacha_Process(ssl->encrypt.chacha, out, input,
05481                    sz - ssl->specs.aead_mac_size)) != 0)
05482         return ret;
05483     
05484     #ifdef HAVE_POLY1305
05485         /* get the tag : future use of hmac could go here*/
05486         if (ssl->options.oldPoly == 1) {
05487             if ((ret = Poly1305TagOld(ssl, additional, (const byte* )out,
05488                         cipher, sz, tag)) != 0)
05489                 return ret;
05490         }
05491         else {
05492             if ((ret = Poly1305Tag(ssl, additional, (const byte* )out,
05493                         cipher, sz, tag)) != 0)
05494                 return ret;
05495         }
05496     #endif
05497     
05498     /* append tag to ciphertext */
05499     XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag));
05500     
05501     AeadIncrementExpIV(ssl);
05502     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05503     
05504     #ifdef CHACHA_AEAD_TEST
05505        printf("mac tag :\n");
05506         for (i = 0; i < 16; i++) {
05507            printf("%02x", tag[i]);
05508            if ((i + 1) % 16 == 0)
05509                printf("\n");
05510         }
05511        printf("\n\noutput after encrypt :\n");
05512         for (i = 0; i < sz; i++) {
05513            printf("%02x", out[i]);
05514            if ((i + 1) % 16 == 0)
05515                printf("\n");
05516         }
05517         printf("\n");
05518     #endif
05519     
05520     return ret;
05521 }
05522 
05523 
05524 static int ChachaAEADDecrypt(CYASSL* ssl, byte* plain, const byte* input,
05525                            word16 sz)
05526 {
05527     byte additional[CHACHA20_BLOCK_SIZE];
05528     byte nonce[AEAD_NONCE_SZ];
05529     byte tag[POLY1305_AUTH_SZ];
05530     byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
05531     int i;
05532     int ret = 0;
05533     
05534     XMEMSET(tag, 0, sizeof(tag));
05535     XMEMSET(cipher, 0, sizeof(cipher));
05536     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05537     XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
05538     
05539     #ifdef CHACHA_AEAD_TEST
05540        printf("input before decrypt :\n");
05541         for (i = 0; i < sz; i++) {
05542            printf("%02x", input[i]);
05543            if ((i + 1) % 16 == 0)
05544                printf("\n");
05545         }
05546         printf("\n");
05547     #endif
05548     
05549     /* get nonce */
05550     c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ
05551             + AEAD_SEQ_OFFSET);
05552     
05553     /* sequence number field is 64-bits, we only use 32-bits */
05554     c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
05555     
05556     /* get AD info */
05557     additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
05558     additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
05559     additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
05560     
05561     /* Store the type, version. */
05562     #ifdef CYASSL_DTLS
05563         if (ssl->options.dtls)
05564             c16toa(ssl->keys.dtls_state.curEpoch, additional);
05565     #endif
05566         
05567     #ifdef CHACHA_AEAD_TEST
05568         printf("Decrypt Additional : ");
05569         for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
05570             printf("%02x", additional[i]);
05571         }
05572         printf("\n\n");
05573     #endif
05574     
05575     /* set nonce and get poly1305 key */
05576     if ((ret = Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0)
05577         return ret;
05578     
05579     if ((ret = Chacha_Process(ssl->decrypt.chacha, cipher,
05580                     cipher, sizeof(cipher))) != 0)
05581         return ret;
05582     
05583     #ifdef HAVE_POLY1305
05584         /* get the tag : future use of hmac could go here*/
05585         if (ssl->options.oldPoly == 1) {
05586             if ((ret = Poly1305TagOld(ssl, additional, input, cipher,
05587                             sz, tag)) != 0)
05588                 return ret;
05589         }
05590         else {
05591             if ((ret = Poly1305Tag(ssl, additional, input, cipher,
05592                             sz, tag)) != 0)
05593                 return ret;
05594         }
05595     #endif
05596     
05597     /* check mac sent along with packet */
05598     ret = 0;
05599     for (i = 0; i <  ssl->specs.aead_mac_size; i++) {
05600         if ((input + sz - ssl->specs.aead_mac_size)[i] != tag[i])
05601             ret = 1;
05602     }
05603     
05604     if (ret == 1) {
05605         CYASSL_MSG("Mac did not match");
05606         SendAlert(ssl, alert_fatal, bad_record_mac);
05607         XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05608         return VERIFY_MAC_ERROR;
05609     }
05610     
05611     /* if mac was good decrypt message */
05612     if ((ret = Chacha_Process(ssl->decrypt.chacha, plain, input,
05613                    sz - ssl->specs.aead_mac_size)) != 0)
05614         return ret;
05615         
05616     #ifdef CHACHA_AEAD_TEST
05617        printf("plain after decrypt :\n");
05618         for (i = 0; i < sz; i++) {
05619            printf("%02x", plain[i]);
05620            if ((i + 1) % 16 == 0)
05621                printf("\n");
05622         }
05623         printf("\n");
05624     #endif
05625     
05626     return ret;
05627 }
05628 #endif /* HAVE_CHACHA */
05629 #endif
05630 
05631 
05632 static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz)
05633 {
05634     (void)out;
05635     (void)input;
05636     (void)sz;
05637 
05638     if (ssl->encrypt.setup == 0) {
05639         CYASSL_MSG("Encrypt ciphers not setup");
05640         return ENCRYPT_ERROR;
05641     }
05642 
05643 #ifdef HAVE_FUZZER
05644     if (ssl->fuzzerCb)
05645         ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx);
05646 #endif
05647 
05648     switch (ssl->specs.bulk_cipher_algorithm) {
05649         #ifdef BUILD_ARC4
05650             case cyassl_rc4:
05651                 Arc4Process(ssl->encrypt.arc4, out, input, sz);
05652                 break;
05653         #endif
05654 
05655         #ifdef BUILD_DES3
05656             case cyassl_triple_des:
05657                 return Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
05658         #endif
05659 
05660         #ifdef BUILD_AES
05661             case cyassl_aes:
05662                 return AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
05663         #endif
05664 
05665         #ifdef BUILD_AESGCM
05666             case cyassl_aes_gcm:
05667                 {
05668                     int  gcmRet;
05669                     byte additional[AEAD_AUTH_DATA_SZ];
05670                     byte nonce[AEAD_NONCE_SZ];
05671                     const byte* additionalSrc = input - 5;
05672 
05673                     XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
05674 
05675                     /* sequence number field is 64-bits, we only use 32-bits */
05676                     c32toa(GetSEQIncrement(ssl, 0),
05677                                             additional + AEAD_SEQ_OFFSET);
05678 
05679                     /* Store the type, version. Unfortunately, they are in
05680                      * the input buffer ahead of the plaintext. */
05681                     #ifdef CYASSL_DTLS
05682                         if (ssl->options.dtls) {
05683                             c16toa(ssl->keys.dtls_epoch, additional);
05684                             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
05685                         }
05686                     #endif
05687                     XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
05688 
05689                     /* Store the length of the plain text minus the explicit
05690                      * IV length minus the authentication tag size. */
05691                     c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
05692                                                 additional + AEAD_LEN_OFFSET);
05693                     XMEMCPY(nonce,
05694                                  ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
05695                     XMEMCPY(nonce + AEAD_IMP_IV_SZ,
05696                                      ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
05697                     gcmRet = AesGcmEncrypt(ssl->encrypt.aes,
05698                                  out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
05699                                  sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
05700                                  nonce, AEAD_NONCE_SZ,
05701                                  out + sz - ssl->specs.aead_mac_size,
05702                                  ssl->specs.aead_mac_size,
05703                                  additional, AEAD_AUTH_DATA_SZ);
05704                     if (gcmRet == 0)
05705                         AeadIncrementExpIV(ssl);
05706                     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05707                     return gcmRet;
05708                 }
05709                 break;
05710         #endif
05711 
05712         #ifdef HAVE_AESCCM
05713             case cyassl_aes_ccm:
05714                 {
05715                     byte additional[AEAD_AUTH_DATA_SZ];
05716                     byte nonce[AEAD_NONCE_SZ];
05717                     const byte* additionalSrc = input - 5;
05718 
05719                     XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
05720 
05721                     /* sequence number field is 64-bits, we only use 32-bits */
05722                     c32toa(GetSEQIncrement(ssl, 0),
05723                                             additional + AEAD_SEQ_OFFSET);
05724 
05725                     /* Store the type, version. Unfortunately, they are in
05726                      * the input buffer ahead of the plaintext. */
05727                     #ifdef CYASSL_DTLS
05728                         if (ssl->options.dtls) {
05729                             c16toa(ssl->keys.dtls_epoch, additional);
05730                             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
05731                         }
05732                     #endif
05733                     XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
05734 
05735                     /* Store the length of the plain text minus the explicit
05736                      * IV length minus the authentication tag size. */
05737                     c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
05738                                                 additional + AEAD_LEN_OFFSET);
05739                     XMEMCPY(nonce,
05740                                  ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
05741                     XMEMCPY(nonce + AEAD_IMP_IV_SZ,
05742                                      ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
05743                     AesCcmEncrypt(ssl->encrypt.aes,
05744                         out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
05745                             sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
05746                         nonce, AEAD_NONCE_SZ,
05747                         out + sz - ssl->specs.aead_mac_size,
05748                         ssl->specs.aead_mac_size,
05749                         additional, AEAD_AUTH_DATA_SZ);
05750                     AeadIncrementExpIV(ssl);
05751                     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05752                 }
05753                 break;
05754         #endif
05755 
05756         #ifdef HAVE_CAMELLIA
05757             case cyassl_camellia:
05758                 CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
05759                 break;
05760         #endif
05761 
05762         #ifdef HAVE_HC128
05763             case cyassl_hc128:
05764                 return Hc128_Process(ssl->encrypt.hc128, out, input, sz);
05765         #endif
05766 
05767         #ifdef BUILD_RABBIT
05768             case cyassl_rabbit:
05769                 return RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
05770         #endif
05771 
05772         #ifdef HAVE_CHACHA
05773             case cyassl_chacha:
05774                 return ChachaAEADEncrypt(ssl, out, input, sz);
05775         #endif
05776 
05777         #ifdef HAVE_NULL_CIPHER
05778             case cyassl_cipher_null:
05779                 if (input != out) {
05780                     XMEMMOVE(out, input, sz);
05781                 }
05782                 break;
05783         #endif
05784 
05785             default:
05786                 CYASSL_MSG("CyaSSL Encrypt programming error");
05787                 return ENCRYPT_ERROR;
05788     }
05789 
05790     return 0;
05791 }
05792 
05793 
05794 
05795 static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
05796                            word16 sz)
05797 {
05798     (void)plain;
05799     (void)input;
05800     (void)sz;
05801 
05802     if (ssl->decrypt.setup == 0) {
05803         CYASSL_MSG("Decrypt ciphers not setup");
05804         return DECRYPT_ERROR;
05805     }
05806 
05807     switch (ssl->specs.bulk_cipher_algorithm) {
05808         #ifdef BUILD_ARC4
05809             case cyassl_rc4:
05810                 Arc4Process(ssl->decrypt.arc4, plain, input, sz);
05811                 break;
05812         #endif
05813 
05814         #ifdef BUILD_DES3
05815             case cyassl_triple_des:
05816                 return Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
05817         #endif
05818 
05819         #ifdef BUILD_AES
05820             case cyassl_aes:
05821                 return AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
05822         #endif
05823 
05824         #ifdef BUILD_AESGCM
05825             case cyassl_aes_gcm:
05826             {
05827                 byte additional[AEAD_AUTH_DATA_SZ];
05828                 byte nonce[AEAD_NONCE_SZ];
05829 
05830                 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
05831 
05832                 /* sequence number field is 64-bits, we only use 32-bits */
05833                 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
05834 
05835                 #ifdef CYASSL_DTLS
05836                     if (ssl->options.dtls)
05837                         c16toa(ssl->keys.dtls_state.curEpoch, additional);
05838                 #endif
05839 
05840                 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
05841                 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
05842                 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
05843 
05844                 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
05845                                         additional + AEAD_LEN_OFFSET);
05846                 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
05847                 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
05848                 if (AesGcmDecrypt(ssl->decrypt.aes,
05849                             plain + AEAD_EXP_IV_SZ,
05850                             input + AEAD_EXP_IV_SZ,
05851                                 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
05852                             nonce, AEAD_NONCE_SZ,
05853                             input + sz - ssl->specs.aead_mac_size,
05854                             ssl->specs.aead_mac_size,
05855                             additional, AEAD_AUTH_DATA_SZ) < 0) {
05856                     SendAlert(ssl, alert_fatal, bad_record_mac);
05857                     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05858                     return VERIFY_MAC_ERROR;
05859                 }
05860                 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05861             }
05862             break;
05863         #endif
05864 
05865         #ifdef HAVE_AESCCM
05866             case cyassl_aes_ccm:
05867             {
05868                 byte additional[AEAD_AUTH_DATA_SZ];
05869                 byte nonce[AEAD_NONCE_SZ];
05870 
05871                 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
05872 
05873                 /* sequence number field is 64-bits, we only use 32-bits */
05874                 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
05875 
05876                 #ifdef CYASSL_DTLS
05877                     if (ssl->options.dtls)
05878                         c16toa(ssl->keys.dtls_state.curEpoch, additional);
05879                 #endif
05880 
05881                 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
05882                 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
05883                 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
05884 
05885                 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
05886                                         additional + AEAD_LEN_OFFSET);
05887                 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
05888                 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
05889                 if (AesCcmDecrypt(ssl->decrypt.aes,
05890                             plain + AEAD_EXP_IV_SZ,
05891                             input + AEAD_EXP_IV_SZ,
05892                                 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
05893                             nonce, AEAD_NONCE_SZ,
05894                             input + sz - ssl->specs.aead_mac_size,
05895                             ssl->specs.aead_mac_size,
05896                             additional, AEAD_AUTH_DATA_SZ) < 0) {
05897                     SendAlert(ssl, alert_fatal, bad_record_mac);
05898                     XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05899                     return VERIFY_MAC_ERROR;
05900                 }
05901                 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
05902             }
05903             break;
05904         #endif
05905 
05906         #ifdef HAVE_CAMELLIA
05907             case cyassl_camellia:
05908                 CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
05909                 break;
05910         #endif
05911 
05912         #ifdef HAVE_HC128
05913             case cyassl_hc128:
05914                 return Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
05915         #endif
05916 
05917         #ifdef BUILD_RABBIT
05918             case cyassl_rabbit:
05919                 return RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
05920         #endif
05921 
05922         #ifdef HAVE_CHACHA
05923             case cyassl_chacha:
05924                 return ChachaAEADDecrypt(ssl, plain, input, sz);
05925         #endif
05926 
05927         #ifdef HAVE_NULL_CIPHER
05928             case cyassl_cipher_null:
05929                 if (input != plain) {
05930                     XMEMMOVE(plain, input, sz);
05931                 }
05932                 break;
05933         #endif
05934 
05935             default:
05936                 CYASSL_MSG("CyaSSL Decrypt programming error");
05937                 return DECRYPT_ERROR;
05938     }
05939     return 0;
05940 }
05941 
05942 
05943 /* check cipher text size for sanity */
05944 static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz)
05945 {
05946 #ifdef HAVE_TRUNCATED_HMAC
05947     word32 minLength = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
05948                                            : ssl->specs.hash_size;
05949 #else
05950     word32 minLength = ssl->specs.hash_size; /* covers stream */
05951 #endif
05952 
05953     if (ssl->specs.cipher_type == block) {
05954         if (encryptSz % ssl->specs.block_size) {
05955             CYASSL_MSG("Block ciphertext not block size");
05956             return SANITY_CIPHER_E;
05957         }
05958 
05959         minLength++;  /* pad byte */
05960 
05961         if (ssl->specs.block_size > minLength)
05962             minLength = ssl->specs.block_size;
05963 
05964         if (ssl->options.tls1_1)
05965             minLength += ssl->specs.block_size;  /* explicit IV */
05966     }
05967     else if (ssl->specs.cipher_type == aead) {
05968         minLength = ssl->specs.aead_mac_size;    /* authTag size */
05969         if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
05970            minLength += AEAD_EXP_IV_SZ;          /* explicit IV  */
05971     }
05972 
05973     if (encryptSz < minLength) {
05974         CYASSL_MSG("Ciphertext not minimum size");
05975         return SANITY_CIPHER_E;
05976     }
05977 
05978     return 0;
05979 }
05980 
05981 
05982 #ifndef NO_OLD_TLS
05983 
05984 static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
05985 {
05986     Md5 md5;
05987     int i;
05988 
05989     InitMd5(&md5);
05990 
05991     for (i = 0; i < rounds; i++)
05992         Md5Update(&md5, data, sz);
05993 }
05994 
05995 
05996 
05997 /* do a dummy sha round */
05998 static INLINE void ShaRounds(int rounds, const byte* data, int sz)
05999 {
06000     Sha sha;
06001     int i;
06002 
06003     InitSha(&sha);  /* no error check on purpose, dummy round */
06004 
06005     for (i = 0; i < rounds; i++)
06006         ShaUpdate(&sha, data, sz);
06007 }
06008 #endif
06009 
06010 
06011 #ifndef NO_SHA256
06012 
06013 static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
06014 {
06015     Sha256 sha256;
06016     int i;
06017 
06018     InitSha256(&sha256);  /* no error check on purpose, dummy round */
06019 
06020     for (i = 0; i < rounds; i++) {
06021         Sha256Update(&sha256, data, sz);
06022         /* no error check on purpose, dummy round */
06023     }
06024 
06025 }
06026 
06027 #endif
06028 
06029 
06030 #ifdef CYASSL_SHA384
06031 
06032 static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
06033 {
06034     Sha384 sha384;
06035     int i;
06036 
06037     InitSha384(&sha384);  /* no error check on purpose, dummy round */
06038 
06039     for (i = 0; i < rounds; i++) {
06040         Sha384Update(&sha384, data, sz);
06041         /* no error check on purpose, dummy round */
06042     }
06043 }
06044 
06045 #endif
06046 
06047 
06048 #ifdef CYASSL_SHA512
06049 
06050 static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
06051 {
06052     Sha512 sha512;
06053     int i;
06054 
06055     InitSha512(&sha512);  /* no error check on purpose, dummy round */
06056 
06057     for (i = 0; i < rounds; i++) {
06058         Sha512Update(&sha512, data, sz);
06059         /* no error check on purpose, dummy round */
06060     }
06061 }
06062 
06063 #endif
06064 
06065 
06066 #ifdef CYASSL_RIPEMD
06067 
06068 static INLINE void RmdRounds(int rounds, const byte* data, int sz)
06069 {
06070     RipeMd ripemd;
06071     int i;
06072 
06073     InitRipeMd(&ripemd);
06074 
06075     for (i = 0; i < rounds; i++)
06076         RipeMdUpdate(&ripemd, data, sz);
06077 }
06078 
06079 #endif
06080 
06081 
06082 /* Do dummy rounds */
06083 static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
06084 {
06085     switch (type) {
06086 
06087         case no_mac :
06088             break;
06089 
06090 #ifndef NO_OLD_TLS
06091 #ifndef NO_MD5
06092         case md5_mac :
06093             Md5Rounds(rounds, data, sz);
06094             break;
06095 #endif
06096 
06097 #ifndef NO_SHA
06098         case sha_mac :
06099             ShaRounds(rounds, data, sz);
06100             break;
06101 #endif
06102 #endif
06103 
06104 #ifndef NO_SHA256
06105         case sha256_mac :
06106             Sha256Rounds(rounds, data, sz);
06107             break;
06108 #endif
06109 
06110 #ifdef CYASSL_SHA384
06111         case sha384_mac :
06112             Sha384Rounds(rounds, data, sz);
06113             break;
06114 #endif
06115 
06116 #ifdef CYASSL_SHA512
06117         case sha512_mac :
06118             Sha512Rounds(rounds, data, sz);
06119             break;
06120 #endif
06121 
06122 #ifdef CYASSL_RIPEMD
06123         case rmd_mac :
06124             RmdRounds(rounds, data, sz);
06125             break;
06126 #endif
06127 
06128         default:
06129             CYASSL_MSG("Bad round type");
06130             break;
06131     }
06132 }
06133 
06134 
06135 /* do number of compression rounds on dummy data */
06136 static INLINE void CompressRounds(CYASSL* ssl, int rounds, const byte* dummy)
06137 {
06138     if (rounds)
06139         DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
06140 }
06141 
06142 
06143 /* check all length bytes for equality, return 0 on success */
06144 static int ConstantCompare(const byte* a, const byte* b, int length)
06145 {
06146     int i;
06147     int good = 0;
06148     int bad  = 0;
06149 
06150     for (i = 0; i < length; i++) {
06151         if (a[i] == b[i])
06152             good++;
06153         else
06154             bad++;
06155     }
06156 
06157     if (good == length)
06158         return 0;
06159     else
06160         return 0 - bad;  /* compare failed */
06161 }
06162 
06163 
06164 /* check all length bytes for the pad value, return 0 on success */
06165 static int PadCheck(const byte* input, byte pad, int length)
06166 {
06167     int i;
06168     int good = 0;
06169     int bad  = 0;
06170 
06171     for (i = 0; i < length; i++) {
06172         if (input[i] == pad)
06173             good++;
06174         else
06175             bad++;
06176     }
06177 
06178     if (good == length)
06179         return 0;
06180     else
06181         return 0 - bad;  /* pad check failed */
06182 }
06183 
06184 
06185 /* get compression extra rounds */
06186 static INLINE int GetRounds(int pLen, int padLen, int t)
06187 {
06188     int  roundL1 = 1;  /* round up flags */
06189     int  roundL2 = 1;
06190 
06191     int L1 = COMPRESS_CONSTANT + pLen - t;
06192     int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
06193 
06194     L1 -= COMPRESS_UPPER;
06195     L2 -= COMPRESS_UPPER;
06196 
06197     if ( (L1 % COMPRESS_LOWER) == 0)
06198         roundL1 = 0;
06199     if ( (L2 % COMPRESS_LOWER) == 0)
06200         roundL2 = 0;
06201 
06202     L1 /= COMPRESS_LOWER;
06203     L2 /= COMPRESS_LOWER;
06204 
06205     L1 += roundL1;
06206     L2 += roundL2;
06207 
06208     return L1 - L2;
06209 }
06210 
06211 
06212 /* timing resistant pad/verify check, return 0 on success */
06213 static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
06214                            int pLen, int content)
06215 {
06216     byte verify[MAX_DIGEST_SIZE];
06217     byte dummy[MAX_PAD_SIZE];
06218     int  ret = 0;
06219 
06220     XMEMSET(dummy, 1, sizeof(dummy));
06221 
06222     if ( (t + padLen + 1) > pLen) {
06223         CYASSL_MSG("Plain Len not long enough for pad/mac");
06224         PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
06225         ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
06226         ConstantCompare(verify, input + pLen - t, t);
06227 
06228         return VERIFY_MAC_ERROR;
06229     }
06230 
06231     if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
06232         CYASSL_MSG("PadCheck failed");
06233         PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
06234         ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
06235         ConstantCompare(verify, input + pLen - t, t);
06236 
06237         return VERIFY_MAC_ERROR;
06238     }
06239 
06240     PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
06241     ret = ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1);
06242 
06243     CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
06244 
06245     if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
06246         CYASSL_MSG("Verify MAC compare failed");
06247         return VERIFY_MAC_ERROR;
06248     }
06249 
06250     if (ret != 0)
06251         return VERIFY_MAC_ERROR;
06252     return 0;
06253 }
06254 
06255 
06256 int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
06257 {
06258     word32 msgSz   = ssl->keys.encryptSz;
06259     word32 idx     = *inOutIdx;
06260     int    dataSz;
06261     int    ivExtra = 0;
06262     byte*  rawData = input + idx;  /* keep current  for hmac */
06263 #ifdef HAVE_LIBZ
06264     byte   decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
06265 #endif
06266 
06267     if (ssl->options.handShakeDone == 0) {
06268         CYASSL_MSG("Received App data before a handshake completed");
06269         SendAlert(ssl, alert_fatal, unexpected_message);
06270         return OUT_OF_ORDER_E;
06271     }
06272 
06273     if (ssl->specs.cipher_type == block) {
06274         if (ssl->options.tls1_1)
06275             ivExtra = ssl->specs.block_size;
06276     }
06277     else if (ssl->specs.cipher_type == aead) {
06278         if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
06279             ivExtra = AEAD_EXP_IV_SZ;
06280     }
06281 
06282     dataSz = msgSz - ivExtra - ssl->keys.padSz;
06283     if (dataSz < 0) {
06284         CYASSL_MSG("App data buffer error, malicious input?");
06285         return BUFFER_ERROR;
06286     }
06287 
06288     /* read data */
06289     if (dataSz) {
06290         int rawSz = dataSz;       /* keep raw size for idx adjustment */
06291 
06292 #ifdef HAVE_LIBZ
06293         if (ssl->options.usingCompression) {
06294             dataSz = myDeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
06295             if (dataSz < 0) return dataSz;
06296         }
06297 #endif
06298         idx += rawSz;
06299 
06300         ssl->buffers.clearOutputBuffer.buffer = rawData;
06301         ssl->buffers.clearOutputBuffer.length = dataSz;
06302     }
06303 
06304     idx += ssl->keys.padSz;
06305 
06306 #ifdef HAVE_LIBZ
06307     /* decompress could be bigger, overwrite after verify */
06308     if (ssl->options.usingCompression)
06309         XMEMMOVE(rawData, decomp, dataSz);
06310 #endif
06311 
06312     *inOutIdx = idx;
06313     return 0;
06314 }
06315 
06316 
06317 /* process alert, return level */
06318 static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type,
06319                    word32 totalSz)
06320 {
06321     byte level;
06322     byte code;
06323 
06324     #ifdef CYASSL_CALLBACKS
06325         if (ssl->hsInfoOn)
06326             AddPacketName("Alert", &ssl->handShakeInfo);
06327         if (ssl->toInfoOn)
06328             /* add record header back on to info + 2 byte level, data */
06329             AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
06330                           RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
06331     #endif
06332 
06333     /* make sure can read the message */
06334     if (*inOutIdx + ALERT_SIZE > totalSz)
06335         return BUFFER_E;
06336 
06337     level = input[(*inOutIdx)++];
06338     code  = input[(*inOutIdx)++];
06339     ssl->alert_history.last_rx.code = code;
06340     ssl->alert_history.last_rx.level = level;
06341     *type = code;
06342     if (level == alert_fatal) {
06343         ssl->options.isClosed = 1;  /* Don't send close_notify */
06344     }
06345 
06346     CYASSL_MSG("Got alert");
06347     if (*type == close_notify) {
06348         CYASSL_MSG("    close notify");
06349         ssl->options.closeNotify = 1;
06350     }
06351     CYASSL_ERROR(*type);
06352 
06353     if (ssl->keys.encryptionOn) {
06354         if (*inOutIdx + ssl->keys.padSz > totalSz)
06355             return BUFFER_E;
06356         *inOutIdx += ssl->keys.padSz;
06357     }
06358 
06359     return level;
06360 }
06361 
06362 static int GetInputData(CYASSL *ssl, word32 size)
06363 {
06364     int in;
06365     int inSz;
06366     int maxLength;
06367     int usedLength;
06368     int dtlsExtra = 0;
06369 
06370 
06371     /* check max input length */
06372     usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
06373     maxLength  = ssl->buffers.inputBuffer.bufferSize - usedLength;
06374     inSz       = (int)(size - usedLength);      /* from last partial read */
06375 
06376 #ifdef CYASSL_DTLS
06377     if (ssl->options.dtls) {
06378         if (size < ssl->dtls_expected_rx)
06379             dtlsExtra = (int)(ssl->dtls_expected_rx - size);
06380         inSz = ssl->dtls_expected_rx;
06381     }
06382 #endif
06383 
06384     if (inSz > maxLength) {
06385         if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
06386             return MEMORY_E;
06387     }
06388 
06389     if (inSz <= 0)
06390         return BUFFER_ERROR;
06391 
06392     /* Put buffer data at start if not there */
06393     if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
06394         XMEMMOVE(ssl->buffers.inputBuffer.buffer,
06395                 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
06396                 usedLength);
06397 
06398     /* remove processed data */
06399     ssl->buffers.inputBuffer.idx    = 0;
06400     ssl->buffers.inputBuffer.length = usedLength;
06401 
06402     /* read data from network */
06403     do {
06404         in = Receive(ssl,
06405                      ssl->buffers.inputBuffer.buffer +
06406                      ssl->buffers.inputBuffer.length,
06407                      inSz);
06408         if (in == -1)
06409             return SOCKET_ERROR_E;
06410 
06411         if (in == WANT_READ)
06412             return WANT_READ;
06413 
06414         if (in > inSz)
06415             return RECV_OVERFLOW_E;
06416 
06417         ssl->buffers.inputBuffer.length += in;
06418         inSz -= in;
06419 
06420     } while (ssl->buffers.inputBuffer.length < size);
06421 
06422     return 0;
06423 }
06424 
06425 
06426 static INLINE int VerifyMac(CYASSL* ssl, const byte* input, word32 msgSz,
06427                             int content, word32* padSz)
06428 {
06429     int    ivExtra = 0;
06430     int    ret;
06431     word32 pad     = 0;
06432     word32 padByte = 0;
06433 #ifdef HAVE_TRUNCATED_HMAC
06434     word32 digestSz = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
06435                                           : ssl->specs.hash_size;
06436 #else
06437     word32 digestSz = ssl->specs.hash_size;
06438 #endif
06439     byte   verify[MAX_DIGEST_SIZE];
06440 
06441     if (ssl->specs.cipher_type == block) {
06442         if (ssl->options.tls1_1)
06443             ivExtra = ssl->specs.block_size;
06444         pad = *(input + msgSz - ivExtra - 1);
06445         padByte = 1;
06446 
06447         if (ssl->options.tls) {
06448             ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra,
06449                                   content);
06450             if (ret != 0)
06451                 return ret;
06452         }
06453         else {  /* sslv3, some implementations have bad padding, but don't
06454                  * allow bad read */
06455             int  badPadLen = 0;
06456             byte dummy[MAX_PAD_SIZE];
06457 
06458             XMEMSET(dummy, 1, sizeof(dummy));
06459 
06460             if (pad > (msgSz - digestSz - 1)) {
06461                 CYASSL_MSG("Plain Len not long enough for pad/mac");
06462                 pad       = 0;  /* no bad read */
06463                 badPadLen = 1;
06464             }
06465             PadCheck(dummy, (byte)pad, MAX_PAD_SIZE);  /* timing only */
06466             ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1,
06467                             content, 1);
06468             if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
06469                                 digestSz) != 0)
06470                 return VERIFY_MAC_ERROR;
06471             if (ret != 0 || badPadLen)
06472                 return VERIFY_MAC_ERROR;
06473         }
06474     }
06475     else if (ssl->specs.cipher_type == stream) {
06476         ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1);
06477         if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
06478             return VERIFY_MAC_ERROR;
06479         }
06480         if (ret != 0)
06481             return VERIFY_MAC_ERROR;
06482     }
06483 
06484     if (ssl->specs.cipher_type == aead) {
06485         *padSz = ssl->specs.aead_mac_size;
06486     }
06487     else {
06488         *padSz = digestSz + pad + padByte;
06489     }
06490 
06491     return 0;
06492 }
06493 
06494 
06495 /* process input requests, return 0 is done, 1 is call again to complete, and
06496    negative number is error */
06497 int ProcessReply(CYASSL* ssl)
06498 {
06499     int    ret = 0, type, readSz;
06500     int    atomicUser = 0;
06501     word32 startIdx = 0;
06502 #ifdef CYASSL_DTLS
06503     int    used;
06504 #endif
06505 
06506 #ifdef ATOMIC_USER
06507     if (ssl->ctx->DecryptVerifyCb)
06508         atomicUser = 1;
06509 #endif
06510 
06511     if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE){
06512         CYASSL_MSG("ProcessReply retry in error state, not allowed");
06513         return ssl->error;
06514     }
06515 
06516     for (;;) {
06517         switch (ssl->options.processReply) {
06518 
06519         /* in the CYASSL_SERVER case, get the first byte for detecting
06520          * old client hello */
06521         case doProcessInit:
06522 
06523             readSz = RECORD_HEADER_SZ;
06524 
06525             #ifdef CYASSL_DTLS
06526                 if (ssl->options.dtls)
06527                     readSz = DTLS_RECORD_HEADER_SZ;
06528             #endif
06529 
06530             /* get header or return error */
06531             if (!ssl->options.dtls) {
06532                 if ((ret = GetInputData(ssl, readSz)) < 0)
06533                     return ret;
06534             } else {
06535             #ifdef CYASSL_DTLS
06536                 /* read ahead may already have header */
06537                 used = ssl->buffers.inputBuffer.length -
06538                        ssl->buffers.inputBuffer.idx;
06539                 if (used < readSz)
06540                     if ((ret = GetInputData(ssl, readSz)) < 0)
06541                         return ret;
06542             #endif
06543             }
06544 
06545 #ifdef OLD_HELLO_ALLOWED
06546 
06547             /* see if sending SSLv2 client hello */
06548             if ( ssl->options.side == CYASSL_SERVER_END &&
06549                  ssl->options.clientState == NULL_STATE &&
06550                  ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
06551                          != handshake) {
06552                 byte b0, b1;
06553 
06554                 ssl->options.processReply = runProcessOldClientHello;
06555 
06556                 /* sanity checks before getting size at front */
06557                 if (ssl->buffers.inputBuffer.buffer[
06558                           ssl->buffers.inputBuffer.idx + 2] != OLD_HELLO_ID) {
06559                     CYASSL_MSG("Not a valid old client hello");
06560                     return PARSE_ERROR;
06561                 }
06562 
06563                 if (ssl->buffers.inputBuffer.buffer[
06564                           ssl->buffers.inputBuffer.idx + 3] != SSLv3_MAJOR &&
06565                     ssl->buffers.inputBuffer.buffer[
06566                           ssl->buffers.inputBuffer.idx + 3] != DTLS_MAJOR) {
06567                     CYASSL_MSG("Not a valid version in old client hello");
06568                     return PARSE_ERROR;
06569                 }
06570 
06571                 /* how many bytes need ProcessOldClientHello */
06572                 b0 =
06573                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
06574                 b1 =
06575                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
06576                 ssl->curSize = (word16)(((b0 & 0x7f) << 8) | b1);
06577             }
06578             else {
06579                 ssl->options.processReply = getRecordLayerHeader;
06580                 continue;
06581             }
06582 
06583         /* in the CYASSL_SERVER case, run the old client hello */
06584         case runProcessOldClientHello:
06585 
06586             /* get sz bytes or return error */
06587             if (!ssl->options.dtls) {
06588                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
06589                     return ret;
06590             } else {
06591             #ifdef CYASSL_DTLS
06592                 /* read ahead may already have */
06593                 used = ssl->buffers.inputBuffer.length -
06594                        ssl->buffers.inputBuffer.idx;
06595                 if (used < ssl->curSize)
06596                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
06597                         return ret;
06598             #endif  /* CYASSL_DTLS */
06599             }
06600 
06601             ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
06602                                         &ssl->buffers.inputBuffer.idx,
06603                                         ssl->buffers.inputBuffer.length -
06604                                         ssl->buffers.inputBuffer.idx,
06605                                         ssl->curSize);
06606             if (ret < 0)
06607                 return ret;
06608 
06609             else if (ssl->buffers.inputBuffer.idx ==
06610                      ssl->buffers.inputBuffer.length) {
06611                 ssl->options.processReply = doProcessInit;
06612                 return 0;
06613             }
06614 
06615 #endif  /* OLD_HELLO_ALLOWED */
06616 
06617         /* get the record layer header */
06618         case getRecordLayerHeader:
06619 
06620             ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
06621                                        &ssl->buffers.inputBuffer.idx,
06622                                        &ssl->curRL, &ssl->curSize);
06623 #ifdef CYASSL_DTLS
06624             if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
06625                 ssl->options.processReply = doProcessInit;
06626                 ssl->buffers.inputBuffer.length = 0;
06627                 ssl->buffers.inputBuffer.idx = 0;
06628                 continue;
06629             }
06630 #endif
06631             if (ret != 0)
06632                 return ret;
06633 
06634             ssl->options.processReply = getData;
06635 
06636         /* retrieve record layer data */
06637         case getData:
06638 
06639             /* get sz bytes or return error */
06640             if (!ssl->options.dtls) {
06641                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
06642                     return ret;
06643             } else {
06644 #ifdef CYASSL_DTLS
06645                 /* read ahead may already have */
06646                 used = ssl->buffers.inputBuffer.length -
06647                        ssl->buffers.inputBuffer.idx;
06648                 if (used < ssl->curSize)
06649                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
06650                         return ret;
06651 #endif
06652             }
06653 
06654             ssl->options.processReply = runProcessingOneMessage;
06655             startIdx = ssl->buffers.inputBuffer.idx;  /* in case > 1 msg per */
06656 
06657         /* the record layer is here */
06658         case runProcessingOneMessage:
06659 
06660             #ifdef CYASSL_DTLS
06661             if (ssl->options.dtls &&
06662                 ssl->keys.dtls_state.curEpoch < ssl->keys.dtls_state.nextEpoch)
06663                 ssl->keys.decryptedCur = 1;
06664             #endif
06665 
06666             if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0)
06667             {
06668                 ret = SanityCheckCipherText(ssl, ssl->curSize);
06669                 if (ret < 0)
06670                     return ret;
06671 
06672                 if (atomicUser) {
06673                 #ifdef ATOMIC_USER
06674                     ret = ssl->ctx->DecryptVerifyCb(ssl,
06675                                   ssl->buffers.inputBuffer.buffer +
06676                                   ssl->buffers.inputBuffer.idx,
06677                                   ssl->buffers.inputBuffer.buffer +
06678                                   ssl->buffers.inputBuffer.idx,
06679                                   ssl->curSize, ssl->curRL.type, 1,
06680                                   &ssl->keys.padSz, ssl->DecryptVerifyCtx);
06681                     if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
06682                         ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
06683                         /* go past TLSv1.1 IV */
06684                     if (ssl->specs.cipher_type == aead &&
06685                             ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
06686                         ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
06687                 #endif /* ATOMIC_USER */
06688                 }
06689                 else {
06690                     ret = Decrypt(ssl, ssl->buffers.inputBuffer.buffer +
06691                                   ssl->buffers.inputBuffer.idx,
06692                                   ssl->buffers.inputBuffer.buffer +
06693                                   ssl->buffers.inputBuffer.idx,
06694                                   ssl->curSize);
06695                     if (ret < 0) {
06696                         CYASSL_ERROR(ret);
06697                         return DECRYPT_ERROR;
06698                     }
06699                     if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
06700                         ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
06701                         /* go past TLSv1.1 IV */
06702                     if (ssl->specs.cipher_type == aead &&
06703                             ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
06704                         ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
06705 
06706                     ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
06707                                     ssl->buffers.inputBuffer.idx,
06708                                     ssl->curSize, ssl->curRL.type,
06709                                     &ssl->keys.padSz);
06710                 }
06711                 if (ret < 0) {
06712                     CYASSL_ERROR(ret);
06713                     return DECRYPT_ERROR;
06714                 }
06715                 ssl->keys.encryptSz    = ssl->curSize;
06716                 ssl->keys.decryptedCur = 1;
06717             }
06718 
06719             if (ssl->options.dtls) {
06720             #ifdef CYASSL_DTLS
06721                 DtlsUpdateWindow(&ssl->keys.dtls_state);
06722             #endif /* CYASSL_DTLS */
06723             }
06724 
06725             CYASSL_MSG("received record layer msg");
06726 
06727             switch (ssl->curRL.type) {
06728                 case handshake :
06729                     /* debugging in DoHandShakeMsg */
06730                     if (!ssl->options.dtls) {
06731                         ret = DoHandShakeMsg(ssl,
06732                                             ssl->buffers.inputBuffer.buffer,
06733                                             &ssl->buffers.inputBuffer.idx,
06734                                             ssl->buffers.inputBuffer.length);
06735                     }
06736                     else {
06737 #ifdef CYASSL_DTLS
06738                         ret = DoDtlsHandShakeMsg(ssl,
06739                                             ssl->buffers.inputBuffer.buffer,
06740                                             &ssl->buffers.inputBuffer.idx,
06741                                             ssl->buffers.inputBuffer.length);
06742 #endif
06743                     }
06744                     if (ret != 0)
06745                         return ret;
06746                     break;
06747 
06748                 case change_cipher_spec:
06749                     CYASSL_MSG("got CHANGE CIPHER SPEC");
06750                     #ifdef CYASSL_CALLBACKS
06751                         if (ssl->hsInfoOn)
06752                             AddPacketName("ChangeCipher", &ssl->handShakeInfo);
06753                         /* add record header back on info */
06754                         if (ssl->toInfoOn) {
06755                             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
06756                                 ssl->buffers.inputBuffer.buffer +
06757                                 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
06758                                 1 + RECORD_HEADER_SZ, ssl->heap);
06759                             AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
06760                         }
06761                     #endif
06762 
06763                     ret = SanityCheckMsgReceived(ssl, change_cipher_hs);
06764                     if (ret != 0)
06765                         return ret;
06766 
06767 #ifdef HAVE_SESSION_TICKET
06768                     if (ssl->options.side == CYASSL_CLIENT_END &&
06769                                                   ssl->expect_session_ticket) {
06770                         CYASSL_MSG("Expected session ticket missing");
06771                         return SESSION_TICKET_EXPECT_E;
06772                     }
06773 #endif
06774 
06775                     if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
06776                         ssl->buffers.inputBuffer.idx += ssl->keys.padSz;
06777                         ssl->curSize -= ssl->buffers.inputBuffer.idx;
06778                     }
06779 
06780                     if (ssl->curSize != 1) {
06781                         CYASSL_MSG("Malicious or corrupted ChangeCipher msg");
06782                         return LENGTH_ERROR;
06783                     }
06784                     #ifndef NO_CERTS
06785                         if (ssl->options.side == CYASSL_SERVER_END &&
06786                                  ssl->options.verifyPeer &&
06787                                  ssl->options.havePeerCert)
06788                             if (!ssl->options.havePeerVerify) {
06789                                 CYASSL_MSG("client didn't send cert verify");
06790                                 return NO_PEER_VERIFY;
06791                             }
06792                     #endif
06793 
06794 
06795                     ssl->buffers.inputBuffer.idx++;
06796                     ssl->keys.encryptionOn = 1;
06797 
06798                     /* setup decrypt keys for following messages */
06799                     if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
06800                         return ret;
06801 
06802                     #ifdef CYASSL_DTLS
06803                         if (ssl->options.dtls) {
06804                             DtlsPoolReset(ssl);
06805                             ssl->keys.dtls_state.nextEpoch++;
06806                             ssl->keys.dtls_state.nextSeq = 0;
06807                         }
06808                     #endif
06809 
06810                     #ifdef HAVE_LIBZ
06811                         if (ssl->options.usingCompression)
06812                             if ( (ret = InitStreams(ssl)) != 0)
06813                                 return ret;
06814                     #endif
06815                     if (ssl->options.resuming && ssl->options.side ==
06816                                                               CYASSL_CLIENT_END)
06817                         ret = BuildFinished(ssl, &ssl->verifyHashes, server);
06818                     else if (!ssl->options.resuming && ssl->options.side ==
06819                                                               CYASSL_SERVER_END)
06820                         ret = BuildFinished(ssl, &ssl->verifyHashes, client);
06821                     if (ret != 0)
06822                         return ret;
06823                     break;
06824 
06825                 case application_data:
06826                     CYASSL_MSG("got app DATA");
06827                     if ((ret = DoApplicationData(ssl,
06828                                                 ssl->buffers.inputBuffer.buffer,
06829                                                &ssl->buffers.inputBuffer.idx))
06830                                                                          != 0) {
06831                         CYASSL_ERROR(ret);
06832                         return ret;
06833                     }
06834                     break;
06835 
06836                 case alert:
06837                     CYASSL_MSG("got ALERT!");
06838                     ret = DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
06839                                   &ssl->buffers.inputBuffer.idx, &type,
06840                                    ssl->buffers.inputBuffer.length);
06841                     if (ret == alert_fatal)
06842                         return FATAL_ERROR;
06843                     else if (ret < 0)
06844                         return ret;
06845 
06846                     /* catch warnings that are handled as errors */
06847                     if (type == close_notify)
06848                         return ssl->error = ZERO_RETURN;
06849 
06850                     if (type == decrypt_error)
06851                         return FATAL_ERROR;
06852                     break;
06853 
06854                 default:
06855                     CYASSL_ERROR(UNKNOWN_RECORD_TYPE);
06856                     return UNKNOWN_RECORD_TYPE;
06857             }
06858 
06859             ssl->options.processReply = doProcessInit;
06860 
06861             /* input exhausted? */
06862             if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
06863                 return 0;
06864             /* more messages per record */
06865             else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
06866                 CYASSL_MSG("More messages in record");
06867                 #ifdef CYASSL_DTLS
06868                     /* read-ahead but dtls doesn't bundle messages per record */
06869                     if (ssl->options.dtls) {
06870                         ssl->options.processReply = doProcessInit;
06871                         continue;
06872                     }
06873                 #endif
06874                 ssl->options.processReply = runProcessingOneMessage;
06875 
06876                 if (ssl->keys.encryptionOn) {
06877                     CYASSL_MSG("Bundled encrypted messages, remove middle pad");
06878                     ssl->buffers.inputBuffer.idx -= ssl->keys.padSz;
06879                 }
06880 
06881                 continue;
06882             }
06883             /* more records */
06884             else {
06885                 CYASSL_MSG("More records in input");
06886                 ssl->options.processReply = doProcessInit;
06887                 continue;
06888             }
06889 
06890         default:
06891             CYASSL_MSG("Bad process input state, programming error");
06892             return INPUT_CASE_ERROR;
06893         }
06894     }
06895 }
06896 
06897 
06898 int SendChangeCipher(CYASSL* ssl)
06899 {
06900     byte              *output;
06901     int                sendSz = RECORD_HEADER_SZ + ENUM_LEN;
06902     int                idx    = RECORD_HEADER_SZ;
06903     int                ret;
06904 
06905     #ifdef CYASSL_DTLS
06906         if (ssl->options.dtls) {
06907             sendSz += DTLS_RECORD_EXTRA;
06908             idx    += DTLS_RECORD_EXTRA;
06909         }
06910     #endif
06911 
06912     /* are we in scr */
06913     if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
06914         sendSz += MAX_MSG_EXTRA;
06915     }
06916 
06917     /* check for avalaible size */
06918     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
06919         return ret;
06920 
06921     /* get ouput buffer */
06922     output = ssl->buffers.outputBuffer.buffer +
06923              ssl->buffers.outputBuffer.length;
06924 
06925     AddRecordHeader(output, 1, change_cipher_spec, ssl);
06926 
06927     output[idx] = 1;             /* turn it on */
06928 
06929     if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
06930         byte input[ENUM_LEN];
06931         int  inputSz = ENUM_LEN;
06932 
06933         input[0] = 1;  /* turn it on */
06934         sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
06935                               change_cipher_spec);
06936         if (sendSz < 0)
06937             return sendSz;
06938     }
06939 
06940     #ifdef CYASSL_DTLS
06941         if (ssl->options.dtls) {
06942             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
06943                 return ret;
06944         }
06945     #endif
06946     #ifdef CYASSL_CALLBACKS
06947         if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
06948         if (ssl->toInfoOn)
06949             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
06950                            ssl->heap);
06951     #endif
06952     ssl->buffers.outputBuffer.length += sendSz;
06953 
06954     if (ssl->options.groupMessages)
06955         return 0;
06956     #ifdef CYASSL_DTLS
06957     else if (ssl->options.dtls) {
06958         /* If using DTLS, force the ChangeCipherSpec message to be in the
06959          * same datagram as the finished message. */
06960         return 0;
06961     }
06962     #endif
06963     else
06964         return SendBuffered(ssl);
06965 }
06966 
06967 
06968 #ifndef NO_OLD_TLS
06969 static int SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
06970                  int content, int verify)
06971 {
06972     byte   result[MAX_DIGEST_SIZE];
06973     word32 digestSz = ssl->specs.hash_size;            /* actual sizes */
06974     word32 padSz    = ssl->specs.pad_size;
06975     int    ret      = 0;
06976 
06977     Md5 md5;
06978     Sha sha;
06979 
06980     /* data */
06981     byte seq[SEQ_SZ];
06982     byte conLen[ENUM_LEN + LENGTH_SZ];     /* content & length */
06983     const byte* macSecret = CyaSSL_GetMacSecret(ssl, verify);
06984 
06985 #ifdef HAVE_FUZZER
06986     if (ssl->fuzzerCb)
06987         ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
06988 #endif
06989 
06990     XMEMSET(seq, 0, SEQ_SZ);
06991     conLen[0] = (byte)content;
06992     c16toa((word16)sz, &conLen[ENUM_LEN]);
06993     c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
06994 
06995     if (ssl->specs.mac_algorithm == md5_mac) {
06996         InitMd5(&md5);
06997         /* inner */
06998         Md5Update(&md5, macSecret, digestSz);
06999         Md5Update(&md5, PAD1, padSz);
07000         Md5Update(&md5, seq, SEQ_SZ);
07001         Md5Update(&md5, conLen, sizeof(conLen));
07002         /* in buffer */
07003         Md5Update(&md5, in, sz);
07004         Md5Final(&md5, result);
07005         /* outer */
07006         Md5Update(&md5, macSecret, digestSz);
07007         Md5Update(&md5, PAD2, padSz);
07008         Md5Update(&md5, result, digestSz);
07009         Md5Final(&md5, digest);
07010     }
07011     else {
07012         ret = InitSha(&sha);
07013         if (ret != 0)
07014             return ret;
07015         /* inner */
07016         ShaUpdate(&sha, macSecret, digestSz);
07017         ShaUpdate(&sha, PAD1, padSz);
07018         ShaUpdate(&sha, seq, SEQ_SZ);
07019         ShaUpdate(&sha, conLen, sizeof(conLen));
07020         /* in buffer */
07021         ShaUpdate(&sha, in, sz);
07022         ShaFinal(&sha, result);
07023         /* outer */
07024         ShaUpdate(&sha, macSecret, digestSz);
07025         ShaUpdate(&sha, PAD2, padSz);
07026         ShaUpdate(&sha, result, digestSz);
07027         ShaFinal(&sha, digest);
07028     }
07029     return 0;
07030 }
07031 
07032 #ifndef NO_CERTS
07033 static void BuildMD5_CertVerify(CYASSL* ssl, byte* digest)
07034 {
07035     byte md5_result[MD5_DIGEST_SIZE];
07036 
07037     /* make md5 inner */
07038     Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
07039     Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
07040     Md5Final(&ssl->hashMd5, md5_result);
07041 
07042     /* make md5 outer */
07043     Md5Update(&ssl->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
07044     Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
07045     Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
07046 
07047     Md5Final(&ssl->hashMd5, digest);
07048 }
07049 
07050 
07051 static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest)
07052 {
07053     byte sha_result[SHA_DIGEST_SIZE];
07054 
07055     /* make sha inner */
07056     ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
07057     ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
07058     ShaFinal(&ssl->hashSha, sha_result);
07059 
07060     /* make sha outer */
07061     ShaUpdate(&ssl->hashSha, ssl->arrays->masterSecret, SECRET_LEN);
07062     ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
07063     ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
07064 
07065     ShaFinal(&ssl->hashSha, digest);
07066 }
07067 #endif /* NO_CERTS */
07068 #endif /* NO_OLD_TLS */
07069 
07070 
07071 #ifndef NO_CERTS
07072 
07073 static int BuildCertHashes(CYASSL* ssl, Hashes* hashes)
07074 {
07075     /* store current states, building requires get_digest which resets state */
07076     #ifndef NO_OLD_TLS
07077     Md5 md5 = ssl->hashMd5;
07078     Sha sha = ssl->hashSha;
07079     #endif
07080     #ifndef NO_SHA256
07081         Sha256 sha256 = ssl->hashSha256;
07082     #endif
07083     #ifdef CYASSL_SHA384
07084         Sha384 sha384 = ssl->hashSha384;
07085     #endif
07086 
07087     if (ssl->options.tls) {
07088 #if ! defined( NO_OLD_TLS )
07089         Md5Final(&ssl->hashMd5, hashes->md5);
07090         ShaFinal(&ssl->hashSha, hashes->sha);
07091 #endif
07092         if (IsAtLeastTLSv1_2(ssl)) {
07093             int ret;
07094 
07095             #ifndef NO_SHA256
07096                 ret = Sha256Final(&ssl->hashSha256, hashes->sha256);
07097                 if (ret != 0)
07098                     return ret;
07099             #endif
07100             #ifdef CYASSL_SHA384
07101                 ret = Sha384Final(&ssl->hashSha384, hashes->sha384);
07102                 if (ret != 0)
07103                     return ret;
07104             #endif
07105         }
07106     }
07107 #if ! defined( NO_OLD_TLS )
07108     else {
07109         BuildMD5_CertVerify(ssl, hashes->md5);
07110         BuildSHA_CertVerify(ssl, hashes->sha);
07111     }
07112 
07113     /* restore */
07114     ssl->hashMd5 = md5;
07115     ssl->hashSha = sha;
07116 #endif
07117     if (IsAtLeastTLSv1_2(ssl)) {
07118         #ifndef NO_SHA256
07119             ssl->hashSha256 = sha256;
07120         #endif
07121         #ifdef CYASSL_SHA384
07122             ssl->hashSha384 = sha384;
07123         #endif
07124     }
07125 
07126     return 0;
07127 }
07128 
07129 #endif /* CYASSL_LEANPSK */
07130 
07131 /* Build SSL Message, encrypted */
07132 static int BuildMessage(CYASSL* ssl, byte* output, int outSz,
07133                         const byte* input, int inSz, int type)
07134 {
07135 #ifdef HAVE_TRUNCATED_HMAC
07136     word32 digestSz = min(ssl->specs.hash_size,
07137                 ssl->truncated_hmac ? TRUNCATED_HMAC_SZ : ssl->specs.hash_size);
07138 #else
07139     word32 digestSz = ssl->specs.hash_size;
07140 #endif
07141     word32 sz = RECORD_HEADER_SZ + inSz + digestSz;
07142     word32 pad  = 0, i;
07143     word32 idx  = RECORD_HEADER_SZ;
07144     word32 ivSz = 0;      /* TLSv1.1  IV */
07145     word32 headerSz = RECORD_HEADER_SZ;
07146     word16 size;
07147     byte               iv[AES_BLOCK_SIZE];                  /* max size */
07148     int ret        = 0;
07149     int atomicUser = 0;
07150 
07151 #ifdef CYASSL_DTLS
07152     if (ssl->options.dtls) {
07153         sz       += DTLS_RECORD_EXTRA;
07154         idx      += DTLS_RECORD_EXTRA;
07155         headerSz += DTLS_RECORD_EXTRA;
07156     }
07157 #endif
07158 
07159 #ifdef ATOMIC_USER
07160     if (ssl->ctx->MacEncryptCb)
07161         atomicUser = 1;
07162 #endif
07163 
07164     if (ssl->specs.cipher_type == block) {
07165         word32 blockSz = ssl->specs.block_size;
07166         if (ssl->options.tls1_1) {
07167             ivSz = blockSz;
07168             sz  += ivSz;
07169 
07170             if (ivSz > (word32)sizeof(iv))
07171                 return BUFFER_E;
07172 
07173             ret = RNG_GenerateBlock(ssl->rng, iv, ivSz);
07174             if (ret != 0)
07175                 return ret;
07176 
07177         }
07178         sz += 1;       /* pad byte */
07179         pad = (sz - headerSz) % blockSz;
07180         pad = blockSz - pad;
07181         sz += pad;
07182     }
07183 
07184 #ifdef HAVE_AEAD
07185     if (ssl->specs.cipher_type == aead) {
07186         if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
07187             ivSz = AEAD_EXP_IV_SZ;
07188 
07189         sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
07190         XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
07191     }
07192 #endif
07193     if (sz > (word32)outSz) {
07194         CYASSL_MSG("Oops, want to write past output buffer size");
07195         return BUFFER_E;
07196     }
07197     size = (word16)(sz - headerSz);    /* include mac and digest */
07198     AddRecordHeader(output, size, (byte)type, ssl);
07199 
07200     /* write to output */
07201     if (ivSz) {
07202         XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
07203         idx += ivSz;
07204     }
07205     XMEMCPY(output + idx, input, inSz);
07206     idx += inSz;
07207 
07208     if (type == handshake) {
07209         ret = HashOutput(ssl, output, headerSz + inSz, ivSz);
07210         if (ret != 0)
07211             return ret;
07212     }
07213 
07214     if (ssl->specs.cipher_type == block) {
07215         word32 tmpIdx = idx + digestSz;
07216 
07217         for (i = 0; i <= pad; i++)
07218             output[tmpIdx++] = (byte)pad; /* pad byte gets pad value too */
07219     }
07220 
07221     if (atomicUser) {   /* User Record Layer Callback handling */
07222 #ifdef ATOMIC_USER
07223         if ( (ret = ssl->ctx->MacEncryptCb(ssl, output + idx,
07224                         output + headerSz + ivSz, inSz, type, 0,
07225                         output + headerSz, output + headerSz, size,
07226                         ssl->MacEncryptCtx)) != 0)
07227             return ret;
07228 #endif
07229     }
07230     else {
07231         if (ssl->specs.cipher_type != aead) {
07232 #ifdef HAVE_TRUNCATED_HMAC
07233             if (ssl->truncated_hmac && ssl->specs.hash_size > digestSz) {
07234             #ifdef CYASSL_SMALL_STACK
07235                 byte* hmac = NULL;
07236             #else
07237                 byte  hmac[MAX_DIGEST_SIZE];
07238             #endif
07239 
07240             #ifdef CYASSL_SMALL_STACK
07241                 hmac = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL,
07242                                                        DYNAMIC_TYPE_TMP_BUFFER);
07243                 if (hmac == NULL)
07244                     return MEMORY_E;
07245             #endif
07246 
07247                 ret = ssl->hmac(ssl, hmac, output + headerSz + ivSz, inSz,
07248                                                                        type, 0);
07249                 XMEMCPY(output + idx, hmac, digestSz);
07250 
07251             #ifdef CYASSL_SMALL_STACK
07252                 XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07253             #endif
07254             } else
07255 #endif
07256                 ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz,
07257                                                                        type, 0);
07258         }
07259         if (ret != 0)
07260             return ret;
07261 
07262         if ( (ret = Encrypt(ssl, output + headerSz, output+headerSz,size)) != 0)
07263             return ret;
07264     }
07265 
07266     return sz;
07267 }
07268 
07269 
07270 int SendFinished(CYASSL* ssl)
07271 {
07272     int              sendSz,
07273                      finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
07274                                                      FINISHED_SZ;
07275     byte             input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ];  /* max */
07276     byte            *output;
07277     Hashes*          hashes;
07278     int              ret;
07279     int              headerSz = HANDSHAKE_HEADER_SZ;
07280     int              outputSz;
07281 
07282     #ifdef CYASSL_DTLS
07283         word32 sequence_number = ssl->keys.dtls_sequence_number;
07284         word16 epoch           = ssl->keys.dtls_epoch;
07285     #endif
07286 
07287     /* setup encrypt keys */
07288     if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
07289         return ret;
07290 
07291     /* check for available size */
07292     outputSz = sizeof(input) + MAX_MSG_EXTRA;
07293     if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
07294         return ret;
07295 
07296     #ifdef CYASSL_DTLS
07297         if (ssl->options.dtls) {
07298             /* Send Finished message with the next epoch, but don't commit that
07299              * change until the other end confirms its reception. */
07300             headerSz += DTLS_HANDSHAKE_EXTRA;
07301             ssl->keys.dtls_epoch++;
07302             ssl->keys.dtls_sequence_number = 0;  /* reset after epoch change */
07303         }
07304     #endif
07305 
07306     /* get ouput buffer */
07307     output = ssl->buffers.outputBuffer.buffer +
07308              ssl->buffers.outputBuffer.length;
07309 
07310     AddHandShakeHeader(input, finishedSz, finished, ssl);
07311 
07312     /* make finished hashes */
07313     hashes = (Hashes*)&input[headerSz];
07314     ret = BuildFinished(ssl, hashes,
07315                       ssl->options.side == CYASSL_CLIENT_END ? client : server);
07316     if (ret != 0) return ret;
07317 
07318 #ifdef HAVE_SECURE_RENEGOTIATION
07319     if (ssl->secure_renegotiation) {
07320         if (ssl->options.side == CYASSL_CLIENT_END)
07321             XMEMCPY(ssl->secure_renegotiation->client_verify_data, hashes,
07322                     TLS_FINISHED_SZ);
07323         else
07324             XMEMCPY(ssl->secure_renegotiation->server_verify_data, hashes,
07325                     TLS_FINISHED_SZ);
07326     }
07327 #endif
07328 
07329     sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz,
07330                           handshake);
07331     if (sendSz < 0)
07332         return BUILD_MSG_ERROR;
07333 
07334     #ifdef CYASSL_DTLS
07335     if (ssl->options.dtls) {
07336         ssl->keys.dtls_epoch = epoch;
07337         ssl->keys.dtls_sequence_number = sequence_number;
07338     }
07339     #endif
07340 
07341     if (!ssl->options.resuming) {
07342 #ifndef NO_SESSION_CACHE
07343         AddSession(ssl);    /* just try */
07344 #endif
07345         if (ssl->options.side == CYASSL_CLIENT_END) {
07346             ret = BuildFinished(ssl, &ssl->verifyHashes, server);
07347             if (ret != 0) return ret;
07348         }
07349         else {
07350             ssl->options.handShakeState = HANDSHAKE_DONE;
07351             ssl->options.handShakeDone  = 1;
07352             #ifdef CYASSL_DTLS
07353                 if (ssl->options.dtls) {
07354                     /* Other side will soon receive our Finished, go to next
07355                      * epoch. */
07356                     ssl->keys.dtls_epoch++;
07357                     ssl->keys.dtls_sequence_number = 1;
07358                 }
07359             #endif
07360         }
07361     }
07362     else {
07363         if (ssl->options.side == CYASSL_CLIENT_END) {
07364             ssl->options.handShakeState = HANDSHAKE_DONE;
07365             ssl->options.handShakeDone  = 1;
07366             #ifdef CYASSL_DTLS
07367                 if (ssl->options.dtls) {
07368                     /* Other side will soon receive our Finished, go to next
07369                      * epoch. */
07370                     ssl->keys.dtls_epoch++;
07371                     ssl->keys.dtls_sequence_number = 1;
07372                 }
07373             #endif
07374         }
07375         else {
07376             ret = BuildFinished(ssl, &ssl->verifyHashes, client);
07377             if (ret != 0) return ret;
07378         }
07379     }
07380     #ifdef CYASSL_DTLS
07381         if (ssl->options.dtls) {
07382             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
07383                 return ret;
07384         }
07385     #endif
07386 
07387     #ifdef CYASSL_CALLBACKS
07388         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
07389         if (ssl->toInfoOn)
07390             AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
07391                           ssl->heap);
07392     #endif
07393 
07394     ssl->buffers.outputBuffer.length += sendSz;
07395 
07396     return SendBuffered(ssl);
07397 }
07398 
07399 #ifndef NO_CERTS
07400 int SendCertificate(CYASSL* ssl)
07401 {
07402     int    sendSz, length, ret = 0;
07403     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
07404     word32 certSz, listSz;
07405     byte*  output = 0;
07406 
07407     if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
07408         return 0;  /* not needed */
07409 
07410     if (ssl->options.sendVerify == SEND_BLANK_CERT) {
07411         certSz = 0;
07412         length = CERT_HEADER_SZ;
07413         listSz = 0;
07414     }
07415     else {
07416         certSz = ssl->buffers.certificate.length;
07417         /* list + cert size */
07418         length = certSz + 2 * CERT_HEADER_SZ;
07419         listSz = certSz + CERT_HEADER_SZ;
07420 
07421         /* may need to send rest of chain, already has leading size(s) */
07422         if (ssl->buffers.certChain.buffer) {
07423             length += ssl->buffers.certChain.length;
07424             listSz += ssl->buffers.certChain.length;
07425         }
07426     }
07427     sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
07428 
07429     #ifdef CYASSL_DTLS
07430         if (ssl->options.dtls) {
07431             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
07432             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
07433         }
07434     #endif
07435 
07436     if (ssl->keys.encryptionOn)
07437         sendSz += MAX_MSG_EXTRA;
07438 
07439     /* check for available size */
07440     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
07441         return ret;
07442 
07443     /* get ouput buffer */
07444     output = ssl->buffers.outputBuffer.buffer +
07445              ssl->buffers.outputBuffer.length;
07446 
07447     AddHeaders(output, length, certificate, ssl);
07448 
07449     /* list total */
07450     c32to24(listSz, output + i);
07451     i += CERT_HEADER_SZ;
07452 
07453     /* member */
07454     if (certSz) {
07455         c32to24(certSz, output + i);
07456         i += CERT_HEADER_SZ;
07457         XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
07458         i += certSz;
07459 
07460         /* send rest of chain? */
07461         if (ssl->buffers.certChain.buffer) {
07462             XMEMCPY(output + i, ssl->buffers.certChain.buffer,
07463                                 ssl->buffers.certChain.length);
07464             i += ssl->buffers.certChain.length;
07465         }
07466     }
07467 
07468     if (ssl->keys.encryptionOn) {
07469         byte* input;
07470         int   inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
07471 
07472         input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
07473         if (input == NULL)
07474             return MEMORY_E;
07475 
07476         XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
07477         sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
07478         XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
07479 
07480         if (sendSz < 0)
07481             return sendSz;
07482     } else {
07483         ret = HashOutput(ssl, output, sendSz, 0);
07484         if (ret != 0)
07485             return ret;
07486     }
07487 
07488     #ifdef CYASSL_DTLS
07489         if (ssl->options.dtls) {
07490             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
07491                 return ret;
07492         }
07493     #endif
07494 
07495     #ifdef CYASSL_CALLBACKS
07496         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
07497         if (ssl->toInfoOn)
07498             AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
07499                            ssl->heap);
07500     #endif
07501 
07502     if (ssl->options.side == CYASSL_SERVER_END)
07503         ssl->options.serverState = SERVER_CERT_COMPLETE;
07504 
07505     ssl->buffers.outputBuffer.length += sendSz;
07506     if (ssl->options.groupMessages)
07507         return 0;
07508     else
07509         return SendBuffered(ssl);
07510 }
07511 
07512 
07513 int SendCertificateRequest(CYASSL* ssl)
07514 {
07515     byte   *output;
07516     int    ret;
07517     int    sendSz;
07518     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
07519 
07520     int  typeTotal = 1;  /* only 1 for now */
07521     int  reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ;  /* add auth later */
07522 
07523     if (IsAtLeastTLSv1_2(ssl))
07524         reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
07525 
07526     if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
07527         return 0;  /* not needed */
07528 
07529     sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
07530 
07531     #ifdef CYASSL_DTLS
07532         if (ssl->options.dtls) {
07533             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
07534             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
07535         }
07536     #endif
07537     /* check for available size */
07538     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
07539         return ret;
07540 
07541     /* get ouput buffer */
07542     output = ssl->buffers.outputBuffer.buffer +
07543              ssl->buffers.outputBuffer.length;
07544 
07545     AddHeaders(output, reqSz, certificate_request, ssl);
07546 
07547     /* write to output */
07548     output[i++] = (byte)typeTotal;  /* # of types */
07549 #ifdef HAVE_ECC
07550     if (ssl->options.cipherSuite0 == ECC_BYTE &&
07551                      ssl->specs.sig_algo == ecc_dsa_sa_algo) {
07552         output[i++] = ecdsa_sign;
07553     } else
07554 #endif /* HAVE_ECC */
07555     {
07556         output[i++] = rsa_sign;
07557     }
07558 
07559     /* supported hash/sig */
07560     if (IsAtLeastTLSv1_2(ssl)) {
07561         c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
07562         i += LENGTH_SZ;
07563 
07564         XMEMCPY(&output[i],
07565                          ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
07566         i += ssl->suites->hashSigAlgoSz;
07567     }
07568 
07569     c16toa(0, &output[i]);  /* auth's */
07570     /* if add more to output, adjust i
07571     i += REQ_HEADER_SZ; */
07572 
07573     #ifdef CYASSL_DTLS
07574         if (ssl->options.dtls) {
07575             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
07576                 return ret;
07577         }
07578     #endif
07579 
07580     ret = HashOutput(ssl, output, sendSz, 0);
07581     if (ret != 0)
07582         return ret;
07583 
07584     #ifdef CYASSL_CALLBACKS
07585         if (ssl->hsInfoOn)
07586             AddPacketName("CertificateRequest", &ssl->handShakeInfo);
07587         if (ssl->toInfoOn)
07588             AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
07589                           sendSz, ssl->heap);
07590     #endif
07591     ssl->buffers.outputBuffer.length += sendSz;
07592     if (ssl->options.groupMessages)
07593         return 0;
07594     else
07595         return SendBuffered(ssl);
07596 }
07597 #endif /* !NO_CERTS */
07598 
07599 
07600 int SendData(CYASSL* ssl, const void* data, int sz)
07601 {
07602     int sent = 0,  /* plainText size */
07603         sendSz,
07604         ret,
07605         dtlsExtra = 0;
07606 
07607     if (ssl->error == WANT_WRITE)
07608         ssl->error = 0;
07609 
07610     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
07611         int err;
07612         CYASSL_MSG("handshake not complete, trying to finish");
07613         if ( (err = CyaSSL_negotiate(ssl)) != SSL_SUCCESS)
07614             return  err;
07615     }
07616 
07617     /* last time system socket output buffer was full, try again to send */
07618     if (ssl->buffers.outputBuffer.length > 0) {
07619         CYASSL_MSG("output buffer was full, trying to send again");
07620         if ( (ssl->error = SendBuffered(ssl)) < 0) {
07621             CYASSL_ERROR(ssl->error);
07622             if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
07623                 return 0;     /* peer reset */
07624             return ssl->error;
07625         }
07626         else {
07627             /* advance sent to previous sent + plain size just sent */
07628             sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
07629             CYASSL_MSG("sent write buffered data");
07630 
07631             if (sent > sz) {
07632                 CYASSL_MSG("error: write() after WANT_WRITE with short size");
07633                 return ssl->error = BAD_FUNC_ARG;
07634             }
07635         }
07636     }
07637 
07638 #ifdef CYASSL_DTLS
07639     if (ssl->options.dtls) {
07640         dtlsExtra = DTLS_RECORD_EXTRA;
07641     }
07642 #endif
07643 
07644     for (;;) {
07645 #ifdef HAVE_MAX_FRAGMENT
07646         int   len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE));
07647 #else
07648         int   len = min(sz - sent, OUTPUT_RECORD_SIZE);
07649 #endif
07650         byte* out;
07651         byte* sendBuffer = (byte*)data + sent;  /* may switch on comp */
07652         int   buffSz = len;                     /* may switch on comp */
07653         int   outputSz;
07654 #ifdef HAVE_LIBZ
07655         byte  comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
07656 #endif
07657 
07658         if (sent == sz) break;
07659 
07660 #ifdef CYASSL_DTLS
07661         if (ssl->options.dtls) {
07662             len    = min(len, MAX_UDP_SIZE);
07663             buffSz = len;
07664         }
07665 #endif
07666 
07667         /* check for available size */
07668         outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
07669         if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
07670             return ssl->error = ret;
07671 
07672         /* get ouput buffer */
07673         out = ssl->buffers.outputBuffer.buffer +
07674               ssl->buffers.outputBuffer.length;
07675 
07676 #ifdef HAVE_LIBZ
07677         if (ssl->options.usingCompression) {
07678             buffSz = myCompress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
07679             if (buffSz < 0) {
07680                 return buffSz;
07681             }
07682             sendBuffer = comp;
07683         }
07684 #endif
07685         sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz,
07686                               application_data);
07687         if (sendSz < 0)
07688             return BUILD_MSG_ERROR;
07689 
07690         ssl->buffers.outputBuffer.length += sendSz;
07691 
07692         if ( (ret = SendBuffered(ssl)) < 0) {
07693             CYASSL_ERROR(ret);
07694             /* store for next call if WANT_WRITE or user embedSend() that
07695                doesn't present like WANT_WRITE */
07696             ssl->buffers.plainSz  = len;
07697             ssl->buffers.prevSent = sent;
07698             if (ret == SOCKET_ERROR_E && ssl->options.connReset)
07699                 return 0;  /* peer reset */
07700             return ssl->error = ret;
07701         }
07702 
07703         sent += len;
07704 
07705         /* only one message per attempt */
07706         if (ssl->options.partialWrite == 1) {
07707             CYASSL_MSG("Paritial Write on, only sending one record");
07708             break;
07709         }
07710     }
07711 
07712     return sent;
07713 }
07714 
07715 /* process input data */
07716 int ReceiveData(CYASSL* ssl, byte* output, int sz, int peek)
07717 {
07718     int size;
07719 
07720     CYASSL_ENTER("ReceiveData()");
07721 
07722     if (ssl->error == WANT_READ)
07723         ssl->error = 0;
07724 
07725     if (ssl->error != 0 && ssl->error != WANT_WRITE) {
07726         CYASSL_MSG("User calling CyaSSL_read in error state, not allowed");
07727         return ssl->error;
07728     }
07729 
07730     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
07731         int err;
07732         CYASSL_MSG("Handshake not complete, trying to finish");
07733         if ( (err = CyaSSL_negotiate(ssl)) != SSL_SUCCESS)
07734             return  err;
07735     }
07736 
07737 #ifdef HAVE_SECURE_RENEGOTIATION
07738 startScr:
07739     if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
07740         int err;
07741         ssl->secure_renegotiation->startScr = 0;  /* only start once */
07742         CYASSL_MSG("Need to start scr, server requested");
07743         if ( (err = CyaSSL_Rehandshake(ssl)) != SSL_SUCCESS)
07744             return  err;
07745     }
07746 #endif
07747 
07748     while (ssl->buffers.clearOutputBuffer.length == 0) {
07749         if ( (ssl->error = ProcessReply(ssl)) < 0) {
07750             CYASSL_ERROR(ssl->error);
07751             if (ssl->error == ZERO_RETURN) {
07752                 CYASSL_MSG("Zero return, no more data coming");
07753                 return 0;         /* no more data coming */
07754             }
07755             if (ssl->error == SOCKET_ERROR_E) {
07756                 if (ssl->options.connReset || ssl->options.isClosed) {
07757                     CYASSL_MSG("Peer reset or closed, connection done");
07758                     return 0;     /* peer reset or closed */
07759                 }
07760             }
07761             return ssl->error;
07762         }
07763         #ifdef HAVE_SECURE_RENEGOTIATION
07764             if (ssl->secure_renegotiation &&
07765                 ssl->secure_renegotiation->startScr) {
07766                 goto startScr;
07767             }
07768         #endif
07769     }
07770 
07771     if (sz < (int)ssl->buffers.clearOutputBuffer.length)
07772         size = sz;
07773     else
07774         size = ssl->buffers.clearOutputBuffer.length;
07775 
07776     XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
07777 
07778     if (peek == 0) {
07779         ssl->buffers.clearOutputBuffer.length -= size;
07780         ssl->buffers.clearOutputBuffer.buffer += size;
07781     }
07782 
07783     if (ssl->buffers.clearOutputBuffer.length == 0 &&
07784                                            ssl->buffers.inputBuffer.dynamicFlag)
07785        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
07786 
07787     CYASSL_LEAVE("ReceiveData()", size);
07788     return size;
07789 }
07790 
07791 
07792 /* send alert message */
07793 int SendAlert(CYASSL* ssl, int severity, int type)
07794 {
07795     byte input[ALERT_SIZE];
07796     byte *output;
07797     int  sendSz;
07798     int  ret;
07799     int  outputSz;
07800     int  dtlsExtra = 0;
07801 
07802     /* if sendalert is called again for nonbloking */
07803     if (ssl->options.sendAlertState != 0) {
07804         ret = SendBuffered(ssl);
07805         if (ret == 0)
07806             ssl->options.sendAlertState = 0;
07807         return ret;
07808     }
07809 
07810    #ifdef CYASSL_DTLS
07811         if (ssl->options.dtls)
07812            dtlsExtra = DTLS_RECORD_EXTRA;
07813    #endif
07814 
07815     /* check for available size */
07816     outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
07817     if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
07818         return ret;
07819 
07820     /* get ouput buffer */
07821     output = ssl->buffers.outputBuffer.buffer +
07822              ssl->buffers.outputBuffer.length;
07823 
07824     input[0] = (byte)severity;
07825     input[1] = (byte)type;
07826     ssl->alert_history.last_tx.code = type;
07827     ssl->alert_history.last_tx.level = severity;
07828     if (severity == alert_fatal) {
07829         ssl->options.isClosed = 1;  /* Don't send close_notify */
07830     }
07831 
07832     /* only send encrypted alert if handshake actually complete, otherwise
07833        other side may not be able to handle it */
07834     if (ssl->keys.encryptionOn && ssl->options.handShakeDone)
07835         sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE, alert);
07836     else {
07837 
07838         AddRecordHeader(output, ALERT_SIZE, alert, ssl);
07839         output += RECORD_HEADER_SZ;
07840         #ifdef CYASSL_DTLS
07841             if (ssl->options.dtls)
07842                 output += DTLS_RECORD_EXTRA;
07843         #endif
07844         XMEMCPY(output, input, ALERT_SIZE);
07845 
07846         sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
07847         #ifdef CYASSL_DTLS
07848             if (ssl->options.dtls)
07849                 sendSz += DTLS_RECORD_EXTRA;
07850         #endif
07851     }
07852     if (sendSz < 0)
07853         return BUILD_MSG_ERROR;
07854 
07855     #ifdef CYASSL_CALLBACKS
07856         if (ssl->hsInfoOn)
07857             AddPacketName("Alert", &ssl->handShakeInfo);
07858         if (ssl->toInfoOn)
07859             AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
07860     #endif
07861 
07862     ssl->buffers.outputBuffer.length += sendSz;
07863     ssl->options.sendAlertState = 1;
07864 
07865     return SendBuffered(ssl);
07866 }
07867 
07868 const char* CyaSSL_ERR_reason_error_string(unsigned long e)
07869 {
07870 #ifdef NO_ERROR_STRINGS
07871 
07872     (void)e;
07873     return "no support for error strings built in";
07874 
07875 #else
07876 
07877     int error = (int)e;
07878 
07879     /* pass to CTaoCrypt */
07880     if (error < MAX_CODE_E && error > MIN_CODE_E) {
07881         return CTaoCryptGetErrorString(error);
07882     }
07883 
07884     switch (error) {
07885 
07886     case UNSUPPORTED_SUITE :
07887         return "unsupported cipher suite";
07888 
07889     case INPUT_CASE_ERROR :
07890         return "input state error";
07891 
07892     case PREFIX_ERROR :
07893         return "bad index to key rounds";
07894 
07895     case MEMORY_ERROR :
07896         return "out of memory";
07897 
07898     case VERIFY_FINISHED_ERROR :
07899         return "verify problem on finished";
07900 
07901     case VERIFY_MAC_ERROR :
07902         return "verify mac problem";
07903 
07904     case PARSE_ERROR :
07905         return "parse error on header";
07906 
07907     case SIDE_ERROR :
07908         return "wrong client/server type";
07909 
07910     case NO_PEER_CERT :
07911         return "peer didn't send cert";
07912 
07913     case UNKNOWN_HANDSHAKE_TYPE :
07914         return "weird handshake type";
07915 
07916     case SOCKET_ERROR_E :
07917         return "error state on socket";
07918 
07919     case SOCKET_NODATA :
07920         return "expected data, not there";
07921 
07922     case INCOMPLETE_DATA :
07923         return "don't have enough data to complete task";
07924 
07925     case UNKNOWN_RECORD_TYPE :
07926         return "unknown type in record hdr";
07927 
07928     case DECRYPT_ERROR :
07929         return "error during decryption";
07930 
07931     case FATAL_ERROR :
07932         return "revcd alert fatal error";
07933 
07934     case ENCRYPT_ERROR :
07935         return "error during encryption";
07936 
07937     case FREAD_ERROR :
07938         return "fread problem";
07939 
07940     case NO_PEER_KEY :
07941         return "need peer's key";
07942 
07943     case NO_PRIVATE_KEY :
07944         return "need the private key";
07945 
07946     case NO_DH_PARAMS :
07947         return "server missing DH params";
07948 
07949     case RSA_PRIVATE_ERROR :
07950         return "error during rsa priv op";
07951 
07952     case MATCH_SUITE_ERROR :
07953         return "can't match cipher suite";
07954 
07955     case BUILD_MSG_ERROR :
07956         return "build message failure";
07957 
07958     case BAD_HELLO :
07959         return "client hello malformed";
07960 
07961     case DOMAIN_NAME_MISMATCH :
07962         return "peer subject name mismatch";
07963 
07964     case WANT_READ :
07965     case SSL_ERROR_WANT_READ :
07966         return "non-blocking socket wants data to be read";
07967 
07968     case NOT_READY_ERROR :
07969         return "handshake layer not ready yet, complete first";
07970 
07971     case PMS_VERSION_ERROR :
07972         return "premaster secret version mismatch error";
07973 
07974     case VERSION_ERROR :
07975         return "record layer version error";
07976 
07977     case WANT_WRITE :
07978     case SSL_ERROR_WANT_WRITE :
07979         return "non-blocking socket write buffer full";
07980 
07981     case BUFFER_ERROR :
07982         return "malformed buffer input error";
07983 
07984     case VERIFY_CERT_ERROR :
07985         return "verify problem on certificate";
07986 
07987     case VERIFY_SIGN_ERROR :
07988         return "verify problem based on signature";
07989 
07990     case CLIENT_ID_ERROR :
07991         return "psk client identity error";
07992 
07993     case SERVER_HINT_ERROR:
07994         return "psk server hint error";
07995 
07996     case PSK_KEY_ERROR:
07997         return "psk key callback error";
07998 
07999     case NTRU_KEY_ERROR:
08000         return "NTRU key error";
08001 
08002     case NTRU_DRBG_ERROR:
08003         return "NTRU drbg error";
08004 
08005     case NTRU_ENCRYPT_ERROR:
08006         return "NTRU encrypt error";
08007 
08008     case NTRU_DECRYPT_ERROR:
08009         return "NTRU decrypt error";
08010 
08011     case ZLIB_INIT_ERROR:
08012         return "zlib init error";
08013 
08014     case ZLIB_COMPRESS_ERROR:
08015         return "zlib compress error";
08016 
08017     case ZLIB_DECOMPRESS_ERROR:
08018         return "zlib decompress error";
08019 
08020     case GETTIME_ERROR:
08021         return "gettimeofday() error";
08022 
08023     case GETITIMER_ERROR:
08024         return "getitimer() error";
08025 
08026     case SIGACT_ERROR:
08027         return "sigaction() error";
08028 
08029     case SETITIMER_ERROR:
08030         return "setitimer() error";
08031 
08032     case LENGTH_ERROR:
08033         return "record layer length error";
08034 
08035     case PEER_KEY_ERROR:
08036         return "cant decode peer key";
08037 
08038     case ZERO_RETURN:
08039     case SSL_ERROR_ZERO_RETURN:
08040         return "peer sent close notify alert";
08041 
08042     case ECC_CURVETYPE_ERROR:
08043         return "Bad ECC Curve Type or unsupported";
08044 
08045     case ECC_CURVE_ERROR:
08046         return "Bad ECC Curve or unsupported";
08047 
08048     case ECC_PEERKEY_ERROR:
08049         return "Bad ECC Peer Key";
08050 
08051     case ECC_MAKEKEY_ERROR:
08052         return "ECC Make Key failure";
08053 
08054     case ECC_EXPORT_ERROR:
08055         return "ECC Export Key failure";
08056 
08057     case ECC_SHARED_ERROR:
08058         return "ECC DHE shared failure";
08059 
08060     case NOT_CA_ERROR:
08061         return "Not a CA by basic constraint error";
08062 
08063     case BAD_PATH_ERROR:
08064         return "Bad path for opendir error";
08065 
08066     case BAD_CERT_MANAGER_ERROR:
08067         return "Bad Cert Manager error";
08068 
08069     case OCSP_CERT_REVOKED:
08070         return "OCSP Cert revoked";
08071 
08072     case CRL_CERT_REVOKED:
08073         return "CRL Cert revoked";
08074 
08075     case CRL_MISSING:
08076         return "CRL missing, not loaded";
08077 
08078     case MONITOR_RUNNING_E:
08079         return "CRL monitor already running";
08080 
08081     case THREAD_CREATE_E:
08082         return "Thread creation problem";
08083 
08084     case OCSP_NEED_URL:
08085         return "OCSP need URL";
08086 
08087     case OCSP_CERT_UNKNOWN:
08088         return "OCSP Cert unknown";
08089 
08090     case OCSP_LOOKUP_FAIL:
08091         return "OCSP Responder lookup fail";
08092 
08093     case MAX_CHAIN_ERROR:
08094         return "Maximum Chain Depth Exceeded";
08095 
08096     case COOKIE_ERROR:
08097         return "DTLS Cookie Error";
08098 
08099     case SEQUENCE_ERROR:
08100         return "DTLS Sequence Error";
08101 
08102     case SUITES_ERROR:
08103         return "Suites Pointer Error";
08104 
08105     case SSL_NO_PEM_HEADER:
08106         return "No PEM Header Error";
08107 
08108     case OUT_OF_ORDER_E:
08109         return "Out of order message, fatal";
08110 
08111     case BAD_KEA_TYPE_E:
08112         return "Bad KEA type found";
08113 
08114     case SANITY_CIPHER_E:
08115         return "Sanity check on ciphertext failed";
08116 
08117     case RECV_OVERFLOW_E:
08118         return "Receive callback returned more than requested";
08119 
08120     case GEN_COOKIE_E:
08121         return "Generate Cookie Error";
08122 
08123     case NO_PEER_VERIFY:
08124         return "Need peer certificate verify Error";
08125 
08126     case FWRITE_ERROR:
08127         return "fwrite Error";
08128 
08129     case CACHE_MATCH_ERROR:
08130         return "Cache restore header match Error";
08131 
08132     case UNKNOWN_SNI_HOST_NAME_E:
08133         return "Unrecognized host name Error";
08134 
08135     case KEYUSE_SIGNATURE_E:
08136         return "Key Use digitalSignature not set Error";
08137 
08138     case KEYUSE_ENCIPHER_E:
08139         return "Key Use keyEncipherment not set Error";
08140 
08141     case EXTKEYUSE_AUTH_E:
08142         return "Ext Key Use server/client auth not set Error";
08143 
08144     case SEND_OOB_READ_E:
08145         return "Send Callback Out of Bounds Read Error";
08146 
08147     case SECURE_RENEGOTIATION_E:
08148         return "Invalid Renegotiation Error";
08149 
08150     case SESSION_TICKET_LEN_E:
08151         return "Session Ticket Too Long Error";
08152 
08153     case SESSION_TICKET_EXPECT_E:
08154         return "Session Ticket Error";
08155 
08156     case SCR_DIFFERENT_CERT_E:
08157         return "Peer sent different cert during SCR";
08158 
08159     case SESSION_SECRET_CB_E:
08160         return "Session Secret Callback Error";
08161 
08162     case NO_CHANGE_CIPHER_E:
08163         return "Finished received from peer before Change Cipher Error";
08164 
08165     case SANITY_MSG_E:
08166         return "Sanity Check on message order Error";
08167 
08168     case DUPLICATE_MSG_E:
08169         return "Duplicate HandShake message Error";
08170 
08171     default :
08172         return "unknown error number";
08173     }
08174 
08175 #endif /* NO_ERROR_STRINGS */
08176 }
08177 
08178 void SetErrorString(int error, char* str)
08179 {
08180     XSTRNCPY(str, CyaSSL_ERR_reason_error_string(error), CYASSL_MAX_ERROR_SZ);
08181 }
08182 
08183 
08184 /* be sure to add to cipher_name_idx too !!!! */
08185 static const char* const cipher_names[] =
08186 {
08187 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
08188     "RC4-SHA",
08189 #endif
08190 
08191 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
08192     "RC4-MD5",
08193 #endif
08194 
08195 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
08196     "DES-CBC3-SHA",
08197 #endif
08198 
08199 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
08200     "AES128-SHA",
08201 #endif
08202 
08203 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
08204     "AES256-SHA",
08205 #endif
08206 
08207 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
08208     "NULL-SHA",
08209 #endif
08210 
08211 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
08212     "NULL-SHA256",
08213 #endif
08214 
08215 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
08216     "DHE-RSA-AES128-SHA",
08217 #endif
08218 
08219 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
08220     "DHE-RSA-AES256-SHA",
08221 #endif
08222 
08223 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
08224     "DHE-PSK-AES256-GCM-SHA384",
08225 #endif
08226 
08227 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
08228     "DHE-PSK-AES128-GCM-SHA256",
08229 #endif
08230 
08231 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
08232     "PSK-AES256-GCM-SHA384",
08233 #endif
08234 
08235 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
08236     "PSK-AES128-GCM-SHA256",
08237 #endif
08238 
08239 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
08240     "DHE-PSK-AES256-CBC-SHA384",
08241 #endif
08242 
08243 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
08244     "DHE-PSK-AES128-CBC-SHA256",
08245 #endif
08246 
08247 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
08248     "PSK-AES256-CBC-SHA384",
08249 #endif
08250 
08251 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
08252     "PSK-AES128-CBC-SHA256",
08253 #endif
08254 
08255 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
08256     "PSK-AES128-CBC-SHA",
08257 #endif
08258 
08259 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
08260     "PSK-AES256-CBC-SHA",
08261 #endif
08262 
08263 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
08264     "DHE-PSK-AES128-CCM",
08265 #endif
08266 
08267 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
08268     "DHE-PSK-AES256-CCM",
08269 #endif
08270 
08271 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
08272     "PSK-AES128-CCM",
08273 #endif
08274 
08275 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
08276     "PSK-AES256-CCM",
08277 #endif
08278 
08279 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
08280     "PSK-AES128-CCM-8",
08281 #endif
08282 
08283 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
08284     "PSK-AES256-CCM-8",
08285 #endif
08286 
08287 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
08288     "DHE-PSK-NULL-SHA384",
08289 #endif
08290 
08291 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
08292     "DHE-PSK-NULL-SHA256",
08293 #endif
08294 
08295 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
08296     "PSK-NULL-SHA384",
08297 #endif
08298 
08299 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
08300     "PSK-NULL-SHA256",
08301 #endif
08302 
08303 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
08304     "PSK-NULL-SHA",
08305 #endif
08306 
08307 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
08308     "HC128-MD5",
08309 #endif
08310 
08311 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
08312     "HC128-SHA",
08313 #endif
08314 
08315 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
08316     "HC128-B2B256",
08317 #endif
08318 
08319 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
08320     "AES128-B2B256",
08321 #endif
08322 
08323 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
08324     "AES256-B2B256",
08325 #endif
08326 
08327 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
08328     "RABBIT-SHA",
08329 #endif
08330 
08331 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
08332     "NTRU-RC4-SHA",
08333 #endif
08334 
08335 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
08336     "NTRU-DES-CBC3-SHA",
08337 #endif
08338 
08339 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
08340     "NTRU-AES128-SHA",
08341 #endif
08342 
08343 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
08344     "NTRU-AES256-SHA",
08345 #endif
08346 
08347 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
08348     "AES128-CCM-8",
08349 #endif
08350 
08351 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
08352     "AES256-CCM-8",
08353 #endif
08354 
08355 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
08356     "ECDHE-ECDSA-AES128-CCM-8",
08357 #endif
08358 
08359 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
08360     "ECDHE-ECDSA-AES256-CCM-8",
08361 #endif
08362 
08363 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
08364     "ECDHE-RSA-AES128-SHA",
08365 #endif
08366 
08367 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
08368     "ECDHE-RSA-AES256-SHA",
08369 #endif
08370 
08371 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
08372     "ECDHE-ECDSA-AES128-SHA",
08373 #endif
08374 
08375 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
08376     "ECDHE-ECDSA-AES256-SHA",
08377 #endif
08378 
08379 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
08380     "ECDHE-RSA-RC4-SHA",
08381 #endif
08382 
08383 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
08384     "ECDHE-RSA-DES-CBC3-SHA",
08385 #endif
08386 
08387 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
08388     "ECDHE-ECDSA-RC4-SHA",
08389 #endif
08390 
08391 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
08392     "ECDHE-ECDSA-DES-CBC3-SHA",
08393 #endif
08394 
08395 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
08396     "AES128-SHA256",
08397 #endif
08398 
08399 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
08400     "AES256-SHA256",
08401 #endif
08402 
08403 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
08404     "DHE-RSA-AES128-SHA256",
08405 #endif
08406 
08407 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
08408     "DHE-RSA-AES256-SHA256",
08409 #endif
08410 
08411 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
08412     "ECDH-RSA-AES128-SHA",
08413 #endif
08414 
08415 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
08416     "ECDH-RSA-AES256-SHA",
08417 #endif
08418 
08419 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
08420     "ECDH-ECDSA-AES128-SHA",
08421 #endif
08422 
08423 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
08424     "ECDH-ECDSA-AES256-SHA",
08425 #endif
08426 
08427 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
08428     "ECDH-RSA-RC4-SHA",
08429 #endif
08430 
08431 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
08432     "ECDH-RSA-DES-CBC3-SHA",
08433 #endif
08434 
08435 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
08436     "ECDH-ECDSA-RC4-SHA",
08437 #endif
08438 
08439 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
08440     "ECDH-ECDSA-DES-CBC3-SHA",
08441 #endif
08442 
08443 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
08444     "AES128-GCM-SHA256",
08445 #endif
08446 
08447 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
08448     "AES256-GCM-SHA384",
08449 #endif
08450 
08451 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
08452     "DHE-RSA-AES128-GCM-SHA256",
08453 #endif
08454 
08455 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
08456     "DHE-RSA-AES256-GCM-SHA384",
08457 #endif
08458 
08459 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
08460     "ECDHE-RSA-AES128-GCM-SHA256",
08461 #endif
08462 
08463 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
08464     "ECDHE-RSA-AES256-GCM-SHA384",
08465 #endif
08466 
08467 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
08468     "ECDHE-ECDSA-AES128-GCM-SHA256",
08469 #endif
08470 
08471 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
08472     "ECDHE-ECDSA-AES256-GCM-SHA384",
08473 #endif
08474 
08475 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
08476     "ECDH-RSA-AES128-GCM-SHA256",
08477 #endif
08478 
08479 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
08480     "ECDH-RSA-AES256-GCM-SHA384",
08481 #endif
08482 
08483 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
08484     "ECDH-ECDSA-AES128-GCM-SHA256",
08485 #endif
08486 
08487 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
08488     "ECDH-ECDSA-AES256-GCM-SHA384",
08489 #endif
08490 
08491 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
08492     "CAMELLIA128-SHA",
08493 #endif
08494 
08495 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
08496     "DHE-RSA-CAMELLIA128-SHA",
08497 #endif
08498 
08499 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
08500     "CAMELLIA256-SHA",
08501 #endif
08502 
08503 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
08504     "DHE-RSA-CAMELLIA256-SHA",
08505 #endif
08506 
08507 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
08508     "CAMELLIA128-SHA256",
08509 #endif
08510 
08511 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
08512     "DHE-RSA-CAMELLIA128-SHA256",
08513 #endif
08514 
08515 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
08516     "CAMELLIA256-SHA256",
08517 #endif
08518 
08519 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
08520     "DHE-RSA-CAMELLIA256-SHA256",
08521 #endif
08522 
08523 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
08524     "ECDHE-RSA-AES128-SHA256",
08525 #endif
08526 
08527 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
08528     "ECDHE-ECDSA-AES128-SHA256",
08529 #endif
08530 
08531 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
08532     "ECDH-RSA-AES128-SHA256",
08533 #endif
08534 
08535 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
08536     "ECDH-ECDSA-AES128-SHA256",
08537 #endif
08538 
08539 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
08540     "ECDHE-RSA-AES256-SHA384",
08541 #endif
08542 
08543 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
08544     "ECDHE-ECDSA-AES256-SHA384",
08545 #endif
08546 
08547 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
08548     "ECDH-RSA-AES256-SHA384",
08549 #endif
08550 
08551 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
08552     "ECDH-ECDSA-AES256-SHA384",
08553 #endif
08554 
08555 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
08556     "ECDHE-RSA-CHACHA20-POLY1305",
08557 #endif
08558 
08559 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
08560     "ECDHE-ECDSA-CHACHA20-POLY1305",
08561 #endif
08562 
08563 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
08564     "DHE-RSA-CHACHA20-POLY1305",
08565 #endif
08566 
08567 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
08568     "ADH-AES128-SHA",
08569 #endif
08570 
08571 #ifdef HAVE_RENEGOTIATION_INDICATION
08572     "RENEGOTIATION-INFO",
08573 #endif
08574 };
08575 
08576 
08577 /* cipher suite number that matches above name table */
08578 static int cipher_name_idx[] =
08579 {
08580 
08581 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
08582     SSL_RSA_WITH_RC4_128_SHA,
08583 #endif
08584 
08585 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
08586     SSL_RSA_WITH_RC4_128_MD5,
08587 #endif
08588 
08589 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
08590     SSL_RSA_WITH_3DES_EDE_CBC_SHA,
08591 #endif
08592 
08593 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
08594     TLS_RSA_WITH_AES_128_CBC_SHA,
08595 #endif
08596 
08597 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
08598     TLS_RSA_WITH_AES_256_CBC_SHA,
08599 #endif
08600 
08601 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
08602     TLS_RSA_WITH_NULL_SHA,
08603 #endif
08604 
08605 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
08606     TLS_RSA_WITH_NULL_SHA256,
08607 #endif
08608 
08609 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
08610     TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
08611 #endif
08612 
08613 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
08614     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
08615 #endif
08616 
08617 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
08618     TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
08619 #endif
08620 
08621 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
08622     TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
08623 #endif
08624 
08625 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
08626     TLS_PSK_WITH_AES_256_GCM_SHA384,
08627 #endif
08628 
08629 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
08630     TLS_PSK_WITH_AES_128_GCM_SHA256,
08631 #endif
08632 
08633 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
08634     TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
08635 #endif
08636 
08637 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
08638     TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
08639 #endif
08640 
08641 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
08642     TLS_PSK_WITH_AES_256_CBC_SHA384,
08643 #endif
08644 
08645 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
08646     TLS_PSK_WITH_AES_128_CBC_SHA256,
08647 #endif
08648 
08649 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
08650     TLS_PSK_WITH_AES_128_CBC_SHA,
08651 #endif
08652 
08653 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
08654     TLS_PSK_WITH_AES_256_CBC_SHA,
08655 #endif
08656 
08657 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
08658     TLS_DHE_PSK_WITH_AES_128_CCM,
08659 #endif
08660 
08661 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
08662     TLS_DHE_PSK_WITH_AES_256_CCM,
08663 #endif
08664 
08665 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
08666     TLS_PSK_WITH_AES_128_CCM,
08667 #endif
08668 
08669 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
08670     TLS_PSK_WITH_AES_256_CCM,
08671 #endif
08672 
08673 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
08674     TLS_PSK_WITH_AES_128_CCM_8,
08675 #endif
08676 
08677 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
08678     TLS_PSK_WITH_AES_256_CCM_8,
08679 #endif
08680 
08681 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
08682     TLS_DHE_PSK_WITH_NULL_SHA384,
08683 #endif
08684 
08685 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
08686     TLS_DHE_PSK_WITH_NULL_SHA256,
08687 #endif
08688 
08689 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
08690     TLS_PSK_WITH_NULL_SHA384,
08691 #endif
08692 
08693 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
08694     TLS_PSK_WITH_NULL_SHA256,
08695 #endif
08696 
08697 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
08698     TLS_PSK_WITH_NULL_SHA,
08699 #endif
08700 
08701 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
08702     TLS_RSA_WITH_HC_128_MD5,
08703 #endif
08704 
08705 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
08706     TLS_RSA_WITH_HC_128_SHA,
08707 #endif
08708 
08709 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
08710     TLS_RSA_WITH_HC_128_B2B256,
08711 #endif
08712 
08713 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
08714     TLS_RSA_WITH_AES_128_CBC_B2B256,
08715 #endif
08716 
08717 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
08718     TLS_RSA_WITH_AES_256_CBC_B2B256,
08719 #endif
08720 
08721 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
08722     TLS_RSA_WITH_RABBIT_SHA,
08723 #endif
08724 
08725 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
08726     TLS_NTRU_RSA_WITH_RC4_128_SHA,
08727 #endif
08728 
08729 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
08730     TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
08731 #endif
08732 
08733 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
08734     TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
08735 #endif
08736 
08737 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
08738     TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
08739 #endif
08740 
08741 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
08742     TLS_RSA_WITH_AES_128_CCM_8,
08743 #endif
08744 
08745 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
08746     TLS_RSA_WITH_AES_256_CCM_8,
08747 #endif
08748 
08749 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
08750     TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
08751 #endif
08752 
08753 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
08754     TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
08755 #endif
08756 
08757 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
08758     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
08759 #endif
08760 
08761 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
08762     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
08763 #endif
08764 
08765 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
08766     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
08767 #endif
08768 
08769 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
08770     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
08771 #endif
08772 
08773 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
08774     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
08775 #endif
08776 
08777 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
08778     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
08779 #endif
08780 
08781 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
08782     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
08783 #endif
08784 
08785 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
08786     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
08787 #endif
08788 
08789 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
08790     TLS_RSA_WITH_AES_128_CBC_SHA256,
08791 #endif
08792 
08793 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
08794     TLS_RSA_WITH_AES_256_CBC_SHA256,
08795 #endif
08796 
08797 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
08798     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
08799 #endif
08800 
08801 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
08802     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
08803 #endif
08804 
08805 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
08806     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
08807 #endif
08808 
08809 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
08810     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
08811 #endif
08812 
08813 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
08814     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
08815 #endif
08816 
08817 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
08818     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
08819 #endif
08820 
08821 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
08822     TLS_ECDH_RSA_WITH_RC4_128_SHA,
08823 #endif
08824 
08825 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
08826     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
08827 #endif
08828 
08829 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
08830     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
08831 #endif
08832 
08833 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
08834     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
08835 #endif
08836 
08837 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
08838     TLS_RSA_WITH_AES_128_GCM_SHA256,
08839 #endif
08840 
08841 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
08842     TLS_RSA_WITH_AES_256_GCM_SHA384,
08843 #endif
08844 
08845 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
08846     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
08847 #endif
08848 
08849 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
08850     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
08851 #endif
08852 
08853 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
08854     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
08855 #endif
08856 
08857 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
08858     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
08859 #endif
08860 
08861 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
08862     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
08863 #endif
08864 
08865 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
08866     TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
08867 #endif
08868 
08869 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
08870     TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
08871 #endif
08872 
08873 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
08874     TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
08875 #endif
08876 
08877 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
08878     TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
08879 #endif
08880 
08881 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
08882     TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
08883 #endif
08884 
08885 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
08886     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
08887 #endif
08888 
08889 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
08890     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
08891 #endif
08892 
08893 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
08894     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
08895 #endif
08896 
08897 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
08898     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
08899 #endif
08900 
08901 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
08902     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
08903 #endif
08904 
08905 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
08906     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
08907 #endif
08908 
08909 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
08910     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
08911 #endif
08912 
08913 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
08914     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
08915 #endif
08916 
08917 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
08918     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
08919 #endif
08920 
08921 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
08922     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
08923 #endif
08924 
08925 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
08926     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
08927 #endif
08928 
08929 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
08930     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
08931 #endif
08932 
08933 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
08934     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
08935 #endif
08936 
08937 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
08938     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
08939 #endif
08940 
08941 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
08942     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
08943 #endif
08944 
08945 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
08946     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
08947 #endif
08948 
08949 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
08950     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
08951 #endif
08952 
08953 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
08954     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
08955 #endif
08956 
08957 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
08958     TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
08959 #endif
08960 
08961 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
08962     TLS_DH_anon_WITH_AES_128_CBC_SHA,
08963 #endif
08964 
08965 #ifdef HAVE_RENEGOTIATION_INDICATION
08966     TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
08967 #endif
08968 };
08969 
08970 
08971 /* returns the cipher_names array */
08972 const char* const* GetCipherNames(void)
08973 {
08974     return cipher_names;
08975 }
08976 
08977 
08978 /* returns the size of the cipher_names array */
08979 int GetCipherNamesSize(void)
08980 {
08981     return (int)(sizeof(cipher_names) / sizeof(char*));
08982 }
08983 
08984 
08985 /**
08986 Set the enabled cipher suites.
08987 
08988 @param [out] suites Suites structure.
08989 @param [in]  list   List of cipher suites, only supports full name from
08990                     cipher_name[] delimited by ':'.
08991 
08992 @return true on success, else false.
08993 */
08994 int SetCipherList(Suites* suites, const char* list)
08995 {
08996     int       ret          = 0;
08997     int       idx          = 0;
08998     int       haveRSAsig   = 0;
08999     int       haveECDSAsig = 0;
09000     int       haveAnon     = 0;
09001     const int suiteSz      = GetCipherNamesSize();
09002     char*     next         = (char*)list;
09003 
09004     if (suites == NULL || list == NULL) {
09005         CYASSL_MSG("SetCipherList parameter error");
09006         return 0;
09007     }
09008 
09009     if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0)
09010         return 1; /* CyaSSL defualt */
09011 
09012     do {
09013         char*  current = next;
09014         char   name[MAX_SUITE_NAME + 1];
09015         int    i;
09016         word32 length;
09017 
09018         next   = XSTRSTR(next, ":");
09019         length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
09020                                          : (word32)(next - current));
09021 
09022         XSTRNCPY(name, current, length);
09023         name[(length == sizeof(name)) ? length - 1 : length] = 0;
09024 
09025         for (i = 0; i < suiteSz; i++) {
09026             if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
09027                 suites->suites[idx++] = (XSTRSTR(name, "CHACHA")) ? CHACHA_BYTE
09028                                       : (XSTRSTR(name, "EC"))     ? ECC_BYTE
09029                                       : (XSTRSTR(name, "CCM"))    ? ECC_BYTE
09030                                       : 0x00; /* normal */
09031 
09032                 suites->suites[idx++] = (byte)cipher_name_idx[i];
09033 
09034                 /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
09035                  * suites don't necessarily have RSA in the name. */
09036                 if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA"))
09037                     haveECDSAsig = 1;
09038                 else if (XSTRSTR(name, "ADH"))
09039                     haveAnon = 1;
09040                 else if ((haveRSAsig == 0) && (XSTRSTR(name, "PSK") == NULL))
09041                     haveRSAsig = 1;
09042 
09043                 ret = 1; /* found at least one */
09044                 break;
09045             }
09046         }
09047     }
09048     while (next++); /* ++ needed to skip ':' */
09049 
09050     if (ret) {
09051         suites->setSuites = 1;
09052         suites->suiteSz   = (word16)idx;
09053         InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon);
09054     }
09055 
09056     return ret;
09057 }
09058 
09059 
09060 static void PickHashSigAlgo(CYASSL* ssl,
09061                              const byte* hashSigAlgo, word32 hashSigAlgoSz)
09062 {
09063     word32 i;
09064 
09065     ssl->suites->sigAlgo = ssl->specs.sig_algo;
09066     ssl->suites->hashAlgo = sha_mac;
09067 
09068     /* i+1 since peek a byte ahead for type */
09069     for (i = 0; (i+1) < hashSigAlgoSz; i += 2) {
09070         if (hashSigAlgo[i+1] == ssl->specs.sig_algo) {
09071             if (hashSigAlgo[i] == sha_mac) {
09072                 break;
09073             }
09074             #ifndef NO_SHA256
09075             else if (hashSigAlgo[i] == sha256_mac) {
09076                 ssl->suites->hashAlgo = sha256_mac;
09077                 break;
09078             }
09079             #endif
09080             #ifdef CYASSL_SHA384
09081             else if (hashSigAlgo[i] == sha384_mac) {
09082                 ssl->suites->hashAlgo = sha384_mac;
09083                 break;
09084             }
09085             #endif
09086         }
09087     }
09088 }
09089 
09090 
09091 #ifdef CYASSL_CALLBACKS
09092 
09093     /* Initialisze HandShakeInfo */
09094     void InitHandShakeInfo(HandShakeInfo* info)
09095     {
09096         int i;
09097 
09098         info->cipherName[0] = 0;
09099         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
09100             info->packetNames[i][0] = 0;
09101         info->numberPackets = 0;
09102         info->negotiationError = 0;
09103     }
09104 
09105     /* Set Final HandShakeInfo parameters */
09106     void FinishHandShakeInfo(HandShakeInfo* info, const CYASSL* ssl)
09107     {
09108         int i;
09109         int sz = sizeof(cipher_name_idx)/sizeof(int);
09110 
09111         for (i = 0; i < sz; i++)
09112             if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
09113                 if (ssl->options.cipherSuite0 == ECC_BYTE)
09114                     continue;   /* ECC suites at end */
09115                 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
09116                 break;
09117             }
09118 
09119         /* error max and min are negative numbers */
09120         if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
09121             info->negotiationError = ssl->error;
09122     }
09123 
09124 
09125     /* Add name to info packet names, increase packet name count */
09126     void AddPacketName(const char* name, HandShakeInfo* info)
09127     {
09128         if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
09129             XSTRNCPY(info->packetNames[info->numberPackets++], name,
09130                     MAX_PACKETNAME_SZ);
09131         }
09132     }
09133 
09134 
09135     /* Initialisze TimeoutInfo */
09136     void InitTimeoutInfo(TimeoutInfo* info)
09137     {
09138         int i;
09139 
09140         info->timeoutName[0] = 0;
09141         info->flags          = 0;
09142 
09143         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
09144             info->packets[i].packetName[0]     = 0;
09145             info->packets[i].timestamp.tv_sec  = 0;
09146             info->packets[i].timestamp.tv_usec = 0;
09147             info->packets[i].bufferValue       = 0;
09148             info->packets[i].valueSz           = 0;
09149         }
09150         info->numberPackets        = 0;
09151         info->timeoutValue.tv_sec  = 0;
09152         info->timeoutValue.tv_usec = 0;
09153     }
09154 
09155 
09156     /* Free TimeoutInfo */
09157     void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
09158     {
09159         int i;
09160         (void)heap;
09161         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
09162             if (info->packets[i].bufferValue) {
09163                 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
09164                 info->packets[i].bufferValue = 0;
09165             }
09166 
09167     }
09168 
09169 
09170     /* Add PacketInfo to TimeoutInfo */
09171     void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
09172                        int sz, void* heap)
09173     {
09174         if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
09175             Timeval currTime;
09176 
09177             /* may add name after */
09178             if (name)
09179                 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
09180                         MAX_PACKETNAME_SZ);
09181 
09182             /* add data, put in buffer if bigger than static buffer */
09183             info->packets[info->numberPackets].valueSz = sz;
09184             if (sz < MAX_VALUE_SZ)
09185                 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
09186             else {
09187                 info->packets[info->numberPackets].bufferValue =
09188                            XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
09189                 if (!info->packets[info->numberPackets].bufferValue)
09190                     /* let next alloc catch, just don't fill, not fatal here  */
09191                     info->packets[info->numberPackets].valueSz = 0;
09192                 else
09193                     XMEMCPY(info->packets[info->numberPackets].bufferValue,
09194                            data, sz);
09195             }
09196             gettimeofday(&currTime, 0);
09197             info->packets[info->numberPackets].timestamp.tv_sec  =
09198                                                              currTime.tv_sec;
09199             info->packets[info->numberPackets].timestamp.tv_usec =
09200                                                              currTime.tv_usec;
09201             info->numberPackets++;
09202         }
09203     }
09204 
09205 
09206     /* Add packet name to previsouly added packet info */
09207     void AddLateName(const char* name, TimeoutInfo* info)
09208     {
09209         /* make sure we have a valid previous one */
09210         if (info->numberPackets > 0 && info->numberPackets <
09211                                                         MAX_PACKETS_HANDSHAKE) {
09212             XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
09213                     MAX_PACKETNAME_SZ);
09214         }
09215     }
09216 
09217     /* Add record header to previsouly added packet info */
09218     void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
09219     {
09220         /* make sure we have a valid previous one */
09221         if (info->numberPackets > 0 && info->numberPackets <
09222                                                         MAX_PACKETS_HANDSHAKE) {
09223             if (info->packets[info->numberPackets - 1].bufferValue)
09224                 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
09225                        RECORD_HEADER_SZ);
09226             else
09227                 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
09228                        RECORD_HEADER_SZ);
09229         }
09230     }
09231 
09232 #endif /* CYASSL_CALLBACKS */
09233 
09234 
09235 
09236 /* client only parts */
09237 #ifndef NO_CYASSL_CLIENT
09238 
09239     int SendClientHello(CYASSL* ssl)
09240     {
09241         byte              *output;
09242         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
09243         int                sendSz;
09244         int                idSz = ssl->options.resuming
09245                                 ? ssl->session.sessionIDSz
09246                                 : 0;
09247         int                ret;
09248 
09249         if (ssl->suites == NULL) {
09250             CYASSL_MSG("Bad suites pointer in SendClientHello");
09251             return SUITES_ERROR;
09252         }
09253 
09254 #ifdef HAVE_SESSION_TICKET
09255         if (ssl->options.resuming && ssl->session.ticketLen > 0) {
09256             SessionTicket* ticket;
09257 
09258             ticket = TLSX_SessionTicket_Create(0,
09259                                    ssl->session.ticket, ssl->session.ticketLen);
09260             if (ticket == NULL) return MEMORY_E;
09261 
09262             ret = TLSX_UseSessionTicket(&ssl->extensions, ticket);
09263             if (ret != SSL_SUCCESS) return ret;
09264 
09265             idSz = 0;
09266         }
09267 #endif
09268 
09269         length = VERSION_SZ + RAN_LEN
09270                + idSz + ENUM_LEN
09271                + ssl->suites->suiteSz + SUITE_LEN
09272                + COMP_LEN + ENUM_LEN;
09273 
09274 #ifdef HAVE_TLS_EXTENSIONS
09275         length += TLSX_GetRequestSize(ssl);
09276 #else
09277         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
09278             length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
09279         }
09280 #endif
09281         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
09282 
09283 #ifdef CYASSL_DTLS
09284         if (ssl->options.dtls) {
09285             length += ENUM_LEN;   /* cookie */
09286             if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
09287             sendSz  = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
09288             idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
09289         }
09290 #endif
09291 
09292         if (ssl->keys.encryptionOn)
09293             sendSz += MAX_MSG_EXTRA;
09294 
09295         /* check for available size */
09296         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
09297             return ret;
09298 
09299         /* get ouput buffer */
09300         output = ssl->buffers.outputBuffer.buffer +
09301                  ssl->buffers.outputBuffer.length;
09302 
09303         AddHeaders(output, length, client_hello, ssl);
09304 
09305             /* client hello, first version */
09306         output[idx++] = ssl->version.major;
09307         output[idx++] = ssl->version.minor;
09308         ssl->chVersion = ssl->version;  /* store in case changed */
09309 
09310             /* then random */
09311         if (ssl->options.connectState == CONNECT_BEGIN) {
09312             ret = RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
09313             if (ret != 0)
09314                 return ret;
09315 
09316                 /* store random */
09317             XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
09318         } else {
09319 #ifdef CYASSL_DTLS
09320                 /* send same random on hello again */
09321             XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
09322 #endif
09323         }
09324         idx += RAN_LEN;
09325 
09326             /* then session id */
09327         output[idx++] = (byte)idSz;
09328         if (idSz) {
09329             XMEMCPY(output + idx, ssl->session.sessionID,
09330                                                       ssl->session.sessionIDSz);
09331             idx += ssl->session.sessionIDSz;
09332         }
09333 
09334             /* then DTLS cookie */
09335 #ifdef CYASSL_DTLS
09336         if (ssl->options.dtls) {
09337             byte cookieSz = ssl->arrays->cookieSz;
09338 
09339             output[idx++] = cookieSz;
09340             if (cookieSz) {
09341                 XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
09342                 idx += cookieSz;
09343             }
09344         }
09345 #endif
09346             /* then cipher suites */
09347         c16toa(ssl->suites->suiteSz, output + idx);
09348         idx += 2;
09349         XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
09350         idx += ssl->suites->suiteSz;
09351 
09352             /* last, compression */
09353         output[idx++] = COMP_LEN;
09354         if (ssl->options.usingCompression)
09355             output[idx++] = ZLIB_COMPRESSION;
09356         else
09357             output[idx++] = NO_COMPRESSION;
09358 
09359 #ifdef HAVE_TLS_EXTENSIONS
09360         idx += TLSX_WriteRequest(ssl, output + idx);
09361 
09362         (void)idx; /* suppress analyzer warning, keep idx current */
09363 #else
09364         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
09365         {
09366             int i;
09367             /* add in the extensions length */
09368             c16toa(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz, output + idx);
09369             idx += 2;
09370 
09371             c16toa(HELLO_EXT_SIG_ALGO, output + idx);
09372             idx += 2;
09373             c16toa(HELLO_EXT_SIGALGO_SZ+ssl->suites->hashSigAlgoSz, output+idx);
09374             idx += 2;
09375             c16toa(ssl->suites->hashSigAlgoSz, output + idx);
09376             idx += 2;
09377             for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
09378                 output[idx] = ssl->suites->hashSigAlgo[i];
09379             }
09380         }
09381 #endif
09382 
09383         if (ssl->keys.encryptionOn) {
09384             byte* input;
09385             int   inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
09386 
09387             input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
09388             if (input == NULL)
09389                 return MEMORY_E;
09390 
09391             XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
09392             sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
09393             XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
09394 
09395             if (sendSz < 0)
09396                 return sendSz;
09397         } else {
09398             ret = HashOutput(ssl, output, sendSz, 0);
09399             if (ret != 0)
09400                 return ret;
09401         }
09402 
09403         #ifdef CYASSL_DTLS
09404             if (ssl->options.dtls) {
09405                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
09406                     return ret;
09407             }
09408         #endif
09409 
09410         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
09411 
09412 #ifdef CYASSL_CALLBACKS
09413         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
09414         if (ssl->toInfoOn)
09415             AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
09416                           ssl->heap);
09417 #endif
09418 
09419         ssl->buffers.outputBuffer.length += sendSz;
09420 
09421         return SendBuffered(ssl);
09422     }
09423 
09424 
09425     static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input,
09426                                     word32* inOutIdx, word32 size)
09427     {
09428         ProtocolVersion pv;
09429         byte            cookieSz;
09430         word32          begin = *inOutIdx;
09431 
09432 #ifdef CYASSL_CALLBACKS
09433         if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
09434                                          &ssl->handShakeInfo);
09435         if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
09436 #endif
09437 
09438 #ifdef CYASSL_DTLS
09439         if (ssl->options.dtls) {
09440             DtlsPoolReset(ssl);
09441         }
09442 #endif
09443 
09444         if ((*inOutIdx - begin) + OPAQUE16_LEN + OPAQUE8_LEN > size)
09445             return BUFFER_ERROR;
09446 
09447         XMEMCPY(&pv, input + *inOutIdx, OPAQUE16_LEN);
09448         *inOutIdx += OPAQUE16_LEN;
09449 
09450         cookieSz = input[(*inOutIdx)++];
09451 
09452         if (cookieSz) {
09453             if ((*inOutIdx - begin) + cookieSz > size)
09454                 return BUFFER_ERROR;
09455 
09456 #ifdef CYASSL_DTLS
09457             if (cookieSz <= MAX_COOKIE_LEN) {
09458                 XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
09459                 ssl->arrays->cookieSz = cookieSz;
09460             }
09461 #endif
09462             *inOutIdx += cookieSz;
09463         }
09464 
09465         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
09466         return 0;
09467     }
09468 
09469 
09470     static INLINE int DSH_CheckSessionId(CYASSL* ssl)
09471     {
09472         int ret = 0;
09473 
09474 #ifdef HAVE_SECRET_CALLBACK
09475         /* If a session secret callback exists, we are using that
09476          * key instead of the saved session key. */
09477         ret = ret || (ssl->sessionSecretCb != NULL);
09478 #endif
09479 
09480 #ifdef HAVE_SESSION_TICKET
09481         ret = ret ||
09482               (!ssl->expect_session_ticket && ssl->session.ticketLen > 0);
09483 #endif
09484 
09485         ret = ret ||
09486               (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
09487                                           ssl->session.sessionID, ID_LEN) == 0);
09488 
09489         return ret;
09490     }
09491 
09492     static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
09493                              word32 helloSz)
09494     {
09495         byte            cs0;   /* cipher suite bytes 0, 1 */
09496         byte            cs1;
09497         ProtocolVersion pv;
09498         byte            compression;
09499         word32          i = *inOutIdx;
09500         word32          begin = i;
09501 
09502 #ifdef CYASSL_CALLBACKS
09503         if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
09504         if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
09505 #endif
09506 
09507         /* protocol version, random and session id length check */
09508         if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
09509             return BUFFER_ERROR;
09510 
09511         /* protocol version */
09512         XMEMCPY(&pv, input + i, OPAQUE16_LEN);
09513         i += OPAQUE16_LEN;
09514 
09515         if (pv.minor > ssl->version.minor) {
09516             CYASSL_MSG("Server using higher version, fatal error");
09517             return VERSION_ERROR;
09518         }
09519         else if (pv.minor < ssl->version.minor) {
09520             CYASSL_MSG("server using lower version");
09521 
09522             if (!ssl->options.downgrade) {
09523                 CYASSL_MSG("    no downgrade allowed, fatal error");
09524                 return VERSION_ERROR;
09525             }
09526             if (pv.minor < ssl->options.minDowngrade) {
09527                 CYASSL_MSG("    version below minimum allowed, fatal error");
09528                 return VERSION_ERROR;
09529             }
09530 
09531             #ifdef HAVE_SECURE_RENEGOTIATION
09532                 if (ssl->secure_renegotiation &&
09533                                          ssl->secure_renegotiation->enabled &&
09534                                          ssl->options.handShakeDone) {
09535                     CYASSL_MSG("Server changed version during scr");
09536                     return VERSION_ERROR;
09537                 }
09538             #endif
09539 
09540             if (pv.minor == SSLv3_MINOR) {
09541                 /* turn off tls */
09542                 CYASSL_MSG("    downgrading to SSLv3");
09543                 ssl->options.tls    = 0;
09544                 ssl->options.tls1_1 = 0;
09545                 ssl->version.minor  = SSLv3_MINOR;
09546             }
09547             else if (pv.minor == TLSv1_MINOR) {
09548                 /* turn off tls 1.1+ */
09549                 CYASSL_MSG("    downgrading to TLSv1");
09550                 ssl->options.tls1_1 = 0;
09551                 ssl->version.minor  = TLSv1_MINOR;
09552             }
09553             else if (pv.minor == TLSv1_1_MINOR) {
09554                 CYASSL_MSG("    downgrading to TLSv1.1");
09555                 ssl->version.minor  = TLSv1_1_MINOR;
09556             }
09557         }
09558 
09559         /* random */
09560         XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
09561         i += RAN_LEN;
09562 
09563         /* session id */
09564         ssl->arrays->sessionIDSz = input[i++];
09565 
09566         if (ssl->arrays->sessionIDSz > ID_LEN) {
09567             CYASSL_MSG("Invalid session ID size");
09568             ssl->arrays->sessionIDSz = 0;
09569             return BUFFER_ERROR;
09570         }
09571         else if (ssl->arrays->sessionIDSz) {
09572             if ((i - begin) + ssl->arrays->sessionIDSz > helloSz)
09573                 return BUFFER_ERROR;
09574 
09575             XMEMCPY(ssl->arrays->sessionID, input + i,
09576                                                       ssl->arrays->sessionIDSz);
09577             i += ssl->arrays->sessionIDSz;
09578             ssl->options.haveSessionId = 1;
09579         }
09580 
09581 
09582         /* suite and compression */
09583         if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
09584             return BUFFER_ERROR;
09585 
09586         cs0 = input[i++];
09587         cs1 = input[i++];
09588 
09589 #ifdef HAVE_SECURE_RENEGOTIATION
09590         if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
09591                                          ssl->options.handShakeDone) {
09592             if (ssl->options.cipherSuite0 != cs0 ||
09593                 ssl->options.cipherSuite  != cs1) {
09594                 CYASSL_MSG("Server changed cipher suite during scr");
09595                 return MATCH_SUITE_ERROR;
09596             }
09597         }
09598 #endif
09599 
09600         ssl->options.cipherSuite0 = cs0;
09601         ssl->options.cipherSuite  = cs1;
09602         compression = input[i++];
09603 
09604         if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
09605             CYASSL_MSG("Server refused compression, turning off");
09606             ssl->options.usingCompression = 0;  /* turn off if server refused */
09607         }
09608 
09609         *inOutIdx = i;
09610 
09611         /* tls extensions */
09612         if ( (i - begin) < helloSz) {
09613 #ifdef HAVE_TLS_EXTENSIONS
09614             if (TLSX_SupportExtensions(ssl)) {
09615                 int    ret = 0;
09616                 word16 totalExtSz;
09617 
09618                 if ((i - begin) + OPAQUE16_LEN > helloSz)
09619                     return BUFFER_ERROR;
09620 
09621                 ato16(&input[i], &totalExtSz);
09622                 i += OPAQUE16_LEN;
09623 
09624                 if ((i - begin) + totalExtSz > helloSz)
09625                     return BUFFER_ERROR;
09626 
09627                 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
09628                                                           totalExtSz, 0, NULL)))
09629                     return ret;
09630 
09631                 i += totalExtSz;
09632                 *inOutIdx = i;
09633             }
09634             else
09635 #endif
09636                 *inOutIdx = begin + helloSz; /* skip extensions */
09637         }
09638 
09639         ssl->options.serverState = SERVER_HELLO_COMPLETE;
09640 
09641         if (ssl->keys.encryptionOn) {
09642             *inOutIdx += ssl->keys.padSz;
09643         }
09644 
09645 #ifdef HAVE_SECRET_CALLBACK
09646         if (ssl->sessionSecretCb != NULL) {
09647             int secretSz = SECRET_LEN, ret;
09648             ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
09649                                               &secretSz, ssl->sessionSecretCtx);
09650             if (ret != 0 || secretSz != SECRET_LEN)
09651                 return SESSION_SECRET_CB_E;
09652         }
09653 #endif /* HAVE_SECRET_CALLBACK */
09654 
09655         if (ssl->options.resuming) {
09656             if (DSH_CheckSessionId(ssl)) {
09657                 if (SetCipherSpecs(ssl) == 0) {
09658                     int ret = -1;
09659 
09660                     XMEMCPY(ssl->arrays->masterSecret,
09661                             ssl->session.masterSecret, SECRET_LEN);
09662                     #ifdef NO_OLD_TLS
09663                         ret = DeriveTlsKeys(ssl);
09664                     #else
09665                         #ifndef NO_TLS
09666                             if (ssl->options.tls)
09667                                 ret = DeriveTlsKeys(ssl);
09668                         #endif
09669                             if (!ssl->options.tls)
09670                                 ret = DeriveKeys(ssl);
09671                     #endif
09672                     ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
09673 
09674                     return ret;
09675                 }
09676                 else {
09677                     CYASSL_MSG("Unsupported cipher suite, DoServerHello");
09678                     return UNSUPPORTED_SUITE;
09679                 }
09680             }
09681             else {
09682                 CYASSL_MSG("Server denied resumption attempt");
09683                 ssl->options.resuming = 0; /* server denied resumption try */
09684             }
09685         }
09686         #ifdef CYASSL_DTLS
09687             if (ssl->options.dtls) {
09688                 DtlsPoolReset(ssl);
09689             }
09690         #endif
09691 
09692         return SetCipherSpecs(ssl);
09693     }
09694 
09695 
09696     /* Make sure client setup is valid for this suite, true on success */
09697     int VerifyClientSuite(CYASSL* ssl)
09698     {
09699         int  havePSK = 0;
09700         byte first   = ssl->options.cipherSuite0;
09701         byte second  = ssl->options.cipherSuite;
09702 
09703         CYASSL_ENTER("VerifyClientSuite");
09704 
09705         #ifndef NO_PSK
09706             havePSK = ssl->options.havePSK;
09707         #endif
09708 
09709         if (CipherRequires(first, second, REQUIRES_PSK)) {
09710             CYASSL_MSG("Requires PSK");
09711             if (havePSK == 0) {
09712                 CYASSL_MSG("Don't have PSK");
09713                 return 0;
09714             }
09715         }
09716 
09717         return 1;  /* success */
09718     }
09719 
09720 
09721 #ifndef NO_CERTS
09722     /* just read in and ignore for now TODO: */
09723     static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*
09724                                     inOutIdx, word32 size)
09725     {
09726         word16 len;
09727         word32 begin = *inOutIdx;
09728 
09729         #ifdef CYASSL_CALLBACKS
09730             if (ssl->hsInfoOn)
09731                 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
09732             if (ssl->toInfoOn)
09733                 AddLateName("CertificateRequest", &ssl->timeoutInfo);
09734         #endif
09735 
09736         if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
09737             return BUFFER_ERROR;
09738 
09739         len = input[(*inOutIdx)++];
09740 
09741         if ((*inOutIdx - begin) + len > size)
09742             return BUFFER_ERROR;
09743 
09744         /* types, read in here */
09745         *inOutIdx += len;
09746 
09747         /* signature and hash signature algorithm */
09748         if (IsAtLeastTLSv1_2(ssl)) {
09749             if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09750                 return BUFFER_ERROR;
09751 
09752             ato16(input + *inOutIdx, &len);
09753             *inOutIdx += OPAQUE16_LEN;
09754 
09755             if ((*inOutIdx - begin) + len > size)
09756                 return BUFFER_ERROR;
09757 
09758             PickHashSigAlgo(ssl, input + *inOutIdx, len);
09759             *inOutIdx += len;
09760         }
09761 
09762         /* authorities */
09763         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09764             return BUFFER_ERROR;
09765 
09766         ato16(input + *inOutIdx, &len);
09767         *inOutIdx += OPAQUE16_LEN;
09768 
09769         if ((*inOutIdx - begin) + len > size)
09770             return BUFFER_ERROR;
09771 
09772         while (len) {
09773             word16 dnSz;
09774 
09775             if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09776                 return BUFFER_ERROR;
09777 
09778             ato16(input + *inOutIdx, &dnSz);
09779             *inOutIdx += OPAQUE16_LEN;
09780 
09781             if ((*inOutIdx - begin) + dnSz > size)
09782                 return BUFFER_ERROR;
09783 
09784             *inOutIdx += dnSz;
09785             len -= OPAQUE16_LEN + dnSz;
09786         }
09787 
09788         /* don't send client cert or cert verify if user hasn't provided
09789            cert and private key */
09790         if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
09791             ssl->options.sendVerify = SEND_CERT;
09792         else if (IsTLS(ssl))
09793             ssl->options.sendVerify = SEND_BLANK_CERT;
09794 
09795         if (ssl->keys.encryptionOn)
09796             *inOutIdx += ssl->keys.padSz;
09797 
09798         return 0;
09799     }
09800 #endif /* !NO_CERTS */
09801 
09802 
09803     static int DoServerKeyExchange(CYASSL* ssl, const byte* input,
09804                                    word32* inOutIdx, word32 size)
09805     {
09806         word16 length = 0;
09807         word32 begin  = *inOutIdx;
09808         int    ret    = 0;
09809         #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
09810 
09811         (void)length; /* shut up compiler warnings */
09812         (void)begin;
09813         (void)ssl;
09814         (void)input;
09815         (void)size;
09816         (void)ret;
09817 
09818     #ifdef CYASSL_CALLBACKS
09819         if (ssl->hsInfoOn)
09820             AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
09821         if (ssl->toInfoOn)
09822             AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
09823     #endif
09824 
09825     #ifndef NO_PSK
09826         if (ssl->specs.kea == psk_kea) {
09827 
09828             if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09829                 return BUFFER_ERROR;
09830 
09831             ato16(input + *inOutIdx, &length);
09832             *inOutIdx += OPAQUE16_LEN;
09833 
09834             if ((*inOutIdx - begin) + length > size)
09835                 return BUFFER_ERROR;
09836 
09837             XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
09838                    min(length, MAX_PSK_ID_LEN));
09839 
09840             ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
09841             *inOutIdx += length;
09842 
09843             return 0;
09844         }
09845     #endif
09846     #ifndef NO_DH
09847         if (ssl->specs.kea == diffie_hellman_kea)
09848         {
09849         /* p */
09850         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09851             return BUFFER_ERROR;
09852 
09853         ato16(input + *inOutIdx, &length);
09854         *inOutIdx += OPAQUE16_LEN;
09855 
09856         if ((*inOutIdx - begin) + length > size)
09857             return BUFFER_ERROR;
09858 
09859         ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
09860                                                          DYNAMIC_TYPE_DH);
09861 
09862         if (ssl->buffers.serverDH_P.buffer)
09863             ssl->buffers.serverDH_P.length = length;
09864         else
09865             return MEMORY_ERROR;
09866 
09867         XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
09868         *inOutIdx += length;
09869 
09870         /* g */
09871         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09872             return BUFFER_ERROR;
09873 
09874         ato16(input + *inOutIdx, &length);
09875         *inOutIdx += OPAQUE16_LEN;
09876 
09877         if ((*inOutIdx - begin) + length > size)
09878             return BUFFER_ERROR;
09879 
09880         ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
09881                                                          DYNAMIC_TYPE_DH);
09882 
09883         if (ssl->buffers.serverDH_G.buffer)
09884             ssl->buffers.serverDH_G.length = length;
09885         else
09886             return MEMORY_ERROR;
09887 
09888         XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
09889         *inOutIdx += length;
09890 
09891         /* pub */
09892         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09893             return BUFFER_ERROR;
09894 
09895         ato16(input + *inOutIdx, &length);
09896         *inOutIdx += OPAQUE16_LEN;
09897 
09898         if ((*inOutIdx - begin) + length > size)
09899             return BUFFER_ERROR;
09900 
09901         ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
09902                                                            DYNAMIC_TYPE_DH);
09903 
09904         if (ssl->buffers.serverDH_Pub.buffer)
09905             ssl->buffers.serverDH_Pub.length = length;
09906         else
09907             return MEMORY_ERROR;
09908 
09909         XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
09910         *inOutIdx += length;
09911         }  /* dh_kea */
09912     #endif /* NO_DH */
09913 
09914     #ifdef HAVE_ECC
09915         if (ssl->specs.kea == ecc_diffie_hellman_kea)
09916         {
09917         byte b;
09918 
09919         if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN + OPAQUE8_LEN > size)
09920             return BUFFER_ERROR;
09921 
09922         b = input[(*inOutIdx)++];
09923 
09924         if (b != named_curve)
09925             return ECC_CURVETYPE_ERROR;
09926 
09927         *inOutIdx += 1;   /* curve type, eat leading 0 */
09928         b = input[(*inOutIdx)++];
09929 
09930         if (b != secp256r1 && b != secp384r1 && b != secp521r1 && b !=
09931                  secp160r1 && b != secp192r1 && b != secp224r1)
09932             return ECC_CURVE_ERROR;
09933 
09934         length = input[(*inOutIdx)++];
09935 
09936         if ((*inOutIdx - begin) + length > size)
09937             return BUFFER_ERROR;
09938 
09939         if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
09940             ecc_free(ssl->peerEccKey);
09941             ssl->peerEccKeyPresent = 0;
09942             ecc_init(ssl->peerEccKey);
09943         }
09944 
09945         if (ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey) != 0)
09946             return ECC_PEERKEY_ERROR;
09947 
09948         *inOutIdx += length;
09949         ssl->peerEccKeyPresent = 1;
09950         }
09951     #endif /* HAVE_ECC */
09952 
09953     #if !defined(NO_DH) && !defined(NO_PSK)
09954     if (ssl->specs.kea == dhe_psk_kea) {
09955         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09956             return BUFFER_ERROR;
09957 
09958         ato16(input + *inOutIdx, &length);
09959         *inOutIdx += OPAQUE16_LEN;
09960 
09961         if ((*inOutIdx - begin) + length > size)
09962             return BUFFER_ERROR;
09963 
09964         XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
09965                min(length, MAX_PSK_ID_LEN));
09966 
09967         ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
09968         *inOutIdx += length;
09969 
09970         /* p */
09971         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09972             return BUFFER_ERROR;
09973 
09974         ato16(input + *inOutIdx, &length);
09975         *inOutIdx += OPAQUE16_LEN;
09976 
09977         if ((*inOutIdx - begin) + length > size)
09978             return BUFFER_ERROR;
09979 
09980         ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
09981                                                          DYNAMIC_TYPE_DH);
09982 
09983         if (ssl->buffers.serverDH_P.buffer)
09984             ssl->buffers.serverDH_P.length = length;
09985         else
09986             return MEMORY_ERROR;
09987 
09988         XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
09989         *inOutIdx += length;
09990 
09991         /* g */
09992         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
09993             return BUFFER_ERROR;
09994 
09995         ato16(input + *inOutIdx, &length);
09996         *inOutIdx += OPAQUE16_LEN;
09997 
09998         if ((*inOutIdx - begin) + length > size)
09999             return BUFFER_ERROR;
10000 
10001         ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
10002                                                          DYNAMIC_TYPE_DH);
10003 
10004         if (ssl->buffers.serverDH_G.buffer)
10005             ssl->buffers.serverDH_G.length = length;
10006         else
10007             return MEMORY_ERROR;
10008 
10009         XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
10010         *inOutIdx += length;
10011 
10012         /* pub */
10013         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
10014             return BUFFER_ERROR;
10015 
10016         ato16(input + *inOutIdx, &length);
10017         *inOutIdx += OPAQUE16_LEN;
10018 
10019         if ((*inOutIdx - begin) + length > size)
10020             return BUFFER_ERROR;
10021 
10022         ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
10023                                                            DYNAMIC_TYPE_DH);
10024 
10025         if (ssl->buffers.serverDH_Pub.buffer)
10026             ssl->buffers.serverDH_Pub.length = length;
10027         else
10028             return MEMORY_ERROR;
10029 
10030         XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
10031         *inOutIdx += length;
10032     }
10033     #endif /* !NO_DH || !NO_PSK */
10034 
10035     #if !defined(NO_DH) || defined(HAVE_ECC)
10036     if (!ssl->options.usingAnon_cipher &&
10037         (ssl->specs.kea == ecc_diffie_hellman_kea ||
10038          ssl->specs.kea == diffie_hellman_kea))
10039     {
10040 #ifndef NO_OLD_TLS
10041 #ifdef CYASSL_SMALL_STACK
10042         Md5*    md5 = NULL;
10043         Sha*    sha = NULL;
10044 #else
10045         Md5     md5[1];
10046         Sha     sha[1];
10047 #endif
10048 #endif
10049 #ifndef NO_SHA256
10050 #ifdef CYASSL_SMALL_STACK
10051         Sha256* sha256  = NULL;
10052         byte*   hash256 = NULL;
10053 #else
10054         Sha256  sha256[1];
10055         byte    hash256[SHA256_DIGEST_SIZE];
10056 #endif
10057 #endif
10058 #ifdef CYASSL_SHA384
10059 #ifdef CYASSL_SMALL_STACK
10060         Sha384* sha384  = NULL;
10061         byte*   hash384 = NULL;
10062 #else
10063         Sha384  sha384[1];
10064         byte    hash384[SHA384_DIGEST_SIZE];
10065 #endif
10066 #endif
10067 #ifdef CYASSL_SMALL_STACK
10068         byte*   hash          = NULL;
10069         byte*   messageVerify = NULL;
10070 #else
10071         byte    hash[FINISHED_SZ];
10072         byte    messageVerify[MAX_DH_SZ];
10073 #endif
10074         byte    hashAlgo = sha_mac;
10075         byte    sigAlgo  = ssl->specs.sig_algo;
10076         word16  verifySz = (word16) (*inOutIdx - begin);
10077 
10078         /* save message for hash verify */
10079         if (verifySz > MAX_DH_SZ)
10080             ERROR_OUT(BUFFER_ERROR, done);
10081 
10082     #ifdef CYASSL_SMALL_STACK
10083         messageVerify = (byte*)XMALLOC(MAX_DH_SZ, NULL,
10084                                                        DYNAMIC_TYPE_TMP_BUFFER);
10085         if (messageVerify == NULL)
10086             ERROR_OUT(MEMORY_E, done);
10087     #endif
10088 
10089         XMEMCPY(messageVerify, input + begin, verifySz);
10090 
10091         if (IsAtLeastTLSv1_2(ssl)) {
10092             if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
10093                 ERROR_OUT(BUFFER_ERROR, done);
10094 
10095             hashAlgo = input[(*inOutIdx)++];
10096             sigAlgo  = input[(*inOutIdx)++];
10097         }
10098 
10099         /* signature */
10100         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
10101             ERROR_OUT(BUFFER_ERROR, done);
10102 
10103         ato16(input + *inOutIdx, &length);
10104         *inOutIdx += OPAQUE16_LEN;
10105 
10106         if ((*inOutIdx - begin) + length > size)
10107             ERROR_OUT(BUFFER_ERROR, done);
10108 
10109         /* inOutIdx updated at the end of the function */
10110 
10111         /* verify signature */
10112     #ifdef CYASSL_SMALL_STACK
10113         hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10114         if (hash == NULL)
10115             ERROR_OUT(MEMORY_E, done);
10116     #endif
10117 
10118 #ifndef NO_OLD_TLS
10119         /* md5 */
10120     #ifdef CYASSL_SMALL_STACK
10121         md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
10122         if (md5 == NULL)
10123             ERROR_OUT(MEMORY_E, done);
10124     #endif
10125         InitMd5(md5);
10126         Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
10127         Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
10128         Md5Update(md5, messageVerify, verifySz);
10129         Md5Final(md5, hash);
10130 
10131         /* sha */
10132     #ifdef CYASSL_SMALL_STACK
10133         sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
10134         if (sha == NULL)
10135             ERROR_OUT(MEMORY_E, done);
10136     #endif
10137         ret = InitSha(sha);
10138         if (ret != 0)
10139             goto done;
10140         ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
10141         ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
10142         ShaUpdate(sha, messageVerify, verifySz);
10143         ShaFinal(sha, hash + MD5_DIGEST_SIZE);
10144 #endif
10145 
10146 #ifndef NO_SHA256
10147     #ifdef CYASSL_SMALL_STACK
10148         sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
10149                                                        DYNAMIC_TYPE_TMP_BUFFER);
10150         hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
10151                                                        DYNAMIC_TYPE_TMP_BUFFER);
10152         if (sha256 == NULL || hash256 == NULL)
10153             ERROR_OUT(MEMORY_E, done);
10154     #endif
10155         if (!(ret = InitSha256(sha256))
10156         &&  !(ret = Sha256Update(sha256, ssl->arrays->clientRandom, RAN_LEN))
10157         &&  !(ret = Sha256Update(sha256, ssl->arrays->serverRandom, RAN_LEN))
10158         &&  !(ret = Sha256Update(sha256, messageVerify, verifySz)))
10159               ret = Sha256Final(sha256, hash256);
10160         if (ret != 0)
10161             goto done;
10162 #endif
10163 
10164 #ifdef CYASSL_SHA384
10165     #ifdef CYASSL_SMALL_STACK
10166         sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
10167                                                        DYNAMIC_TYPE_TMP_BUFFER);
10168         hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
10169                                                        DYNAMIC_TYPE_TMP_BUFFER);
10170         if (sha384 == NULL || hash384 == NULL)
10171             ERROR_OUT(MEMORY_E, done);
10172     #endif
10173         if (!(ret = InitSha384(sha384))
10174         &&  !(ret = Sha384Update(sha384, ssl->arrays->clientRandom, RAN_LEN))
10175         &&  !(ret = Sha384Update(sha384, ssl->arrays->serverRandom, RAN_LEN))
10176         &&  !(ret = Sha384Update(sha384, messageVerify, verifySz)))
10177               ret = Sha384Final(sha384, hash384);
10178         if (ret != 0)
10179             goto done;
10180 #endif
10181 
10182 #ifndef NO_RSA
10183         /* rsa */
10184         if (sigAlgo == rsa_sa_algo)
10185         {
10186             byte*  out        = NULL;
10187             byte   doUserRsa  = 0;
10188             word32 verifiedSz = 0;
10189 
10190             #ifdef HAVE_PK_CALLBACKS
10191                 if (ssl->ctx->RsaVerifyCb)
10192                     doUserRsa = 1;
10193             #endif /*HAVE_PK_CALLBACKS */
10194 
10195             if (!ssl->peerRsaKeyPresent)
10196                 ERROR_OUT(NO_PEER_KEY, done);
10197 
10198             if (doUserRsa) {
10199             #ifdef HAVE_PK_CALLBACKS
10200                 verifiedSz = ssl->ctx->RsaVerifyCb(ssl,
10201                                                  (byte *)input + *inOutIdx,
10202                                                  length, &out,
10203                                                  ssl->buffers.peerRsaKey.buffer,
10204                                                  ssl->buffers.peerRsaKey.length,
10205                                                  ssl->RsaVerifyCtx);
10206             #endif /*HAVE_PK_CALLBACKS */
10207             }
10208             else
10209                 verifiedSz = RsaSSL_VerifyInline((byte *)input + *inOutIdx,
10210                                                  length, &out, ssl->peerRsaKey);
10211 
10212             if (IsAtLeastTLSv1_2(ssl)) {
10213                 word32 encSigSz;
10214 #ifndef NO_OLD_TLS
10215                 byte*  digest = &hash[MD5_DIGEST_SIZE];
10216                 int    typeH = SHAh;
10217                 int    digestSz = SHA_DIGEST_SIZE;
10218 #else
10219                 byte*  digest = hash256;
10220                 int    typeH =  SHA256h;
10221                 int    digestSz = SHA256_DIGEST_SIZE;
10222 #endif
10223 #ifdef CYASSL_SMALL_STACK
10224                 byte*  encodedSig = NULL;
10225 #else
10226                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
10227 #endif
10228 
10229                 if (hashAlgo == sha_mac) {
10230                     #ifndef NO_SHA
10231                         digest   = &hash[MD5_DIGEST_SIZE];
10232                         typeH    = SHAh;
10233                         digestSz = SHA_DIGEST_SIZE;
10234                     #endif
10235                 }
10236                 else if (hashAlgo == sha256_mac) {
10237                     #ifndef NO_SHA256
10238                         digest   = hash256;
10239                         typeH    = SHA256h;
10240                         digestSz = SHA256_DIGEST_SIZE;
10241                     #endif
10242                 }
10243                 else if (hashAlgo == sha384_mac) {
10244                     #ifdef CYASSL_SHA384
10245                         digest   = hash384;
10246                         typeH    = SHA384h;
10247                         digestSz = SHA384_DIGEST_SIZE;
10248                     #endif
10249                 }
10250 
10251             #ifdef CYASSL_SMALL_STACK
10252                 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
10253                                                        DYNAMIC_TYPE_TMP_BUFFER);
10254                 if (encodedSig == NULL)
10255                     ERROR_OUT(MEMORY_E, done);
10256             #endif
10257 
10258                 encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
10259 
10260                 if (encSigSz != verifiedSz || !out || XMEMCMP(out, encodedSig,
10261                                         min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
10262                     ret = VERIFY_SIGN_ERROR;
10263 
10264             #ifdef CYASSL_SMALL_STACK
10265                 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10266             #endif
10267                 if (ret != 0)
10268                     goto done;
10269             }
10270             else if (verifiedSz != FINISHED_SZ || !out || XMEMCMP(out,
10271                                                         hash, FINISHED_SZ) != 0)
10272                 ERROR_OUT(VERIFY_SIGN_ERROR, done);
10273         } else
10274 #endif
10275 #ifdef HAVE_ECC
10276         /* ecdsa */
10277         if (sigAlgo == ecc_dsa_sa_algo) {
10278             int verify = 0;
10279 #ifndef NO_OLD_TLS
10280             byte* digest = &hash[MD5_DIGEST_SIZE];
10281             word32 digestSz = SHA_DIGEST_SIZE;
10282 #else
10283             byte* digest = hash256;
10284             word32 digestSz = SHA256_DIGEST_SIZE;
10285 #endif
10286             byte doUserEcc = 0;
10287 
10288             #ifdef HAVE_PK_CALLBACKS
10289                 if (ssl->ctx->EccVerifyCb)
10290                     doUserEcc = 1;
10291             #endif
10292 
10293             if (!ssl->peerEccDsaKeyPresent)
10294                 ERROR_OUT(NO_PEER_KEY, done);
10295 
10296             if (IsAtLeastTLSv1_2(ssl)) {
10297                 if (hashAlgo == sha_mac) {
10298                     #ifndef NO_SHA
10299                         digest   = &hash[MD5_DIGEST_SIZE];
10300                         digestSz = SHA_DIGEST_SIZE;
10301                     #endif
10302                 }
10303                 else if (hashAlgo == sha256_mac) {
10304                     #ifndef NO_SHA256
10305                         digest   = hash256;
10306                         digestSz = SHA256_DIGEST_SIZE;
10307                     #endif
10308                 }
10309                 else if (hashAlgo == sha384_mac) {
10310                     #ifdef CYASSL_SHA384
10311                         digest   = hash384;
10312                         digestSz = SHA384_DIGEST_SIZE;
10313                     #endif
10314                 }
10315             }
10316             if (doUserEcc) {
10317             #ifdef HAVE_PK_CALLBACKS
10318                 ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, length,
10319                                             digest, digestSz,
10320                                             ssl->buffers.peerEccDsaKey.buffer,
10321                                             ssl->buffers.peerEccDsaKey.length,
10322                                             &verify, ssl->EccVerifyCtx);
10323             #endif
10324             }
10325             else {
10326                 ret = ecc_verify_hash(input + *inOutIdx, length,
10327                                  digest, digestSz, &verify, ssl->peerEccDsaKey);
10328             }
10329             if (ret != 0 || verify == 0)
10330                 ERROR_OUT(VERIFY_SIGN_ERROR, done);
10331         }
10332         else
10333 #endif /* HAVE_ECC */
10334             ERROR_OUT(ALGO_ID_E, done);
10335 
10336         /* signature length */
10337         *inOutIdx += length;
10338 
10339         ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
10340 
10341     done:
10342 #ifdef CYASSL_SMALL_STACK
10343     #ifndef NO_OLD_TLS
10344         XFREE(md5,           NULL, DYNAMIC_TYPE_TMP_BUFFER);
10345         XFREE(sha,           NULL, DYNAMIC_TYPE_TMP_BUFFER);
10346     #endif
10347     #ifndef NO_SHA256
10348         XFREE(sha256,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
10349         XFREE(hash256,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
10350     #endif
10351     #ifdef CYASSL_SHA384
10352         XFREE(sha384,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
10353         XFREE(hash384,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
10354     #endif
10355         XFREE(hash,          NULL, DYNAMIC_TYPE_TMP_BUFFER);
10356         XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10357 #endif
10358         if (ret != 0)
10359             return ret;
10360     }
10361 
10362     if (ssl->keys.encryptionOn) {
10363         *inOutIdx += ssl->keys.padSz;
10364     }
10365 
10366     return 0;
10367 #else  /* !NO_DH or HAVE_ECC */
10368         return NOT_COMPILED_IN;  /* not supported by build */
10369 #endif /* !NO_DH or HAVE_ECC */
10370 
10371         #undef ERROR_OUT
10372     }
10373 
10374 
10375     int SendClientKeyExchange(CYASSL* ssl)
10376     {
10377 #ifdef CYASSL_SMALL_STACK
10378         byte*  encSecret = NULL;
10379 #else
10380         byte   encSecret[MAX_ENCRYPT_SZ];
10381 #endif
10382         word32 encSz = 0;
10383         word32 idx = 0;
10384         int    ret = 0;
10385         byte   doUserRsa = 0;
10386 
10387         (void)doUserRsa;
10388 
10389 #ifdef HAVE_PK_CALLBACKS
10390     #ifndef NO_RSA
10391         if (ssl->ctx->RsaEncCb)
10392             doUserRsa = 1;
10393     #endif /* NO_RSA */
10394 #endif /*HAVE_PK_CALLBACKS */
10395 
10396     #ifdef CYASSL_SMALL_STACK
10397         encSecret = (byte*)XMALLOC(MAX_ENCRYPT_SZ, NULL,
10398                                                        DYNAMIC_TYPE_TMP_BUFFER);
10399         if (encSecret == NULL)
10400             return MEMORY_E;
10401     #endif
10402 
10403         switch (ssl->specs.kea) {
10404         #ifndef NO_RSA
10405             case rsa_kea:
10406                 ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
10407                                                                     SECRET_LEN);
10408                 if (ret != 0) {
10409                 #ifdef CYASSL_SMALL_STACK
10410                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10411                 #endif
10412                     return ret;
10413                 }
10414 
10415                 ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
10416                 ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
10417                 ssl->arrays->preMasterSz = SECRET_LEN;
10418 
10419                 if (ssl->peerRsaKeyPresent == 0) {
10420                 #ifdef CYASSL_SMALL_STACK
10421                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10422                 #endif
10423                     return NO_PEER_KEY;
10424                 }
10425 
10426                 if (doUserRsa) {
10427                 #ifdef HAVE_PK_CALLBACKS
10428                     #ifndef NO_RSA
10429                         encSz = MAX_ENCRYPT_SZ;
10430                         ret = ssl->ctx->RsaEncCb(ssl,
10431                                             ssl->arrays->preMasterSecret,
10432                                             SECRET_LEN,
10433                                             encSecret, &encSz,
10434                                             ssl->buffers.peerRsaKey.buffer,
10435                                             ssl->buffers.peerRsaKey.length,
10436                                             ssl->RsaEncCtx);
10437                     #endif /* NO_RSA */
10438                 #endif /*HAVE_PK_CALLBACKS */
10439                 }
10440                 else {
10441                     ret = RsaPublicEncrypt(ssl->arrays->preMasterSecret,
10442                                  SECRET_LEN, encSecret, MAX_ENCRYPT_SZ,
10443                                  ssl->peerRsaKey, ssl->rng);
10444                     if (ret > 0) {
10445                         encSz = ret;
10446                         ret = 0;   /* set success to 0 */
10447                     }
10448                 }
10449                 break;
10450         #endif
10451         #ifndef NO_DH
10452             case diffie_hellman_kea:
10453                 {
10454                     buffer  serverP   = ssl->buffers.serverDH_P;
10455                     buffer  serverG   = ssl->buffers.serverDH_G;
10456                     buffer  serverPub = ssl->buffers.serverDH_Pub;
10457                 #ifdef CYASSL_SMALL_STACK
10458                     byte*   priv = NULL;
10459                 #else
10460                     byte    priv[ENCRYPT_LEN];
10461                 #endif
10462                     word32  privSz = 0;
10463                     DhKey   key;
10464 
10465                     if (serverP.buffer == 0 || serverG.buffer == 0 ||
10466                                                serverPub.buffer == 0) {
10467                     #ifdef CYASSL_SMALL_STACK
10468                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10469                     #endif
10470                         return NO_PEER_KEY;
10471                     }
10472 
10473                 #ifdef CYASSL_SMALL_STACK
10474                     priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
10475                                                        DYNAMIC_TYPE_TMP_BUFFER);
10476                     if (priv == NULL) {
10477                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10478                         return MEMORY_E;
10479                     }
10480                 #endif
10481 
10482                     InitDhKey(&key);
10483                     ret = DhSetKey(&key, serverP.buffer, serverP.length,
10484                                    serverG.buffer, serverG.length);
10485                     if (ret == 0)
10486                         /* for DH, encSecret is Yc, agree is pre-master */
10487                         ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
10488                                                 encSecret, &encSz);
10489                     if (ret == 0)
10490                         ret = DhAgree(&key, ssl->arrays->preMasterSecret,
10491                                       &ssl->arrays->preMasterSz, priv, privSz,
10492                                       serverPub.buffer, serverPub.length);
10493                 #ifdef CYASSL_SMALL_STACK
10494                     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10495                 #endif
10496                     FreeDhKey(&key);
10497                 }
10498                 break;
10499         #endif /* NO_DH */
10500         #ifndef NO_PSK
10501             case psk_kea:
10502                 {
10503                     byte* pms = ssl->arrays->preMasterSecret;
10504 
10505                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
10506                         ssl->arrays->server_hint, ssl->arrays->client_identity,
10507                         MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
10508                     if (ssl->arrays->psk_keySz == 0 ||
10509                         ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
10510                     #ifdef CYASSL_SMALL_STACK
10511                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10512                     #endif
10513                         return PSK_KEY_ERROR;
10514                     }
10515                     encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
10516                     if (encSz > MAX_PSK_ID_LEN) {
10517                     #ifdef CYASSL_SMALL_STACK
10518                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10519                     #endif
10520                         return CLIENT_ID_ERROR;
10521                     }
10522                     XMEMCPY(encSecret, ssl->arrays->client_identity, encSz);
10523 
10524                     /* make psk pre master secret */
10525                     /* length of key + length 0s + length of key + key */
10526                     c16toa((word16)ssl->arrays->psk_keySz, pms);
10527                     pms += 2;
10528                     XMEMSET(pms, 0, ssl->arrays->psk_keySz);
10529                     pms += ssl->arrays->psk_keySz;
10530                     c16toa((word16)ssl->arrays->psk_keySz, pms);
10531                     pms += 2;
10532                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
10533                     ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
10534                     XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
10535                     ssl->arrays->psk_keySz = 0; /* No further need */
10536                 }
10537                 break;
10538         #endif /* NO_PSK */
10539         #if !defined(NO_DH) && !defined(NO_PSK)
10540             case dhe_psk_kea:
10541                 {
10542                     byte* pms = ssl->arrays->preMasterSecret;
10543                     byte* es  = encSecret;
10544                     buffer  serverP   = ssl->buffers.serverDH_P;
10545                     buffer  serverG   = ssl->buffers.serverDH_G;
10546                     buffer  serverPub = ssl->buffers.serverDH_Pub;
10547                 #ifdef CYASSL_SMALL_STACK
10548                     byte*   priv = NULL;
10549                 #else
10550                     byte    priv[ENCRYPT_LEN];
10551                 #endif
10552                     word32  privSz = 0;
10553                     word32  pubSz = 0;
10554                     word32  esSz = 0;
10555                     DhKey   key;
10556 
10557                     if (serverP.buffer == 0 || serverG.buffer == 0 ||
10558                                                serverPub.buffer == 0) {
10559                     #ifdef CYASSL_SMALL_STACK
10560                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10561                     #endif
10562                         return NO_PEER_KEY;
10563                     }
10564 
10565                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
10566                          ssl->arrays->server_hint, ssl->arrays->client_identity,
10567                          MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
10568                     if (ssl->arrays->psk_keySz == 0 ||
10569                                      ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
10570                     #ifdef CYASSL_SMALL_STACK
10571                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10572                     #endif
10573                         return PSK_KEY_ERROR;
10574                     }
10575                     esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
10576 
10577                     if (esSz > MAX_PSK_ID_LEN) {
10578                     #ifdef CYASSL_SMALL_STACK
10579                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10580                     #endif
10581                         return CLIENT_ID_ERROR;
10582                     }
10583 
10584                 #ifdef CYASSL_SMALL_STACK
10585                     priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
10586                                                        DYNAMIC_TYPE_TMP_BUFFER);
10587                     if (priv == NULL) {
10588                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10589                         return MEMORY_E;
10590                     }
10591                 #endif
10592                     c16toa((word16)esSz, es);
10593                     es += OPAQUE16_LEN;
10594                     XMEMCPY(es, ssl->arrays->client_identity, esSz);
10595                     es += esSz;
10596                     encSz = esSz + OPAQUE16_LEN;
10597 
10598                     InitDhKey(&key);
10599                     ret = DhSetKey(&key, serverP.buffer, serverP.length,
10600                                    serverG.buffer, serverG.length);
10601                     if (ret == 0)
10602                         /* for DH, encSecret is Yc, agree is pre-master */
10603                         ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
10604                                                 es + OPAQUE16_LEN, &pubSz);
10605                     if (ret == 0)
10606                         ret = DhAgree(&key, pms + OPAQUE16_LEN,
10607                                       &ssl->arrays->preMasterSz, priv, privSz,
10608                                       serverPub.buffer, serverPub.length);
10609                     FreeDhKey(&key);
10610                 #ifdef CYASSL_SMALL_STACK
10611                     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10612                 #endif
10613                     if (ret != 0) {
10614                     #ifdef CYASSL_SMALL_STACK
10615                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10616                     #endif
10617                         return ret;
10618                     }
10619 
10620                     c16toa((word16)pubSz, es);
10621                     encSz += pubSz + OPAQUE16_LEN;
10622                     c16toa((word16)ssl->arrays->preMasterSz, pms);
10623                     ssl->arrays->preMasterSz += OPAQUE16_LEN;
10624                     pms += ssl->arrays->preMasterSz;
10625 
10626                     /* make psk pre master secret */
10627                     /* length of key + length 0s + length of key + key */
10628                     c16toa((word16)ssl->arrays->psk_keySz, pms);
10629                     pms += OPAQUE16_LEN;
10630                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
10631                     ssl->arrays->preMasterSz +=
10632                                           ssl->arrays->psk_keySz + OPAQUE16_LEN;
10633                     XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
10634                     ssl->arrays->psk_keySz = 0; /* No further need */
10635                 }
10636                 break;
10637         #endif /* !NO_DH && !NO_PSK */
10638         #ifdef HAVE_NTRU
10639             case ntru_kea:
10640                 {
10641                     word32 rc;
10642                     word16 cipherLen = MAX_ENCRYPT_SZ;
10643                     DRBG_HANDLE drbg;
10644                     static uint8_t const cyasslStr[] = {
10645                         'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
10646                     };
10647 
10648                     ret = RNG_GenerateBlock(ssl->rng,
10649                                       ssl->arrays->preMasterSecret, SECRET_LEN);
10650                     if (ret != 0) {
10651                     #ifdef CYASSL_SMALL_STACK
10652                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10653                     #endif
10654                         return ret;
10655                     }
10656 
10657                     ssl->arrays->preMasterSz = SECRET_LEN;
10658 
10659                     if (ssl->peerNtruKeyPresent == 0) {
10660                     #ifdef CYASSL_SMALL_STACK
10661                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10662                     #endif
10663                         return NO_PEER_KEY;
10664                     }
10665 
10666                     rc = ntru_crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr,
10667                                                  sizeof(cyasslStr), GetEntropy,
10668                                                  &drbg);
10669                     if (rc != DRBG_OK) {
10670                     #ifdef CYASSL_SMALL_STACK
10671                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10672                     #endif
10673                         return NTRU_DRBG_ERROR;
10674                     }
10675 
10676                     rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
10677                                                   ssl->peerNtruKey,
10678                                                   ssl->arrays->preMasterSz,
10679                                                   ssl->arrays->preMasterSecret,
10680                                                   &cipherLen, encSecret);
10681                     ntru_crypto_drbg_uninstantiate(drbg);
10682                     if (rc != NTRU_OK) {
10683                     #ifdef CYASSL_SMALL_STACK
10684                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10685                     #endif
10686                         return NTRU_ENCRYPT_ERROR;
10687                     }
10688 
10689                     encSz = cipherLen;
10690                     ret = 0;
10691                 }
10692                 break;
10693         #endif /* HAVE_NTRU */
10694         #ifdef HAVE_ECC
10695             case ecc_diffie_hellman_kea:
10696                 {
10697                     ecc_key  myKey;
10698                     ecc_key* peerKey = NULL;
10699                     word32   size = MAX_ENCRYPT_SZ;
10700 
10701                     if (ssl->specs.static_ecdh) {
10702                         /* TODO: EccDsa is really fixed Ecc change naming */
10703                         if (!ssl->peerEccDsaKeyPresent ||
10704                                                       !ssl->peerEccDsaKey->dp) {
10705                         #ifdef CYASSL_SMALL_STACK
10706                             XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10707                         #endif
10708                             return NO_PEER_KEY;
10709                         }
10710                         peerKey = ssl->peerEccDsaKey;
10711                     }
10712                     else {
10713                         if (!ssl->peerEccKeyPresent || !ssl->peerEccKey->dp) {
10714                         #ifdef CYASSL_SMALL_STACK
10715                             XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10716                         #endif
10717                             return NO_PEER_KEY;
10718                         }
10719                         peerKey = ssl->peerEccKey;
10720                     }
10721 
10722                     if (peerKey == NULL) {
10723                     #ifdef CYASSL_SMALL_STACK
10724                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10725                     #endif
10726                         return NO_PEER_KEY;
10727                     }
10728 
10729                     ecc_init(&myKey);
10730                     ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
10731                     if (ret != 0) {
10732                     #ifdef CYASSL_SMALL_STACK
10733                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10734                     #endif
10735                         return ECC_MAKEKEY_ERROR;
10736                     }
10737 
10738                     /* precede export with 1 byte length */
10739                     ret = ecc_export_x963(&myKey, encSecret + 1, &size);
10740                     encSecret[0] = (byte)size;
10741                     encSz = size + 1;
10742 
10743                     if (ret != 0)
10744                         ret = ECC_EXPORT_ERROR;
10745                     else {
10746                         size = sizeof(ssl->arrays->preMasterSecret);
10747                         ret  = ecc_shared_secret(&myKey, peerKey,
10748                                                  ssl->arrays->preMasterSecret, &size);
10749                         if (ret != 0)
10750                             ret = ECC_SHARED_ERROR;
10751                     }
10752 
10753                     ssl->arrays->preMasterSz = size;
10754                     ecc_free(&myKey);
10755                 }
10756                 break;
10757         #endif /* HAVE_ECC */
10758             default:
10759             #ifdef CYASSL_SMALL_STACK
10760                 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10761             #endif
10762                 return ALGO_ID_E; /* unsupported kea */
10763         }
10764 
10765         if (ret == 0) {
10766             byte              *output;
10767             int                sendSz;
10768             word32             tlsSz = 0;
10769 
10770             if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
10771                 tlsSz = 2;
10772 
10773             if (ssl->specs.kea == ecc_diffie_hellman_kea ||
10774                 ssl->specs.kea == dhe_psk_kea)  /* always off */
10775                 tlsSz = 0;
10776 
10777             sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
10778             idx    = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
10779 
10780             #ifdef CYASSL_DTLS
10781                 if (ssl->options.dtls) {
10782                     sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
10783                     idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
10784                 }
10785             #endif
10786 
10787             if (ssl->keys.encryptionOn)
10788                 sendSz += MAX_MSG_EXTRA;
10789 
10790             /* check for available size */
10791             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
10792             #ifdef CYASSL_SMALL_STACK
10793                 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10794             #endif
10795                 return ret;
10796             }
10797 
10798             /* get ouput buffer */
10799             output = ssl->buffers.outputBuffer.buffer +
10800                      ssl->buffers.outputBuffer.length;
10801 
10802             AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
10803 
10804             if (tlsSz) {
10805                 c16toa((word16)encSz, &output[idx]);
10806                 idx += 2;
10807             }
10808             XMEMCPY(output + idx, encSecret, encSz);
10809             idx += encSz;
10810 
10811             if (ssl->keys.encryptionOn) {
10812                 byte* input;
10813                 int   inputSz = idx-RECORD_HEADER_SZ; /* buildmsg adds rechdr */
10814 
10815                 input = (byte*)XMALLOC(inputSz, ssl->heap,
10816                                        DYNAMIC_TYPE_TMP_BUFFER);
10817                 if (input == NULL) {
10818                 #ifdef CYASSL_SMALL_STACK
10819                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10820                 #endif
10821                     return MEMORY_E;
10822                 }
10823 
10824                 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
10825                 sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
10826                                       handshake);
10827                 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
10828                 if (sendSz < 0) {
10829                 #ifdef CYASSL_SMALL_STACK
10830                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10831                 #endif
10832                     return sendSz;
10833                 }
10834             } else {
10835                 ret = HashOutput(ssl, output, sendSz, 0);
10836                 if (ret != 0) {
10837                 #ifdef CYASSL_SMALL_STACK
10838                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10839                 #endif
10840                     return ret;
10841                 }
10842             }
10843 
10844             #ifdef CYASSL_DTLS
10845                 if (ssl->options.dtls) {
10846                     if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
10847                     #ifdef CYASSL_SMALL_STACK
10848                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10849                     #endif
10850                         return ret;
10851                     }
10852                 }
10853             #endif
10854 
10855             #ifdef CYASSL_CALLBACKS
10856                 if (ssl->hsInfoOn)
10857                     AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
10858                 if (ssl->toInfoOn)
10859                     AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
10860                                   output, sendSz, ssl->heap);
10861             #endif
10862 
10863             ssl->buffers.outputBuffer.length += sendSz;
10864 
10865             if (ssl->options.groupMessages)
10866                 ret = 0;
10867             else
10868                 ret = SendBuffered(ssl);
10869         }
10870 
10871     #ifdef CYASSL_SMALL_STACK
10872         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10873     #endif
10874 
10875         if (ret == 0 || ret == WANT_WRITE) {
10876             int tmpRet = MakeMasterSecret(ssl);
10877             if (tmpRet != 0)
10878                 ret = tmpRet;   /* save WANT_WRITE unless more serious */
10879             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
10880         }
10881         /* No further need for PMS */
10882         XMEMSET(ssl->arrays->preMasterSecret, 0, ssl->arrays->preMasterSz);
10883         ssl->arrays->preMasterSz = 0;
10884 
10885         return ret;
10886     }
10887 
10888 #ifndef NO_CERTS
10889     int SendCertificateVerify(CYASSL* ssl)
10890     {
10891         byte              *output;
10892         int                sendSz = MAX_CERT_VERIFY_SZ, length, ret;
10893         word32             idx = 0;
10894         word32             sigOutSz = 0;
10895 #ifndef NO_RSA
10896         RsaKey             key;
10897         int                initRsaKey = 0;
10898 #endif
10899         int                usingEcc = 0;
10900 #ifdef HAVE_ECC
10901         ecc_key            eccKey;
10902 #endif
10903 
10904         (void)idx;
10905 
10906         if (ssl->options.sendVerify == SEND_BLANK_CERT)
10907             return 0;  /* sent blank cert, can't verify */
10908 
10909         if (ssl->keys.encryptionOn)
10910             sendSz += MAX_MSG_EXTRA;
10911 
10912         /* check for available size */
10913         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
10914             return ret;
10915 
10916         /* get ouput buffer */
10917         output = ssl->buffers.outputBuffer.buffer +
10918                  ssl->buffers.outputBuffer.length;
10919 
10920         ret = BuildCertHashes(ssl, &ssl->certHashes);
10921         if (ret != 0)
10922             return ret;
10923 
10924 #ifdef HAVE_ECC
10925         ecc_init(&eccKey);
10926 #endif
10927 #ifndef NO_RSA
10928         ret = InitRsaKey(&key, ssl->heap);
10929         if (ret == 0) initRsaKey = 1;
10930         if (ret == 0)
10931             ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
10932                                       ssl->buffers.key.length);
10933         if (ret == 0)
10934             sigOutSz = RsaEncryptSize(&key);
10935         else
10936 #endif
10937         {
10938     #ifdef HAVE_ECC
10939             CYASSL_MSG("Trying ECC client cert, RSA didn't work");
10940 
10941             idx = 0;
10942             ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
10943                                       ssl->buffers.key.length);
10944             if (ret == 0) {
10945                 CYASSL_MSG("Using ECC client cert");
10946                 usingEcc = 1;
10947                 sigOutSz = MAX_ENCODED_SIG_SZ;
10948             }
10949             else {
10950                 CYASSL_MSG("Bad client cert type");
10951             }
10952     #endif
10953         }
10954         if (ret == 0) {
10955             byte*  verify = (byte*)&output[RECORD_HEADER_SZ +
10956                                            HANDSHAKE_HEADER_SZ];
10957 #ifndef NO_OLD_TLS
10958             byte*  signBuffer = ssl->certHashes.md5;
10959 #else
10960             byte*  signBuffer = NULL;
10961 #endif
10962             word32 signSz = FINISHED_SZ;
10963             word32 extraSz = 0;  /* tls 1.2 hash/sig */
10964 #ifdef CYASSL_SMALL_STACK
10965             byte*  encodedSig = NULL;
10966 #else
10967             byte   encodedSig[MAX_ENCODED_SIG_SZ];
10968 #endif
10969 
10970 #ifdef CYASSL_SMALL_STACK
10971             encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
10972                                                        DYNAMIC_TYPE_TMP_BUFFER);
10973             if (encodedSig == NULL) {
10974             #ifndef NO_RSA
10975                 if (initRsaKey)
10976                     FreeRsaKey(&key);
10977             #endif
10978             #ifdef HAVE_ECC
10979                 ecc_free(&eccKey);
10980             #endif
10981                 return MEMORY_E;
10982             }
10983 #endif
10984 
10985             (void)encodedSig;
10986             (void)signSz;
10987             (void)signBuffer;
10988 
10989             #ifdef CYASSL_DTLS
10990                 if (ssl->options.dtls)
10991                     verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
10992             #endif
10993             length = sigOutSz;
10994             if (IsAtLeastTLSv1_2(ssl)) {
10995                 verify[0] = ssl->suites->hashAlgo;
10996                 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
10997                 extraSz = HASH_SIG_SIZE;
10998             }
10999 
11000             if (usingEcc) {
11001 #ifdef HAVE_ECC
11002                 word32 localSz = MAX_ENCODED_SIG_SZ;
11003                 word32 digestSz;
11004                 byte*  digest;
11005                 byte   doUserEcc = 0;
11006 #ifndef NO_OLD_TLS
11007                 /* old tls default */
11008                 digestSz = SHA_DIGEST_SIZE;
11009                 digest   = ssl->certHashes.sha;
11010 #else
11011                 /* new tls default */
11012                 digestSz = SHA256_DIGEST_SIZE;
11013                 digest   = ssl->certHashes.sha256;
11014 #endif
11015 
11016                 #ifdef HAVE_PK_CALLBACKS
11017                     #ifdef HAVE_ECC
11018                         if (ssl->ctx->EccSignCb)
11019                             doUserEcc = 1;
11020                     #endif /* HAVE_ECC */
11021                 #endif /*HAVE_PK_CALLBACKS */
11022 
11023                 if (IsAtLeastTLSv1_2(ssl)) {
11024                     if (ssl->suites->hashAlgo == sha_mac) {
11025                         #ifndef NO_SHA
11026                             digest = ssl->certHashes.sha;
11027                             digestSz = SHA_DIGEST_SIZE;
11028                         #endif
11029                     }
11030                     else if (ssl->suites->hashAlgo == sha256_mac) {
11031                         #ifndef NO_SHA256
11032                             digest = ssl->certHashes.sha256;
11033                             digestSz = SHA256_DIGEST_SIZE;
11034                         #endif
11035                     }
11036                     else if (ssl->suites->hashAlgo == sha384_mac) {
11037                         #ifdef CYASSL_SHA384
11038                             digest = ssl->certHashes.sha384;
11039                             digestSz = SHA384_DIGEST_SIZE;
11040                         #endif
11041                     }
11042                 }
11043 
11044                 if (doUserEcc) {
11045                 #ifdef HAVE_PK_CALLBACKS
11046                     #ifdef HAVE_ECC
11047                         ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
11048                                         encodedSig, &localSz,
11049                                         ssl->buffers.key.buffer,
11050                                         ssl->buffers.key.length,
11051                                         ssl->EccSignCtx);
11052                     #endif /* HAVE_ECC */
11053                 #endif /*HAVE_PK_CALLBACKS */
11054                 }
11055                 else {
11056                     ret = ecc_sign_hash(digest, digestSz, encodedSig,
11057                                         &localSz, ssl->rng, &eccKey);
11058                 }
11059                 if (ret == 0) {
11060                     length = localSz;
11061                     c16toa((word16)length, verify + extraSz); /* prepend hdr */
11062                     XMEMCPY(verify + extraSz + VERIFY_HEADER,encodedSig,length);
11063                 }
11064 #endif
11065             }
11066 #ifndef NO_RSA
11067             else {
11068                 byte doUserRsa = 0;
11069 
11070                 #ifdef HAVE_PK_CALLBACKS
11071                     if (ssl->ctx->RsaSignCb)
11072                         doUserRsa = 1;
11073                 #endif /*HAVE_PK_CALLBACKS */
11074 
11075                 if (IsAtLeastTLSv1_2(ssl)) {
11076 #ifndef NO_OLD_TLS
11077                     byte* digest = ssl->certHashes.sha;
11078                     int   digestSz = SHA_DIGEST_SIZE;
11079                     int   typeH = SHAh;
11080 #else
11081                     byte* digest = ssl->certHashes.sha256;
11082                     int   digestSz = SHA256_DIGEST_SIZE;
11083                     int   typeH = SHA256h;
11084 #endif
11085 
11086                     if (ssl->suites->hashAlgo == sha_mac) {
11087                         #ifndef NO_SHA
11088                             digest = ssl->certHashes.sha;
11089                             typeH    = SHAh;
11090                             digestSz = SHA_DIGEST_SIZE;
11091                         #endif
11092                     }
11093                     else if (ssl->suites->hashAlgo == sha256_mac) {
11094                         #ifndef NO_SHA256
11095                             digest = ssl->certHashes.sha256;
11096                             typeH    = SHA256h;
11097                             digestSz = SHA256_DIGEST_SIZE;
11098                         #endif
11099                     }
11100                     else if (ssl->suites->hashAlgo == sha384_mac) {
11101                         #ifdef CYASSL_SHA384
11102                             digest = ssl->certHashes.sha384;
11103                             typeH    = SHA384h;
11104                             digestSz = SHA384_DIGEST_SIZE;
11105                         #endif
11106                     }
11107 
11108                     signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
11109                     signBuffer = encodedSig;
11110                 }
11111 
11112                 c16toa((word16)length, verify + extraSz); /* prepend hdr */
11113                 if (doUserRsa) {
11114                 #ifdef HAVE_PK_CALLBACKS
11115                     #ifndef NO_RSA
11116                         word32 ioLen = ENCRYPT_LEN;
11117                         ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
11118                                             verify + extraSz + VERIFY_HEADER,
11119                                             &ioLen,
11120                                             ssl->buffers.key.buffer,
11121                                             ssl->buffers.key.length,
11122                                             ssl->RsaSignCtx);
11123                     #endif /* NO_RSA */
11124                 #endif /*HAVE_PK_CALLBACKS */
11125                 }
11126                 else {
11127                     ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
11128                                   VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng);
11129                 }
11130 
11131                 if (ret > 0)
11132                     ret = 0;  /* RSA reset */
11133             }
11134 #endif
11135 #ifdef CYASSL_SMALL_STACK
11136             XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11137 #endif
11138 
11139             if (ret == 0) {
11140                 AddHeaders(output, length + extraSz + VERIFY_HEADER,
11141                            certificate_verify, ssl);
11142 
11143                 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
11144                          extraSz + VERIFY_HEADER;
11145 
11146                 #ifdef CYASSL_DTLS
11147                     if (ssl->options.dtls) {
11148                         sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11149                     }
11150                 #endif
11151 
11152                 if (ssl->keys.encryptionOn) {
11153                     byte* input;
11154                     int   inputSz = sendSz - RECORD_HEADER_SZ;
11155                                     /* build msg adds rec hdr */
11156                     input = (byte*)XMALLOC(inputSz, ssl->heap,
11157                                            DYNAMIC_TYPE_TMP_BUFFER);
11158                     if (input == NULL)
11159                         ret = MEMORY_E;
11160                     else {
11161                         XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
11162                         sendSz = BuildMessage(ssl, output,
11163                                               MAX_CERT_VERIFY_SZ +MAX_MSG_EXTRA,
11164                                               input, inputSz, handshake);
11165                         XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
11166 
11167                         if (sendSz < 0)
11168                             ret = sendSz;
11169                     }
11170                 } else {
11171                     ret = HashOutput(ssl, output, sendSz, 0);
11172                 }
11173 
11174                 #ifdef CYASSL_DTLS
11175                     if (ssl->options.dtls) {
11176                         if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
11177                             return ret;
11178                     }
11179                 #endif
11180             }
11181         }
11182 #ifndef NO_RSA
11183         if (initRsaKey)
11184             FreeRsaKey(&key);
11185 #endif
11186 #ifdef HAVE_ECC
11187         ecc_free(&eccKey);
11188 #endif
11189 
11190         if (ret == 0) {
11191             #ifdef CYASSL_CALLBACKS
11192                 if (ssl->hsInfoOn)
11193                     AddPacketName("CertificateVerify", &ssl->handShakeInfo);
11194                 if (ssl->toInfoOn)
11195                     AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
11196                                   output, sendSz, ssl->heap);
11197             #endif
11198             ssl->buffers.outputBuffer.length += sendSz;
11199             if (ssl->options.groupMessages)
11200                 return 0;
11201             else
11202                 return SendBuffered(ssl);
11203         }
11204         else
11205             return ret;
11206     }
11207 #endif /* NO_CERTS */
11208 
11209 #ifdef HAVE_SESSION_TICKET
11210 int DoSessionTicket(CYASSL* ssl,
11211                                const byte* input, word32* inOutIdx, word32 size)
11212 {
11213     word32 begin = *inOutIdx;
11214     word32 lifetime;
11215     word16 length;
11216 
11217     if (ssl->expect_session_ticket == 0) {
11218         CYASSL_MSG("Unexpected session ticket");
11219         return SESSION_TICKET_EXPECT_E;
11220     }
11221 
11222     if ((*inOutIdx - begin) + OPAQUE32_LEN > size)
11223         return BUFFER_ERROR;
11224 
11225     ato32(input + *inOutIdx, &lifetime);
11226     *inOutIdx += OPAQUE32_LEN;
11227 
11228     if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
11229         return BUFFER_ERROR;
11230 
11231     ato16(input + *inOutIdx, &length);
11232     *inOutIdx += OPAQUE16_LEN;
11233 
11234     if (length > sizeof(ssl->session.ticket))
11235         return SESSION_TICKET_LEN_E;
11236 
11237     if ((*inOutIdx - begin) + length > size)
11238         return BUFFER_ERROR;
11239 
11240     /* If the received ticket including its length is greater than
11241      * a length value, the save it. Otherwise, don't save it. */
11242     if (length > 0) {
11243         XMEMCPY(ssl->session.ticket, input + *inOutIdx, length);
11244         *inOutIdx += length;
11245         ssl->session.ticketLen = length;
11246         ssl->timeout = lifetime;
11247         if (ssl->session_ticket_cb != NULL) {
11248             ssl->session_ticket_cb(ssl,
11249                                    ssl->session.ticket, ssl->session.ticketLen,
11250                                    ssl->session_ticket_ctx);
11251         }
11252         /* Create a fake sessionID based on the ticket, this will
11253          * supercede the existing session cache info. */
11254         ssl->options.haveSessionId = 1;
11255         XMEMCPY(ssl->arrays->sessionID,
11256                                  ssl->session.ticket + length - ID_LEN, ID_LEN);
11257 #ifndef NO_SESSION_CACHE
11258         AddSession(ssl);
11259 #endif
11260 
11261     }
11262     else {
11263         ssl->session.ticketLen = 0;
11264     }
11265 
11266     if (ssl->keys.encryptionOn) {
11267         *inOutIdx += ssl->keys.padSz;
11268     }
11269 
11270     ssl->expect_session_ticket = 0;
11271 
11272     return BuildFinished(ssl, &ssl->verifyHashes, server);
11273 }
11274 #endif /* HAVE_SESSION_TICKET */
11275 
11276 #endif /* NO_CYASSL_CLIENT */
11277 
11278 
11279 #ifndef NO_CYASSL_SERVER
11280 
11281     int SendServerHello(CYASSL* ssl)
11282     {
11283         byte              *output;
11284         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
11285         int                sendSz;
11286         int                ret;
11287 
11288         length = VERSION_SZ + RAN_LEN
11289                + ID_LEN + ENUM_LEN
11290                + SUITE_LEN
11291                + ENUM_LEN;
11292 
11293 #ifdef HAVE_TLS_EXTENSIONS
11294         length += TLSX_GetResponseSize(ssl);
11295 #endif
11296 
11297         /* check for avalaible size */
11298         if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
11299             return ret;
11300 
11301         /* get ouput buffer */
11302         output = ssl->buffers.outputBuffer.buffer +
11303                  ssl->buffers.outputBuffer.length;
11304 
11305         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
11306         AddHeaders(output, length, server_hello, ssl);
11307 
11308         #ifdef CYASSL_DTLS
11309             if (ssl->options.dtls) {
11310                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11311                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11312             }
11313         #endif
11314         /* now write to output */
11315             /* first version */
11316         output[idx++] = ssl->version.major;
11317         output[idx++] = ssl->version.minor;
11318 
11319             /* then random */
11320         if (!ssl->options.resuming) {
11321             ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
11322                                                                        RAN_LEN);
11323             if (ret != 0)
11324                 return ret;
11325         }
11326 
11327         XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
11328         idx += RAN_LEN;
11329 
11330 #ifdef SHOW_SECRETS
11331         {
11332             int j;
11333             printf("server random: ");
11334             for (j = 0; j < RAN_LEN; j++)
11335                 printf("%02x", ssl->arrays->serverRandom[j]);
11336             printf("\n");
11337         }
11338 #endif
11339             /* then session id */
11340         output[idx++] = ID_LEN;
11341 
11342         if (!ssl->options.resuming) {
11343             ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID, ID_LEN);
11344             if (ret != 0)
11345                 return ret;
11346         }
11347 
11348         XMEMCPY(output + idx, ssl->arrays->sessionID, ID_LEN);
11349         idx += ID_LEN;
11350 
11351             /* then cipher suite */
11352         output[idx++] = ssl->options.cipherSuite0;
11353         output[idx++] = ssl->options.cipherSuite;
11354 
11355             /* then compression */
11356         if (ssl->options.usingCompression)
11357             output[idx++] = ZLIB_COMPRESSION;
11358         else
11359             output[idx++] = NO_COMPRESSION;
11360 
11361             /* last, extensions */
11362 #ifdef HAVE_TLS_EXTENSIONS
11363         TLSX_WriteResponse(ssl, output + idx);
11364 #endif
11365 
11366         ssl->buffers.outputBuffer.length += sendSz;
11367         #ifdef CYASSL_DTLS
11368             if (ssl->options.dtls) {
11369                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
11370                     return ret;
11371             }
11372         #endif
11373 
11374         ret = HashOutput(ssl, output, sendSz, 0);
11375         if (ret != 0)
11376             return ret;
11377 
11378         #ifdef CYASSL_CALLBACKS
11379             if (ssl->hsInfoOn)
11380                 AddPacketName("ServerHello", &ssl->handShakeInfo);
11381             if (ssl->toInfoOn)
11382                 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
11383                               ssl->heap);
11384         #endif
11385 
11386         ssl->options.serverState = SERVER_HELLO_COMPLETE;
11387 
11388         if (ssl->options.groupMessages)
11389             return 0;
11390         else
11391             return SendBuffered(ssl);
11392     }
11393 
11394 
11395 #ifdef HAVE_ECC
11396 
11397     static byte SetCurveId(int size)
11398     {
11399         switch(size) {
11400             case 20:
11401                 return secp160r1;
11402             case 24:
11403                 return secp192r1;
11404             case 28:
11405                 return secp224r1;
11406             case 32:
11407                 return secp256r1;
11408             case 48:
11409                 return secp384r1;
11410             case 66:
11411                 return secp521r1;
11412             default:
11413                 return 0;
11414         }
11415     }
11416 
11417 #endif /* HAVE_ECC */
11418 
11419 
11420     int SendServerKeyExchange(CYASSL* ssl)
11421     {
11422         int ret = 0;
11423         (void)ssl;
11424         #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
11425 
11426     #ifndef NO_PSK
11427         if (ssl->specs.kea == psk_kea)
11428         {
11429             byte    *output;
11430             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
11431             int      sendSz;
11432             if (ssl->arrays->server_hint[0] == 0) return 0; /* don't send */
11433 
11434             /* include size part */
11435             length = (word32)XSTRLEN(ssl->arrays->server_hint);
11436             if (length > MAX_PSK_ID_LEN)
11437                 return SERVER_HINT_ERROR;
11438 
11439             length += HINT_LEN_SZ;
11440             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
11441 
11442         #ifdef CYASSL_DTLS
11443             if (ssl->options.dtls) {
11444                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11445                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11446             }
11447         #endif
11448             /* check for available size */
11449             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
11450                return ret;
11451 
11452             /* get ouput buffer */
11453             output = ssl->buffers.outputBuffer.buffer +
11454                      ssl->buffers.outputBuffer.length;
11455 
11456             AddHeaders(output, length, server_key_exchange, ssl);
11457 
11458             /* key data */
11459             c16toa((word16)(length - HINT_LEN_SZ), output + idx);
11460             idx += HINT_LEN_SZ;
11461             XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
11462 
11463         #ifdef CYASSL_DTLS
11464             if (ssl->options.dtls)
11465                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
11466                     return ret;
11467         #endif
11468 
11469             ret = HashOutput(ssl, output, sendSz, 0);
11470             if (ret != 0)
11471                 return ret;
11472 
11473         #ifdef CYASSL_CALLBACKS
11474             if (ssl->hsInfoOn)
11475                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
11476             if (ssl->toInfoOn)
11477                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
11478                                                              sendSz, ssl->heap);
11479         #endif
11480 
11481             ssl->buffers.outputBuffer.length += sendSz;
11482             if (ssl->options.groupMessages)
11483                 ret = 0;
11484             else
11485                 ret = SendBuffered(ssl);
11486             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
11487         }
11488     #endif /*NO_PSK */
11489 
11490     #if !defined(NO_DH) && !defined(NO_PSK)
11491         if (ssl->specs.kea == dhe_psk_kea) {
11492             byte    *output;
11493             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
11494             word32   hintLen;
11495             int      sendSz;
11496             DhKey    dhKey;
11497 
11498             if (ssl->buffers.serverDH_P.buffer == NULL ||
11499                 ssl->buffers.serverDH_G.buffer == NULL)
11500                 return NO_DH_PARAMS;
11501 
11502             if (ssl->buffers.serverDH_Pub.buffer == NULL) {
11503                 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
11504                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
11505                         DYNAMIC_TYPE_DH);
11506                 if (ssl->buffers.serverDH_Pub.buffer == NULL)
11507                     return MEMORY_E;
11508             }
11509 
11510             if (ssl->buffers.serverDH_Priv.buffer == NULL) {
11511                 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
11512                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
11513                         DYNAMIC_TYPE_DH);
11514                 if (ssl->buffers.serverDH_Priv.buffer == NULL)
11515                     return MEMORY_E;
11516             }
11517 
11518             InitDhKey(&dhKey);
11519             ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
11520                                    ssl->buffers.serverDH_P.length,
11521                                    ssl->buffers.serverDH_G.buffer,
11522                                    ssl->buffers.serverDH_G.length);
11523             if (ret == 0)
11524                 ret = DhGenerateKeyPair(&dhKey, ssl->rng,
11525                                          ssl->buffers.serverDH_Priv.buffer,
11526                                         &ssl->buffers.serverDH_Priv.length,
11527                                          ssl->buffers.serverDH_Pub.buffer,
11528                                         &ssl->buffers.serverDH_Pub.length);
11529             FreeDhKey(&dhKey);
11530             if (ret != 0)
11531                 return ret;
11532 
11533             length = LENGTH_SZ * 3 + /* p, g, pub */
11534                      ssl->buffers.serverDH_P.length +
11535                      ssl->buffers.serverDH_G.length +
11536                      ssl->buffers.serverDH_Pub.length;
11537 
11538             /* include size part */
11539             hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
11540             if (hintLen > MAX_PSK_ID_LEN)
11541                 return SERVER_HINT_ERROR;
11542             length += hintLen + HINT_LEN_SZ;
11543             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
11544 
11545         #ifdef CYASSL_DTLS
11546             if (ssl->options.dtls) {
11547                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11548                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11549             }
11550         #endif
11551 
11552             /* check for available size */
11553             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
11554                return ret;
11555 
11556             /* get ouput buffer */
11557             output = ssl->buffers.outputBuffer.buffer +
11558                      ssl->buffers.outputBuffer.length;
11559 
11560             AddHeaders(output, length, server_key_exchange, ssl);
11561 
11562             /* key data */
11563             c16toa((word16)hintLen, output + idx);
11564             idx += HINT_LEN_SZ;
11565             XMEMCPY(output + idx, ssl->arrays->server_hint, hintLen);
11566             idx += hintLen;
11567 
11568             /* add p, g, pub */
11569             c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
11570             idx += LENGTH_SZ;
11571             XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
11572                                   ssl->buffers.serverDH_P.length);
11573             idx += ssl->buffers.serverDH_P.length;
11574 
11575             /*  g */
11576             c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
11577             idx += LENGTH_SZ;
11578             XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
11579                                   ssl->buffers.serverDH_G.length);
11580             idx += ssl->buffers.serverDH_G.length;
11581 
11582             /*  pub */
11583             c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
11584             idx += LENGTH_SZ;
11585             XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
11586                                   ssl->buffers.serverDH_Pub.length);
11587             idx += ssl->buffers.serverDH_Pub.length;
11588             (void)idx; /* suppress analyzer warning, and keep idx current */
11589 
11590         #ifdef CYASSL_DTLS
11591             if (ssl->options.dtls)
11592                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
11593                     return ret;
11594         #endif
11595 
11596             ret = HashOutput(ssl, output, sendSz, 0);
11597 
11598             if (ret != 0)
11599                 return ret;
11600 
11601         #ifdef CYASSL_CALLBACKS
11602             if (ssl->hsInfoOn)
11603                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
11604             if (ssl->toInfoOn)
11605                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
11606                                                              sendSz, ssl->heap);
11607         #endif
11608 
11609             ssl->buffers.outputBuffer.length += sendSz;
11610             if (ssl->options.groupMessages)
11611                 ret = 0;
11612             else
11613                 ret = SendBuffered(ssl);
11614             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
11615         }
11616     #endif /* !NO_DH && !NO_PSK */
11617 
11618     #ifdef HAVE_ECC
11619         if (ssl->specs.kea == ecc_diffie_hellman_kea)
11620         {
11621             byte    *output;
11622             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
11623             int      sendSz;
11624             word32   sigSz;
11625             word32   preSigSz, preSigIdx;
11626         #ifndef NO_RSA
11627             RsaKey   rsaKey;
11628         #endif
11629             ecc_key  dsaKey;
11630         #ifdef CYASSL_SMALL_STACK
11631             byte*    exportBuf = NULL;
11632         #else
11633             byte     exportBuf[MAX_EXPORT_ECC_SZ];
11634         #endif
11635             word32   expSz = MAX_EXPORT_ECC_SZ;
11636 
11637             if (ssl->specs.static_ecdh) {
11638                 CYASSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
11639                 return 0;
11640             }
11641 
11642             /* curve type, named curve, length(1) */
11643             length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
11644             /* pub key size */
11645             CYASSL_MSG("Using ephemeral ECDH");
11646 
11647             /* need ephemeral key now, create it if missing */
11648             if (ssl->eccTempKeyPresent == 0) {
11649                 if (ecc_make_key(ssl->rng, ssl->eccTempKeySz,
11650                                  ssl->eccTempKey) != 0) {
11651                     return ECC_MAKEKEY_ERROR;
11652                 }
11653                 ssl->eccTempKeyPresent = 1;
11654             }
11655 
11656         #ifdef CYASSL_SMALL_STACK
11657             exportBuf = (byte*)XMALLOC(MAX_EXPORT_ECC_SZ, NULL,
11658                                                        DYNAMIC_TYPE_TMP_BUFFER);
11659             if (exportBuf == NULL)
11660                 return MEMORY_E;
11661         #endif
11662 
11663             if (ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0)
11664                 ERROR_OUT(ECC_EXPORT_ERROR, done_a);
11665             length += expSz;
11666 
11667             preSigSz  = length;
11668             preSigIdx = idx;
11669 
11670         #ifndef NO_RSA
11671             ret = InitRsaKey(&rsaKey, ssl->heap);
11672             if (ret != 0)
11673                 goto done_a;
11674         #endif
11675 
11676             ecc_init(&dsaKey);
11677 
11678             /* sig length */
11679             length += LENGTH_SZ;
11680 
11681             if (!ssl->buffers.key.buffer) {
11682             #ifndef NO_RSA
11683                 FreeRsaKey(&rsaKey);
11684             #endif
11685                 ecc_free(&dsaKey);
11686                 ERROR_OUT(NO_PRIVATE_KEY, done_a);
11687             }
11688 
11689         #ifndef NO_RSA
11690             if (ssl->specs.sig_algo == rsa_sa_algo) {
11691                 /* rsa sig size */
11692                 word32 i = 0;
11693                 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
11694                                           &rsaKey, ssl->buffers.key.length);
11695                 if (ret != 0)
11696                     goto done_a;
11697                 sigSz = RsaEncryptSize(&rsaKey);
11698             } else
11699         #endif
11700 
11701             if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
11702                 /* ecdsa sig size */
11703                 word32 i = 0;
11704                 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
11705                                           &dsaKey, ssl->buffers.key.length);
11706                 if (ret != 0)
11707                     goto done_a;
11708                 sigSz = ecc_sig_size(&dsaKey);  /* worst case estimate */
11709             }
11710             else {
11711             #ifndef NO_RSA
11712                 FreeRsaKey(&rsaKey);
11713             #endif
11714                 ecc_free(&dsaKey);
11715                 ERROR_OUT(ALGO_ID_E, done_a);  /* unsupported type */
11716             }
11717             length += sigSz;
11718 
11719             if (IsAtLeastTLSv1_2(ssl))
11720                 length += HASH_SIG_SIZE;
11721 
11722             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
11723 
11724         #ifdef CYASSL_DTLS
11725             if (ssl->options.dtls) {
11726                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11727                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11728                 preSigIdx = idx;
11729             }
11730         #endif
11731             /* check for available size */
11732             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
11733             #ifndef NO_RSA
11734                 FreeRsaKey(&rsaKey);
11735             #endif
11736                 ecc_free(&dsaKey);
11737                 goto done_a;
11738             }
11739 
11740             /* get ouput buffer */
11741             output = ssl->buffers.outputBuffer.buffer +
11742                      ssl->buffers.outputBuffer.length;
11743 
11744             /* record and message headers will be added below, when we're sure
11745                of the sig length */
11746 
11747             /* key exchange data */
11748             output[idx++] = named_curve;
11749             output[idx++] = 0x00;          /* leading zero */
11750             output[idx++] = SetCurveId(ecc_size(ssl->eccTempKey));
11751             output[idx++] = (byte)expSz;
11752             XMEMCPY(output + idx, exportBuf, expSz);
11753             idx += expSz;
11754             if (IsAtLeastTLSv1_2(ssl)) {
11755                 output[idx++] = ssl->suites->hashAlgo;
11756                 output[idx++] = ssl->suites->sigAlgo;
11757             }
11758 
11759             /* Signtaure length will be written later, when we're sure what it
11760                is */
11761 
11762         #ifdef HAVE_FUZZER
11763             if (ssl->fuzzerCb)
11764                 ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE,
11765                               ssl->fuzzerCtx);
11766         #endif
11767 
11768             /* do signature */
11769             {
11770         #ifndef NO_OLD_TLS
11771             #ifdef CYASSL_SMALL_STACK
11772                 Md5*   md5  = NULL;
11773                 Sha*   sha  = NULL;
11774             #else
11775                 Md5    md5[1];
11776                 Sha    sha[1];
11777             #endif
11778         #endif
11779             #ifdef CYASSL_SMALL_STACK
11780                 byte*  hash = NULL;
11781             #else
11782                 byte   hash[FINISHED_SZ];
11783             #endif
11784         #ifndef NO_SHA256
11785             #ifdef CYASSL_SMALL_STACK
11786                 Sha256* sha256  = NULL;
11787                 byte*   hash256 = NULL;
11788             #else
11789                 Sha256  sha256[1];
11790                 byte    hash256[SHA256_DIGEST_SIZE];
11791             #endif
11792         #endif
11793         #ifdef CYASSL_SHA384
11794             #ifdef CYASSL_SMALL_STACK
11795                 Sha384* sha384  = NULL;
11796                 byte*   hash384 = NULL;
11797             #else
11798                 Sha384  sha384[1];
11799                 byte    hash384[SHA384_DIGEST_SIZE];
11800             #endif
11801         #endif
11802 
11803             #ifdef CYASSL_SMALL_STACK
11804                 hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
11805                                                        DYNAMIC_TYPE_TMP_BUFFER);
11806                 if (hash == NULL)
11807                     ERROR_OUT(MEMORY_E, done_a);
11808             #endif
11809 
11810         #ifndef NO_OLD_TLS
11811                 /* md5 */
11812             #ifdef CYASSL_SMALL_STACK
11813                 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11814                 if (md5 == NULL)
11815                     ERROR_OUT(MEMORY_E, done_a2);
11816             #endif
11817                 InitMd5(md5);
11818                 Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
11819                 Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
11820                 Md5Update(md5, output + preSigIdx, preSigSz);
11821                 Md5Final(md5, hash);
11822 
11823                 /* sha */
11824             #ifdef CYASSL_SMALL_STACK
11825                 sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
11826                 if (sha == NULL)
11827                     ERROR_OUT(MEMORY_E, done_a2);
11828             #endif
11829                 ret = InitSha(sha);
11830                 if (ret != 0)
11831                     goto done_a2;
11832                 ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
11833                 ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
11834                 ShaUpdate(sha, output + preSigIdx, preSigSz);
11835                 ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
11836         #endif
11837 
11838         #ifndef NO_SHA256
11839             #ifdef CYASSL_SMALL_STACK
11840                 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
11841                                                        DYNAMIC_TYPE_TMP_BUFFER);
11842                 hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
11843                                                        DYNAMIC_TYPE_TMP_BUFFER);
11844                 if (sha256 == NULL || hash256 == NULL)
11845                     ERROR_OUT(MEMORY_E, done_a2);
11846             #endif
11847 
11848                 if (!(ret = InitSha256(sha256))
11849                 &&  !(ret = Sha256Update(sha256, ssl->arrays->clientRandom,
11850                                                                        RAN_LEN))
11851                 &&  !(ret = Sha256Update(sha256, ssl->arrays->serverRandom,
11852                                                                        RAN_LEN))
11853                 &&  !(ret = Sha256Update(sha256, output + preSigIdx, preSigSz)))
11854                     ret = Sha256Final(sha256, hash256);
11855 
11856                 if (ret != 0)
11857                     goto done_a2;
11858         #endif
11859 
11860         #ifdef CYASSL_SHA384
11861             #ifdef CYASSL_SMALL_STACK
11862                 sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
11863                                                        DYNAMIC_TYPE_TMP_BUFFER);
11864                 hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
11865                                                        DYNAMIC_TYPE_TMP_BUFFER);
11866                 if (sha384 == NULL || hash384 == NULL)
11867                     ERROR_OUT(MEMORY_E, done_a2);
11868             #endif
11869 
11870                 if (!(ret = InitSha384(sha384))
11871                 &&  !(ret = Sha384Update(sha384, ssl->arrays->clientRandom,
11872                                                                        RAN_LEN))
11873                 &&  !(ret = Sha384Update(sha384, ssl->arrays->serverRandom,
11874                                                                        RAN_LEN))
11875                 &&  !(ret = Sha384Update(sha384, output + preSigIdx, preSigSz)))
11876                     ret = Sha384Final(sha384, hash384);
11877 
11878                 if (ret != 0)
11879                     goto done_a2;
11880         #endif
11881 
11882             #ifndef NO_RSA
11883                 if (ssl->suites->sigAlgo == rsa_sa_algo) {
11884                     byte*  signBuffer = hash;
11885                     word32 signSz     = FINISHED_SZ;
11886                     byte   doUserRsa = 0;
11887                 #ifdef CYASSL_SMALL_STACK
11888                     byte*  encodedSig = NULL;
11889                 #else
11890                     byte   encodedSig[MAX_ENCODED_SIG_SZ];
11891                 #endif
11892 
11893                 #ifdef HAVE_PK_CALLBACKS
11894                     if (ssl->ctx->RsaSignCb)
11895                         doUserRsa = 1;
11896                 #endif
11897 
11898                 #ifdef CYASSL_SMALL_STACK
11899                     encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
11900                                                        DYNAMIC_TYPE_TMP_BUFFER);
11901                     if (encodedSig == NULL)
11902                         ERROR_OUT(MEMORY_E, done_a2);
11903                 #endif
11904 
11905                     if (IsAtLeastTLSv1_2(ssl)) {
11906                         byte* digest   = &hash[MD5_DIGEST_SIZE];
11907                         int   typeH    = SHAh;
11908                         int   digestSz = SHA_DIGEST_SIZE;
11909 
11910                         if (ssl->suites->hashAlgo == sha256_mac) {
11911                         #ifndef NO_SHA256
11912                             digest   = hash256;
11913                             typeH    = SHA256h;
11914                             digestSz = SHA256_DIGEST_SIZE;
11915                         #endif
11916                         }
11917                         else if (ssl->suites->hashAlgo == sha384_mac) {
11918                         #ifdef CYASSL_SHA384
11919                             digest   = hash384;
11920                             typeH    = SHA384h;
11921                             digestSz = SHA384_DIGEST_SIZE;
11922                         #endif
11923                         }
11924 
11925                         signSz = EncodeSignature(encodedSig, digest, digestSz,
11926                                                  typeH);
11927                         signBuffer = encodedSig;
11928                     }
11929                     /* write sig size here */
11930                     c16toa((word16)sigSz, output + idx);
11931                     idx += LENGTH_SZ;
11932 
11933                     if (doUserRsa) {
11934                     #ifdef HAVE_PK_CALLBACKS
11935                         word32 ioLen = sigSz;
11936                         ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
11937                                             output + idx, &ioLen,
11938                                             ssl->buffers.key.buffer,
11939                                             ssl->buffers.key.length,
11940                                             ssl->RsaSignCtx);
11941                     #endif /*HAVE_PK_CALLBACKS */
11942                     }
11943                     else
11944                         ret = RsaSSL_Sign(signBuffer, signSz, output + idx,
11945                                           sigSz, &rsaKey, ssl->rng);
11946 
11947                     FreeRsaKey(&rsaKey);
11948                     ecc_free(&dsaKey);
11949 
11950                 #ifdef CYASSL_SMALL_STACK
11951                     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11952                 #endif
11953 
11954                     if (ret < 0)
11955                         goto done_a2;
11956                 } else
11957             #endif
11958 
11959                 if (ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
11960                 #ifndef NO_OLD_TLS
11961                     byte* digest = &hash[MD5_DIGEST_SIZE];
11962                     word32 digestSz = SHA_DIGEST_SIZE;
11963                 #else
11964                     byte* digest = hash256;
11965                     word32 digestSz = SHA256_DIGEST_SIZE;
11966                 #endif
11967                     word32 sz = sigSz;
11968                     byte   doUserEcc = 0;
11969 
11970                 #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
11971                     if (ssl->ctx->EccSignCb)
11972                         doUserEcc = 1;
11973                 #endif
11974 
11975                     if (IsAtLeastTLSv1_2(ssl)) {
11976                         if (ssl->suites->hashAlgo == sha_mac) {
11977                         #ifndef NO_SHA
11978                             digest   = &hash[MD5_DIGEST_SIZE];
11979                             digestSz = SHA_DIGEST_SIZE;
11980                         #endif
11981                         }
11982                         else if (ssl->suites->hashAlgo == sha256_mac) {
11983                         #ifndef NO_SHA256
11984                             digest   = hash256;
11985                             digestSz = SHA256_DIGEST_SIZE;
11986                         #endif
11987                         }
11988                         else if (ssl->suites->hashAlgo == sha384_mac) {
11989                         #ifdef CYASSL_SHA384
11990                             digest   = hash384;
11991                             digestSz = SHA384_DIGEST_SIZE;
11992                         #endif
11993                         }
11994                     }
11995 
11996                     if (doUserEcc) {
11997                     #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
11998                         ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
11999                                                   output + LENGTH_SZ + idx, &sz,
12000                                                   ssl->buffers.key.buffer,
12001                                                   ssl->buffers.key.length,
12002                                                   ssl->EccSignCtx);
12003                     #endif
12004                     }
12005                     else {
12006                         ret = ecc_sign_hash(digest, digestSz,
12007                               output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
12008                     }
12009                 #ifndef NO_RSA
12010                     FreeRsaKey(&rsaKey);
12011                 #endif
12012                     ecc_free(&dsaKey);
12013 
12014                     if (ret < 0)
12015                         goto done_a2;
12016 
12017                     /* Now that we know the real sig size, write it. */
12018                     c16toa((word16)sz, output + idx);
12019 
12020                     /* And adjust length and sendSz from estimates */
12021                     length += sz - sigSz;
12022                     sendSz += sz - sigSz;
12023                 }
12024 
12025             done_a2:
12026         #ifdef CYASSL_SMALL_STACK
12027             #ifndef NO_OLD_TLS
12028                 XFREE(md5,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
12029                 XFREE(sha,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
12030             #endif
12031                 XFREE(hash,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
12032             #ifndef NO_SHA256
12033                 XFREE(sha256,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
12034                 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12035             #endif
12036             #ifdef CYASSL_SHA384
12037                 XFREE(sha384,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
12038                 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12039             #endif
12040         #endif
12041 
12042                 if (ret < 0)
12043                     goto done_a;
12044             }
12045 
12046             AddHeaders(output, length, server_key_exchange, ssl);
12047 
12048         #ifdef CYASSL_DTLS
12049             if (ssl->options.dtls)
12050                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
12051                     goto done_a;
12052         #endif
12053 
12054             if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
12055                 goto done_a;
12056 
12057         #ifdef CYASSL_CALLBACKS
12058             if (ssl->hsInfoOn)
12059                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
12060             if (ssl->toInfoOn)
12061                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
12062                               output, sendSz, ssl->heap);
12063         #endif
12064 
12065             ssl->buffers.outputBuffer.length += sendSz;
12066             if (ssl->options.groupMessages)
12067                 ret = 0;
12068             else
12069                 ret = SendBuffered(ssl);
12070             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
12071 
12072         done_a:
12073         #ifdef CYASSL_SMALL_STACK
12074             XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12075         #endif
12076 
12077             return ret;
12078         }
12079     #endif /* HAVE_ECC */
12080 
12081     #if !defined(NO_DH) && !defined(NO_RSA)
12082         if (ssl->specs.kea == diffie_hellman_kea) {
12083             byte    *output;
12084             word32   length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
12085             int      sendSz;
12086             word32   sigSz = 0, i = 0;
12087             word32   preSigSz = 0, preSigIdx = 0;
12088             RsaKey   rsaKey;
12089             DhKey    dhKey;
12090 
12091             if (ssl->buffers.serverDH_P.buffer == NULL ||
12092                 ssl->buffers.serverDH_G.buffer == NULL)
12093                 return NO_DH_PARAMS;
12094 
12095             if (ssl->buffers.serverDH_Pub.buffer == NULL) {
12096                 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
12097                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
12098                         DYNAMIC_TYPE_DH);
12099                 if (ssl->buffers.serverDH_Pub.buffer == NULL)
12100                     return MEMORY_E;
12101             }
12102 
12103             if (ssl->buffers.serverDH_Priv.buffer == NULL) {
12104                 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
12105                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
12106                         DYNAMIC_TYPE_DH);
12107                 if (ssl->buffers.serverDH_Priv.buffer == NULL)
12108                     return MEMORY_E;
12109             }
12110 
12111             InitDhKey(&dhKey);
12112             ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
12113                                    ssl->buffers.serverDH_P.length,
12114                                    ssl->buffers.serverDH_G.buffer,
12115                                    ssl->buffers.serverDH_G.length);
12116             if (ret == 0)
12117                 ret = DhGenerateKeyPair(&dhKey, ssl->rng,
12118                                          ssl->buffers.serverDH_Priv.buffer,
12119                                         &ssl->buffers.serverDH_Priv.length,
12120                                          ssl->buffers.serverDH_Pub.buffer,
12121                                         &ssl->buffers.serverDH_Pub.length);
12122             FreeDhKey(&dhKey);
12123 
12124             if (ret != 0) return ret;
12125 
12126             length = LENGTH_SZ * 3;  /* p, g, pub */
12127             length += ssl->buffers.serverDH_P.length +
12128                       ssl->buffers.serverDH_G.length +
12129                       ssl->buffers.serverDH_Pub.length;
12130 
12131             preSigIdx = idx;
12132             preSigSz  = length;
12133 
12134             if (!ssl->options.usingAnon_cipher) {
12135                 ret = InitRsaKey(&rsaKey, ssl->heap);
12136                 if (ret != 0) return ret;
12137 
12138                 /* sig length */
12139                 length += LENGTH_SZ;
12140 
12141                 if (!ssl->buffers.key.buffer)
12142                     return NO_PRIVATE_KEY;
12143 
12144                 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
12145                                           ssl->buffers.key.length);
12146                 if (ret == 0) {
12147                     sigSz = RsaEncryptSize(&rsaKey);
12148                     length += sigSz;
12149                 }
12150                 else {
12151                     FreeRsaKey(&rsaKey);
12152                     return ret;
12153                 }
12154 
12155                 if (IsAtLeastTLSv1_2(ssl))
12156                     length += HASH_SIG_SIZE;
12157             }
12158 
12159             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
12160 
12161         #ifdef CYASSL_DTLS
12162             if (ssl->options.dtls) {
12163                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
12164                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
12165                 preSigIdx = idx;
12166             }
12167         #endif
12168 
12169             /* check for available size */
12170             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
12171                 if (!ssl->options.usingAnon_cipher)
12172                     FreeRsaKey(&rsaKey);
12173                 return ret;
12174             }
12175 
12176             /* get ouput buffer */
12177             output = ssl->buffers.outputBuffer.buffer +
12178                      ssl->buffers.outputBuffer.length;
12179 
12180             AddHeaders(output, length, server_key_exchange, ssl);
12181 
12182             /* add p, g, pub */
12183             c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
12184             idx += LENGTH_SZ;
12185             XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
12186                                   ssl->buffers.serverDH_P.length);
12187             idx += ssl->buffers.serverDH_P.length;
12188 
12189             /*  g */
12190             c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
12191             idx += LENGTH_SZ;
12192             XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
12193                                   ssl->buffers.serverDH_G.length);
12194             idx += ssl->buffers.serverDH_G.length;
12195 
12196             /*  pub */
12197             c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
12198             idx += LENGTH_SZ;
12199             XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
12200                                   ssl->buffers.serverDH_Pub.length);
12201             idx += ssl->buffers.serverDH_Pub.length;
12202 
12203         #ifdef HAVE_FUZZER
12204             if (ssl->fuzzerCb)
12205                 ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE,
12206                         ssl->fuzzerCtx);
12207         #endif
12208 
12209             /* Add signature */
12210             if (!ssl->options.usingAnon_cipher) {
12211         #ifndef NO_OLD_TLS
12212             #ifdef CYASSL_SMALL_STACK
12213                 Md5*   md5  = NULL;
12214                 Sha*   sha  = NULL;
12215             #else
12216                 Md5    md5[1];
12217                 Sha    sha[1];
12218             #endif
12219         #endif
12220             #ifdef CYASSL_SMALL_STACK
12221                 byte*  hash = NULL;
12222             #else
12223                 byte   hash[FINISHED_SZ];
12224             #endif
12225         #ifndef NO_SHA256
12226             #ifdef CYASSL_SMALL_STACK
12227                 Sha256* sha256  = NULL;
12228                 byte*   hash256 = NULL;
12229             #else
12230                 Sha256  sha256[1];
12231                 byte    hash256[SHA256_DIGEST_SIZE];
12232             #endif
12233         #endif
12234         #ifdef CYASSL_SHA384
12235             #ifdef CYASSL_SMALL_STACK
12236                 Sha384* sha384  = NULL;
12237                 byte*   hash384 = NULL;
12238             #else
12239                 Sha384  sha384[1];
12240                 byte    hash384[SHA384_DIGEST_SIZE];
12241             #endif
12242         #endif
12243 
12244             /* Add hash/signature algo ID */
12245             if (IsAtLeastTLSv1_2(ssl)) {
12246                 output[idx++] = ssl->suites->hashAlgo;
12247                 output[idx++] = ssl->suites->sigAlgo;
12248             }
12249 
12250             /* signature size */
12251             c16toa((word16)sigSz, output + idx);
12252             idx += LENGTH_SZ;
12253 
12254             /* do signature */
12255             #ifdef CYASSL_SMALL_STACK
12256                 hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
12257                                                        DYNAMIC_TYPE_TMP_BUFFER);
12258                 if (hash == NULL)
12259                     return MEMORY_E; /* No heap commitment before this point,
12260                                         from now on, the resources are freed
12261                                         at done_b. */
12262             #endif
12263 
12264         #ifndef NO_OLD_TLS
12265                 /* md5 */
12266             #ifdef CYASSL_SMALL_STACK
12267                 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
12268                 if (md5 == NULL)
12269                     ERROR_OUT(MEMORY_E, done_b);
12270             #endif
12271                 InitMd5(md5);
12272                 Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
12273                 Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
12274                 Md5Update(md5, output + preSigIdx, preSigSz);
12275                 Md5Final(md5, hash);
12276 
12277                 /* sha */
12278             #ifdef CYASSL_SMALL_STACK
12279                 sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
12280                 if (sha == NULL)
12281                     ERROR_OUT(MEMORY_E, done_b);
12282             #endif
12283 
12284                 if ((ret = InitSha(sha) != 0))
12285                     goto done_b;
12286 
12287                 ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
12288                 ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
12289                 ShaUpdate(sha, output + preSigIdx, preSigSz);
12290                 ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
12291         #endif
12292 
12293         #ifndef NO_SHA256
12294             #ifdef CYASSL_SMALL_STACK
12295                 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
12296                                                        DYNAMIC_TYPE_TMP_BUFFER);
12297                 hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
12298                                                        DYNAMIC_TYPE_TMP_BUFFER);
12299                 if (sha256 == NULL || hash256 == NULL)
12300                     ERROR_OUT(MEMORY_E, done_b);
12301             #endif
12302 
12303                 if (!(ret = InitSha256(sha256))
12304                 &&  !(ret = Sha256Update(sha256, ssl->arrays->clientRandom,
12305                                                                        RAN_LEN))
12306                 &&  !(ret = Sha256Update(sha256, ssl->arrays->serverRandom,
12307                                                                        RAN_LEN))
12308                 &&  !(ret = Sha256Update(sha256, output + preSigIdx, preSigSz)))
12309                     ret = Sha256Final(sha256, hash256);
12310 
12311                 if (ret != 0)
12312                     goto done_b;
12313             #endif
12314 
12315         #ifdef CYASSL_SHA384
12316             #ifdef CYASSL_SMALL_STACK
12317                 sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
12318                                                        DYNAMIC_TYPE_TMP_BUFFER);
12319                 hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
12320                                                        DYNAMIC_TYPE_TMP_BUFFER);
12321                 if (sha384 == NULL || hash384 == NULL)
12322                     ERROR_OUT(MEMORY_E, done_b);
12323             #endif
12324 
12325                 if (!(ret = InitSha384(sha384))
12326                 &&  !(ret = Sha384Update(sha384, ssl->arrays->clientRandom,
12327                                                                        RAN_LEN))
12328                 &&  !(ret = Sha384Update(sha384, ssl->arrays->serverRandom,
12329                                                                        RAN_LEN))
12330                 &&  !(ret = Sha384Update(sha384, output + preSigIdx, preSigSz)))
12331                     ret = Sha384Final(sha384, hash384);
12332 
12333                 if (ret != 0)
12334                     goto done_b;
12335         #endif
12336 
12337             #ifndef NO_RSA
12338                 if (ssl->suites->sigAlgo == rsa_sa_algo) {
12339                     byte*  signBuffer = hash;
12340                     word32 signSz     = FINISHED_SZ;
12341                 #ifdef CYASSL_SMALL_STACK
12342                     byte*  encodedSig = NULL;
12343                 #else
12344                     byte   encodedSig[MAX_ENCODED_SIG_SZ];
12345                 #endif
12346                     byte   doUserRsa = 0;
12347 
12348                 #ifdef HAVE_PK_CALLBACKS
12349                     if (ssl->ctx->RsaSignCb)
12350                         doUserRsa = 1;
12351                 #endif
12352 
12353                 #ifdef CYASSL_SMALL_STACK
12354                     encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
12355                                                        DYNAMIC_TYPE_TMP_BUFFER);
12356                     if (encodedSig == NULL)
12357                         ERROR_OUT(MEMORY_E, done_b);
12358                 #endif
12359 
12360                     if (IsAtLeastTLSv1_2(ssl)) {
12361                         byte* digest   = &hash[MD5_DIGEST_SIZE];
12362                         int   typeH    = SHAh;
12363                         int   digestSz = SHA_DIGEST_SIZE;
12364 
12365                         if (ssl->suites->hashAlgo == sha256_mac) {
12366                         #ifndef NO_SHA256
12367                             digest   = hash256;
12368                             typeH    = SHA256h;
12369                             digestSz = SHA256_DIGEST_SIZE;
12370                         #endif
12371                         }
12372                         else if (ssl->suites->hashAlgo == sha384_mac) {
12373                         #ifdef CYASSL_SHA384
12374                             digest   = hash384;
12375                             typeH    = SHA384h;
12376                             digestSz = SHA384_DIGEST_SIZE;
12377                         #endif
12378                         }
12379 
12380                         signSz = EncodeSignature(encodedSig, digest, digestSz,
12381                                                  typeH);
12382                         signBuffer = encodedSig;
12383                     }
12384                     if (doUserRsa) {
12385                     #ifdef HAVE_PK_CALLBACKS
12386                         word32 ioLen = sigSz;
12387                         ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
12388                                                   output + idx, &ioLen,
12389                                                   ssl->buffers.key.buffer,
12390                                                   ssl->buffers.key.length,
12391                                                   ssl->RsaSignCtx);
12392                     #endif
12393                     }
12394                     else
12395                         ret = RsaSSL_Sign(signBuffer, signSz, output + idx,
12396                                           sigSz, &rsaKey, ssl->rng);
12397 
12398                     FreeRsaKey(&rsaKey);
12399 
12400                 #ifdef CYASSL_SMALL_STACK
12401                     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12402                 #endif
12403                 }
12404             #endif
12405 
12406             done_b:
12407         #ifdef CYASSL_SMALL_STACK
12408             #ifndef NO_OLD_TLS
12409                 XFREE(md5,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
12410                 XFREE(sha,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
12411             #endif
12412                 XFREE(hash,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
12413             #ifndef NO_SHA256
12414                 XFREE(sha256,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
12415                 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12416             #endif
12417             #ifdef CYASSL_SHA384
12418                 XFREE(sha384,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
12419                 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12420             #endif
12421         #endif
12422 
12423                 if (ret < 0) return ret;
12424             }
12425 
12426         #ifdef CYASSL_DTLS
12427             if (ssl->options.dtls)
12428                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
12429                     return ret;
12430         #endif
12431 
12432             if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
12433                 return ret;
12434 
12435         #ifdef CYASSL_CALLBACKS
12436             if (ssl->hsInfoOn)
12437                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
12438             if (ssl->toInfoOn)
12439                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
12440                               output, sendSz, ssl->heap);
12441         #endif
12442 
12443             ssl->buffers.outputBuffer.length += sendSz;
12444             if (ssl->options.groupMessages)
12445                 ret = 0;
12446             else
12447                 ret = SendBuffered(ssl);
12448             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
12449         }
12450     #endif /* NO_DH */
12451 
12452         return ret;
12453         #undef ERROR_OUT
12454     }
12455 
12456 
12457     /* Make sure server cert/key are valid for this suite, true on success */
12458     static int VerifyServerSuite(CYASSL* ssl, word16 idx)
12459     {
12460         int  haveRSA = !ssl->options.haveStaticECC;
12461         int  havePSK = 0;
12462         byte first;
12463         byte second;
12464 
12465         CYASSL_ENTER("VerifyServerSuite");
12466 
12467         if (ssl->suites == NULL) {
12468             CYASSL_MSG("Suites pointer error");
12469             return 0;
12470         }
12471 
12472         first   = ssl->suites->suites[idx];
12473         second  = ssl->suites->suites[idx+1];
12474 
12475         #ifndef NO_PSK
12476             havePSK = ssl->options.havePSK;
12477         #endif
12478 
12479         if (ssl->options.haveNTRU)
12480             haveRSA = 0;
12481 
12482         if (CipherRequires(first, second, REQUIRES_RSA)) {
12483             CYASSL_MSG("Requires RSA");
12484             if (haveRSA == 0) {
12485                 CYASSL_MSG("Don't have RSA");
12486                 return 0;
12487             }
12488         }
12489 
12490         if (CipherRequires(first, second, REQUIRES_DHE)) {
12491             CYASSL_MSG("Requires DHE");
12492             if (ssl->options.haveDH == 0) {
12493                 CYASSL_MSG("Don't have DHE");
12494                 return 0;
12495             }
12496         }
12497 
12498         if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
12499             CYASSL_MSG("Requires ECCDSA");
12500             if (ssl->options.haveECDSAsig == 0) {
12501                 CYASSL_MSG("Don't have ECCDSA");
12502                 return 0;
12503             }
12504         }
12505 
12506         if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
12507             CYASSL_MSG("Requires static ECC");
12508             if (ssl->options.haveStaticECC == 0) {
12509                 CYASSL_MSG("Don't have static ECC");
12510                 return 0;
12511             }
12512         }
12513 
12514         if (CipherRequires(first, second, REQUIRES_PSK)) {
12515             CYASSL_MSG("Requires PSK");
12516             if (havePSK == 0) {
12517                 CYASSL_MSG("Don't have PSK");
12518                 return 0;
12519             }
12520         }
12521 
12522         if (CipherRequires(first, second, REQUIRES_NTRU)) {
12523             CYASSL_MSG("Requires NTRU");
12524             if (ssl->options.haveNTRU == 0) {
12525                 CYASSL_MSG("Don't have NTRU");
12526                 return 0;
12527             }
12528         }
12529 
12530         if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
12531             CYASSL_MSG("Requires RSA Signature");
12532             if (ssl->options.side == CYASSL_SERVER_END &&
12533                                            ssl->options.haveECDSAsig == 1) {
12534                 CYASSL_MSG("Don't have RSA Signature");
12535                 return 0;
12536             }
12537         }
12538 
12539 #ifdef HAVE_SUPPORTED_CURVES
12540         if (!TLSX_ValidateEllipticCurves(ssl, first, second)) {
12541             CYASSL_MSG("Don't have matching curves");
12542                 return 0;
12543         }
12544 #endif
12545 
12546         /* ECCDHE is always supported if ECC on */
12547 
12548         return 1;
12549     }
12550 
12551 
12552     static int MatchSuite(CYASSL* ssl, Suites* peerSuites)
12553     {
12554         word16 i, j;
12555 
12556         CYASSL_ENTER("MatchSuite");
12557 
12558         /* & 0x1 equivalent % 2 */
12559         if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
12560             return MATCH_SUITE_ERROR;
12561 
12562         if (ssl->suites == NULL)
12563             return SUITES_ERROR;
12564         /* start with best, if a match we are good */
12565         for (i = 0; i < ssl->suites->suiteSz; i += 2)
12566             for (j = 0; j < peerSuites->suiteSz; j += 2)
12567                 if (ssl->suites->suites[i]   == peerSuites->suites[j] &&
12568                     ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
12569 
12570                     if (VerifyServerSuite(ssl, i)) {
12571                         int result;
12572                         CYASSL_MSG("Verified suite validity");
12573                         ssl->options.cipherSuite0 = ssl->suites->suites[i];
12574                         ssl->options.cipherSuite  = ssl->suites->suites[i+1];
12575                         result = SetCipherSpecs(ssl);
12576                         if (result == 0)
12577                             PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
12578                                                  peerSuites->hashSigAlgoSz);
12579                         return result;
12580                     }
12581                     else {
12582                         CYASSL_MSG("Could not verify suite validity, continue");
12583                     }
12584                 }
12585 
12586         return MATCH_SUITE_ERROR;
12587     }
12588 
12589 
12590 #ifdef OLD_HELLO_ALLOWED
12591 
12592     /* process old style client hello, deprecate? */
12593     int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
12594                               word32 inSz, word16 sz)
12595     {
12596         word32          idx = *inOutIdx;
12597         word16          sessionSz;
12598         word16          randomSz;
12599         word16          i, j;
12600         ProtocolVersion pv;
12601         Suites          clSuites;
12602 
12603         (void)inSz;
12604         CYASSL_MSG("Got old format client hello");
12605 #ifdef CYASSL_CALLBACKS
12606         if (ssl->hsInfoOn)
12607             AddPacketName("ClientHello", &ssl->handShakeInfo);
12608         if (ssl->toInfoOn)
12609             AddLateName("ClientHello", &ssl->timeoutInfo);
12610 #endif
12611 
12612         /* manually hash input since different format */
12613 #ifndef NO_OLD_TLS
12614 #ifndef NO_MD5
12615         Md5Update(&ssl->hashMd5, input + idx, sz);
12616 #endif
12617 #ifndef NO_SHA
12618         ShaUpdate(&ssl->hashSha, input + idx, sz);
12619 #endif
12620 #endif
12621 #ifndef NO_SHA256
12622         if (IsAtLeastTLSv1_2(ssl)) {
12623             int shaRet = Sha256Update(&ssl->hashSha256, input + idx, sz);
12624 
12625             if (shaRet != 0)
12626                 return shaRet;
12627         }
12628 #endif
12629 
12630         /* does this value mean client_hello? */
12631         idx++;
12632 
12633         /* version */
12634         pv.major = input[idx++];
12635         pv.minor = input[idx++];
12636         ssl->chVersion = pv;  /* store */
12637 
12638         if (ssl->version.minor > pv.minor) {
12639             byte haveRSA = 0;
12640             byte havePSK = 0;
12641             if (!ssl->options.downgrade) {
12642                 CYASSL_MSG("Client trying to connect with lesser version");
12643                 return VERSION_ERROR;
12644             }
12645             if (pv.minor < ssl->options.minDowngrade) {
12646                 CYASSL_MSG("    version below minimum allowed, fatal error");
12647                 return VERSION_ERROR;
12648             }
12649             if (pv.minor == SSLv3_MINOR) {
12650                 /* turn off tls */
12651                 CYASSL_MSG("    downgrading to SSLv3");
12652                 ssl->options.tls    = 0;
12653                 ssl->options.tls1_1 = 0;
12654                 ssl->version.minor  = SSLv3_MINOR;
12655             }
12656             else if (pv.minor == TLSv1_MINOR) {
12657                 CYASSL_MSG("    downgrading to TLSv1");
12658                 /* turn off tls 1.1+ */
12659                 ssl->options.tls1_1 = 0;
12660                 ssl->version.minor  = TLSv1_MINOR;
12661             }
12662             else if (pv.minor == TLSv1_1_MINOR) {
12663                 CYASSL_MSG("    downgrading to TLSv1.1");
12664                 ssl->version.minor  = TLSv1_1_MINOR;
12665             }
12666 #ifndef NO_RSA
12667             haveRSA = 1;
12668 #endif
12669 #ifndef NO_PSK
12670             havePSK = ssl->options.havePSK;
12671 #endif
12672 
12673             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
12674                        ssl->options.haveDH, ssl->options.haveNTRU,
12675                        ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
12676                        ssl->options.side);
12677         }
12678 
12679         /* suite size */
12680         ato16(&input[idx], &clSuites.suiteSz);
12681         idx += 2;
12682 
12683         if (clSuites.suiteSz > MAX_SUITE_SZ)
12684             return BUFFER_ERROR;
12685         clSuites.hashSigAlgoSz = 0;
12686 
12687         /* session size */
12688         ato16(&input[idx], &sessionSz);
12689         idx += 2;
12690 
12691         if (sessionSz > ID_LEN)
12692             return BUFFER_ERROR;
12693 
12694         /* random size */
12695         ato16(&input[idx], &randomSz);
12696         idx += 2;
12697 
12698         if (randomSz > RAN_LEN)
12699             return BUFFER_ERROR;
12700 
12701         /* suites */
12702         for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
12703             byte first = input[idx++];
12704             if (!first) { /* implicit: skip sslv2 type */
12705                 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
12706                 j += 2;
12707             }
12708             idx += 2;
12709         }
12710         clSuites.suiteSz = j;
12711 
12712         /* session id */
12713         if (sessionSz) {
12714             XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
12715             idx += sessionSz;
12716             ssl->options.resuming = 1;
12717         }
12718 
12719         /* random */
12720         if (randomSz < RAN_LEN)
12721             XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
12722         XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
12723                randomSz);
12724         idx += randomSz;
12725 
12726         if (ssl->options.usingCompression)
12727             ssl->options.usingCompression = 0;  /* turn off */
12728 
12729         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
12730         *inOutIdx = idx;
12731 
12732         ssl->options.haveSessionId = 1;
12733         /* DoClientHello uses same resume code */
12734         if (ssl->options.resuming) {  /* let's try */
12735             int ret = -1;
12736             CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
12737             if (!session) {
12738                 CYASSL_MSG("Session lookup for resume failed");
12739                 ssl->options.resuming = 0;
12740             } else {
12741                 if (MatchSuite(ssl, &clSuites) < 0) {
12742                     CYASSL_MSG("Unsupported cipher suite, OldClientHello");
12743                     return UNSUPPORTED_SUITE;
12744                 }
12745                 #ifdef SESSION_CERTS
12746                     ssl->session = *session; /* restore session certs. */
12747                 #endif
12748 
12749                 ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
12750                                                                        RAN_LEN);
12751                 if (ret != 0)
12752                     return ret;
12753 
12754                 #ifdef NO_OLD_TLS
12755                     ret = DeriveTlsKeys(ssl);
12756                 #else
12757                     #ifndef NO_TLS
12758                         if (ssl->options.tls)
12759                             ret = DeriveTlsKeys(ssl);
12760                     #endif
12761                         if (!ssl->options.tls)
12762                             ret = DeriveKeys(ssl);
12763                 #endif
12764                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
12765 
12766                 return ret;
12767             }
12768         }
12769 
12770         return MatchSuite(ssl, &clSuites);
12771     }
12772 
12773 #endif /* OLD_HELLO_ALLOWED */
12774 
12775 
12776     static int DoClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
12777                              word32 helloSz)
12778     {
12779         byte            b;
12780         ProtocolVersion pv;
12781         Suites          clSuites;
12782         word32          i = *inOutIdx;
12783         word32          begin = i;
12784 
12785 #ifdef CYASSL_CALLBACKS
12786         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
12787         if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
12788 #endif
12789 
12790         /* protocol version, random and session id length check */
12791         if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
12792             return BUFFER_ERROR;
12793 
12794         /* protocol version */
12795         XMEMCPY(&pv, input + i, OPAQUE16_LEN);
12796         ssl->chVersion = pv;   /* store */
12797         i += OPAQUE16_LEN;
12798 
12799         if (ssl->version.minor > pv.minor) {
12800             byte haveRSA = 0;
12801             byte havePSK = 0;
12802 
12803             if (!ssl->options.downgrade) {
12804                 CYASSL_MSG("Client trying to connect with lesser version");
12805                 return VERSION_ERROR;
12806             }
12807             if (pv.minor < ssl->options.minDowngrade) {
12808                 CYASSL_MSG("    version below minimum allowed, fatal error");
12809                 return VERSION_ERROR;
12810             }
12811 
12812             if (pv.minor == SSLv3_MINOR) {
12813                 /* turn off tls */
12814                 CYASSL_MSG("    downgrading to SSLv3");
12815                 ssl->options.tls    = 0;
12816                 ssl->options.tls1_1 = 0;
12817                 ssl->version.minor  = SSLv3_MINOR;
12818             }
12819             else if (pv.minor == TLSv1_MINOR) {
12820                 /* turn off tls 1.1+ */
12821                 CYASSL_MSG("    downgrading to TLSv1");
12822                 ssl->options.tls1_1 = 0;
12823                 ssl->version.minor  = TLSv1_MINOR;
12824             }
12825             else if (pv.minor == TLSv1_1_MINOR) {
12826                 CYASSL_MSG("    downgrading to TLSv1.1");
12827                 ssl->version.minor  = TLSv1_1_MINOR;
12828             }
12829 #ifndef NO_RSA
12830             haveRSA = 1;
12831 #endif
12832 #ifndef NO_PSK
12833             havePSK = ssl->options.havePSK;
12834 #endif
12835             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
12836                        ssl->options.haveDH, ssl->options.haveNTRU,
12837                        ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
12838                        ssl->options.side);
12839         }
12840 
12841         /* random */
12842         XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
12843         i += RAN_LEN;
12844 
12845 #ifdef SHOW_SECRETS
12846         {
12847             int j;
12848             printf("client random: ");
12849             for (j = 0; j < RAN_LEN; j++)
12850                 printf("%02x", ssl->arrays->clientRandom[j]);
12851             printf("\n");
12852         }
12853 #endif
12854 
12855         /* session id */
12856         b = input[i++];
12857 
12858         if (b == ID_LEN) {
12859             if ((i - begin) + ID_LEN > helloSz)
12860                 return BUFFER_ERROR;
12861 
12862             XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
12863             i += ID_LEN;
12864             ssl->options.resuming = 1; /* client wants to resume */
12865             CYASSL_MSG("Client wants to resume session");
12866         }
12867         else if (b) {
12868             CYASSL_MSG("Invalid session ID size");
12869             return BUFFER_ERROR; /* session ID nor 0 neither 32 bytes long */
12870         }
12871 
12872         #ifdef CYASSL_DTLS
12873             /* cookie */
12874             if (ssl->options.dtls) {
12875 
12876                 if ((i - begin) + OPAQUE8_LEN > helloSz)
12877                     return BUFFER_ERROR;
12878 
12879                 b = input[i++];
12880 
12881                 if (b) {
12882                     byte cookie[MAX_COOKIE_LEN];
12883 
12884                     if (b > MAX_COOKIE_LEN)
12885                         return BUFFER_ERROR;
12886 
12887                     if ((i - begin) + b > helloSz)
12888                         return BUFFER_ERROR;
12889 
12890                     if (ssl->ctx->CBIOCookie == NULL) {
12891                         CYASSL_MSG("Your Cookie callback is null, please set");
12892                         return COOKIE_ERROR;
12893                     }
12894 
12895                     if ((ssl->ctx->CBIOCookie(ssl, cookie, COOKIE_SZ,
12896                                               ssl->IOCB_CookieCtx) != COOKIE_SZ)
12897                             || (b != COOKIE_SZ)
12898                             || (XMEMCMP(cookie, input + i, b) != 0)) {
12899                         return COOKIE_ERROR;
12900                     }
12901 
12902                     i += b;
12903                 }
12904             }
12905         #endif
12906 
12907         /* suites */
12908         if ((i - begin) + OPAQUE16_LEN > helloSz)
12909             return BUFFER_ERROR;
12910 
12911         ato16(&input[i], &clSuites.suiteSz);
12912         i += OPAQUE16_LEN;
12913 
12914         /* suites and compression length check */
12915         if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
12916             return BUFFER_ERROR;
12917 
12918         if (clSuites.suiteSz > MAX_SUITE_SZ)
12919             return BUFFER_ERROR;
12920 
12921         XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
12922         i += clSuites.suiteSz;
12923         clSuites.hashSigAlgoSz = 0;
12924 
12925         /* compression length */
12926         b = input[i++];
12927 
12928         if ((i - begin) + b > helloSz)
12929             return BUFFER_ERROR;
12930 
12931         if (ssl->options.usingCompression) {
12932             int match = 0;
12933 
12934             while (b--) {
12935                 byte comp = input[i++];
12936 
12937                 if (comp == ZLIB_COMPRESSION)
12938                     match = 1;
12939             }
12940 
12941             if (!match) {
12942                 CYASSL_MSG("Not matching compression, turning off");
12943                 ssl->options.usingCompression = 0;  /* turn off */
12944             }
12945         }
12946         else
12947             i += b; /* ignore, since we're not on */
12948 
12949         *inOutIdx = i;
12950 
12951         /* tls extensions */
12952         if ((i - begin) < helloSz) {
12953 #ifdef HAVE_TLS_EXTENSIONS
12954             if (TLSX_SupportExtensions(ssl)) {
12955                 int ret = 0;
12956 #else
12957             if (IsAtLeastTLSv1_2(ssl)) {
12958 #endif
12959                 /* Process the hello extension. Skip unsupported. */
12960                 word16 totalExtSz;
12961 
12962                 if ((i - begin) + OPAQUE16_LEN > helloSz)
12963                     return BUFFER_ERROR;
12964 
12965                 ato16(&input[i], &totalExtSz);
12966                 i += OPAQUE16_LEN;
12967 
12968                 if ((i - begin) + totalExtSz > helloSz)
12969                     return BUFFER_ERROR;
12970 
12971 #ifdef HAVE_TLS_EXTENSIONS
12972                 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
12973                                                      totalExtSz, 1, &clSuites)))
12974                     return ret;
12975 
12976                 i += totalExtSz;
12977 #else
12978                 while (totalExtSz) {
12979                     word16 extId, extSz;
12980 
12981                     if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
12982                         return BUFFER_ERROR;
12983 
12984                     ato16(&input[i], &extId);
12985                     i += OPAQUE16_LEN;
12986                     ato16(&input[i], &extSz);
12987                     i += OPAQUE16_LEN;
12988 
12989                     if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
12990                         return BUFFER_ERROR;
12991 
12992                     if (extId == HELLO_EXT_SIG_ALGO) {
12993                         ato16(&input[i], &clSuites.hashSigAlgoSz);
12994                         i += OPAQUE16_LEN;
12995 
12996                         if (OPAQUE16_LEN + clSuites.hashSigAlgoSz > extSz)
12997                             return BUFFER_ERROR;
12998 
12999                         XMEMCPY(clSuites.hashSigAlgo, &input[i],
13000                             min(clSuites.hashSigAlgoSz, HELLO_EXT_SIGALGO_MAX));
13001                         i += clSuites.hashSigAlgoSz;
13002 
13003                         if (clSuites.hashSigAlgoSz > HELLO_EXT_SIGALGO_MAX)
13004                             clSuites.hashSigAlgoSz = HELLO_EXT_SIGALGO_MAX;
13005                     }
13006                     else
13007                         i += extSz;
13008 
13009                     totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
13010                 }
13011 #endif
13012                 *inOutIdx = i;
13013             }
13014             else
13015                 *inOutIdx = begin + helloSz; /* skip extensions */
13016         }
13017 
13018         ssl->options.clientState   = CLIENT_HELLO_COMPLETE;
13019         ssl->options.haveSessionId = 1;
13020 
13021         /* ProcessOld uses same resume code */
13022         if (ssl->options.resuming && (!ssl->options.dtls ||
13023                ssl->options.acceptState == HELLO_VERIFY_SENT)) { /* let's try */
13024             int ret = -1;
13025             CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
13026 
13027             if (!session) {
13028                 CYASSL_MSG("Session lookup for resume failed");
13029                 ssl->options.resuming = 0;
13030             }
13031             else {
13032                 if (MatchSuite(ssl, &clSuites) < 0) {
13033                     CYASSL_MSG("Unsupported cipher suite, ClientHello");
13034                     return UNSUPPORTED_SUITE;
13035                 }
13036                 #ifdef SESSION_CERTS
13037                     ssl->session = *session; /* restore session certs. */
13038                 #endif
13039 
13040                 ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
13041                                                                        RAN_LEN);
13042                 if (ret != 0)
13043                     return ret;
13044 
13045                 #ifdef NO_OLD_TLS
13046                     ret = DeriveTlsKeys(ssl);
13047                 #else
13048                     #ifndef NO_TLS
13049                         if (ssl->options.tls)
13050                             ret = DeriveTlsKeys(ssl);
13051                     #endif
13052                         if (!ssl->options.tls)
13053                             ret = DeriveKeys(ssl);
13054                 #endif
13055                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
13056 
13057                 return ret;
13058             }
13059         }
13060         return MatchSuite(ssl, &clSuites);
13061     }
13062 
13063 #if !defined(NO_RSA) || defined(HAVE_ECC)
13064     static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutIdx,
13065                                    word32 size)
13066     {
13067         word16      sz = 0;
13068         int         ret = VERIFY_CERT_ERROR;   /* start in error state */
13069         byte        hashAlgo = sha_mac;
13070         byte        sigAlgo = anonymous_sa_algo;
13071         word32      begin = *inOutIdx;
13072 
13073         #ifdef CYASSL_CALLBACKS
13074             if (ssl->hsInfoOn)
13075                 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
13076             if (ssl->toInfoOn)
13077                 AddLateName("CertificateVerify", &ssl->timeoutInfo);
13078         #endif
13079 
13080 
13081         if (IsAtLeastTLSv1_2(ssl)) {
13082             if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
13083                 return BUFFER_ERROR;
13084 
13085             hashAlgo = input[(*inOutIdx)++];
13086             sigAlgo  = input[(*inOutIdx)++];
13087         }
13088 
13089         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
13090             return BUFFER_ERROR;
13091 
13092         ato16(input + *inOutIdx, &sz);
13093         *inOutIdx += OPAQUE16_LEN;
13094 
13095         if ((*inOutIdx - begin) + sz > size || sz > ENCRYPT_LEN)
13096             return BUFFER_ERROR;
13097 
13098         /* RSA */
13099 #ifndef NO_RSA
13100         if (ssl->peerRsaKeyPresent != 0) {
13101             byte* out       = NULL;
13102             int   outLen    = 0;
13103             byte  doUserRsa = 0;
13104 
13105             #ifdef HAVE_PK_CALLBACKS
13106                 if (ssl->ctx->RsaVerifyCb)
13107                     doUserRsa = 1;
13108             #endif /*HAVE_PK_CALLBACKS */
13109 
13110             CYASSL_MSG("Doing RSA peer cert verify");
13111 
13112             if (doUserRsa) {
13113             #ifdef HAVE_PK_CALLBACKS
13114                 outLen = ssl->ctx->RsaVerifyCb(ssl, input + *inOutIdx, sz,
13115                                             &out,
13116                                             ssl->buffers.peerRsaKey.buffer,
13117                                             ssl->buffers.peerRsaKey.length,
13118                                             ssl->RsaVerifyCtx);
13119             #endif /*HAVE_PK_CALLBACKS */
13120             }
13121             else {
13122                 outLen = RsaSSL_VerifyInline(input + *inOutIdx, sz, &out,
13123                                                                ssl->peerRsaKey);
13124             }
13125 
13126             if (IsAtLeastTLSv1_2(ssl)) {
13127 #ifdef CYASSL_SMALL_STACK
13128                 byte*  encodedSig = NULL;
13129 #else
13130                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
13131 #endif
13132                 word32 sigSz;
13133                 byte*  digest = ssl->certHashes.sha;
13134                 int    typeH = SHAh;
13135                 int    digestSz = SHA_DIGEST_SIZE;
13136 
13137 #ifdef CYASSL_SMALL_STACK
13138                 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
13139                                                        DYNAMIC_TYPE_TMP_BUFFER);
13140                 if (encodedSig == NULL)
13141                     return MEMORY_E;
13142 #endif
13143 
13144                 if (sigAlgo != rsa_sa_algo) {
13145                     CYASSL_MSG("Oops, peer sent RSA key but not in verify");
13146                 }
13147 
13148                 if (hashAlgo == sha256_mac) {
13149                     #ifndef NO_SHA256
13150                         digest = ssl->certHashes.sha256;
13151                         typeH    = SHA256h;
13152                         digestSz = SHA256_DIGEST_SIZE;
13153                     #endif
13154                 }
13155                 else if (hashAlgo == sha384_mac) {
13156                     #ifdef CYASSL_SHA384
13157                         digest = ssl->certHashes.sha384;
13158                         typeH    = SHA384h;
13159                         digestSz = SHA384_DIGEST_SIZE;
13160                     #endif
13161                 }
13162 
13163                 sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
13164 
13165                 if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig,
13166                                            min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
13167                     ret = 0; /* verified */
13168 
13169 #ifdef CYASSL_SMALL_STACK
13170                 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13171 #endif
13172             }
13173             else {
13174                 if (outLen == FINISHED_SZ && out && XMEMCMP(out,
13175                                             &ssl->certHashes, FINISHED_SZ) == 0)
13176                     ret = 0; /* verified */
13177             }
13178         }
13179 #endif
13180 #ifdef HAVE_ECC
13181         if (ssl->peerEccDsaKeyPresent) {
13182             int verify =  0;
13183             int err    = -1;
13184             byte* digest = ssl->certHashes.sha;
13185             word32 digestSz = SHA_DIGEST_SIZE;
13186             byte doUserEcc = 0;
13187 
13188             #ifdef HAVE_PK_CALLBACKS
13189                 if (ssl->ctx->EccVerifyCb)
13190                     doUserEcc = 1;
13191             #endif
13192 
13193             CYASSL_MSG("Doing ECC peer cert verify");
13194 
13195             if (IsAtLeastTLSv1_2(ssl)) {
13196                 if (sigAlgo != ecc_dsa_sa_algo) {
13197                     CYASSL_MSG("Oops, peer sent ECC key but not in verify");
13198                 }
13199 
13200                 if (hashAlgo == sha256_mac) {
13201                     #ifndef NO_SHA256
13202                         digest = ssl->certHashes.sha256;
13203                         digestSz = SHA256_DIGEST_SIZE;
13204                     #endif
13205                 }
13206                 else if (hashAlgo == sha384_mac) {
13207                     #ifdef CYASSL_SHA384
13208                         digest = ssl->certHashes.sha384;
13209                         digestSz = SHA384_DIGEST_SIZE;
13210                     #endif
13211                 }
13212             }
13213 
13214             if (doUserEcc) {
13215             #ifdef HAVE_PK_CALLBACKS
13216                 ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, sz, digest,
13217                                             digestSz,
13218                                             ssl->buffers.peerEccDsaKey.buffer,
13219                                             ssl->buffers.peerEccDsaKey.length,
13220                                             &verify, ssl->EccVerifyCtx);
13221             #endif
13222             }
13223             else {
13224                 err = ecc_verify_hash(input + *inOutIdx, sz, digest, digestSz,
13225                                                    &verify, ssl->peerEccDsaKey);
13226             }
13227 
13228             if (err == 0 && verify == 1)
13229                ret = 0; /* verified */
13230         }
13231 #endif
13232         *inOutIdx += sz;
13233 
13234         if (ret == 0)
13235             ssl->options.havePeerVerify = 1;
13236 
13237         return ret;
13238     }
13239 #endif /* !NO_RSA || HAVE_ECC */
13240 
13241     int SendServerHelloDone(CYASSL* ssl)
13242     {
13243         byte              *output;
13244         int                sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
13245         int                ret;
13246 
13247         #ifdef CYASSL_DTLS
13248             if (ssl->options.dtls)
13249                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
13250         #endif
13251         /* check for available size */
13252         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
13253             return ret;
13254 
13255         /* get ouput buffer */
13256         output = ssl->buffers.outputBuffer.buffer +
13257                  ssl->buffers.outputBuffer.length;
13258 
13259         AddHeaders(output, 0, server_hello_done, ssl);
13260 
13261         #ifdef CYASSL_DTLS
13262             if (ssl->options.dtls) {
13263                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
13264                     return 0;
13265             }
13266         #endif
13267 
13268         ret = HashOutput(ssl, output, sendSz, 0);
13269             if (ret != 0)
13270                 return ret;
13271 
13272 #ifdef CYASSL_CALLBACKS
13273         if (ssl->hsInfoOn)
13274             AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
13275         if (ssl->toInfoOn)
13276             AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
13277                           ssl->heap);
13278 #endif
13279         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
13280 
13281         ssl->buffers.outputBuffer.length += sendSz;
13282 
13283         return SendBuffered(ssl);
13284     }
13285 
13286 #ifdef CYASSL_DTLS
13287     int SendHelloVerifyRequest(CYASSL* ssl)
13288     {
13289         byte* output;
13290         byte  cookieSz = COOKIE_SZ;
13291         int   length = VERSION_SZ + ENUM_LEN + cookieSz;
13292         int   idx    = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
13293         int   sendSz = length + idx;
13294         int   ret;
13295 
13296         /* check for available size */
13297         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
13298             return ret;
13299 
13300         /* get ouput buffer */
13301         output = ssl->buffers.outputBuffer.buffer +
13302                  ssl->buffers.outputBuffer.length;
13303 
13304         AddHeaders(output, length, hello_verify_request, ssl);
13305 
13306         output[idx++] =  ssl->chVersion.major;
13307         output[idx++] =  ssl->chVersion.minor;
13308 
13309         output[idx++] = cookieSz;
13310         if (ssl->ctx->CBIOCookie == NULL) {
13311             CYASSL_MSG("Your Cookie callback is null, please set");
13312             return COOKIE_ERROR;
13313         }
13314         if ((ret = ssl->ctx->CBIOCookie(ssl, output + idx, cookieSz,
13315                                         ssl->IOCB_CookieCtx)) < 0)
13316             return ret;
13317 
13318         ret = HashOutput(ssl, output, sendSz, 0);
13319         if (ret != 0)
13320             return ret;
13321 
13322 #ifdef CYASSL_CALLBACKS
13323         if (ssl->hsInfoOn)
13324             AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
13325         if (ssl->toInfoOn)
13326             AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
13327                           sendSz, ssl->heap);
13328 #endif
13329         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
13330 
13331         ssl->buffers.outputBuffer.length += sendSz;
13332 
13333         return SendBuffered(ssl);
13334     }
13335 #endif
13336 
13337     static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32* inOutIdx,
13338                                                                     word32 size)
13339     {
13340         int    ret = 0;
13341         word32 length = 0;
13342         byte*  out = NULL;
13343         word32 begin = *inOutIdx;
13344 
13345         (void)length; /* shut up compiler warnings */
13346         (void)out;
13347         (void)input;
13348         (void)size;
13349         (void)begin;
13350 
13351         if (ssl->options.side != CYASSL_SERVER_END) {
13352             CYASSL_MSG("Client received client keyexchange, attack?");
13353             CYASSL_ERROR(ssl->error = SIDE_ERROR);
13354             return SSL_FATAL_ERROR;
13355         }
13356 
13357         if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
13358             CYASSL_MSG("Client sending keyexchange at wrong time");
13359             SendAlert(ssl, alert_fatal, unexpected_message);
13360             return OUT_OF_ORDER_E;
13361         }
13362 
13363         #ifndef NO_CERTS
13364             if (ssl->options.verifyPeer && ssl->options.failNoCert)
13365                 if (!ssl->options.havePeerCert) {
13366                     CYASSL_MSG("client didn't present peer cert");
13367                     return NO_PEER_CERT;
13368                 }
13369         #endif
13370 
13371         #ifdef CYASSL_CALLBACKS
13372             if (ssl->hsInfoOn)
13373                 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
13374             if (ssl->toInfoOn)
13375                 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
13376         #endif
13377 
13378         switch (ssl->specs.kea) {
13379         #ifndef NO_RSA
13380             case rsa_kea:
13381             {
13382                 word32 idx = 0;
13383                 RsaKey key;
13384                 byte   doUserRsa = 0;
13385 
13386                 #ifdef HAVE_PK_CALLBACKS
13387                     if (ssl->ctx->RsaDecCb)
13388                         doUserRsa = 1;
13389                 #endif
13390 
13391                 ret = InitRsaKey(&key, ssl->heap);
13392                 if (ret != 0) return ret;
13393 
13394                 if (ssl->buffers.key.buffer)
13395                     ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx,
13396                                              &key, ssl->buffers.key.length);
13397                 else
13398                     return NO_PRIVATE_KEY;
13399 
13400                 if (ret == 0) {
13401                     length = RsaEncryptSize(&key);
13402                     ssl->arrays->preMasterSz = SECRET_LEN;
13403 
13404                     if (ssl->options.tls) {
13405                         word16 check;
13406 
13407                         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
13408                             return BUFFER_ERROR;
13409 
13410                         ato16(input + *inOutIdx, &check);
13411                         *inOutIdx += OPAQUE16_LEN;
13412 
13413                         if ((word32) check != length) {
13414                             CYASSL_MSG("RSA explicit size doesn't match");
13415                             FreeRsaKey(&key);
13416                             return RSA_PRIVATE_ERROR;
13417                         }
13418                     }
13419 
13420                     if ((*inOutIdx - begin) + length > size) {
13421                         CYASSL_MSG("RSA message too big");
13422                         FreeRsaKey(&key);
13423                         return BUFFER_ERROR;
13424                     }
13425 
13426                     if (doUserRsa) {
13427                         #ifdef HAVE_PK_CALLBACKS
13428                             ret = ssl->ctx->RsaDecCb(ssl,
13429                                         input + *inOutIdx, length, &out,
13430                                         ssl->buffers.key.buffer,
13431                                         ssl->buffers.key.length,
13432                                         ssl->RsaDecCtx);
13433                         #endif
13434                     }
13435                     else {
13436                         ret = RsaPrivateDecryptInline(input + *inOutIdx, length,
13437                                                                     &out, &key);
13438                     }
13439 
13440                     *inOutIdx += length;
13441 
13442                     if (ret == SECRET_LEN) {
13443                         XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN);
13444                         if (ssl->arrays->preMasterSecret[0] !=
13445                                                            ssl->chVersion.major
13446                             || ssl->arrays->preMasterSecret[1] !=
13447                                                            ssl->chVersion.minor)
13448                             ret = PMS_VERSION_ERROR;
13449                         else
13450                             ret = MakeMasterSecret(ssl);
13451                     }
13452                     else {
13453                         ret = RSA_PRIVATE_ERROR;
13454                     }
13455                 }
13456 
13457                 FreeRsaKey(&key);
13458             }
13459             break;
13460         #endif
13461         #ifndef NO_PSK
13462             case psk_kea:
13463             {
13464                 byte* pms = ssl->arrays->preMasterSecret;
13465                 word16 ci_sz;
13466 
13467                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
13468                     return BUFFER_ERROR;
13469 
13470                 ato16(input + *inOutIdx, &ci_sz);
13471                 *inOutIdx += OPAQUE16_LEN;
13472 
13473                 if (ci_sz > MAX_PSK_ID_LEN)
13474                     return CLIENT_ID_ERROR;
13475 
13476                 if ((*inOutIdx - begin) + ci_sz > size)
13477                     return BUFFER_ERROR;
13478 
13479                 XMEMCPY(ssl->arrays->client_identity, input + *inOutIdx, ci_sz);
13480                 *inOutIdx += ci_sz;
13481 
13482                 ssl->arrays->client_identity[min(ci_sz, MAX_PSK_ID_LEN-1)] = 0;
13483                 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
13484                     ssl->arrays->client_identity, ssl->arrays->psk_key,
13485                     MAX_PSK_KEY_LEN);
13486 
13487                 if (ssl->arrays->psk_keySz == 0 ||
13488                                        ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
13489                     return PSK_KEY_ERROR;
13490 
13491                 /* make psk pre master secret */
13492                 /* length of key + length 0s + length of key + key */
13493                 c16toa((word16) ssl->arrays->psk_keySz, pms);
13494                 pms += OPAQUE16_LEN;
13495 
13496                 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
13497                 pms += ssl->arrays->psk_keySz;
13498 
13499                 c16toa((word16) ssl->arrays->psk_keySz, pms);
13500                 pms += OPAQUE16_LEN;
13501 
13502                 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
13503                 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
13504 
13505                 ret = MakeMasterSecret(ssl);
13506 
13507                 /* No further need for PSK */
13508                 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
13509                 ssl->arrays->psk_keySz = 0;
13510             }
13511             break;
13512         #endif /* NO_PSK */
13513         #ifdef HAVE_NTRU
13514             case ntru_kea:
13515             {
13516                 word16 cipherLen;
13517                 word16 plainLen = sizeof(ssl->arrays->preMasterSecret);
13518 
13519                 if (!ssl->buffers.key.buffer)
13520                     return NO_PRIVATE_KEY;
13521 
13522                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
13523                     return BUFFER_ERROR;
13524 
13525                 ato16(input + *inOutIdx, &cipherLen);
13526                 *inOutIdx += OPAQUE16_LEN;
13527 
13528                 if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
13529                     return NTRU_KEY_ERROR;
13530 
13531                 if ((*inOutIdx - begin) + cipherLen > size)
13532                     return BUFFER_ERROR;
13533 
13534                 if (NTRU_OK != ntru_crypto_ntru_decrypt(
13535                             (word16) ssl->buffers.key.length,
13536                             ssl->buffers.key.buffer, cipherLen,
13537                             input + *inOutIdx, &plainLen,
13538                             ssl->arrays->preMasterSecret))
13539                     return NTRU_DECRYPT_ERROR;
13540 
13541                 if (plainLen != SECRET_LEN)
13542                     return NTRU_DECRYPT_ERROR;
13543 
13544                 *inOutIdx += cipherLen;
13545 
13546                 ssl->arrays->preMasterSz = plainLen;
13547                 ret = MakeMasterSecret(ssl);
13548             }
13549             break;
13550         #endif /* HAVE_NTRU */
13551         #ifdef HAVE_ECC
13552             case ecc_diffie_hellman_kea:
13553             {
13554                 if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
13555                     return BUFFER_ERROR;
13556 
13557                 length = input[(*inOutIdx)++];
13558 
13559                 if ((*inOutIdx - begin) + length > size)
13560                     return BUFFER_ERROR;
13561 
13562                 if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
13563                     ecc_free(ssl->peerEccKey);
13564                     ssl->peerEccKeyPresent = 0;
13565                     ecc_init(ssl->peerEccKey);
13566                 }
13567 
13568                 if (ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey))
13569                     return ECC_PEERKEY_ERROR;
13570 
13571                 *inOutIdx += length;
13572                 ssl->peerEccKeyPresent = 1;
13573 
13574                 length = sizeof(ssl->arrays->preMasterSecret);
13575 
13576                 if (ssl->specs.static_ecdh) {
13577                     ecc_key staticKey;
13578                     word32 i = 0;
13579 
13580                     ecc_init(&staticKey);
13581                     ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
13582                                            &staticKey, ssl->buffers.key.length);
13583 
13584                     if (ret == 0)
13585                         ret = ecc_shared_secret(&staticKey, ssl->peerEccKey,
13586                                          ssl->arrays->preMasterSecret, &length);
13587 
13588                     ecc_free(&staticKey);
13589                 }
13590                 else {
13591                     if (ssl->eccTempKeyPresent == 0) {
13592                         CYASSL_MSG("Ecc ephemeral key not made correctly");
13593                         ret = ECC_MAKEKEY_ERROR;
13594                     } else {
13595                         ret = ecc_shared_secret(ssl->eccTempKey,ssl->peerEccKey,
13596                                          ssl->arrays->preMasterSecret, &length);
13597                     }
13598                 }
13599 
13600                 if (ret != 0)
13601                     return ECC_SHARED_ERROR;
13602 
13603                 ssl->arrays->preMasterSz = length;
13604                 ret = MakeMasterSecret(ssl);
13605             }
13606             break;
13607         #endif /* HAVE_ECC */
13608         #ifndef NO_DH
13609             case diffie_hellman_kea:
13610             {
13611                 word16 clientPubSz;
13612                 DhKey  dhKey;
13613 
13614                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
13615                     return BUFFER_ERROR;
13616 
13617                 ato16(input + *inOutIdx, &clientPubSz);
13618                 *inOutIdx += OPAQUE16_LEN;
13619 
13620                 if ((*inOutIdx - begin) + clientPubSz > size)
13621                     return BUFFER_ERROR;
13622 
13623                 InitDhKey(&dhKey);
13624                 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
13625                                        ssl->buffers.serverDH_P.length,
13626                                        ssl->buffers.serverDH_G.buffer,
13627                                        ssl->buffers.serverDH_G.length);
13628                 if (ret == 0)
13629                     ret = DhAgree(&dhKey, ssl->arrays->preMasterSecret,
13630                                          &ssl->arrays->preMasterSz,
13631                                           ssl->buffers.serverDH_Priv.buffer,
13632                                           ssl->buffers.serverDH_Priv.length,
13633                                           input + *inOutIdx, clientPubSz);
13634                 FreeDhKey(&dhKey);
13635 
13636                 *inOutIdx += clientPubSz;
13637 
13638                 if (ret == 0)
13639                     ret = MakeMasterSecret(ssl);
13640             }
13641             break;
13642         #endif /* NO_DH */
13643         #if !defined(NO_DH) && !defined(NO_PSK)
13644             case dhe_psk_kea:
13645             {
13646                 byte* pms = ssl->arrays->preMasterSecret;
13647                 word16 clientSz;
13648                 DhKey  dhKey;
13649 
13650                 /* Read in the PSK hint */
13651                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
13652                     return BUFFER_ERROR;
13653 
13654                 ato16(input + *inOutIdx, &clientSz);
13655                 *inOutIdx += OPAQUE16_LEN;
13656                 if (clientSz > MAX_PSK_ID_LEN)
13657                     return CLIENT_ID_ERROR;
13658 
13659                 if ((*inOutIdx - begin) + clientSz > size)
13660                     return BUFFER_ERROR;
13661 
13662                 XMEMCPY(ssl->arrays->client_identity,
13663                                                    input + *inOutIdx, clientSz);
13664                 *inOutIdx += clientSz;
13665                 ssl->arrays->client_identity[min(clientSz, MAX_PSK_ID_LEN-1)] =
13666                                                                               0;
13667 
13668                 /* Read in the DHE business */
13669                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
13670                     return BUFFER_ERROR;
13671 
13672                 ato16(input + *inOutIdx, &clientSz);
13673                 *inOutIdx += OPAQUE16_LEN;
13674 
13675                 if ((*inOutIdx - begin) + clientSz > size)
13676                     return BUFFER_ERROR;
13677 
13678                 InitDhKey(&dhKey);
13679                 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
13680                                        ssl->buffers.serverDH_P.length,
13681                                        ssl->buffers.serverDH_G.buffer,
13682                                        ssl->buffers.serverDH_G.length);
13683                 if (ret == 0)
13684                     ret = DhAgree(&dhKey, pms + OPAQUE16_LEN,
13685                                           &ssl->arrays->preMasterSz,
13686                                           ssl->buffers.serverDH_Priv.buffer,
13687                                           ssl->buffers.serverDH_Priv.length,
13688                                           input + *inOutIdx, clientSz);
13689                 FreeDhKey(&dhKey);
13690 
13691                 *inOutIdx += clientSz;
13692                 c16toa((word16)ssl->arrays->preMasterSz, pms);
13693                 ssl->arrays->preMasterSz += OPAQUE16_LEN;
13694                 pms += ssl->arrays->preMasterSz;
13695 
13696                 /* Use the PSK hint to look up the PSK and add it to the
13697                  * preMasterSecret here. */
13698                 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
13699                     ssl->arrays->client_identity, ssl->arrays->psk_key,
13700                     MAX_PSK_KEY_LEN);
13701 
13702                 if (ssl->arrays->psk_keySz == 0 ||
13703                                        ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
13704                     return PSK_KEY_ERROR;
13705 
13706                 c16toa((word16) ssl->arrays->psk_keySz, pms);
13707                 pms += OPAQUE16_LEN;
13708 
13709                 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
13710                 ssl->arrays->preMasterSz +=
13711                                           ssl->arrays->psk_keySz + OPAQUE16_LEN;
13712                 if (ret == 0)
13713                     ret = MakeMasterSecret(ssl);
13714 
13715                 /* No further need for PSK */
13716                 XMEMSET(ssl->arrays->psk_key, 0, ssl->arrays->psk_keySz);
13717                 ssl->arrays->psk_keySz = 0;
13718             }
13719             break;
13720         #endif /* !NO_DH && !NO_PSK */
13721             default:
13722             {
13723                 CYASSL_MSG("Bad kea type");
13724                 ret = BAD_KEA_TYPE_E;
13725             }
13726             break;
13727         }
13728 
13729         /* No further need for PMS */
13730         XMEMSET(ssl->arrays->preMasterSecret, 0, ssl->arrays->preMasterSz);
13731         ssl->arrays->preMasterSz = 0;
13732 
13733         if (ret == 0) {
13734             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
13735             #ifndef NO_CERTS
13736                 if (ssl->options.verifyPeer)
13737                     ret = BuildCertHashes(ssl, &ssl->certHashes);
13738             #endif
13739         }
13740 
13741         return ret;
13742     }
13743 
13744 #endif /* NO_CYASSL_SERVER */