3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
5 * This file is part of CyaSSL.
7 * CyaSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * CyaSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27 #include <cyassl/internal.h>
28 #include <cyassl/error.h>
29 #include <cyassl/ctaocrypt/asn.h>
36 #include "crypto_ntru.h"
39 #if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS)
44 #include <sys/filio.h>
51 #if defined(OPENSSL_EXTRA) && defined(NO_DH)
52 #error OPENSSL_EXTRA needs DH, please remove NO_DH
56 #ifndef NO_CYASSL_CLIENT
57 static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*);
58 static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
59 static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*);
60 static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*);
64 #ifndef NO_CYASSL_SERVER
65 static int DoClientHello(CYASSL* ssl, const byte* input, word32*, word32,
67 static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32);
68 static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32*);
73 #ifndef NO_CYASSL_SERVER
74 runProcessOldClientHello,
78 runProcessingOneMessage
81 static void Hmac(CYASSL* ssl, byte* digest, const byte* buffer, word32 sz,
82 int content, int verify);
84 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes);
89 static INLINE word32 min(word32 a, word32 b)
97 int IsTLS(const CYASSL* ssl)
99 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
106 int IsAtLeastTLSv1_2(const CYASSL* ssl)
108 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
117 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
119 /* TODO: add locking? */
123 int ret = InitRng(&rng);
133 if (cmd == GET_BYTE_OF_ENTROPY) {
134 RNG_GenerateBlock(&rng, out, 1);
138 if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
146 #endif /* HAVE_NTRU */
148 /* used by ssl.c too */
149 void c32to24(word32 in, word24 out)
151 out[0] = (in >> 16) & 0xff;
152 out[1] = (in >> 8) & 0xff;
159 static INLINE void c32to48(word32 in, byte out[6])
163 out[2] = (in >> 24) & 0xff;
164 out[3] = (in >> 16) & 0xff;
165 out[4] = (in >> 8) & 0xff;
169 #endif /* CYASSL_DTLS */
172 /* convert 16 bit integer to opaque */
173 static INLINE void c16toa(word16 u16, byte* c)
175 c[0] = (u16 >> 8) & 0xff;
180 /* convert 32 bit integer to opaque */
181 static INLINE void c32toa(word32 u32, byte* c)
183 c[0] = (u32 >> 24) & 0xff;
184 c[1] = (u32 >> 16) & 0xff;
185 c[2] = (u32 >> 8) & 0xff;
190 /* convert a 24 bit integer into a 32 bit one */
191 static INLINE void c24to32(const word24 u24, word32* u32)
194 *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
198 /* convert opaque to 16 bit integer */
199 static INLINE void ato16(const byte* c, word16* u16)
202 *u16 = (c[0] << 8) | (c[1]);
208 /* convert opaque to 32 bit integer */
209 static INLINE void ato32(const byte* c, word32* u32)
212 *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
215 #endif /* CYASSL_DTLS */
220 /* alloc user allocs to work with zlib */
221 static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
224 return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
228 static void myFree(void* opaque, void* memory)
231 XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
235 /* init zlib comp/decomp streams, 0 on success */
236 static int InitStreams(CYASSL* ssl)
238 ssl->c_stream.zalloc = (alloc_func)myAlloc;
239 ssl->c_stream.zfree = (free_func)myFree;
240 ssl->c_stream.opaque = (voidpf)ssl->heap;
242 if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
243 return ZLIB_INIT_ERROR;
245 ssl->didStreamInit = 1;
247 ssl->d_stream.zalloc = (alloc_func)myAlloc;
248 ssl->d_stream.zfree = (free_func)myFree;
249 ssl->d_stream.opaque = (voidpf)ssl->heap;
251 if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
257 static void FreeStreams(CYASSL* ssl)
259 if (ssl->didStreamInit) {
260 deflateEnd(&ssl->c_stream);
261 inflateEnd(&ssl->d_stream);
266 /* compress in to out, return out size or error */
267 static int Compress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
270 int currTotal = ssl->c_stream.total_out;
272 ssl->c_stream.next_in = in;
273 ssl->c_stream.avail_in = inSz;
274 ssl->c_stream.next_out = out;
275 ssl->c_stream.avail_out = outSz;
277 err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
278 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
280 return ssl->c_stream.total_out - currTotal;
284 /* decompress in to out, returnn out size or error */
285 static int DeCompress(CYASSL* ssl, byte* in, int inSz, byte* out, int outSz)
288 int currTotal = ssl->d_stream.total_out;
290 ssl->d_stream.next_in = in;
291 ssl->d_stream.avail_in = inSz;
292 ssl->d_stream.next_out = out;
293 ssl->d_stream.avail_out = outSz;
295 err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
296 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
298 return ssl->d_stream.total_out - currTotal;
301 #endif /* HAVE_LIBZ */
304 void InitSSL_Method(CYASSL_METHOD* method, ProtocolVersion pv)
306 method->version = pv;
307 method->side = CLIENT_END;
308 method->downgrade = 0;
312 /* Initialze SSL context, return 0 on success */
313 int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
315 ctx->method = method;
316 ctx->refCount = 1; /* so either CTX_free or SSL_free can release */
317 ctx->certificate.buffer = 0;
318 ctx->certChain.buffer = 0;
319 ctx->privateKey.buffer = 0;
320 ctx->serverDH_P.buffer = 0;
321 ctx->serverDH_G.buffer = 0;
323 ctx->haveNTRU = 0; /* start off */
324 ctx->haveECDSAsig = 0; /* start off */
325 ctx->haveStaticECC = 0; /* start off */
326 ctx->heap = ctx; /* defaults to self */
329 ctx->server_hint[0] = 0;
330 ctx->client_psk_cb = 0;
331 ctx->server_psk_cb = 0;
334 ctx->eccTempKeySz = ECDHE_SIZE;
340 #endif /* OPENSSL_EXTRA */
342 ctx->timeout = DEFAULT_TIMEOUT;
344 #ifndef CYASSL_USER_IO
345 ctx->CBIORecv = EmbedReceive;
346 ctx->CBIOSend = EmbedSend;
349 ctx->CBIORecv = NULL;
350 ctx->CBIOSend = NULL;
352 ctx->partialWrite = 0;
353 ctx->verifyCallback = 0;
355 ctx->cm = CyaSSL_CertManagerNew();
357 if (method->side == CLIENT_END)
358 ctx->haveNTRU = 1; /* always on cliet side */
359 /* server can turn on by loading key */
362 if (method->side == CLIENT_END) {
363 ctx->haveECDSAsig = 1; /* always on cliet side */
364 ctx->haveStaticECC = 1; /* server can turn on by loading key */
367 ctx->suites.setSuites = 0; /* user hasn't set yet */
368 /* remove DH later if server didn't set, add psk later */
369 InitSuites(&ctx->suites, method->version, TRUE, FALSE, ctx->haveNTRU,
370 ctx->haveECDSAsig, ctx->haveStaticECC, method->side);
374 ctx->sessionCacheOff = 0; /* initially on */
375 ctx->sessionCacheFlushOff = 0; /* initially on */
377 ctx->quietShutdown = 0;
378 ctx->groupMessages = 0;
380 CyaSSL_OCSP_Init(&ctx->ocsp);
383 if (InitMutex(&ctx->countMutex) < 0) {
384 CYASSL_MSG("Mutex error on CTX init");
385 return BAD_MUTEX_ERROR;
387 if (ctx->cm == NULL) {
388 CYASSL_MSG("Bad Cert Manager New");
389 return BAD_CERT_MANAGER_ERROR;
395 /* In case contexts are held in array and don't want to free actual ctx */
396 void SSL_CtxResourceFree(CYASSL_CTX* ctx)
398 XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
399 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
400 XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
401 XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
402 XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
403 XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
405 CyaSSL_CertManagerFree(ctx->cm);
408 CyaSSL_OCSP_Cleanup(&ctx->ocsp);
413 void FreeSSL_Ctx(CYASSL_CTX* ctx)
417 if (LockMutex(&ctx->countMutex) != 0) {
418 CYASSL_MSG("Couldn't lock count mutex");
422 if (ctx->refCount == 0)
424 UnLockMutex(&ctx->countMutex);
427 CYASSL_MSG("CTX ref count down to 0, doing full free");
428 SSL_CtxResourceFree(ctx);
429 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
433 CYASSL_MSG("CTX ref count not 0 yet, no free");
438 void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
439 byte haveNTRU, byte haveECDSAsig, byte haveStaticECC, int side)
442 int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
443 int tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
447 (void)tls; /* shut up compiler */
453 if (suites->setSuites)
454 return; /* trust user settings, don't override */
456 if (side == SERVER_END && haveStaticECC)
457 haveRSA = 0; /* can't do RSA with ECDSA key */
459 if (side == SERVER_END && haveECDSAsig)
460 haveRSAsig = 0; /* can't have RSA sig if signed by ECDSA */
463 if (pv.major == DTLS_MAJOR && pv.minor == DTLS_MINOR)
467 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
468 if (tls && haveNTRU && haveRSA) {
469 suites->suites[idx++] = 0;
470 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
474 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
475 if (tls && haveNTRU && haveRSA) {
476 suites->suites[idx++] = 0;
477 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
481 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
482 if (tls && haveNTRU && haveRSA) {
483 suites->suites[idx++] = 0;
484 suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
488 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
489 if (tls && haveNTRU && haveRSA) {
490 suites->suites[idx++] = 0;
491 suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
495 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
496 if (tls1_2 && haveStaticECC) {
497 suites->suites[idx++] = ECC_BYTE;
498 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
502 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
503 if (tls && haveStaticECC) {
504 suites->suites[idx++] = ECC_BYTE;
505 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
509 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
510 if (tls1_2 && haveECDSAsig && haveStaticECC) {
511 suites->suites[idx++] = ECC_BYTE;
512 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
516 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
517 if (tls && haveECDSAsig && haveStaticECC) {
518 suites->suites[idx++] = ECC_BYTE;
519 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
523 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
524 if (tls1_2 && haveStaticECC) {
525 suites->suites[idx++] = ECC_BYTE;
526 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
530 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
531 if (tls && haveStaticECC) {
532 suites->suites[idx++] = ECC_BYTE;
533 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
537 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
538 if (tls1_2 && haveECDSAsig && haveStaticECC) {
539 suites->suites[idx++] = ECC_BYTE;
540 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
544 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
545 if (tls && haveECDSAsig && haveStaticECC) {
546 suites->suites[idx++] = ECC_BYTE;
547 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
551 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
552 if (tls && haveStaticECC) {
553 suites->suites[idx++] = ECC_BYTE;
554 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
558 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
559 if (tls && haveECDSAsig && haveStaticECC) {
560 suites->suites[idx++] = ECC_BYTE;
561 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
565 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
566 if (tls && haveStaticECC) {
567 suites->suites[idx++] = ECC_BYTE;
568 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
572 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
573 if (tls && haveECDSAsig && haveStaticECC) {
574 suites->suites[idx++] = ECC_BYTE;
575 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
579 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
580 if (tls1_2 && haveRSA) {
581 suites->suites[idx++] = ECC_BYTE;
582 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
586 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
587 if (tls && haveRSA) {
588 suites->suites[idx++] = ECC_BYTE;
589 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
593 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
594 if (tls1_2 && haveRSAsig && haveStaticECC) {
595 suites->suites[idx++] = ECC_BYTE;
596 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
600 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
601 if (tls && haveRSAsig && haveStaticECC) {
602 suites->suites[idx++] = ECC_BYTE;
603 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
607 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
608 if (tls1_2 && haveRSA) {
609 suites->suites[idx++] = ECC_BYTE;
610 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
614 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
615 if (tls && haveRSA) {
616 suites->suites[idx++] = ECC_BYTE;
617 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
621 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
622 if (tls1_2 && haveRSAsig && haveStaticECC) {
623 suites->suites[idx++] = ECC_BYTE;
624 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
628 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
629 if (tls && haveRSAsig && haveStaticECC) {
630 suites->suites[idx++] = ECC_BYTE;
631 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
635 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
636 if (tls && haveRSA) {
637 suites->suites[idx++] = ECC_BYTE;
638 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
642 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
643 if (tls && haveRSAsig && haveStaticECC) {
644 suites->suites[idx++] = ECC_BYTE;
645 suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
649 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
650 if (tls && haveRSA) {
651 suites->suites[idx++] = ECC_BYTE;
652 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
656 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
657 if (tls && haveRSAsig && haveStaticECC) {
658 suites->suites[idx++] = ECC_BYTE;
659 suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
663 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
664 if (tls1_2 && haveDH && haveRSA) {
665 suites->suites[idx++] = 0;
666 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
670 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
671 if (tls1_2 && haveDH && haveRSA) {
672 suites->suites[idx++] = 0;
673 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
677 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
678 if (tls1_2 && haveDH && haveRSA) {
679 suites->suites[idx++] = 0;
680 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
684 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
685 if (tls1_2 && haveDH && haveRSA) {
686 suites->suites[idx++] = 0;
687 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
691 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
692 if (tls && haveDH && haveRSA) {
693 suites->suites[idx++] = 0;
694 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
698 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
699 if (tls && haveDH && haveRSA) {
700 suites->suites[idx++] = 0;
701 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
705 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
706 if (tls1_2 && haveRSA) {
707 suites->suites[idx++] = 0;
708 suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
712 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
713 if (tls1_2 && haveRSA) {
714 suites->suites[idx++] = 0;
715 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
719 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
720 if (tls1_2 && haveRSA) {
721 suites->suites[idx++] = 0;
722 suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
726 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
727 if (tls1_2 && haveRSA) {
728 suites->suites[idx++] = 0;
729 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
733 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
734 if (tls && haveRSA) {
735 suites->suites[idx++] = 0;
736 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
740 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
741 if (tls && haveRSA) {
742 suites->suites[idx++] = 0;
743 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
747 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
748 if (tls && havePSK) {
749 suites->suites[idx++] = 0;
750 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
754 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
755 if (tls && havePSK) {
756 suites->suites[idx++] = 0;
757 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
761 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
763 suites->suites[idx++] = 0;
764 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
768 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
770 suites->suites[idx++] = 0;
771 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
775 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
777 suites->suites[idx++] = 0;
778 suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
782 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
783 if (tls && haveRSA) {
784 suites->suites[idx++] = 0;
785 suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_MD5;
789 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
790 if (tls && haveRSA) {
791 suites->suites[idx++] = 0;
792 suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_SHA;
796 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
797 if (tls && haveRSA) {
798 suites->suites[idx++] = 0;
799 suites->suites[idx++] = TLS_RSA_WITH_RABBIT_CBC_SHA;
803 suites->suiteSz = idx;
807 /* init everything to 0, NULL, default values before calling anything that may
808 fail so that desctructor has a "good" state to cleanup */
809 int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
814 ssl->ctx = ctx; /* only for passing to calls, options could change */
815 ssl->version = ctx->method->version;
816 ssl->suites = ctx->suites;
819 ssl->didStreamInit = 0;
822 ssl->buffers.certificate.buffer = 0;
823 ssl->buffers.key.buffer = 0;
824 ssl->buffers.certChain.buffer = 0;
825 ssl->buffers.inputBuffer.length = 0;
826 ssl->buffers.inputBuffer.idx = 0;
827 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
828 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
829 ssl->buffers.inputBuffer.dynamicFlag = 0;
830 ssl->buffers.outputBuffer.length = 0;
831 ssl->buffers.outputBuffer.idx = 0;
832 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
833 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
834 ssl->buffers.outputBuffer.dynamicFlag = 0;
835 ssl->buffers.domainName.buffer = 0;
836 ssl->buffers.serverDH_P.buffer = 0;
837 ssl->buffers.serverDH_G.buffer = 0;
838 ssl->buffers.serverDH_Pub.buffer = 0;
839 ssl->buffers.serverDH_Priv.buffer = 0;
840 ssl->buffers.clearOutputBuffer.buffer = 0;
841 ssl->buffers.clearOutputBuffer.length = 0;
842 ssl->buffers.prevSent = 0;
843 ssl->buffers.plainSz = 0;
846 ssl->peerCert.derCert.buffer = NULL;
847 ssl->peerCert.altNames = NULL;
848 ssl->peerCert.altNamesNext = NULL;
852 ssl->eccTempKeySz = ctx->eccTempKeySz;
853 ssl->peerEccKeyPresent = 0;
854 ssl->peerEccDsaKeyPresent = 0;
855 ssl->eccDsaKeyPresent = 0;
856 ssl->eccTempKeyPresent = 0;
857 ecc_init(&ssl->peerEccKey);
858 ecc_init(&ssl->peerEccDsaKey);
859 ecc_init(&ssl->eccDsaKey);
860 ecc_init(&ssl->eccTempKey);
863 ssl->timeout = ctx->timeout;
864 ssl->rfd = -1; /* set to invalid descriptor */
869 ssl->IOCB_ReadCtx = &ssl->rfd; /* prevent invalid pointer acess if not */
870 ssl->IOCB_WriteCtx = &ssl->wfd; /* correctly set */
872 InitMd5(&ssl->hashMd5);
873 InitSha(&ssl->hashSha);
875 InitSha256(&ssl->hashSha256);
878 InitSha384(&ssl->hashSha384);
880 InitRsaKey(&ssl->peerRsaKey, ctx->heap);
882 ssl->verifyCallback = ctx->verifyCallback;
883 ssl->peerRsaKeyPresent = 0;
884 ssl->options.side = ctx->method->side;
885 ssl->options.downgrade = ctx->method->downgrade;
887 ssl->options.connReset = 0;
888 ssl->options.isClosed = 0;
889 ssl->options.closeNotify = 0;
890 ssl->options.sentNotify = 0;
891 ssl->options.usingCompression = 0;
892 if (ssl->options.side == SERVER_END)
893 ssl->options.haveDH = ctx->haveDH;
895 ssl->options.haveDH = 0;
896 ssl->options.haveNTRU = ctx->haveNTRU;
897 ssl->options.haveECDSAsig = ctx->haveECDSAsig;
898 ssl->options.haveStaticECC = ctx->haveStaticECC;
899 ssl->options.havePeerCert = 0;
900 ssl->options.usingPSK_cipher = 0;
901 ssl->options.sendAlertState = 0;
903 havePSK = ctx->havePSK;
904 ssl->options.havePSK = ctx->havePSK;
905 ssl->options.client_psk_cb = ctx->client_psk_cb;
906 ssl->options.server_psk_cb = ctx->server_psk_cb;
909 ssl->options.serverState = NULL_STATE;
910 ssl->options.clientState = NULL_STATE;
911 ssl->options.connectState = CONNECT_BEGIN;
912 ssl->options.acceptState = ACCEPT_BEGIN;
913 ssl->options.handShakeState = NULL_STATE;
914 ssl->options.processReply = doProcessInit;
917 ssl->keys.dtls_sequence_number = 0;
918 ssl->keys.dtls_peer_sequence_number = 0;
919 ssl->keys.dtls_handshake_number = 0;
920 ssl->keys.dtls_epoch = 0;
921 ssl->keys.dtls_peer_epoch = 0;
922 ssl->arrays.cookieSz = 0;
924 ssl->keys.encryptionOn = 0; /* initially off */
925 ssl->options.sessionCacheOff = ctx->sessionCacheOff;
926 ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
928 ssl->options.verifyPeer = ctx->verifyPeer;
929 ssl->options.verifyNone = ctx->verifyNone;
930 ssl->options.failNoCert = ctx->failNoCert;
931 ssl->options.sendVerify = ctx->sendVerify;
933 ssl->options.resuming = 0;
934 ssl->options.haveSessionId = 0;
935 ssl->hmac = Hmac; /* default to SSLv3 */
936 ssl->heap = ctx->heap; /* defaults to self */
937 ssl->options.tls = 0;
938 ssl->options.tls1_1 = 0;
939 ssl->options.dtls = 0;
940 ssl->options.partialWrite = ctx->partialWrite;
941 ssl->options.quietShutdown = ctx->quietShutdown;
942 ssl->options.certOnly = 0;
943 ssl->options.groupMessages = ctx->groupMessages;
945 /* ctx still owns certificate, certChain, key, dh, and cm */
946 ssl->buffers.certificate = ctx->certificate;
947 ssl->buffers.certChain = ctx->certChain;
948 ssl->buffers.key = ctx->privateKey;
949 if (ssl->options.side == SERVER_END) {
950 ssl->buffers.serverDH_P = ctx->serverDH_P;
951 ssl->buffers.serverDH_G = ctx->serverDH_G;
953 ssl->buffers.weOwnCert = 0;
954 ssl->buffers.weOwnKey = 0;
955 ssl->buffers.weOwnDH = 0;
958 ssl->peerCert.issuer.sz = 0;
959 ssl->peerCert.subject.sz = 0;
963 ssl->session.chain.count = 0;
966 ssl->cipher.ssl = ssl;
974 #ifdef CYASSL_CALLBACKS
980 ssl->arrays.client_identity[0] = 0;
981 if (ctx->server_hint[0]) { /* set in CTX */
982 XSTRNCPY(ssl->arrays.server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
983 ssl->arrays.server_hint[MAX_PSK_ID_LEN - 1] = '\0';
986 ssl->arrays.server_hint[0] = 0;
989 /* all done with init, now can return errors, call other stuff */
991 /* increment CTX reference count */
992 if (LockMutex(&ctx->countMutex) != 0) {
993 CYASSL_MSG("Couldn't lock CTX count mutex");
994 return BAD_MUTEX_ERROR;
997 UnLockMutex(&ctx->countMutex);
999 if ( (ret = InitRng(&ssl->rng)) != 0)
1002 /* make sure server has cert and key unless using PSK */
1003 if (ssl->options.side == SERVER_END && !havePSK)
1004 if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
1005 CYASSL_MSG("Server missing certificate and/or private key");
1006 return NO_PRIVATE_KEY;
1009 /* make sure server has DH parms, and add PSK if there, add NTRU too */
1010 if (ssl->options.side == SERVER_END)
1011 InitSuites(&ssl->suites, ssl->version,ssl->options.haveDH, havePSK,
1012 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
1013 ssl->options.haveStaticECC, ssl->options.side);
1015 InitSuites(&ssl->suites, ssl->version, TRUE, havePSK,
1016 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
1017 ssl->options.haveStaticECC, ssl->options.side);
1023 /* In case holding SSL object in array and don't want to free actual ssl */
1024 void SSL_ResourceFree(CYASSL* ssl)
1026 XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
1027 XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
1028 /* parameters (p,g) may be owned by ctx */
1029 if (ssl->buffers.weOwnDH || ssl->options.side == CLIENT_END) {
1030 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
1031 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
1033 XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
1035 /* CYASSL_CTX always owns certChain */
1036 if (ssl->buffers.weOwnCert)
1037 XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
1038 if (ssl->buffers.weOwnKey)
1039 XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
1041 FreeRsaKey(&ssl->peerRsaKey);
1042 if (ssl->buffers.inputBuffer.dynamicFlag)
1043 ShrinkInputBuffer(ssl, FORCED_FREE);
1044 if (ssl->buffers.outputBuffer.dynamicFlag)
1045 ShrinkOutputBuffer(ssl);
1046 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
1047 XFREE(ssl->peerCert.derCert.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
1048 if (ssl->peerCert.altNames)
1049 FreeAltNames(ssl->peerCert.altNames, ssl->heap);
1050 CyaSSL_BIO_free(ssl->biord);
1051 if (ssl->biord != ssl->biowr) /* in case same as write */
1052 CyaSSL_BIO_free(ssl->biowr);
1058 ecc_free(&ssl->peerEccKey);
1059 ecc_free(&ssl->peerEccDsaKey);
1060 ecc_free(&ssl->eccTempKey);
1061 ecc_free(&ssl->eccDsaKey);
1066 void FreeSSL(CYASSL* ssl)
1068 FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */
1069 SSL_ResourceFree(ssl);
1070 XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
1074 ProtocolVersion MakeSSLv3(void)
1077 pv.major = SSLv3_MAJOR;
1078 pv.minor = SSLv3_MINOR;
1086 ProtocolVersion MakeDTLSv1(void)
1089 pv.major = DTLS_MAJOR;
1090 pv.minor = DTLS_MINOR;
1095 #endif /* CYASSL_DTLS */
1100 #ifdef USE_WINDOWS_API
1104 static int init = 0;
1105 static LARGE_INTEGER freq;
1106 LARGE_INTEGER count;
1109 QueryPerformanceFrequency(&freq);
1113 QueryPerformanceCounter(&count);
1115 return (double)count.QuadPart / freq.QuadPart;
1119 word32 LowResTimer(void)
1121 return (word32)Timer();
1125 #elif defined(THREADX)
1127 #include "rtptime.h"
1129 word32 LowResTimer(void)
1131 return (word32)rtp_get_system_sec();
1135 #elif defined(MICRIUM)
1137 word32 LowResTimer(void)
1139 NET_SECURE_OS_TICK clk;
1141 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
1142 clk = NetSecure_OS_TimeGet();
1147 #elif defined(USER_TICKS)
1149 word32 LowResTimer(void)
1152 write your own clock tick function if don't want time(0)
1153 needs second accuracy but doesn't have to correlated to EPOCH
1157 #else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !USER_TICKS */
1161 word32 LowResTimer(void)
1167 #endif /* USE_WINDOWS_API */
1170 /* add output to md5 and sha handshake hashes, exclude record header */
1171 static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
1173 const byte* adj = output + RECORD_HEADER_SZ + ivSz;
1174 sz -= RECORD_HEADER_SZ;
1177 if (ssl->options.dtls) {
1178 adj += DTLS_RECORD_EXTRA;
1179 sz -= DTLS_RECORD_EXTRA;
1183 Md5Update(&ssl->hashMd5, adj, sz);
1184 ShaUpdate(&ssl->hashSha, adj, sz);
1185 if (IsAtLeastTLSv1_2(ssl)) {
1187 Sha256Update(&ssl->hashSha256, adj, sz);
1189 #ifdef CYASSL_SHA384
1190 Sha384Update(&ssl->hashSha384, adj, sz);
1196 /* add input to md5 and sha handshake hashes, include handshake header */
1197 static void HashInput(CYASSL* ssl, const byte* input, int sz)
1199 const byte* adj = input - HANDSHAKE_HEADER_SZ;
1200 sz += HANDSHAKE_HEADER_SZ;
1203 if (ssl->options.dtls) {
1204 adj -= DTLS_HANDSHAKE_EXTRA;
1205 sz += DTLS_HANDSHAKE_EXTRA;
1209 Md5Update(&ssl->hashMd5, adj, sz);
1210 ShaUpdate(&ssl->hashSha, adj, sz);
1211 if (IsAtLeastTLSv1_2(ssl)) {
1213 Sha256Update(&ssl->hashSha256, adj, sz);
1215 #ifdef CYASSL_SHA384
1216 Sha384Update(&ssl->hashSha384, adj, sz);
1222 /* add record layer header for message */
1223 static void AddRecordHeader(byte* output, word32 length, byte type, CYASSL* ssl)
1225 RecordLayerHeader* rl;
1227 /* record layer header */
1228 rl = (RecordLayerHeader*)output;
1230 rl->version = ssl->version; /* type and version same in each */
1232 if (!ssl->options.dtls)
1233 c16toa((word16)length, rl->length);
1236 DtlsRecordLayerHeader* dtls;
1238 /* dtls record layer header extensions */
1239 dtls = (DtlsRecordLayerHeader*)output;
1240 c16toa(ssl->keys.dtls_epoch, dtls->epoch);
1241 c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
1242 c16toa((word16)length, dtls->length);
1248 /* add handshake header for message */
1249 static void AddHandShakeHeader(byte* output, word32 length, byte type,
1252 HandShakeHeader* hs;
1255 /* handshake header */
1256 hs = (HandShakeHeader*)output;
1258 c32to24(length, hs->length); /* type and length same for each */
1260 if (ssl->options.dtls) {
1261 DtlsHandShakeHeader* dtls;
1263 /* dtls handshake header extensions */
1264 dtls = (DtlsHandShakeHeader*)output;
1265 c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
1266 c32to24(0, dtls->fragment_offset);
1267 c32to24(length, dtls->fragment_length);
1273 /* add both headers for handshake message */
1274 static void AddHeaders(byte* output, word32 length, byte type, CYASSL* ssl)
1276 if (!ssl->options.dtls) {
1277 AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
1278 AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
1282 AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
1283 AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
1289 /* return bytes received, -1 on error */
1290 static int Receive(CYASSL* ssl, byte* buf, word32 sz)
1295 recvd = ssl->ctx->CBIORecv((char *)buf, (int)sz, ssl->IOCB_ReadCtx);
1298 case IO_ERR_GENERAL: /* general/unknown error */
1301 case IO_ERR_WANT_READ: /* want read, would block */
1304 case IO_ERR_CONN_RST: /* connection reset */
1305 ssl->options.connReset = 1;
1308 case IO_ERR_ISR: /* interrupt */
1309 /* see if we got our timeout */
1310 #ifdef CYASSL_CALLBACKS
1311 if (ssl->toInfoOn) {
1312 struct itimerval timeout;
1313 getitimer(ITIMER_REAL, &timeout);
1314 if (timeout.it_value.tv_sec == 0 &&
1315 timeout.it_value.tv_usec == 0) {
1316 XSTRNCPY(ssl->timeoutInfo.timeoutName,
1317 "recv() timeout", MAX_TIMEOUT_NAME_SZ);
1318 CYASSL_MSG("Got our timeout");
1325 case IO_ERR_CONN_CLOSE: /* peer closed connection */
1326 ssl->options.isClosed = 1;
1337 /* Switch dynamic output buffer back to static, buffer is assumed clear */
1338 void ShrinkOutputBuffer(CYASSL* ssl)
1340 CYASSL_MSG("Shrinking output buffer\n");
1341 XFREE(ssl->buffers.outputBuffer.buffer, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
1342 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
1343 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
1344 ssl->buffers.outputBuffer.dynamicFlag = 0;
1348 /* Switch dynamic input buffer back to static, keep any remaining input */
1349 /* forced free means cleaning up */
1350 void ShrinkInputBuffer(CYASSL* ssl, int forcedFree)
1352 int usedLength = ssl->buffers.inputBuffer.length -
1353 ssl->buffers.inputBuffer.idx;
1354 if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
1357 CYASSL_MSG("Shrinking input buffer\n");
1359 if (!forcedFree && usedLength)
1360 XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
1361 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
1364 XFREE(ssl->buffers.inputBuffer.buffer, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
1365 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
1366 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
1367 ssl->buffers.inputBuffer.dynamicFlag = 0;
1368 ssl->buffers.inputBuffer.idx = 0;
1369 ssl->buffers.inputBuffer.length = usedLength;
1373 int SendBuffered(CYASSL* ssl)
1375 while (ssl->buffers.outputBuffer.length > 0) {
1376 int sent = ssl->ctx->CBIOSend((char*)ssl->buffers.outputBuffer.buffer +
1377 ssl->buffers.outputBuffer.idx,
1378 (int)ssl->buffers.outputBuffer.length,
1379 ssl->IOCB_WriteCtx);
1383 case IO_ERR_WANT_WRITE: /* would block */
1386 case IO_ERR_CONN_RST: /* connection reset */
1387 ssl->options.connReset = 1;
1390 case IO_ERR_ISR: /* interrupt */
1391 /* see if we got our timeout */
1392 #ifdef CYASSL_CALLBACKS
1393 if (ssl->toInfoOn) {
1394 struct itimerval timeout;
1395 getitimer(ITIMER_REAL, &timeout);
1396 if (timeout.it_value.tv_sec == 0 &&
1397 timeout.it_value.tv_usec == 0) {
1398 XSTRNCPY(ssl->timeoutInfo.timeoutName,
1399 "send() timeout", MAX_TIMEOUT_NAME_SZ);
1400 CYASSL_MSG("Got our timeout");
1407 case IO_ERR_CONN_CLOSE: /* epipe / conn closed, same as reset */
1408 ssl->options.connReset = 1;
1412 return SOCKET_ERROR_E;
1415 return SOCKET_ERROR_E;
1418 ssl->buffers.outputBuffer.idx += sent;
1419 ssl->buffers.outputBuffer.length -= sent;
1422 ssl->buffers.outputBuffer.idx = 0;
1424 if (ssl->buffers.outputBuffer.dynamicFlag)
1425 ShrinkOutputBuffer(ssl);
1431 /* Grow the output buffer */
1432 static INLINE int GrowOutputBuffer(CYASSL* ssl, int size)
1434 byte* tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length,
1435 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
1436 CYASSL_MSG("growing output buffer\n");
1438 if (!tmp) return MEMORY_E;
1440 if (ssl->buffers.outputBuffer.length)
1441 XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
1442 ssl->buffers.outputBuffer.length);
1444 if (ssl->buffers.outputBuffer.dynamicFlag)
1445 XFREE(ssl->buffers.outputBuffer.buffer, ssl->heap,
1446 DYNAMIC_TYPE_OUT_BUFFER);
1447 ssl->buffers.outputBuffer.dynamicFlag = 1;
1448 ssl->buffers.outputBuffer.buffer = tmp;
1449 ssl->buffers.outputBuffer.bufferSize = size +
1450 ssl->buffers.outputBuffer.length;
1455 /* Grow the input buffer, should only be to read cert or big app data */
1456 static INLINE int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
1458 byte* tmp = (byte*) XMALLOC(size + usedLength, ssl->heap,
1459 DYNAMIC_TYPE_IN_BUFFER);
1460 CYASSL_MSG("growing input buffer\n");
1462 if (!tmp) return MEMORY_E;
1465 XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
1466 ssl->buffers.inputBuffer.idx, usedLength);
1468 if (ssl->buffers.inputBuffer.dynamicFlag)
1469 XFREE(ssl->buffers.inputBuffer.buffer,ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
1471 ssl->buffers.inputBuffer.dynamicFlag = 1;
1472 ssl->buffers.inputBuffer.buffer = tmp;
1473 ssl->buffers.inputBuffer.bufferSize = size + usedLength;
1474 ssl->buffers.inputBuffer.idx = 0;
1475 ssl->buffers.inputBuffer.length = usedLength;
1481 /* check avalaible size into output buffer, make room if needed */
1482 static INLINE int CheckAvalaibleSize(CYASSL *ssl, int size)
1484 if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
1486 if (GrowOutputBuffer(ssl, size) < 0)
1493 /* do all verify and sanity checks on record header */
1494 static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
1495 RecordLayerHeader* rh, word16 *size)
1497 if (!ssl->options.dtls) {
1498 XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
1499 *inOutIdx += RECORD_HEADER_SZ;
1500 ato16(rh->length, size);
1504 /* type and version in same sport */
1505 XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
1506 *inOutIdx += ENUM_LEN + VERSION_SZ;
1507 *inOutIdx += 4; /* skip epoch and first 2 seq bytes for now */
1508 ato32(input + *inOutIdx, &ssl->keys.dtls_peer_sequence_number);
1509 *inOutIdx += 4; /* advance past rest of seq */
1510 ato16(input + *inOutIdx, size);
1511 *inOutIdx += LENGTH_SZ;
1515 /* catch version mismatch */
1516 if (rh->version.major != ssl->version.major ||
1517 rh->version.minor != ssl->version.minor) {
1519 if (ssl->options.side == SERVER_END &&
1520 ssl->options.acceptState == ACCEPT_BEGIN)
1521 CYASSL_MSG("Client attempting to connect with different version");
1522 else if (ssl->options.side == CLIENT_END && ssl->options.downgrade &&
1523 ssl->options.connectState < FIRST_REPLY_DONE)
1524 CYASSL_MSG("Server attempting to accept with different version");
1526 CYASSL_MSG("SSL version error");
1527 return VERSION_ERROR; /* only use requested version */
1531 /* record layer length check */
1532 if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
1533 return LENGTH_ERROR;
1535 /* verify record type here as well */
1536 switch ((enum ContentType)rh->type) {
1538 case change_cipher_spec:
1539 case application_data:
1544 CYASSL_MSG("Unknown Record Type");
1545 return UNKNOWN_RECORD_TYPE;
1552 static int GetHandShakeHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
1553 byte *type, word32 *size)
1555 const byte *ptr = input + *inOutIdx;
1557 *inOutIdx += HANDSHAKE_HEADER_SZ;
1560 if (ssl->options.dtls)
1561 *inOutIdx += DTLS_HANDSHAKE_EXTRA;
1565 c24to32(&ptr[1], size);
1571 /* fill with MD5 pad size since biggest required */
1572 static const byte PAD1[PAD_MD5] =
1573 { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1574 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1575 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1576 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1577 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1578 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
1580 static const byte PAD2[PAD_MD5] =
1581 { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1582 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1583 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1584 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1585 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1586 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
1589 /* calculate MD5 hash for finished */
1590 static void BuildMD5(CYASSL* ssl, Hashes* hashes, const byte* sender)
1592 byte md5_result[MD5_DIGEST_SIZE];
1594 /* make md5 inner */
1595 Md5Update(&ssl->hashMd5, sender, SIZEOF_SENDER);
1596 Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
1597 Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
1598 Md5Final(&ssl->hashMd5, md5_result);
1600 /* make md5 outer */
1601 Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
1602 Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
1603 Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
1605 Md5Final(&ssl->hashMd5, hashes->md5);
1609 /* calculate SHA hash for finished */
1610 static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender)
1612 byte sha_result[SHA_DIGEST_SIZE];
1614 /* make sha inner */
1615 ShaUpdate(&ssl->hashSha, sender, SIZEOF_SENDER);
1616 ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
1617 ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
1618 ShaFinal(&ssl->hashSha, sha_result);
1620 /* make sha outer */
1621 ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
1622 ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
1623 ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
1625 ShaFinal(&ssl->hashSha, hashes->sha);
1629 static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
1631 /* store current states, building requires get_digest which resets state */
1632 Md5 md5 = ssl->hashMd5;
1633 Sha sha = ssl->hashSha;
1637 #ifdef CYASSL_SHA384
1642 InitSha256(&sha256);
1643 if (IsAtLeastTLSv1_2(ssl))
1644 sha256 = ssl->hashSha256;
1646 #ifdef CYASSL_SHA384
1647 InitSha384(&sha384);
1648 if (IsAtLeastTLSv1_2(ssl))
1649 sha384 = ssl->hashSha384;
1652 if (ssl->options.tls)
1653 BuildTlsFinished(ssl, hashes, sender);
1655 BuildMD5(ssl, hashes, sender);
1656 BuildSHA(ssl, hashes, sender);
1662 if (IsAtLeastTLSv1_2(ssl)) {
1664 ssl->hashSha256 = sha256;
1666 #ifdef CYASSL_SHA384
1667 ssl->hashSha384 = sha384;
1673 static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
1675 word32 listSz, i = *inOutIdx;
1678 int totalCerts = 0; /* number of certs in certs buffer */
1680 char domain[ASN_NAME_MAX];
1681 buffer certs[MAX_CHAIN_DEPTH];
1683 #ifdef CYASSL_CALLBACKS
1684 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
1685 if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
1687 c24to32(&input[i], &listSz);
1688 i += CERT_HEADER_SZ;
1690 CYASSL_MSG("Loading peer's cert chain");
1691 /* first put cert chain into buffer so can verify top down
1692 we're sent bottom up */
1697 if (totalCerts >= MAX_CHAIN_DEPTH)
1698 return MAX_CHAIN_ERROR;
1700 c24to32(&input[i], &certSz);
1701 i += CERT_HEADER_SZ;
1703 if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
1706 certs[totalCerts].length = certSz;
1707 certs[totalCerts].buffer = input + i;
1709 #ifdef SESSION_CERTS
1710 if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
1711 certSz < MAX_X509_SIZE) {
1712 ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
1713 XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
1715 ssl->session.chain.count++;
1717 CYASSL_MSG("Couldn't store chain cert for session");
1722 listSz -= certSz + CERT_HEADER_SZ;
1725 CYASSL_MSG(" Put another cert into chain");
1730 /* verify up to peer's first */
1732 buffer myCert = certs[count - 1];
1735 InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
1736 ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
1738 if (ret == 0 && dCert.isCA == 0) {
1739 CYASSL_MSG("Chain cert is not a CA, not adding as one");
1741 else if (ret == 0 && ssl->options.verifyNone) {
1742 CYASSL_MSG("Chain cert not verified by option, not adding as CA");
1744 else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, dCert.subjectHash)) {
1746 add.length = myCert.length;
1747 add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
1749 CYASSL_MSG("Adding CA from chain");
1751 if (add.buffer == NULL)
1753 XMEMCPY(add.buffer, myCert.buffer, myCert.length);
1755 ret = AddCA(ssl->ctx->cm, add, CYASSL_CHAIN_CA,
1756 ssl->ctx->verifyPeer);
1757 if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
1759 else if (ret != 0) {
1760 CYASSL_MSG("Failed to verify CA from chain");
1763 CYASSL_MSG("Verified CA from chain and already had it");
1767 if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) {
1768 CYASSL_MSG("Doing Non Leaf CRL check");
1769 ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
1772 CYASSL_MSG("\tCRL check not ok");
1775 #endif /* HAVE_CRL */
1777 if (ret != 0 && anyError == 0)
1778 anyError = ret; /* save error from last time */
1780 FreeDecodedCert(&dCert);
1784 /* peer's, may not have one if blank client cert sent by TLSv1.2 */
1786 buffer myCert = certs[0];
1790 CYASSL_MSG("Veriying Peer's cert");
1792 InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
1793 ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
1796 CYASSL_MSG("Verified Peer's cert");
1799 else if (ret == ASN_PARSE_E) {
1800 CYASSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
1804 CYASSL_MSG("Failed to verify Peer's cert");
1805 if (ssl->verifyCallback) {
1806 CYASSL_MSG("\tCallback override availalbe, will continue");
1810 CYASSL_MSG("\tNo callback override availalbe, fatal");
1816 ret = CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert);
1818 CYASSL_MSG("\tOCSP Lookup not ok");
1824 if (fatal == 0 && ssl->ctx->cm->crlEnabled) {
1825 CYASSL_MSG("Doing Leaf CRL check");
1826 ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
1829 CYASSL_MSG("\tCRL check not ok");
1833 #endif /* HAVE_CRL */
1835 #ifdef OPENSSL_EXTRA
1836 /* set X509 format for peer cert even if fatal */
1837 XSTRNCPY(ssl->peerCert.issuer.name, dCert.issuer, ASN_NAME_MAX);
1838 ssl->peerCert.issuer.name[ASN_NAME_MAX - 1] = '\0';
1839 ssl->peerCert.issuer.sz = (int)XSTRLEN(ssl->peerCert.issuer.name) + 1;
1841 XSTRNCPY(ssl->peerCert.subject.name, dCert.subject, ASN_NAME_MAX);
1842 ssl->peerCert.subject.name[ASN_NAME_MAX - 1] = '\0';
1843 ssl->peerCert.subject.sz = (int)XSTRLEN(ssl->peerCert.subject.name) + 1;
1845 XMEMCPY(ssl->peerCert.serial, dCert.serial, EXTERNAL_SERIAL_SIZE);
1846 ssl->peerCert.serialSz = dCert.serialSz;
1847 if (dCert.subjectCNLen < ASN_NAME_MAX) {
1848 XMEMCPY(ssl->peerCert.subjectCN,dCert.subjectCN,dCert.subjectCNLen);
1849 ssl->peerCert.subjectCN[dCert.subjectCNLen] = '\0';
1852 ssl->peerCert.subjectCN[0] = '\0';
1854 /* store cert for potential retrieval */
1855 ssl->peerCert.derCert.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
1857 if (ssl->peerCert.derCert.buffer == NULL) {
1862 XMEMCPY(ssl->peerCert.derCert.buffer, myCert.buffer, myCert.length);
1863 ssl->peerCert.derCert.length = myCert.length;
1866 ssl->peerCert.altNames = dCert.altNames;
1867 dCert.altNames = NULL; /* takes ownership */
1868 ssl->peerCert.altNamesNext = ssl->peerCert.altNames; /* index hint */
1872 FreeDecodedCert(&dCert);
1876 ssl->options.havePeerCert = 1;
1878 /* store for callback use */
1879 if (dCert.subjectCNLen < ASN_NAME_MAX) {
1880 XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen);
1881 domain[dCert.subjectCNLen] = '\0';
1886 if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer)
1887 if (XSTRNCMP((char*)ssl->buffers.domainName.buffer,
1889 ssl->buffers.domainName.length - 1)) {
1890 ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
1893 /* decode peer key */
1894 if (dCert.keyOID == RSAk) {
1896 if (RsaPublicKeyDecode(dCert.publicKey, &idx,
1897 &ssl->peerRsaKey, dCert.pubKeySize) != 0) {
1898 ret = PEER_KEY_ERROR;
1901 ssl->peerRsaKeyPresent = 1;
1904 else if (dCert.keyOID == NTRUk) {
1905 if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) {
1906 ret = PEER_KEY_ERROR;
1909 XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize);
1910 ssl->peerNtruKeyLen = (word16)dCert.pubKeySize;
1911 ssl->peerNtruKeyPresent = 1;
1914 #endif /* HAVE_NTRU */
1916 else if (dCert.keyOID == ECDSAk) {
1917 if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize,
1918 &ssl->peerEccDsaKey) != 0) {
1919 ret = PEER_KEY_ERROR;
1922 ssl->peerEccDsaKeyPresent = 1;
1924 #endif /* HAVE_ECC */
1926 FreeDecodedCert(&dCert);
1929 if (anyError != 0 && ret == 0)
1932 if (ret == 0 && ssl->options.side == CLIENT_END)
1933 ssl->options.serverState = SERVER_CERT_COMPLETE;
1936 if (!ssl->options.verifyNone) {
1937 int why = bad_certificate;
1938 if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
1939 why = certificate_expired;
1940 if (ssl->verifyCallback) {
1942 CYASSL_X509_STORE_CTX store;
1945 store.error_depth = totalCerts;
1946 store.domain = domain;
1947 #ifdef OPENSSL_EXTRA
1948 store.current_cert = &ssl->peerCert;
1950 store.current_cert = NULL;
1953 store.ex_data = ssl;
1955 ok = ssl->verifyCallback(0, &store);
1957 CYASSL_MSG("Verify callback overriding error!");
1962 SendAlert(ssl, alert_fatal, why); /* try to send */
1963 ssl->options.isClosed = 1;
1970 if (ssl->verifyCallback) {
1972 CYASSL_X509_STORE_CTX store;
1975 store.error_depth = totalCerts;
1976 store.domain = domain;
1977 store.current_cert = &ssl->peerCert;
1978 store.ex_data = ssl;
1980 ok = ssl->verifyCallback(1, &store);
1982 CYASSL_MSG("Verify callback overriding valid certificate!");
1984 SendAlert(ssl, alert_fatal, bad_certificate);
1985 ssl->options.isClosed = 1;
1996 static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx)
1998 if (ssl->keys.encryptionOn) {
2000 int padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ -
2001 ssl->specs.hash_size;
2002 byte verify[SHA256_DIGEST_SIZE];
2004 ssl->hmac(ssl, verify, input + *inOutIdx - HANDSHAKE_HEADER_SZ,
2005 HANDSHAKE_HEADER_SZ, handshake, 1);
2006 /* read mac and fill */
2007 mac = input + *inOutIdx;
2008 *inOutIdx += ssl->specs.hash_size;
2010 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
2011 padSz -= ssl->specs.block_size;
2016 if (XMEMCMP(mac, verify, ssl->specs.hash_size)) {
2017 CYASSL_MSG(" hello_request verify mac error");
2018 return VERIFY_MAC_ERROR;
2022 return SendAlert(ssl, alert_warning, no_renegotiation);
2026 int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
2028 byte verifyMAC[SHA256_DIGEST_SIZE];
2029 int finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ;
2030 int headerSz = HANDSHAKE_HEADER_SZ;
2031 word32 macSz = finishedSz + HANDSHAKE_HEADER_SZ,
2033 padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - finishedSz -
2034 ssl->specs.hash_size;
2038 if (ssl->options.dtls) {
2039 headerSz += DTLS_HANDSHAKE_EXTRA;
2040 macSz += DTLS_HANDSHAKE_EXTRA;
2041 padSz -= DTLS_HANDSHAKE_EXTRA;
2045 #ifdef CYASSL_CALLBACKS
2046 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
2047 if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
2049 if (sniff == NO_SNIFF) {
2050 if (XMEMCMP(input + idx, &ssl->verifyHashes, finishedSz)) {
2051 CYASSL_MSG("Verify finished error on hashes");
2052 return VERIFY_FINISHED_ERROR;
2056 if (ssl->specs.cipher_type != aead) {
2057 ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
2061 /* read mac and fill */
2063 idx += ssl->specs.hash_size;
2065 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
2066 padSz -= ssl->specs.block_size;
2071 if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size)) {
2072 CYASSL_MSG("Verify finished error on mac");
2073 return VERIFY_MAC_ERROR;
2077 idx += (finishedSz + AEAD_AUTH_TAG_SZ);
2080 if (ssl->options.side == CLIENT_END) {
2081 ssl->options.serverState = SERVER_FINISHED_COMPLETE;
2082 if (!ssl->options.resuming)
2083 ssl->options.handShakeState = HANDSHAKE_DONE;
2086 ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
2087 if (ssl->options.resuming)
2088 ssl->options.handShakeState = HANDSHAKE_DONE;
2096 static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
2103 CYASSL_ENTER("DoHandShakeMsg()");
2105 if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size) != 0)
2108 if (*inOutIdx + size > totalSz)
2109 return INCOMPLETE_DATA;
2111 HashInput(ssl, input + *inOutIdx, size);
2112 #ifdef CYASSL_CALLBACKS
2113 /* add name later, add on record and handshake header part back on */
2114 if (ssl->toInfoOn) {
2115 int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
2116 AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
2117 size + add, ssl->heap);
2118 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
2125 CYASSL_MSG("processing hello request");
2126 ret = DoHelloRequest(ssl, input, inOutIdx);
2129 #ifndef NO_CYASSL_CLIENT
2130 case hello_verify_request:
2131 CYASSL_MSG("processing hello verify request");
2132 ret = DoHelloVerifyRequest(ssl, input,inOutIdx);
2136 CYASSL_MSG("processing server hello");
2137 ret = DoServerHello(ssl, input, inOutIdx, size);
2140 case certificate_request:
2141 CYASSL_MSG("processing certificate request");
2142 ret = DoCertificateRequest(ssl, input, inOutIdx);
2145 case server_key_exchange:
2146 CYASSL_MSG("processing server key exchange");
2147 ret = DoServerKeyExchange(ssl, input, inOutIdx);
2152 CYASSL_MSG("processing certificate");
2153 ret = DoCertificate(ssl, input, inOutIdx);
2156 case server_hello_done:
2157 CYASSL_MSG("processing server hello done");
2158 #ifdef CYASSL_CALLBACKS
2160 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
2162 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
2164 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
2168 CYASSL_MSG("processing finished");
2169 ret = DoFinished(ssl, input, inOutIdx, NO_SNIFF);
2172 #ifndef NO_CYASSL_SERVER
2174 CYASSL_MSG("processing client hello");
2175 ret = DoClientHello(ssl, input, inOutIdx, totalSz, size);
2178 case client_key_exchange:
2179 CYASSL_MSG("processing client key exchange");
2180 ret = DoClientKeyExchange(ssl, input, inOutIdx);
2183 case certificate_verify:
2184 CYASSL_MSG("processing certificate verify");
2185 ret = DoCertificateVerify(ssl, input, inOutIdx, totalSz);
2191 CYASSL_MSG("Unknown handshake message type");
2192 ret = UNKNOWN_HANDSHAKE_TYPE;
2195 CYASSL_LEAVE("DoHandShakeMsg()", ret);
2200 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
2203 return ssl->keys.peer_sequence_number++;
2205 return ssl->keys.sequence_number++;
2209 static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
2211 switch (ssl->specs.bulk_cipher_algorithm) {
2214 Arc4Process(&ssl->encrypt.arc4, out, input, sz);
2220 Des3_CbcEncrypt(&ssl->encrypt.des3, out, input, sz);
2227 if ((word)input % 16) {
2228 byte buffer[MAX_RECORD_SIZE + MAX_COMP_EXTRA+MAX_MSG_EXTRA];
2229 XMEMCPY(buffer, input, sz);
2230 AesCbcEncrypt(&ssl->encrypt.aes, buffer, buffer, sz);
2231 XMEMCPY(out, buffer, sz);
2235 AesCbcEncrypt(&ssl->encrypt.aes, out, input, sz);
2242 byte additional[AES_BLOCK_SIZE];
2244 XMEMSET(additional, 0, AES_BLOCK_SIZE);
2246 /* sequence number field is 64-bits, we only use 32-bits */
2247 c32toa(GetSEQIncrement(ssl, 0),
2248 additional + AEAD_SEQ_OFFSET);
2250 /* Store the type, version. Unfortunately, they are in
2251 * the input buffer ahead of the plaintext. */
2252 XMEMCPY(additional + AEAD_TYPE_OFFSET, input - 5, 3);
2254 /* Store the length of the plain text minus the explicit
2255 * IV length minus the authentication tag size. */
2256 c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
2257 additional + AEAD_LEN_OFFSET);
2258 AesGcmEncrypt(&ssl->encrypt.aes,
2259 out + AES_GCM_EXP_IV_SZ, input + AES_GCM_EXP_IV_SZ,
2260 sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
2261 out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
2262 additional, AEAD_AUTH_DATA_SZ);
2263 AesGcmIncExpIV(&ssl->encrypt.aes);
2270 Hc128_Process(&ssl->encrypt.hc128, out, input, sz);
2276 RabbitProcess(&ssl->encrypt.rabbit, out, input, sz);
2281 CYASSL_MSG("CyaSSL Encrypt programming error");
2286 static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
2289 switch (ssl->specs.bulk_cipher_algorithm) {
2292 Arc4Process(&ssl->decrypt.arc4, plain, input, sz);
2298 Des3_CbcDecrypt(&ssl->decrypt.des3, plain, input, sz);
2304 AesCbcDecrypt(&ssl->decrypt.aes, plain, input, sz);
2311 byte additional[AES_BLOCK_SIZE];
2313 AesGcmSetExpIV(&ssl->decrypt.aes, input);
2314 XMEMSET(additional, 0, AES_BLOCK_SIZE);
2316 /* sequence number field is 64-bits, we only use 32-bits */
2317 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
2319 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
2320 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.version.major;
2321 additional[AEAD_VMIN_OFFSET] = ssl->curRL.version.minor;
2323 c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
2324 additional + AEAD_LEN_OFFSET);
2325 if (AesGcmDecrypt(&ssl->decrypt.aes,
2326 plain + AES_GCM_EXP_IV_SZ,
2327 input + AES_GCM_EXP_IV_SZ,
2328 sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
2329 input + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
2330 additional, AEAD_AUTH_DATA_SZ) < 0) {
2331 SendAlert(ssl, alert_fatal, bad_record_mac);
2332 return VERIFY_MAC_ERROR;
2340 Hc128_Process(&ssl->decrypt.hc128, plain, input, sz);
2346 RabbitProcess(&ssl->decrypt.rabbit, plain, input, sz);
2351 CYASSL_MSG("CyaSSL Decrypt programming error");
2357 /* decrypt input message in place */
2358 static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx)
2360 int decryptResult = Decrypt(ssl, input, input, sz);
2362 if (decryptResult == 0)
2364 ssl->keys.encryptSz = sz;
2365 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
2366 *idx += ssl->specs.block_size; /* go past TLSv1.1 IV */
2367 if (ssl->specs.cipher_type == aead)
2368 *idx += AES_GCM_EXP_IV_SZ;
2371 return decryptResult;
2375 int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
2377 word32 msgSz = ssl->keys.encryptSz;
2381 digestSz = ssl->specs.hash_size;
2384 byte* rawData = input + idx; /* keep current for hmac */
2386 byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
2389 byte verify[SHA256_DIGEST_SIZE];
2392 if (ssl->specs.cipher_type == block) {
2393 if (ssl->options.tls1_1)
2394 ivExtra = ssl->specs.block_size;
2395 pad = *(input + idx + msgSz - ivExtra - 1);
2398 if (ssl->specs.cipher_type == aead) {
2399 ivExtra = AES_GCM_EXP_IV_SZ;
2400 digestSz = AEAD_AUTH_TAG_SZ;
2403 dataSz = msgSz - ivExtra - digestSz - pad - padByte;
2405 CYASSL_MSG("App data buffer error, malicious input?");
2406 return BUFFER_ERROR;
2411 int rawSz = dataSz; /* keep raw size for hmac */
2413 if (ssl->specs.cipher_type != aead)
2414 ssl->hmac(ssl, verify, rawData, rawSz, application_data, 1);
2417 if (ssl->options.usingCompression) {
2418 dataSz = DeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
2419 if (dataSz < 0) return dataSz;
2423 if (ssl->options.usingCompression)
2428 ssl->buffers.clearOutputBuffer.buffer = rawData;
2429 ssl->buffers.clearOutputBuffer.length = dataSz;
2432 /* read mac and fill */
2442 if (ssl->specs.cipher_type != aead && XMEMCMP(mac, verify, digestSz)) {
2443 CYASSL_MSG("App data verify mac error");
2444 return VERIFY_MAC_ERROR;
2448 GetSEQIncrement(ssl, 1); /* even though no data, increment verify */
2451 /* decompress could be bigger, overwrite after verify */
2452 if (ssl->options.usingCompression)
2453 XMEMMOVE(rawData, decomp, dataSz);
2461 /* process alert, return level */
2462 static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type)
2466 #ifdef CYASSL_CALLBACKS
2468 AddPacketName("Alert", &ssl->handShakeInfo);
2470 /* add record header back on to info + 2 byte level, data */
2471 AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
2472 RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
2474 level = input[(*inOutIdx)++];
2475 *type = (int)input[(*inOutIdx)++];
2477 CYASSL_MSG("Got alert");
2478 if (*type == close_notify) {
2479 CYASSL_MSG(" close notify");
2480 ssl->options.closeNotify = 1;
2482 CYASSL_ERROR(*type);
2484 if (ssl->keys.encryptionOn) {
2485 if (ssl->specs.cipher_type != aead) {
2486 int aSz = ALERT_SIZE;
2488 byte verify[SHA256_DIGEST_SIZE];
2489 int padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
2491 ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
2493 /* read mac and fill */
2494 mac = input + *inOutIdx;
2495 *inOutIdx += (ssl->specs.hash_size + padSz);
2498 if (XMEMCMP(mac, verify, ssl->specs.hash_size)) {
2499 CYASSL_MSG(" alert verify mac error");
2500 return VERIFY_MAC_ERROR;
2504 *inOutIdx += AEAD_AUTH_TAG_SZ;
2511 static int GetInputData(CYASSL *ssl, word32 size)
2519 /* check max input length */
2520 usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
2521 maxLength = ssl->buffers.inputBuffer.bufferSize - usedLength;
2522 inSz = (int)(size - usedLength); /* from last partial read */
2525 if (ssl->options.dtls)
2526 inSz = MAX_MTU; /* read ahead up to MTU */
2529 if (inSz > maxLength) {
2530 if (GrowInputBuffer(ssl, size, usedLength) < 0)
2535 return BUFFER_ERROR;
2537 /* Put buffer data at start if not there */
2538 if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
2539 XMEMMOVE(ssl->buffers.inputBuffer.buffer,
2540 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
2543 /* remove processed data */
2544 ssl->buffers.inputBuffer.idx = 0;
2545 ssl->buffers.inputBuffer.length = usedLength;
2547 /* read data from network */
2550 ssl->buffers.inputBuffer.buffer +
2551 ssl->buffers.inputBuffer.length,
2554 return SOCKET_ERROR_E;
2556 if (in == WANT_READ)
2559 ssl->buffers.inputBuffer.length += in;
2562 } while (ssl->buffers.inputBuffer.length < size);
2567 /* process input requests, return 0 is done, 1 is call again to complete, and
2568 negative number is error */
2569 int ProcessReply(CYASSL* ssl)
2571 int ret, type, readSz;
2572 word32 startIdx = 0;
2573 #ifndef NO_CYASSL_SERVER
2581 switch ((processReply)ssl->options.processReply) {
2583 /* in the CYASSL_SERVER case, get the first byte for detecting
2584 * old client hello */
2587 readSz = RECORD_HEADER_SZ;
2590 if (ssl->options.dtls)
2591 readSz = DTLS_RECORD_HEADER_SZ;
2594 /* get header or return error */
2595 if (!ssl->options.dtls) {
2596 if ((ret = GetInputData(ssl, readSz)) < 0)
2600 /* read ahead may already have header */
2601 used = ssl->buffers.inputBuffer.length -
2602 ssl->buffers.inputBuffer.idx;
2604 if ((ret = GetInputData(ssl, readSz)) < 0)
2609 #ifndef NO_CYASSL_SERVER
2611 /* see if sending SSLv2 client hello */
2612 if ( ssl->options.side == SERVER_END &&
2613 ssl->options.clientState == NULL_STATE &&
2614 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
2616 ssl->options.processReply = runProcessOldClientHello;
2618 /* how many bytes need ProcessOldClientHello */
2620 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
2622 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
2623 ssl->curSize = ((b0 & 0x7f) << 8) | b1;
2626 ssl->options.processReply = getRecordLayerHeader;
2630 /* in the CYASSL_SERVER case, run the old client hello */
2631 case runProcessOldClientHello:
2633 /* get sz bytes or return error */
2634 if (!ssl->options.dtls) {
2635 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
2639 /* read ahead may already have */
2640 used = ssl->buffers.inputBuffer.length -
2641 ssl->buffers.inputBuffer.idx;
2642 if (used < ssl->curSize)
2643 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
2645 #endif /* CYASSL_DTLS */
2648 ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
2649 &ssl->buffers.inputBuffer.idx,
2650 ssl->buffers.inputBuffer.length -
2651 ssl->buffers.inputBuffer.idx,
2656 else if (ssl->buffers.inputBuffer.idx ==
2657 ssl->buffers.inputBuffer.length) {
2658 ssl->options.processReply = doProcessInit;
2662 #endif /* NO_CYASSL_SERVER */
2664 /* get the record layer header */
2665 case getRecordLayerHeader:
2667 ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
2668 &ssl->buffers.inputBuffer.idx,
2669 &ssl->curRL, &ssl->curSize);
2673 ssl->options.processReply = getData;
2675 /* retrieve record layer data */
2678 /* get sz bytes or return error */
2679 if (!ssl->options.dtls) {
2680 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
2684 /* read ahead may already have */
2685 used = ssl->buffers.inputBuffer.length -
2686 ssl->buffers.inputBuffer.idx;
2687 if (used < ssl->curSize)
2688 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
2693 ssl->options.processReply = runProcessingOneMessage;
2694 startIdx = ssl->buffers.inputBuffer.idx; /* in case > 1 msg per */
2696 /* the record layer is here */
2697 case runProcessingOneMessage:
2699 if (ssl->keys.encryptionOn)
2700 if (DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer +
2701 ssl->buffers.inputBuffer.idx,
2703 &ssl->buffers.inputBuffer.idx) < 0)
2704 return DECRYPT_ERROR;
2706 CYASSL_MSG("received record layer msg");
2708 switch (ssl->curRL.type) {
2710 /* debugging in DoHandShakeMsg */
2711 if ((ret = DoHandShakeMsg(ssl,
2712 ssl->buffers.inputBuffer.buffer,
2713 &ssl->buffers.inputBuffer.idx,
2714 ssl->buffers.inputBuffer.length))
2719 case change_cipher_spec:
2720 CYASSL_MSG("got CHANGE CIPHER SPEC");
2721 #ifdef CYASSL_CALLBACKS
2723 AddPacketName("ChangeCipher", &ssl->handShakeInfo);
2724 /* add record header back on info */
2725 if (ssl->toInfoOn) {
2726 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
2727 ssl->buffers.inputBuffer.buffer +
2728 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
2729 1 + RECORD_HEADER_SZ, ssl->heap);
2730 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
2733 ssl->buffers.inputBuffer.idx++;
2734 ssl->keys.encryptionOn = 1;
2737 if (ssl->options.dtls)
2738 ssl->keys.dtls_peer_epoch++;
2742 if (ssl->options.usingCompression)
2743 if ( (ret = InitStreams(ssl)) != 0)
2746 if (ssl->options.resuming && ssl->options.side ==
2748 BuildFinished(ssl, &ssl->verifyHashes, server);
2749 else if (!ssl->options.resuming && ssl->options.side ==
2751 BuildFinished(ssl, &ssl->verifyHashes, client);
2754 case application_data:
2755 CYASSL_MSG("got app DATA");
2756 if ((ret = DoApplicationData(ssl,
2757 ssl->buffers.inputBuffer.buffer,
2758 &ssl->buffers.inputBuffer.idx))
2766 CYASSL_MSG("got ALERT!");
2767 if (DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
2768 &ssl->buffers.inputBuffer.idx, &type) == alert_fatal)
2771 /* catch warnings that are handled as errors */
2772 if (type == close_notify)
2773 return ssl->error = ZERO_RETURN;
2775 if (type == decrypt_error)
2780 CYASSL_ERROR(UNKNOWN_RECORD_TYPE);
2781 return UNKNOWN_RECORD_TYPE;
2784 ssl->options.processReply = doProcessInit;
2786 /* input exhausted? */
2787 if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
2789 /* more messages per record */
2790 else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
2791 CYASSL_MSG("More messages in record");
2793 /* read-ahead but dtls doesn't bundle messages per record */
2794 if (ssl->options.dtls) {
2795 ssl->options.processReply = doProcessInit;
2799 ssl->options.processReply = runProcessingOneMessage;
2804 CYASSL_MSG("More records in input");
2805 ssl->options.processReply = doProcessInit;
2809 CYASSL_MSG("Bad process input state, programming error");
2810 return INPUT_CASE_ERROR;
2816 int SendChangeCipher(CYASSL* ssl)
2819 int sendSz = RECORD_HEADER_SZ + ENUM_LEN;
2820 int idx = RECORD_HEADER_SZ;
2824 if (ssl->options.dtls) {
2825 sendSz += DTLS_RECORD_EXTRA;
2826 idx += DTLS_RECORD_EXTRA;
2830 /* check for avalaible size */
2831 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
2834 /* get ouput buffer */
2835 output = ssl->buffers.outputBuffer.buffer +
2836 ssl->buffers.outputBuffer.length;
2838 AddRecordHeader(output, 1, change_cipher_spec, ssl);
2840 output[idx] = 1; /* turn it on */
2842 #ifdef CYASSL_CALLBACKS
2843 if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
2845 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
2848 ssl->buffers.outputBuffer.length += sendSz;
2850 if (ssl->options.groupMessages)
2853 return SendBuffered(ssl);
2857 static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify)
2859 if ( (ssl->options.side == CLIENT_END && !verify) ||
2860 (ssl->options.side == SERVER_END && verify) )
2861 return ssl->keys.client_write_MAC_secret;
2863 return ssl->keys.server_write_MAC_secret;
2867 static void Hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
2868 int content, int verify)
2870 byte result[SHA256_DIGEST_SIZE]; /* max possible sizes */
2871 word32 digestSz = ssl->specs.hash_size; /* actual sizes */
2872 word32 padSz = ssl->specs.pad_size;
2878 byte seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 };
2879 byte conLen[ENUM_LEN + LENGTH_SZ]; /* content & length */
2880 const byte* macSecret = GetMacSecret(ssl, verify);
2882 conLen[0] = (byte)content;
2883 c16toa((word16)sz, &conLen[ENUM_LEN]);
2884 c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
2886 if (ssl->specs.mac_algorithm == md5_mac) {
2889 Md5Update(&md5, macSecret, digestSz);
2890 Md5Update(&md5, PAD1, padSz);
2891 Md5Update(&md5, seq, SEQ_SZ);
2892 Md5Update(&md5, conLen, sizeof(conLen));
2894 Md5Update(&md5, in, sz);
2895 Md5Final(&md5, result);
2897 Md5Update(&md5, macSecret, digestSz);
2898 Md5Update(&md5, PAD2, padSz);
2899 Md5Update(&md5, result, digestSz);
2900 Md5Final(&md5, digest);
2905 ShaUpdate(&sha, macSecret, digestSz);
2906 ShaUpdate(&sha, PAD1, padSz);
2907 ShaUpdate(&sha, seq, SEQ_SZ);
2908 ShaUpdate(&sha, conLen, sizeof(conLen));
2910 ShaUpdate(&sha, in, sz);
2911 ShaFinal(&sha, result);
2913 ShaUpdate(&sha, macSecret, digestSz);
2914 ShaUpdate(&sha, PAD2, padSz);
2915 ShaUpdate(&sha, result, digestSz);
2916 ShaFinal(&sha, digest);
2921 static void BuildMD5_CertVerify(CYASSL* ssl, byte* digest)
2923 byte md5_result[MD5_DIGEST_SIZE];
2925 /* make md5 inner */
2926 Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
2927 Md5Update(&ssl->hashMd5, PAD1, PAD_MD5);
2928 Md5Final(&ssl->hashMd5, md5_result);
2930 /* make md5 outer */
2931 Md5Update(&ssl->hashMd5, ssl->arrays.masterSecret, SECRET_LEN);
2932 Md5Update(&ssl->hashMd5, PAD2, PAD_MD5);
2933 Md5Update(&ssl->hashMd5, md5_result, MD5_DIGEST_SIZE);
2935 Md5Final(&ssl->hashMd5, digest);
2939 static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest)
2941 byte sha_result[SHA_DIGEST_SIZE];
2943 /* make sha inner */
2944 ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
2945 ShaUpdate(&ssl->hashSha, PAD1, PAD_SHA);
2946 ShaFinal(&ssl->hashSha, sha_result);
2948 /* make sha outer */
2949 ShaUpdate(&ssl->hashSha, ssl->arrays.masterSecret, SECRET_LEN);
2950 ShaUpdate(&ssl->hashSha, PAD2, PAD_SHA);
2951 ShaUpdate(&ssl->hashSha, sha_result, SHA_DIGEST_SIZE);
2953 ShaFinal(&ssl->hashSha, digest);
2957 static void BuildCertHashes(CYASSL* ssl, Hashes* hashes)
2959 /* store current states, building requires get_digest which resets state */
2960 Md5 md5 = ssl->hashMd5;
2961 Sha sha = ssl->hashSha;
2962 #ifndef NO_SHA256 /* for possible future changes */
2964 InitSha256(&sha256);
2965 if (IsAtLeastTLSv1_2(ssl))
2966 sha256 = ssl->hashSha256;
2969 if (ssl->options.tls) {
2970 Md5Final(&ssl->hashMd5, hashes->md5);
2971 ShaFinal(&ssl->hashSha, hashes->sha);
2974 BuildMD5_CertVerify(ssl, hashes->md5);
2975 BuildSHA_CertVerify(ssl, hashes->sha);
2982 if (IsAtLeastTLSv1_2(ssl))
2983 ssl->hashSha256 = sha256;
2988 /* Build SSL Message, encrypted */
2989 static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
2992 word32 digestSz = ssl->specs.hash_size;
2993 word32 sz = RECORD_HEADER_SZ + inSz + digestSz;
2995 word32 idx = RECORD_HEADER_SZ;
2996 word32 ivSz = 0; /* TLSv1.1 IV */
2997 word32 headerSz = RECORD_HEADER_SZ;
2999 byte iv[AES_BLOCK_SIZE]; /* max size */
3002 if (ssl->options.dtls) {
3003 sz += DTLS_RECORD_EXTRA;
3004 idx += DTLS_RECORD_EXTRA;
3005 headerSz += DTLS_RECORD_EXTRA;
3009 if (ssl->specs.cipher_type == block) {
3010 word32 blockSz = ssl->specs.block_size;
3011 if (ssl->options.tls1_1) {
3014 RNG_GenerateBlock(&ssl->rng, iv, ivSz);
3016 sz += 1; /* pad byte */
3017 pad = (sz - headerSz) % blockSz;
3018 pad = blockSz - pad;
3023 if (ssl->specs.cipher_type == aead) {
3024 ivSz = AES_GCM_EXP_IV_SZ;
3025 sz += (ivSz + 16 - digestSz);
3026 AesGcmGetExpIV(&ssl->encrypt.aes, iv);
3029 size = (word16)(sz - headerSz); /* include mac and digest */
3030 AddRecordHeader(output, size, (byte)type, ssl);
3032 /* write to output */
3034 XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
3037 XMEMCPY(output + idx, input, inSz);
3040 if (type == handshake)
3041 HashOutput(ssl, output, headerSz + inSz, ivSz);
3042 if (ssl->specs.cipher_type != aead) {
3043 ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
3047 if (ssl->specs.cipher_type == block)
3048 for (i = 0; i <= pad; i++)
3049 output[idx++] = (byte)pad; /* pad byte gets pad value too */
3051 Encrypt(ssl, output + headerSz, output + headerSz, size);
3057 int SendFinished(CYASSL* ssl)
3060 finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
3062 byte input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ]; /* max */
3066 int headerSz = HANDSHAKE_HEADER_SZ;
3070 if (ssl->options.dtls) {
3071 headerSz += DTLS_HANDSHAKE_EXTRA;
3072 ssl->keys.dtls_epoch++;
3073 ssl->keys.dtls_sequence_number = 0; /* reset after epoch change */
3077 /* check for avalaible size */
3078 if ((ret = CheckAvalaibleSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0)
3081 /* get ouput buffer */
3082 output = ssl->buffers.outputBuffer.buffer +
3083 ssl->buffers.outputBuffer.length;
3085 AddHandShakeHeader(input, finishedSz, finished, ssl);
3087 /* make finished hashes */
3088 hashes = (Hashes*)&input[headerSz];
3089 BuildFinished(ssl, hashes, ssl->options.side == CLIENT_END ? client :
3092 if ( (sendSz = BuildMessage(ssl, output, input, headerSz +
3093 finishedSz, handshake)) < 0)
3094 return BUILD_MSG_ERROR;
3096 if (!ssl->options.resuming) {
3097 #ifndef NO_SESSION_CACHE
3098 AddSession(ssl); /* just try */
3100 if (ssl->options.side == CLIENT_END)
3101 BuildFinished(ssl, &ssl->verifyHashes, server);
3103 ssl->options.handShakeState = HANDSHAKE_DONE;
3106 if (ssl->options.side == CLIENT_END)
3107 ssl->options.handShakeState = HANDSHAKE_DONE;
3109 BuildFinished(ssl, &ssl->verifyHashes, client);
3112 #ifdef CYASSL_CALLBACKS
3113 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
3115 AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
3119 ssl->buffers.outputBuffer.length += sendSz;
3121 return SendBuffered(ssl);
3125 int SendCertificate(CYASSL* ssl)
3127 int sendSz, length, ret = 0;
3128 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
3129 word32 certSz, listSz;
3132 if (ssl->options.usingPSK_cipher) return 0; /* not needed */
3134 if (ssl->options.sendVerify == SEND_BLANK_CERT) {
3136 length = CERT_HEADER_SZ;
3140 certSz = ssl->buffers.certificate.length;
3141 /* list + cert size */
3142 length = certSz + 2 * CERT_HEADER_SZ;
3143 listSz = certSz + CERT_HEADER_SZ;
3145 /* may need to send rest of chain, already has leading size(s) */
3146 if (ssl->buffers.certChain.buffer) {
3147 length += ssl->buffers.certChain.length;
3148 listSz += ssl->buffers.certChain.length;
3151 sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
3154 if (ssl->options.dtls) {
3155 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
3156 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
3160 /* check for avalaible size */
3161 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
3164 /* get ouput buffer */
3165 output = ssl->buffers.outputBuffer.buffer +
3166 ssl->buffers.outputBuffer.length;
3168 AddHeaders(output, length, certificate, ssl);
3171 c32to24(listSz, output + i);
3172 i += CERT_HEADER_SZ;
3176 c32to24(certSz, output + i);
3177 i += CERT_HEADER_SZ;
3178 XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
3181 /* send rest of chain? */
3182 if (ssl->buffers.certChain.buffer) {
3183 XMEMCPY(output + i, ssl->buffers.certChain.buffer,
3184 ssl->buffers.certChain.length);
3185 i += ssl->buffers.certChain.length;
3188 HashOutput(ssl, output, sendSz, 0);
3189 #ifdef CYASSL_CALLBACKS
3190 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
3192 AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
3196 if (ssl->options.side == SERVER_END)
3197 ssl->options.serverState = SERVER_CERT_COMPLETE;
3199 ssl->buffers.outputBuffer.length += sendSz;
3200 if (ssl->options.groupMessages)
3203 return SendBuffered(ssl);
3207 int SendCertificateRequest(CYASSL* ssl)
3212 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
3214 int typeTotal = 1; /* only rsa for now */
3215 int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */
3217 if (IsAtLeastTLSv1_2(ssl))
3218 reqSz += LENGTH_SZ + HASH_SIG_SIZE;
3220 if (ssl->options.usingPSK_cipher) return 0; /* not needed */
3222 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
3225 if (ssl->options.dtls) {
3226 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
3227 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
3230 /* check for avalaible size */
3231 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
3234 /* get ouput buffer */
3235 output = ssl->buffers.outputBuffer.buffer +
3236 ssl->buffers.outputBuffer.length;
3238 AddHeaders(output, reqSz, certificate_request, ssl);
3240 /* write to output */
3241 output[i++] = (byte)typeTotal; /* # of types */
3242 output[i++] = rsa_sign;
3244 /* supported hash/sig */
3245 if (IsAtLeastTLSv1_2(ssl)) {
3246 c16toa(HASH_SIG_SIZE, &output[i]);
3249 output[i++] = sha_mac; /* hash */
3250 output[i++] = rsa_sa_algo; /* sig */
3253 c16toa(0, &output[i]); /* auth's */
3256 HashOutput(ssl, output, sendSz, 0);
3258 #ifdef CYASSL_CALLBACKS
3260 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
3262 AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
3265 ssl->buffers.outputBuffer.length += sendSz;
3266 if (ssl->options.groupMessages)
3269 return SendBuffered(ssl);
3273 int SendData(CYASSL* ssl, const void* data, int sz)
3275 int sent = 0, /* plainText size */
3279 if (ssl->error == WANT_WRITE)
3282 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
3284 CYASSL_MSG("handshake not complete, trying to finish");
3285 if ( (err = CyaSSL_negotiate(ssl)) != 0)
3289 /* last time system socket output buffer was full, try again to send */
3290 if (ssl->buffers.outputBuffer.length > 0) {
3291 CYASSL_MSG("output buffer was full, trying to send again");
3292 if ( (ssl->error = SendBuffered(ssl)) < 0) {
3293 CYASSL_ERROR(ssl->error);
3294 if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
3295 return 0; /* peer reset */
3299 /* advance sent to previous sent + plain size just sent */
3300 sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
3301 CYASSL_MSG("sent write buffered data");
3306 int len = min(sz - sent, OUTPUT_RECORD_SIZE);
3308 byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
3309 int buffSz = len; /* may switch on comp */
3311 byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
3314 if (sent == sz) break;
3317 if (ssl->options.dtls) {
3318 len = min(len, MAX_UDP_SIZE);
3323 /* check for avalaible size */
3324 if ((ret = CheckAvalaibleSize(ssl, len + COMP_EXTRA +
3325 MAX_MSG_EXTRA)) != 0)
3328 /* get ouput buffer */
3329 out = ssl->buffers.outputBuffer.buffer +
3330 ssl->buffers.outputBuffer.length;
3333 if (ssl->options.usingCompression) {
3334 buffSz = Compress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
3341 sendSz = BuildMessage(ssl, out, sendBuffer, buffSz,
3344 ssl->buffers.outputBuffer.length += sendSz;
3346 if ( (ret = SendBuffered(ssl)) < 0) {
3348 /* store for next call if WANT_WRITE or user embedSend() that
3349 doesn't present like WANT_WRITE */
3350 ssl->buffers.plainSz = len;
3351 ssl->buffers.prevSent = sent;
3352 if (ret == SOCKET_ERROR_E && ssl->options.connReset)
3353 return 0; /* peer reset */
3354 return ssl->error = ret;
3359 /* only one message per attempt */
3360 if (ssl->options.partialWrite == 1) {
3361 CYASSL_MSG("Paritial Write on, only sending one record");
3369 /* process input data */
3370 int ReceiveData(CYASSL* ssl, byte* output, int sz)
3374 CYASSL_ENTER("ReceiveData()");
3376 if (ssl->error == WANT_READ)
3379 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
3381 CYASSL_MSG("Handshake not complete, trying to finish");
3382 if ( (err = CyaSSL_negotiate(ssl)) != 0)
3386 while (ssl->buffers.clearOutputBuffer.length == 0)
3387 if ( (ssl->error = ProcessReply(ssl)) < 0) {
3388 CYASSL_ERROR(ssl->error);
3389 if (ssl->error == ZERO_RETURN) {
3390 CYASSL_MSG("Zero return, no more data coming");
3391 ssl->options.isClosed = 1;
3392 return 0; /* no more data coming */
3394 if (ssl->error == SOCKET_ERROR_E) {
3395 if (ssl->options.connReset || ssl->options.isClosed) {
3396 CYASSL_MSG("Peer reset or closed, connection done");
3397 return 0; /* peer reset or closed */
3403 if (sz < (int)ssl->buffers.clearOutputBuffer.length)
3406 size = ssl->buffers.clearOutputBuffer.length;
3408 XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
3409 ssl->buffers.clearOutputBuffer.length -= size;
3410 ssl->buffers.clearOutputBuffer.buffer += size;
3412 if (ssl->buffers.clearOutputBuffer.length == 0 &&
3413 ssl->buffers.inputBuffer.dynamicFlag)
3414 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
3416 CYASSL_LEAVE("ReceiveData()", size);
3421 /* send alert message */
3422 int SendAlert(CYASSL* ssl, int severity, int type)
3424 byte input[ALERT_SIZE];
3429 /* if sendalert is called again for nonbloking */
3430 if (ssl->options.sendAlertState != 0) {
3431 ret = SendBuffered(ssl);
3433 ssl->options.sendAlertState = 0;
3437 /* check for avalaible size */
3438 if ((ret = CheckAvalaibleSize(ssl, ALERT_SIZE + MAX_MSG_EXTRA)) != 0)
3441 /* get ouput buffer */
3442 output = ssl->buffers.outputBuffer.buffer +
3443 ssl->buffers.outputBuffer.length;
3445 input[0] = (byte)severity;
3446 input[1] = (byte)type;
3448 if (ssl->keys.encryptionOn)
3449 sendSz = BuildMessage(ssl, output, input, ALERT_SIZE, alert);
3451 RecordLayerHeader *const rl = (RecordLayerHeader*)output;
3453 rl->version = ssl->version;
3454 c16toa(ALERT_SIZE, rl->length);
3456 XMEMCPY(output + RECORD_HEADER_SZ, input, ALERT_SIZE);
3457 sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
3460 #ifdef CYASSL_CALLBACKS
3462 AddPacketName("Alert", &ssl->handShakeInfo);
3464 AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
3467 ssl->buffers.outputBuffer.length += sendSz;
3468 ssl->options.sendAlertState = 1;
3470 return SendBuffered(ssl);
3475 void SetErrorString(int error, char* str)
3477 const int max = MAX_ERROR_SZ; /* shorthand */
3479 #ifdef NO_ERROR_STRINGS
3481 XSTRNCPY(str, "no support for error strings built in", max);
3485 /* pass to CTaoCrypt */
3486 if (error < MAX_CODE_E && error > MIN_CODE_E) {
3487 CTaoCryptErrorString(error, str);
3493 case UNSUPPORTED_SUITE :
3494 XSTRNCPY(str, "unsupported cipher suite", max);
3497 case INPUT_CASE_ERROR :
3498 XSTRNCPY(str, "input state error", max);
3502 XSTRNCPY(str, "bad index to key rounds", max);
3506 XSTRNCPY(str, "out of memory", max);
3509 case VERIFY_FINISHED_ERROR :
3510 XSTRNCPY(str, "verify problem on finished", max);
3513 case VERIFY_MAC_ERROR :
3514 XSTRNCPY(str, "verify mac problem", max);
3518 XSTRNCPY(str, "parse error on header", max);
3522 XSTRNCPY(str, "wrong client/server type", max);
3526 XSTRNCPY(str, "peer didn't send cert", max);
3529 case UNKNOWN_HANDSHAKE_TYPE :
3530 XSTRNCPY(str, "weird handshake type", max);
3533 case SOCKET_ERROR_E :
3534 XSTRNCPY(str, "error state on socket", max);
3537 case SOCKET_NODATA :
3538 XSTRNCPY(str, "expected data, not there", max);
3541 case INCOMPLETE_DATA :
3542 XSTRNCPY(str, "don't have enough data to complete task", max);
3545 case UNKNOWN_RECORD_TYPE :
3546 XSTRNCPY(str, "unknown type in record hdr", max);
3549 case DECRYPT_ERROR :
3550 XSTRNCPY(str, "error during decryption", max);
3554 XSTRNCPY(str, "revcd alert fatal error", max);
3557 case ENCRYPT_ERROR :
3558 XSTRNCPY(str, "error during encryption", max);
3562 XSTRNCPY(str, "fread problem", max);
3566 XSTRNCPY(str, "need peer's key", max);
3569 case NO_PRIVATE_KEY :
3570 XSTRNCPY(str, "need the private key", max);
3574 XSTRNCPY(str, "server missing DH params", max);
3577 case RSA_PRIVATE_ERROR :
3578 XSTRNCPY(str, "error during rsa priv op", max);
3581 case MATCH_SUITE_ERROR :
3582 XSTRNCPY(str, "can't match cipher suite", max);
3585 case BUILD_MSG_ERROR :
3586 XSTRNCPY(str, "build message failure", max);
3590 XSTRNCPY(str, "client hello malformed", max);
3593 case DOMAIN_NAME_MISMATCH :
3594 XSTRNCPY(str, "peer subject name mismatch", max);
3598 XSTRNCPY(str, "non-blocking socket wants data to be read", max);
3601 case NOT_READY_ERROR :
3602 XSTRNCPY(str, "handshake layer not ready yet, complete first", max);
3605 case PMS_VERSION_ERROR :
3606 XSTRNCPY(str, "premaster secret version mismatch error", max);
3609 case VERSION_ERROR :
3610 XSTRNCPY(str, "record layer version error", max);
3614 XSTRNCPY(str, "non-blocking socket write buffer full", max);
3618 XSTRNCPY(str, "malformed buffer input error", max);
3621 case VERIFY_CERT_ERROR :
3622 XSTRNCPY(str, "verify problem on certificate", max);
3625 case VERIFY_SIGN_ERROR :
3626 XSTRNCPY(str, "verify problem based on signature", max);
3629 case CLIENT_ID_ERROR :
3630 XSTRNCPY(str, "psk client identity error", max);
3633 case SERVER_HINT_ERROR:
3634 XSTRNCPY(str, "psk server hint error", max);
3638 XSTRNCPY(str, "psk key callback error", max);
3641 case NTRU_KEY_ERROR:
3642 XSTRNCPY(str, "NTRU key error", max);
3645 case NTRU_DRBG_ERROR:
3646 XSTRNCPY(str, "NTRU drbg error", max);
3649 case NTRU_ENCRYPT_ERROR:
3650 XSTRNCPY(str, "NTRU encrypt error", max);
3653 case NTRU_DECRYPT_ERROR:
3654 XSTRNCPY(str, "NTRU decrypt error", max);
3657 case ZLIB_INIT_ERROR:
3658 XSTRNCPY(str, "zlib init error", max);
3661 case ZLIB_COMPRESS_ERROR:
3662 XSTRNCPY(str, "zlib compress error", max);
3665 case ZLIB_DECOMPRESS_ERROR:
3666 XSTRNCPY(str, "zlib decompress error", max);
3670 XSTRNCPY(str, "gettimeofday() error", max);
3673 case GETITIMER_ERROR:
3674 XSTRNCPY(str, "getitimer() error", max);
3678 XSTRNCPY(str, "sigaction() error", max);
3681 case SETITIMER_ERROR:
3682 XSTRNCPY(str, "setitimer() error", max);
3686 XSTRNCPY(str, "record layer length error", max);
3689 case PEER_KEY_ERROR:
3690 XSTRNCPY(str, "cant decode peer key", max);
3694 XSTRNCPY(str, "peer sent close notify alert", max);
3697 case ECC_CURVETYPE_ERROR:
3698 XSTRNCPY(str, "Bad ECC Curve Type or unsupported", max);
3701 case ECC_CURVE_ERROR:
3702 XSTRNCPY(str, "Bad ECC Curve or unsupported", max);
3705 case ECC_PEERKEY_ERROR:
3706 XSTRNCPY(str, "Bad ECC Peer Key", max);
3709 case ECC_MAKEKEY_ERROR:
3710 XSTRNCPY(str, "ECC Make Key failure", max);
3713 case ECC_EXPORT_ERROR:
3714 XSTRNCPY(str, "ECC Export Key failure", max);
3717 case ECC_SHARED_ERROR:
3718 XSTRNCPY(str, "ECC DHE shared failure", max);
3721 case BAD_MUTEX_ERROR:
3722 XSTRNCPY(str, "Bad mutex, operation failed", max);
3726 XSTRNCPY(str, "Not a CA by basic constraint error", max);
3729 case BAD_PATH_ERROR:
3730 XSTRNCPY(str, "Bad path for opendir error", max);
3733 case BAD_CERT_MANAGER_ERROR:
3734 XSTRNCPY(str, "Bad Cert Manager error", max);
3737 case OCSP_CERT_REVOKED:
3738 XSTRNCPY(str, "OCSP Cert revoked", max);
3741 case CRL_CERT_REVOKED:
3742 XSTRNCPY(str, "CRL Cert revoked", max);
3746 XSTRNCPY(str, "CRL missing, not loaded", max);
3749 case MONITOR_RUNNING_E:
3750 XSTRNCPY(str, "CRL monitor already running", max);
3753 case THREAD_CREATE_E:
3754 XSTRNCPY(str, "Thread creation problem", max);
3758 XSTRNCPY(str, "OCSP need URL", max);
3761 case OCSP_CERT_UNKNOWN:
3762 XSTRNCPY(str, "OCSP Cert unknown", max);
3765 case OCSP_LOOKUP_FAIL:
3766 XSTRNCPY(str, "OCSP Responder lookup fail", max);
3769 case MAX_CHAIN_ERROR:
3770 XSTRNCPY(str, "Maximum Chain Depth Exceeded", max);
3774 XSTRNCPY(str, "DTLS Cookie Error", max);
3778 XSTRNCPY(str, "unknown error number", max);
3781 #endif /* NO_ERROR_STRINGS */
3786 /* be sure to add to cipher_name_idx too !!!! */
3787 const char* const cipher_names[] =
3789 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
3793 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
3797 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
3801 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
3805 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
3809 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
3810 "DHE-RSA-AES128-SHA",
3813 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
3814 "DHE-RSA-AES256-SHA",
3817 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
3818 "PSK-AES128-CBC-SHA",
3821 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
3822 "PSK-AES256-CBC-SHA",
3825 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
3829 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
3833 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
3837 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
3841 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
3842 "NTRU-DES-CBC3-SHA",
3845 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
3849 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
3853 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
3854 "ECDHE-RSA-AES128-SHA",
3857 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
3858 "ECDHE-RSA-AES256-SHA",
3861 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
3862 "ECDHE-ECDSA-AES128-SHA",
3865 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
3866 "ECDHE-ECDSA-AES256-SHA",
3869 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
3870 "ECDHE-RSA-RC4-SHA",
3873 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
3874 "ECDHE-RSA-DES-CBC3-SHA",
3877 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
3878 "ECDHE-ECDSA-RC4-SHA",
3881 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
3882 "ECDHE-ECDSA-DES-CBC3-SHA",
3885 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
3889 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
3893 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
3894 "DHE-RSA-AES128-SHA256",
3897 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
3898 "DHE-RSA-AES256-SHA256",
3901 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
3902 "ECDH-RSA-AES128-SHA",
3905 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
3906 "ECDH-RSA-AES256-SHA",
3909 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
3910 "ECDH-ECDSA-AES128-SHA",
3913 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
3914 "ECDH-ECDSA-AES256-SHA",
3917 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
3921 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
3922 "ECDH-RSA-DES-CBC3-SHA",
3925 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
3926 "ECDH-ECDSA-RC4-SHA",
3929 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
3930 "ECDH-ECDSA-DES-CBC3-SHA",
3933 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
3934 "AES128-GCM-SHA256",
3937 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
3938 "AES256-GCM-SHA384",
3941 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
3942 "DHE-RSA-AES128-GCM-SHA256",
3945 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
3946 "DHE-RSA-AES256-GCM-SHA384",
3949 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
3950 "ECDHE-RSA-AES128-GCM-SHA256",
3953 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
3954 "ECDHE-RSA-AES256-GCM-SHA384",
3957 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
3958 "ECDHE-ECDSA-AES128-GCM-SHA256",
3961 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
3962 "ECDHE-ECDSA-AES256-GCM-SHA384",
3965 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
3966 "ECDH-RSA-AES128-GCM-SHA256",
3969 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
3970 "ECDH-RSA-AES256-GCM-SHA384",
3973 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
3974 "ECDH-ECDSA-AES128-GCM-SHA256",
3977 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
3978 "ECDH-ECDSA-AES256-GCM-SHA384"
3985 /* cipher suite number that matches above name table */
3986 int cipher_name_idx[] =
3989 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
3990 SSL_RSA_WITH_RC4_128_SHA,
3993 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
3994 SSL_RSA_WITH_RC4_128_MD5,
3997 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
3998 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
4001 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
4002 TLS_RSA_WITH_AES_128_CBC_SHA,
4005 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
4006 TLS_RSA_WITH_AES_256_CBC_SHA,
4009 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
4010 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
4013 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
4014 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
4017 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
4018 TLS_PSK_WITH_AES_128_CBC_SHA,
4021 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
4022 TLS_PSK_WITH_AES_256_CBC_SHA,
4025 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
4026 TLS_RSA_WITH_HC_128_CBC_MD5,
4029 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
4030 TLS_RSA_WITH_HC_128_CBC_SHA,
4033 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
4034 TLS_RSA_WITH_RABBIT_CBC_SHA,
4037 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
4038 TLS_NTRU_RSA_WITH_RC4_128_SHA,
4041 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
4042 TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
4045 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
4046 TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
4049 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
4050 TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
4053 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
4054 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
4057 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
4058 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
4061 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
4062 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
4065 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
4066 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
4069 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
4070 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
4073 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
4074 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
4077 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
4078 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
4081 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
4082 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
4085 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
4086 TLS_RSA_WITH_AES_128_CBC_SHA256,
4089 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
4090 TLS_RSA_WITH_AES_256_CBC_SHA256,
4093 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
4094 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
4097 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
4098 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
4101 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
4102 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
4105 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
4106 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
4109 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
4110 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
4113 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
4114 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
4117 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
4118 TLS_ECDH_RSA_WITH_RC4_128_SHA,
4121 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
4122 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
4125 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
4126 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
4129 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
4130 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
4133 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
4134 TLS_RSA_WITH_AES_128_GCM_SHA256,
4137 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
4138 TLS_RSA_WITH_AES_256_GCM_SHA384,
4141 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
4142 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
4145 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
4146 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
4149 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
4150 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
4153 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
4154 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
4157 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
4158 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
4161 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
4162 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
4165 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
4166 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
4169 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
4170 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
4173 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
4174 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
4177 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
4178 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
4184 /* return true if set, else false */
4185 /* only supports full name from cipher_name[] delimited by : */
4186 int SetCipherList(Suites* s, const char* list)
4189 char name[MAX_SUITE_NAME];
4191 char needle[] = ":";
4192 char* haystack = (char*)list;
4195 const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]);
4201 if (*list == 0) return 1; /* CyaSSL default */
4203 if (XSTRNCMP(haystack, "ALL", 3) == 0) return 1; /* CyaSSL defualt */
4208 haystack = XSTRSTR(haystack, needle);
4210 if (!haystack) /* last cipher */
4211 len = min(sizeof(name), XSTRLEN(prev));
4213 len = min(sizeof(name), (word32)(haystack - prev));
4215 XSTRNCPY(name, prev, len);
4216 name[(len == sizeof(name)) ? len - 1 : len] = 0;
4218 for (i = 0; i < suiteSz; i++)
4219 if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
4220 if (XSTRSTR(name, "EC"))
4221 s->suites[idx++] = ECC_BYTE; /* ECC suite */
4223 s->suites[idx++] = 0x00; /* normal */
4224 s->suites[idx++] = (byte)cipher_name_idx[i];
4226 if (!ret) ret = 1; /* found at least one */
4229 if (!haystack) break;
4235 s->suiteSz = (word16)idx;
4242 #ifdef CYASSL_CALLBACKS
4244 /* Initialisze HandShakeInfo */
4245 void InitHandShakeInfo(HandShakeInfo* info)
4249 info->cipherName[0] = 0;
4250 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
4251 info->packetNames[i][0] = 0;
4252 info->numberPackets = 0;
4253 info->negotiationError = 0;
4256 /* Set Final HandShakeInfo parameters */
4257 void FinishHandShakeInfo(HandShakeInfo* info, const CYASSL* ssl)
4260 int sz = sizeof(cipher_name_idx)/sizeof(int);
4262 for (i = 0; i < sz; i++)
4263 if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
4264 if (ssl->options.cipherSuite0 == ECC_BYTE)
4265 continue; /* ECC suites at end */
4266 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
4270 /* error max and min are negative numbers */
4271 if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
4272 info->negotiationError = ssl->error;
4276 /* Add name to info packet names, increase packet name count */
4277 void AddPacketName(const char* name, HandShakeInfo* info)
4279 if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
4280 XSTRNCPY(info->packetNames[info->numberPackets++], name,
4286 /* Initialisze TimeoutInfo */
4287 void InitTimeoutInfo(TimeoutInfo* info)
4291 info->timeoutName[0] = 0;
4294 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
4295 info->packets[i].packetName[0] = 0;
4296 info->packets[i].timestamp.tv_sec = 0;
4297 info->packets[i].timestamp.tv_usec = 0;
4298 info->packets[i].bufferValue = 0;
4299 info->packets[i].valueSz = 0;
4301 info->numberPackets = 0;
4302 info->timeoutValue.tv_sec = 0;
4303 info->timeoutValue.tv_usec = 0;
4307 /* Free TimeoutInfo */
4308 void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
4311 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
4312 if (info->packets[i].bufferValue) {
4313 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
4314 info->packets[i].bufferValue = 0;
4320 /* Add PacketInfo to TimeoutInfo */
4321 void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
4324 if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
4327 /* may add name after */
4329 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
4332 /* add data, put in buffer if bigger than static buffer */
4333 info->packets[info->numberPackets].valueSz = sz;
4334 if (sz < MAX_VALUE_SZ)
4335 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
4337 info->packets[info->numberPackets].bufferValue =
4338 XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
4339 if (!info->packets[info->numberPackets].bufferValue)
4340 /* let next alloc catch, just don't fill, not fatal here */
4341 info->packets[info->numberPackets].valueSz = 0;
4343 XMEMCPY(info->packets[info->numberPackets].bufferValue,
4346 gettimeofday(&currTime, 0);
4347 info->packets[info->numberPackets].timestamp.tv_sec =
4349 info->packets[info->numberPackets].timestamp.tv_usec =
4351 info->numberPackets++;
4356 /* Add packet name to previsouly added packet info */
4357 void AddLateName(const char* name, TimeoutInfo* info)
4359 /* make sure we have a valid previous one */
4360 if (info->numberPackets > 0 && info->numberPackets <
4361 MAX_PACKETS_HANDSHAKE) {
4362 XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
4367 /* Add record header to previsouly added packet info */
4368 void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
4370 /* make sure we have a valid previous one */
4371 if (info->numberPackets > 0 && info->numberPackets <
4372 MAX_PACKETS_HANDSHAKE) {
4373 if (info->packets[info->numberPackets - 1].bufferValue)
4374 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
4377 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
4382 #endif /* CYASSL_CALLBACKS */
4386 /* client only parts */
4387 #ifndef NO_CYASSL_CLIENT
4389 int SendClientHello(CYASSL* ssl)
4392 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
4394 int idSz = ssl->options.resuming ? ID_LEN : 0;
4397 length = sizeof(ProtocolVersion) + RAN_LEN
4399 + ssl->suites.suiteSz + SUITE_LEN
4400 + COMP_LEN + ENUM_LEN;
4402 if (IsAtLeastTLSv1_2(ssl))
4403 length += HELLO_EXT_SZ;
4405 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
4408 if (ssl->options.dtls) {
4409 length += ENUM_LEN; /* cookie */
4410 if (ssl->arrays.cookieSz != 0) length += ssl->arrays.cookieSz;
4411 sendSz = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
4412 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
4416 /* check for avalaible size */
4417 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
4420 /* get ouput buffer */
4421 output = ssl->buffers.outputBuffer.buffer +
4422 ssl->buffers.outputBuffer.length;
4424 AddHeaders(output, length, client_hello, ssl);
4426 /* client hello, first version */
4427 XMEMCPY(output + idx, &ssl->version, sizeof(ProtocolVersion));
4428 idx += sizeof(ProtocolVersion);
4429 ssl->chVersion = ssl->version; /* store in case changed */
4432 if (ssl->options.connectState == CONNECT_BEGIN) {
4433 RNG_GenerateBlock(&ssl->rng, output + idx, RAN_LEN);
4436 XMEMCPY(ssl->arrays.clientRandom, output + idx, RAN_LEN);
4439 /* send same random on hello again */
4440 XMEMCPY(output + idx, ssl->arrays.clientRandom, RAN_LEN);
4445 /* then session id */
4446 output[idx++] = (byte)idSz;
4448 XMEMCPY(output + idx, ssl->session.sessionID, ID_LEN);
4452 /* then DTLS cookie */
4454 if (ssl->options.dtls) {
4455 byte cookieSz = ssl->arrays.cookieSz;
4457 output[idx++] = cookieSz;
4459 XMEMCPY(&output[idx], ssl->arrays.cookie, cookieSz);
4464 /* then cipher suites */
4465 c16toa(ssl->suites.suiteSz, output + idx);
4467 XMEMCPY(output + idx, &ssl->suites.suites, ssl->suites.suiteSz);
4468 idx += ssl->suites.suiteSz;
4470 /* last, compression */
4471 output[idx++] = COMP_LEN;
4472 if (ssl->options.usingCompression)
4473 output[idx++] = ZLIB_COMPRESSION;
4475 output[idx++] = NO_COMPRESSION;
4477 if (IsAtLeastTLSv1_2(ssl))
4479 /* add in the extensions length */
4480 c16toa(HELLO_EXT_LEN, output + idx);
4483 c16toa(HELLO_EXT_SIG_ALGO, output + idx);
4485 c16toa(HELLO_EXT_SIGALGO_SZ, output + idx);
4487 /* This is a lazy list setup. Eventually, we'll need to support
4488 * using other hash types or even other extensions. */
4489 c16toa(HELLO_EXT_SIGALGO_LEN, output + idx);
4491 output[idx++] = sha_mac;
4492 output[idx++] = rsa_sa_algo;
4493 output[idx++] = sha_mac;
4494 output[idx++] = dsa_sa_algo;
4495 output[idx++] = sha_mac;
4496 output[idx++] = ecc_dsa_sa_algo;
4499 HashOutput(ssl, output, sendSz, 0);
4501 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
4503 #ifdef CYASSL_CALLBACKS
4504 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
4506 AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
4510 ssl->buffers.outputBuffer.length += sendSz;
4512 return SendBuffered(ssl);
4516 static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input,
4522 #ifdef CYASSL_CALLBACKS
4523 if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
4524 &ssl->handShakeInfo);
4525 if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
4527 XMEMCPY(&pv, input + *inOutIdx, sizeof(pv));
4528 *inOutIdx += sizeof(pv);
4530 cookieSz = input[(*inOutIdx)++];
4534 if (cookieSz < MAX_COOKIE_LEN) {
4535 XMEMCPY(ssl->arrays.cookie, input + *inOutIdx, cookieSz);
4536 ssl->arrays.cookieSz = cookieSz;
4539 *inOutIdx += cookieSz;
4542 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
4547 static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
4553 word32 i = *inOutIdx;
4556 #ifdef CYASSL_CALLBACKS
4557 if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
4558 if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
4560 XMEMCPY(&pv, input + i, sizeof(pv));
4562 if (pv.minor > ssl->version.minor) {
4563 CYASSL_MSG("Server using higher version, fatal error");
4564 return VERSION_ERROR;
4566 else if (pv.minor < ssl->version.minor) {
4567 CYASSL_MSG("server using lower version");
4568 if (!ssl->options.downgrade) {
4569 CYASSL_MSG(" no downgrade allowed, fatal error");
4570 return VERSION_ERROR;
4572 else if (pv.minor == SSLv3_MINOR) {
4574 CYASSL_MSG(" downgrading to SSLv3");
4575 ssl->options.tls = 0;
4576 ssl->options.tls1_1 = 0;
4577 ssl->version.minor = SSLv3_MINOR;
4579 else if (pv.minor == TLSv1_MINOR) {
4580 /* turn off tls 1.1+ */
4581 CYASSL_MSG(" downgrading to TLSv1");
4582 ssl->options.tls1_1 = 0;
4583 ssl->version.minor = TLSv1_MINOR;
4585 else if (pv.minor == TLSv1_1_MINOR) {
4586 CYASSL_MSG(" downgrading to TLSv1.1");
4587 ssl->version.minor = TLSv1_1_MINOR;
4590 XMEMCPY(ssl->arrays.serverRandom, input + i, RAN_LEN);
4594 XMEMCPY(ssl->arrays.sessionID, input + i, min(b, ID_LEN));
4596 ssl->options.haveSessionId = 1;
4598 ssl->options.cipherSuite0 = input[i++];
4599 ssl->options.cipherSuite = input[i++];
4600 compression = input[i++];
4602 if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
4603 CYASSL_MSG("Server refused compression, turning off");
4604 ssl->options.usingCompression = 0; /* turn off if server refused */
4608 if ( (i - begin) < helloSz)
4609 *inOutIdx = begin + helloSz; /* skip extensions */
4611 ssl->options.serverState = SERVER_HELLO_COMPLETE;
4615 if (ssl->options.resuming) {
4616 if (ssl->options.haveSessionId && XMEMCMP(ssl->arrays.sessionID,
4617 ssl->session.sessionID, ID_LEN) == 0) {
4618 if (SetCipherSpecs(ssl) == 0) {
4620 XMEMCPY(ssl->arrays.masterSecret, ssl->session.masterSecret,
4622 if (ssl->options.tls)
4623 ret = DeriveTlsKeys(ssl);
4625 ret = DeriveKeys(ssl);
4626 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
4630 CYASSL_MSG("Unsupported cipher suite, DoServerHello");
4631 return UNSUPPORTED_SUITE;
4635 CYASSL_MSG("Server denied resumption attempt");
4636 ssl->options.resuming = 0; /* server denied resumption try */
4640 return SetCipherSpecs(ssl);
4644 /* just read in and ignore for now TODO: */
4645 static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*
4650 #ifdef CYASSL_CALLBACKS
4652 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
4654 AddLateName("CertificateRequest", &ssl->timeoutInfo);
4656 len = input[(*inOutIdx)++];
4658 /* types, read in here */
4660 ato16(&input[*inOutIdx], &len);
4661 *inOutIdx += LENGTH_SZ;
4663 if (IsAtLeastTLSv1_2(ssl)) {
4664 /* hash sig format */
4666 ato16(&input[*inOutIdx], &len);
4667 *inOutIdx += LENGTH_SZ;
4674 ato16(&input[*inOutIdx], &dnSz);
4675 *inOutIdx += (REQUEST_HEADER + dnSz);
4676 len -= dnSz + REQUEST_HEADER;
4679 /* don't send client cert or cert verify if user hasn't provided
4680 cert and private key */
4681 if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
4682 ssl->options.sendVerify = SEND_CERT;
4683 else if (IsAtLeastTLSv1_2(ssl))
4684 ssl->options.sendVerify = SEND_BLANK_CERT;
4690 static int DoServerKeyExchange(CYASSL* ssl, const byte* input,
4693 #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
4696 word16 verifySz = (word16)*inOutIdx; /* keep start idx */
4697 byte* signature = 0;
4704 #ifdef CYASSL_CALLBACKS
4706 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
4708 AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
4712 if (ssl->specs.kea == psk_kea) {
4714 ato16(&input[*inOutIdx], &pskLen);
4715 *inOutIdx += LENGTH_SZ;
4716 XMEMCPY(ssl->arrays.server_hint, &input[*inOutIdx],
4717 min(pskLen, MAX_PSK_ID_LEN));
4718 if (pskLen < MAX_PSK_ID_LEN)
4719 ssl->arrays.server_hint[pskLen] = 0;
4721 ssl->arrays.server_hint[MAX_PSK_ID_LEN - 1] = 0;
4722 *inOutIdx += pskLen;
4727 #ifdef OPENSSL_EXTRA
4728 if (ssl->specs.kea == diffie_hellman_kea)
4731 ato16(&input[*inOutIdx], &length);
4732 *inOutIdx += LENGTH_SZ;
4734 ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
4736 if (ssl->buffers.serverDH_P.buffer)
4737 ssl->buffers.serverDH_P.length = length;
4739 return MEMORY_ERROR;
4740 XMEMCPY(ssl->buffers.serverDH_P.buffer, &input[*inOutIdx], length);
4741 *inOutIdx += length;
4744 ato16(&input[*inOutIdx], &length);
4745 *inOutIdx += LENGTH_SZ;
4747 ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
4749 if (ssl->buffers.serverDH_G.buffer)
4750 ssl->buffers.serverDH_G.length = length;
4752 return MEMORY_ERROR;
4753 XMEMCPY(ssl->buffers.serverDH_G.buffer, &input[*inOutIdx], length);
4754 *inOutIdx += length;
4757 ato16(&input[*inOutIdx], &length);
4758 *inOutIdx += LENGTH_SZ;
4760 ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
4762 if (ssl->buffers.serverDH_Pub.buffer)
4763 ssl->buffers.serverDH_Pub.length = length;
4765 return MEMORY_ERROR;
4766 XMEMCPY(ssl->buffers.serverDH_Pub.buffer, &input[*inOutIdx], length);
4767 *inOutIdx += length;
4769 #endif /* OPENSSL_EXTRA */
4772 if (ssl->specs.kea == ecc_diffie_hellman_kea)
4774 byte b = input[*inOutIdx];
4777 if (b != named_curve)
4778 return ECC_CURVETYPE_ERROR;
4780 *inOutIdx += 1; /* curve type, eat leading 0 */
4781 b = input[*inOutIdx];
4784 if (b != secp256r1 && b != secp384r1 && b != secp521r1 && b !=
4785 secp160r1 && b != secp192r1 && b != secp224r1)
4786 return ECC_CURVE_ERROR;
4788 length = input[*inOutIdx];
4791 if (ecc_import_x963(&input[*inOutIdx], length, &ssl->peerEccKey) != 0)
4792 return ECC_PEERKEY_ERROR;
4794 *inOutIdx += length;
4795 ssl->peerEccKeyPresent = 1;
4797 #endif /* HAVE_ECC */
4799 #if defined(OPENSSL_EXTRA) || defined(HAVE_ECC)
4803 byte hash[FINISHED_SZ];
4804 byte messageVerify[MAX_DH_SZ];
4806 /* adjust from start idx */
4807 verifySz = (word16)(*inOutIdx - verifySz);
4809 /* save message for hash verify */
4810 if (verifySz > sizeof(messageVerify))
4811 return BUFFER_ERROR;
4812 XMEMCPY(messageVerify, &input[*inOutIdx - verifySz], verifySz);
4814 if (IsAtLeastTLSv1_2(ssl)) {
4815 /* just advance for now TODO: validate hash algo params */
4816 *inOutIdx += LENGTH_SZ;
4820 ato16(&input[*inOutIdx], &length);
4821 *inOutIdx += LENGTH_SZ;
4823 signature = (byte*)&input[*inOutIdx];
4824 *inOutIdx += length;
4827 /* verify signature */
4831 Md5Update(&md5, ssl->arrays.clientRandom, RAN_LEN);
4832 Md5Update(&md5, ssl->arrays.serverRandom, RAN_LEN);
4833 Md5Update(&md5, messageVerify, verifySz);
4834 Md5Final(&md5, hash);
4838 ShaUpdate(&sha, ssl->arrays.clientRandom, RAN_LEN);
4839 ShaUpdate(&sha, ssl->arrays.serverRandom, RAN_LEN);
4840 ShaUpdate(&sha, messageVerify, verifySz);
4841 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
4844 if (ssl->specs.sig_algo == rsa_sa_algo)
4849 if (!ssl->peerRsaKeyPresent)
4852 ret = RsaSSL_VerifyInline(signature, sigLen,&out, &ssl->peerRsaKey);
4854 if (IsAtLeastTLSv1_2(ssl)) {
4855 byte encodedSig[MAX_ENCODED_SIG_SZ];
4862 digest = &hash[MD5_DIGEST_SIZE];
4864 digestSz = SHA_DIGEST_SIZE;
4866 encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
4868 if (encSigSz != (word32)ret || XMEMCMP(out, encodedSig,
4869 min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
4870 return VERIFY_SIGN_ERROR;
4873 if (ret != sizeof(hash) || XMEMCMP(out, hash, sizeof(hash)))
4874 return VERIFY_SIGN_ERROR;
4879 else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
4880 int verify = 0, ret;
4881 if (!ssl->peerEccDsaKeyPresent)
4884 ret = ecc_verify_hash(signature, sigLen, &hash[MD5_DIGEST_SIZE],
4885 SHA_DIGEST_SIZE, &verify, &ssl->peerEccDsaKey);
4886 if (ret != 0 || verify == 0)
4887 return VERIFY_SIGN_ERROR;
4889 #endif /* HAVE_ECC */
4893 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
4898 #else /* HAVE_OPENSSL or HAVE_ECC */
4899 return NOT_COMPILED_IN; /* not supported by build */
4900 #endif /* HAVE_OPENSSL or HAVE_ECC */
4904 int SendClientKeyExchange(CYASSL* ssl)
4906 byte encSecret[MAX_NTRU_ENCRYPT_SZ];
4911 if (ssl->specs.kea == rsa_kea) {
4912 RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret,
4914 ssl->arrays.preMasterSecret[0] = ssl->chVersion.major;
4915 ssl->arrays.preMasterSecret[1] = ssl->chVersion.minor;
4916 ssl->arrays.preMasterSz = SECRET_LEN;
4918 if (ssl->peerRsaKeyPresent == 0)
4921 ret = RsaPublicEncrypt(ssl->arrays.preMasterSecret, SECRET_LEN,
4922 encSecret, sizeof(encSecret), &ssl->peerRsaKey,
4926 ret = 0; /* set success to 0 */
4928 #ifdef OPENSSL_EXTRA
4929 } else if (ssl->specs.kea == diffie_hellman_kea) {
4930 buffer serverP = ssl->buffers.serverDH_P;
4931 buffer serverG = ssl->buffers.serverDH_G;
4932 buffer serverPub = ssl->buffers.serverDH_Pub;
4933 byte priv[ENCRYPT_LEN];
4937 if (serverP.buffer == 0 || serverG.buffer == 0 ||
4938 serverPub.buffer == 0)
4942 ret = DhSetKey(&key, serverP.buffer, serverP.length,
4943 serverG.buffer, serverG.length);
4945 /* for DH, encSecret is Yc, agree is pre-master */
4946 ret = DhGenerateKeyPair(&key, &ssl->rng, priv, &privSz,
4949 ret = DhAgree(&key, ssl->arrays.preMasterSecret,
4950 &ssl->arrays.preMasterSz, priv, privSz,
4951 serverPub.buffer, serverPub.length);
4953 #endif /* OPENSSL_EXTRA */
4955 } else if (ssl->specs.kea == psk_kea) {
4956 byte* pms = ssl->arrays.preMasterSecret;
4958 ssl->arrays.psk_keySz = ssl->options.client_psk_cb(ssl,
4959 ssl->arrays.server_hint, ssl->arrays.client_identity,
4960 MAX_PSK_ID_LEN, ssl->arrays.psk_key, MAX_PSK_KEY_LEN);
4961 if (ssl->arrays.psk_keySz == 0 ||
4962 ssl->arrays.psk_keySz > MAX_PSK_KEY_LEN)
4963 return PSK_KEY_ERROR;
4964 encSz = (word32)XSTRLEN(ssl->arrays.client_identity);
4965 if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
4966 XMEMCPY(encSecret, ssl->arrays.client_identity, encSz);
4968 /* make psk pre master secret */
4969 /* length of key + length 0s + length of key + key */
4970 c16toa((word16)ssl->arrays.psk_keySz, pms);
4972 XMEMSET(pms, 0, ssl->arrays.psk_keySz);
4973 pms += ssl->arrays.psk_keySz;
4974 c16toa((word16)ssl->arrays.psk_keySz, pms);
4976 XMEMCPY(pms, ssl->arrays.psk_key, ssl->arrays.psk_keySz);
4977 ssl->arrays.preMasterSz = ssl->arrays.psk_keySz * 2 + 4;
4980 } else if (ssl->specs.kea == ntru_kea) {
4982 word16 cipherLen = sizeof(encSecret);
4984 static uint8_t const cyasslStr[] = {
4985 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
4988 RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret,
4990 ssl->arrays.preMasterSz = SECRET_LEN;
4992 if (ssl->peerNtruKeyPresent == 0)
4995 rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr,
4996 sizeof(cyasslStr), GetEntropy, &drbg);
4998 return NTRU_DRBG_ERROR;
5000 rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,ssl->peerNtruKey,
5001 ssl->arrays.preMasterSz,
5002 ssl->arrays.preMasterSecret,
5003 &cipherLen, encSecret);
5004 crypto_drbg_uninstantiate(drbg);
5006 return NTRU_ENCRYPT_ERROR;
5010 #endif /* HAVE_NTRU */
5012 } else if (ssl->specs.kea == ecc_diffie_hellman_kea) {
5014 ecc_key* peerKey = &myKey;
5015 word32 size = sizeof(encSecret);
5017 if (ssl->specs.static_ecdh) {
5018 /* TODO: EccDsa is really fixed Ecc change naming */
5019 if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey.dp)
5021 peerKey = &ssl->peerEccDsaKey;
5024 if (!ssl->peerEccKeyPresent || !ssl->peerEccKey.dp)
5026 peerKey = &ssl->peerEccKey;
5030 ret = ecc_make_key(&ssl->rng, peerKey->dp->size, &myKey);
5032 return ECC_MAKEKEY_ERROR;
5034 /* precede export with 1 byte length */
5035 ret = ecc_export_x963(&myKey, encSecret + 1, &size);
5036 encSecret[0] = (byte)size;
5040 ret = ECC_EXPORT_ERROR;
5042 size = sizeof(ssl->arrays.preMasterSecret);
5043 ret = ecc_shared_secret(&myKey, peerKey,
5044 ssl->arrays.preMasterSecret, &size);
5046 ret = ECC_SHARED_ERROR;
5049 ssl->arrays.preMasterSz = size;
5051 #endif /* HAVE_ECC */
5053 return ALGO_ID_E; /* unsupported kea */
5060 if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
5063 if (ssl->specs.kea == ecc_diffie_hellman_kea) /* always off */
5066 sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5067 idx = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5070 if (ssl->options.dtls) {
5071 sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
5072 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
5076 /* check for avalaible size */
5077 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
5080 /* get ouput buffer */
5081 output = ssl->buffers.outputBuffer.buffer +
5082 ssl->buffers.outputBuffer.length;
5084 AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
5087 c16toa((word16)encSz, &output[idx]);
5090 XMEMCPY(output + idx, encSecret, encSz);
5093 HashOutput(ssl, output, sendSz, 0);
5095 #ifdef CYASSL_CALLBACKS
5097 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
5099 AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
5100 output, sendSz, ssl->heap);
5103 ssl->buffers.outputBuffer.length += sendSz;
5105 if (ssl->options.groupMessages)
5108 ret = SendBuffered(ssl);
5111 if (ret == 0 || ret == WANT_WRITE) {
5112 int tmpRet = MakeMasterSecret(ssl);
5114 ret = tmpRet; /* save WANT_WRITE unless more serious */
5115 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
5121 int SendCertificateVerify(CYASSL* ssl)
5124 int sendSz = 0, length, ret;
5126 word32 sigOutSz = 0;
5133 if (ssl->options.sendVerify == SEND_BLANK_CERT)
5134 return 0; /* sent blank cert, can't verify */
5136 /* check for avalaible size */
5137 if ((ret = CheckAvalaibleSize(ssl, MAX_CERT_VERIFY_SZ)) != 0)
5140 /* get ouput buffer */
5141 output = ssl->buffers.outputBuffer.buffer +
5142 ssl->buffers.outputBuffer.length;
5144 BuildCertHashes(ssl, &ssl->certHashes);
5149 InitRsaKey(&key, ssl->heap);
5150 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
5151 ssl->buffers.key.length);
5153 sigOutSz = RsaEncryptSize(&key);
5156 CYASSL_MSG("Trying ECC client cert, RSA didn't work");
5159 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
5160 ssl->buffers.key.length);
5162 CYASSL_MSG("Using ECC client cert");
5164 sigOutSz = ecc_sig_size(&eccKey);
5167 CYASSL_MSG("Bad client cert type");
5172 byte* verify = (byte*)&output[RECORD_HEADER_SZ +
5173 HANDSHAKE_HEADER_SZ];
5174 byte* signBuffer = ssl->certHashes.md5;
5175 word32 signSz = sizeof(Hashes);
5176 byte encodedSig[MAX_ENCODED_SIG_SZ];
5177 word32 extraSz = 0; /* tls 1.2 hash/sig */
5180 if (ssl->options.dtls)
5181 verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5184 if (IsAtLeastTLSv1_2(ssl)) {
5185 verify[0] = sha_mac;
5186 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
5187 extraSz = HASH_SIG_SIZE;
5189 c16toa((word16)length, verify + extraSz); /* prepend verify header*/
5193 word32 localSz = sigOutSz;
5194 ret = ecc_sign_hash(signBuffer + MD5_DIGEST_SIZE,
5195 SHA_DIGEST_SIZE, verify + extraSz + VERIFY_HEADER,
5196 &localSz, &ssl->rng, &eccKey);
5200 if (IsAtLeastTLSv1_2(ssl)) {
5206 digest = ssl->certHashes.sha;
5208 digestSz = SHA_DIGEST_SIZE;
5210 signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
5211 signBuffer = encodedSig;
5214 ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
5215 VERIFY_HEADER, ENCRYPT_LEN, &key, &ssl->rng);
5218 ret = 0; /* RSA reset */
5222 AddHeaders(output, length + extraSz + VERIFY_HEADER,
5223 certificate_verify, ssl);
5225 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
5226 extraSz + VERIFY_HEADER;
5228 if (ssl->options.dtls)
5229 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5231 HashOutput(ssl, output, sendSz, 0);
5241 #ifdef CYASSL_CALLBACKS
5243 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
5245 AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
5246 output, sendSz, ssl->heap);
5248 ssl->buffers.outputBuffer.length += sendSz;
5249 if (ssl->options.groupMessages)
5252 return SendBuffered(ssl);
5260 #endif /* NO_CYASSL_CLIENT */
5263 #ifndef NO_CYASSL_SERVER
5265 int SendServerHello(CYASSL* ssl)
5268 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
5272 length = sizeof(ProtocolVersion) + RAN_LEN
5277 /* check for avalaible size */
5278 if ((ret = CheckAvalaibleSize(ssl, MAX_HELLO_SZ)) != 0)
5281 /* get ouput buffer */
5282 output = ssl->buffers.outputBuffer.buffer +
5283 ssl->buffers.outputBuffer.length;
5285 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5286 AddHeaders(output, length, server_hello, ssl);
5289 if (ssl->options.dtls) {
5290 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5291 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5294 /* now write to output */
5296 XMEMCPY(output + idx, &ssl->version, sizeof(ProtocolVersion));
5297 idx += sizeof(ProtocolVersion);
5300 if (!ssl->options.resuming)
5301 RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
5302 XMEMCPY(output + idx, ssl->arrays.serverRandom, RAN_LEN);
5308 printf("server random: ");
5309 for (j = 0; j < RAN_LEN; j++)
5310 printf("%02x", ssl->arrays.serverRandom[j]);
5314 /* then session id */
5315 output[idx++] = ID_LEN;
5316 if (!ssl->options.resuming)
5317 RNG_GenerateBlock(&ssl->rng, ssl->arrays.sessionID, ID_LEN);
5318 XMEMCPY(output + idx, ssl->arrays.sessionID, ID_LEN);
5321 /* then cipher suite */
5322 output[idx++] = ssl->options.cipherSuite0;
5323 output[idx++] = ssl->options.cipherSuite;
5325 /* last, compression */
5326 if (ssl->options.usingCompression)
5327 output[idx++] = ZLIB_COMPRESSION;
5329 output[idx++] = NO_COMPRESSION;
5331 ssl->buffers.outputBuffer.length += sendSz;
5332 HashOutput(ssl, output, sendSz, 0);
5334 #ifdef CYASSL_CALLBACKS
5336 AddPacketName("ServerHello", &ssl->handShakeInfo);
5338 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
5342 ssl->options.serverState = SERVER_HELLO_COMPLETE;
5344 if (ssl->options.groupMessages)
5347 return SendBuffered(ssl);
5353 static byte SetCurveId(int size)
5379 #endif /* HAVE_ECC */
5382 int SendServerKeyExchange(CYASSL* ssl)
5388 if (ssl->specs.kea == psk_kea)
5391 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
5393 if (ssl->arrays.server_hint[0] == 0) return 0; /* don't send */
5395 /* include size part */
5396 length = (word32)XSTRLEN(ssl->arrays.server_hint);
5397 if (length > MAX_PSK_ID_LEN) return SERVER_HINT_ERROR;
5398 length += HINT_LEN_SZ;
5399 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5402 if (ssl->options.dtls) {
5403 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5404 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5407 /* check for avalaible size */
5408 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
5411 /* get ouput buffer */
5412 output = ssl->buffers.outputBuffer.buffer +
5413 ssl->buffers.outputBuffer.length;
5415 AddHeaders(output, length, server_key_exchange, ssl);
5418 c16toa((word16)(length - HINT_LEN_SZ), output + idx);
5420 XMEMCPY(output + idx, ssl->arrays.server_hint, length -HINT_LEN_SZ);
5422 HashOutput(ssl, output, sendSz, 0);
5424 #ifdef CYASSL_CALLBACKS
5426 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
5428 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
5429 output, sendSz, ssl->heap);
5432 ssl->buffers.outputBuffer.length += sendSz;
5433 if (ssl->options.groupMessages)
5436 ret = SendBuffered(ssl);
5437 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
5442 if (ssl->specs.kea == ecc_diffie_hellman_kea)
5445 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
5447 byte exportBuf[MAX_EXPORT_ECC_SZ];
5448 word32 expSz = sizeof(exportBuf);
5450 word32 preSigSz, preSigIdx;
5454 if (ssl->specs.static_ecdh) {
5455 CYASSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
5459 /* curve type, named curve, length(1) */
5460 length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
5462 CYASSL_MSG("Using ephemeral ECDH");
5463 if (ecc_export_x963(&ssl->eccTempKey, exportBuf, &expSz) != 0)
5464 return ECC_EXPORT_ERROR;
5470 InitRsaKey(&rsaKey, ssl->heap);
5474 length += LENGTH_SZ;
5476 if (!ssl->buffers.key.buffer) {
5477 FreeRsaKey(&rsaKey);
5479 return NO_PRIVATE_KEY;
5482 if (ssl->specs.sig_algo == rsa_sa_algo) {
5485 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
5486 &rsaKey, ssl->buffers.key.length);
5487 if (ret != 0) return ret;
5488 sigSz = RsaEncryptSize(&rsaKey);
5490 else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
5491 /* ecdsa sig size */
5493 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
5494 &dsaKey, ssl->buffers.key.length);
5495 if (ret != 0) return ret;
5496 sigSz = ecc_sig_size(&dsaKey);
5499 FreeRsaKey(&rsaKey);
5501 return ALGO_ID_E; /* unsupported type */
5505 if (IsAtLeastTLSv1_2(ssl))
5506 length += HASH_SIG_SIZE;
5508 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5511 if (ssl->options.dtls) {
5512 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5513 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5517 /* check for avalaible size */
5518 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0) {
5519 FreeRsaKey(&rsaKey);
5524 /* get ouput buffer */
5525 output = ssl->buffers.outputBuffer.buffer +
5526 ssl->buffers.outputBuffer.length;
5528 AddHeaders(output, length, server_key_exchange, ssl);
5530 /* key exchange data */
5531 output[idx++] = named_curve;
5532 output[idx++] = 0x00; /* leading zero */
5533 output[idx++] = SetCurveId(ecc_size(&ssl->eccTempKey));
5534 output[idx++] = (byte)expSz;
5535 XMEMCPY(output + idx, exportBuf, expSz);
5537 if (IsAtLeastTLSv1_2(ssl)) {
5538 output[idx++] = sha_mac;
5539 output[idx++] = ssl->specs.sig_algo;
5541 c16toa((word16)sigSz, output + idx);
5548 byte hash[FINISHED_SZ];
5549 byte* signBuffer = hash;
5550 word32 signSz = sizeof(hash);
5554 Md5Update(&md5, ssl->arrays.clientRandom, RAN_LEN);
5555 Md5Update(&md5, ssl->arrays.serverRandom, RAN_LEN);
5556 Md5Update(&md5, output + preSigIdx, preSigSz);
5557 Md5Final(&md5, hash);
5561 ShaUpdate(&sha, ssl->arrays.clientRandom, RAN_LEN);
5562 ShaUpdate(&sha, ssl->arrays.serverRandom, RAN_LEN);
5563 ShaUpdate(&sha, output + preSigIdx, preSigSz);
5564 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
5566 if (ssl->specs.sig_algo == rsa_sa_algo) {
5567 byte encodedSig[MAX_ENCODED_SIG_SZ];
5568 if (IsAtLeastTLSv1_2(ssl)) {
5574 digest = &hash[MD5_DIGEST_SIZE];
5576 digestSz = SHA_DIGEST_SIZE;
5578 signSz = EncodeSignature(encodedSig, digest, digestSz,
5580 signBuffer = encodedSig;
5582 ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
5583 &rsaKey, &ssl->rng);
5584 FreeRsaKey(&rsaKey);
5587 ret = 0; /* reset on success */
5591 else if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
5594 ret = ecc_sign_hash(&hash[MD5_DIGEST_SIZE], SHA_DIGEST_SIZE,
5595 output + idx, &sz, &ssl->rng, &dsaKey);
5596 FreeRsaKey(&rsaKey);
5598 if (ret < 0) return ret;
5602 HashOutput(ssl, output, sendSz, 0);
5604 #ifdef CYASSL_CALLBACKS
5606 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
5608 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
5609 output, sendSz, ssl->heap);
5612 ssl->buffers.outputBuffer.length += sendSz;
5613 if (ssl->options.groupMessages)
5616 ret = SendBuffered(ssl);
5617 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
5619 #endif /* HAVE_ECC */
5621 #ifdef OPENSSL_EXTRA
5622 if (ssl->specs.kea == diffie_hellman_kea) {
5624 word32 length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
5626 word32 sigSz = 0, i = 0;
5627 word32 preSigSz = 0, preSigIdx = 0;
5631 if (ssl->buffers.serverDH_P.buffer == NULL ||
5632 ssl->buffers.serverDH_G.buffer == NULL)
5633 return NO_DH_PARAMS;
5635 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
5636 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
5637 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
5639 if (ssl->buffers.serverDH_Pub.buffer == NULL)
5643 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
5644 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
5645 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
5647 if (ssl->buffers.serverDH_Priv.buffer == NULL)
5652 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
5653 ssl->buffers.serverDH_P.length,
5654 ssl->buffers.serverDH_G.buffer,
5655 ssl->buffers.serverDH_G.length);
5657 ret = DhGenerateKeyPair(&dhKey, &ssl->rng,
5658 ssl->buffers.serverDH_Priv.buffer,
5659 &ssl->buffers.serverDH_Priv.length,
5660 ssl->buffers.serverDH_Pub.buffer,
5661 &ssl->buffers.serverDH_Pub.length);
5665 length = LENGTH_SZ * 3; /* p, g, pub */
5666 length += ssl->buffers.serverDH_P.length +
5667 ssl->buffers.serverDH_G.length +
5668 ssl->buffers.serverDH_Pub.length;
5674 length += LENGTH_SZ;
5676 if (!ssl->buffers.key.buffer)
5677 return NO_PRIVATE_KEY;
5679 InitRsaKey(&rsaKey, ssl->heap);
5680 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
5681 ssl->buffers.key.length);
5683 sigSz = RsaEncryptSize(&rsaKey);
5688 FreeRsaKey(&rsaKey);
5692 if (IsAtLeastTLSv1_2(ssl))
5693 length += HASH_SIG_SIZE;
5695 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
5698 if (ssl->options.dtls) {
5699 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5700 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
5704 /* check for avalaible size */
5705 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0) {
5706 FreeRsaKey(&rsaKey);
5710 /* get ouput buffer */
5711 output = ssl->buffers.outputBuffer.buffer +
5712 ssl->buffers.outputBuffer.length;
5714 AddHeaders(output, length, server_key_exchange, ssl);
5717 c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
5719 XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
5720 ssl->buffers.serverDH_P.length);
5721 idx += ssl->buffers.serverDH_P.length;
5724 c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
5726 XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
5727 ssl->buffers.serverDH_G.length);
5728 idx += ssl->buffers.serverDH_G.length;
5731 c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
5733 XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
5734 ssl->buffers.serverDH_Pub.length);
5735 idx += ssl->buffers.serverDH_Pub.length;
5738 if (IsAtLeastTLSv1_2(ssl)) {
5739 output[idx++] = sha_mac;
5740 output[idx++] = ssl->specs.sig_algo;
5743 c16toa((word16)sigSz, output + idx);
5750 byte hash[FINISHED_SZ];
5751 byte* signBuffer = hash;
5752 word32 signSz = sizeof(hash);
5756 Md5Update(&md5, ssl->arrays.clientRandom, RAN_LEN);
5757 Md5Update(&md5, ssl->arrays.serverRandom, RAN_LEN);
5758 Md5Update(&md5, output + preSigIdx, preSigSz);
5759 Md5Final(&md5, hash);
5763 ShaUpdate(&sha, ssl->arrays.clientRandom, RAN_LEN);
5764 ShaUpdate(&sha, ssl->arrays.serverRandom, RAN_LEN);
5765 ShaUpdate(&sha, output + preSigIdx, preSigSz);
5766 ShaFinal(&sha, &hash[MD5_DIGEST_SIZE]);
5768 if (ssl->specs.sig_algo == rsa_sa_algo) {
5769 byte encodedSig[MAX_ENCODED_SIG_SZ];
5770 if (IsAtLeastTLSv1_2(ssl)) {
5776 digest = &hash[MD5_DIGEST_SIZE];
5778 digestSz = SHA_DIGEST_SIZE;
5780 signSz = EncodeSignature(encodedSig, digest, digestSz,
5782 signBuffer = encodedSig;
5784 ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz,
5785 &rsaKey, &ssl->rng);
5786 FreeRsaKey(&rsaKey);
5788 ret = 0; /* reset on success */
5794 HashOutput(ssl, output, sendSz, 0);
5796 #ifdef CYASSL_CALLBACKS
5798 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
5800 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
5801 output, sendSz, ssl->heap);
5804 ssl->buffers.outputBuffer.length += sendSz;
5805 if (ssl->options.groupMessages)
5808 ret = SendBuffered(ssl);
5809 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
5811 #endif /* OPENSSL_EXTRA */
5817 /* cipher requirements */
5822 REQUIRES_ECC_STATIC,
5830 /* Does this cipher suite (first, second) have the requirement
5831 an ephemeral key exchange will still require the key for signing
5832 the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
5833 static int CipherRequires(byte first, byte second, int requirement)
5835 /* ECC extensions */
5836 if (first == ECC_BYTE) {
5840 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
5841 if (requirement == REQUIRES_RSA)
5845 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
5846 if (requirement == REQUIRES_ECC_STATIC)
5848 if (requirement == REQUIRES_RSA_SIG)
5852 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
5853 if (requirement == REQUIRES_RSA)
5857 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
5858 if (requirement == REQUIRES_ECC_STATIC)
5860 if (requirement == REQUIRES_RSA_SIG)
5864 case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
5865 if (requirement == REQUIRES_RSA)
5869 case TLS_ECDH_RSA_WITH_RC4_128_SHA :
5870 if (requirement == REQUIRES_ECC_STATIC)
5872 if (requirement == REQUIRES_RSA_SIG)
5876 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
5877 if (requirement == REQUIRES_ECC_DSA)
5881 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
5882 if (requirement == REQUIRES_ECC_STATIC)
5886 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
5887 if (requirement == REQUIRES_ECC_DSA)
5891 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
5892 if (requirement == REQUIRES_ECC_STATIC)
5896 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
5897 if (requirement == REQUIRES_RSA)
5901 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
5902 if (requirement == REQUIRES_ECC_STATIC)
5904 if (requirement == REQUIRES_RSA_SIG)
5908 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
5909 if (requirement == REQUIRES_ECC_DSA)
5913 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
5914 if (requirement == REQUIRES_ECC_STATIC)
5918 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
5919 if (requirement == REQUIRES_ECC_DSA)
5923 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
5924 if (requirement == REQUIRES_ECC_STATIC)
5928 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
5929 if (requirement == REQUIRES_ECC_DSA)
5933 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
5934 if (requirement == REQUIRES_ECC_DSA)
5938 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
5939 if (requirement == REQUIRES_ECC_STATIC)
5943 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
5944 if (requirement == REQUIRES_ECC_STATIC)
5948 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
5949 if (requirement == REQUIRES_RSA)
5953 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
5954 if (requirement == REQUIRES_RSA)
5958 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
5959 if (requirement == REQUIRES_ECC_STATIC)
5961 if (requirement == REQUIRES_RSA_SIG)
5965 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
5966 if (requirement == REQUIRES_ECC_STATIC)
5968 if (requirement == REQUIRES_RSA_SIG)
5973 CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
5977 if (first != ECC_BYTE) { /* normal suites */
5980 case SSL_RSA_WITH_RC4_128_SHA :
5981 if (requirement == REQUIRES_RSA)
5985 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
5986 if (requirement == REQUIRES_NTRU)
5990 case SSL_RSA_WITH_RC4_128_MD5 :
5991 if (requirement == REQUIRES_RSA)
5995 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
5996 if (requirement == REQUIRES_RSA)
6000 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
6001 if (requirement == REQUIRES_NTRU)
6005 case TLS_RSA_WITH_AES_128_CBC_SHA :
6006 if (requirement == REQUIRES_RSA)
6010 case TLS_RSA_WITH_AES_128_CBC_SHA256 :
6011 if (requirement == REQUIRES_RSA)
6015 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
6016 if (requirement == REQUIRES_NTRU)
6020 case TLS_RSA_WITH_AES_256_CBC_SHA :
6021 if (requirement == REQUIRES_RSA)
6025 case TLS_RSA_WITH_AES_256_CBC_SHA256 :
6026 if (requirement == REQUIRES_RSA)
6030 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
6031 if (requirement == REQUIRES_NTRU)
6035 case TLS_PSK_WITH_AES_128_CBC_SHA :
6036 if (requirement == REQUIRES_PSK)
6040 case TLS_PSK_WITH_AES_256_CBC_SHA :
6041 if (requirement == REQUIRES_PSK)
6045 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
6046 if (requirement == REQUIRES_RSA)
6048 if (requirement == REQUIRES_DHE)
6052 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
6053 if (requirement == REQUIRES_RSA)
6055 if (requirement == REQUIRES_DHE)
6059 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
6060 if (requirement == REQUIRES_RSA)
6062 if (requirement == REQUIRES_DHE)
6066 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
6067 if (requirement == REQUIRES_RSA)
6069 if (requirement == REQUIRES_DHE)
6073 case TLS_RSA_WITH_HC_128_CBC_MD5 :
6074 if (requirement == REQUIRES_RSA)
6078 case TLS_RSA_WITH_HC_128_CBC_SHA :
6079 if (requirement == REQUIRES_RSA)
6083 case TLS_RSA_WITH_RABBIT_CBC_SHA :
6084 if (requirement == REQUIRES_RSA)
6088 case TLS_RSA_WITH_AES_128_GCM_SHA256 :
6089 case TLS_RSA_WITH_AES_256_GCM_SHA384 :
6090 if (requirement == REQUIRES_RSA)
6094 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
6095 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
6096 if (requirement == REQUIRES_RSA)
6098 if (requirement == REQUIRES_DHE)
6103 CYASSL_MSG("Unsupported cipher suite, CipherRequires");
6106 } /* if ECC / Normal suites else */
6115 /* Make sure cert/key are valid for this suite, true on success */
6116 static int VerifySuite(CYASSL* ssl, word16 idx)
6118 int haveRSA = !ssl->options.haveStaticECC;
6120 byte first = ssl->suites.suites[idx];
6121 byte second = ssl->suites.suites[idx+1];
6123 CYASSL_ENTER("VerifySuite");
6126 havePSK = ssl->options.havePSK;
6129 if (ssl->options.haveNTRU)
6132 if (CipherRequires(first, second, REQUIRES_RSA)) {
6133 CYASSL_MSG("Requires RSA");
6135 CYASSL_MSG("Don't have RSA");
6140 if (CipherRequires(first, second, REQUIRES_DHE)) {
6141 CYASSL_MSG("Requires DHE");
6142 if (ssl->options.haveDH == 0) {
6143 CYASSL_MSG("Don't have DHE");
6148 if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
6149 CYASSL_MSG("Requires ECCDSA");
6150 if (ssl->options.haveECDSAsig == 0) {
6151 CYASSL_MSG("Don't have ECCDSA");
6156 if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
6157 CYASSL_MSG("Requires static ECC");
6158 if (ssl->options.haveStaticECC == 0) {
6159 CYASSL_MSG("Don't have static ECC");
6164 if (CipherRequires(first, second, REQUIRES_PSK)) {
6165 CYASSL_MSG("Requires PSK");
6167 CYASSL_MSG("Don't have PSK");
6172 if (CipherRequires(first, second, REQUIRES_NTRU)) {
6173 CYASSL_MSG("Requires NTRU");
6174 if (ssl->options.haveNTRU == 0) {
6175 CYASSL_MSG("Don't have NTRU");
6180 if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
6181 CYASSL_MSG("Requires RSA Signature");
6182 if (ssl->options.side == SERVER_END && ssl->options.haveECDSAsig == 1) {
6183 CYASSL_MSG("Don't have RSA Signature");
6188 /* ECCDHE is always supported if ECC on */
6194 static int MatchSuite(CYASSL* ssl, Suites* peerSuites)
6198 CYASSL_ENTER("MatchSuite");
6200 /* & 0x1 equivalent % 2 */
6201 if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
6202 return MATCH_SUITE_ERROR;
6204 /* start with best, if a match we are good */
6205 for (i = 0; i < ssl->suites.suiteSz; i += 2)
6206 for (j = 0; j < peerSuites->suiteSz; j += 2)
6207 if (ssl->suites.suites[i] == peerSuites->suites[j] &&
6208 ssl->suites.suites[i+1] == peerSuites->suites[j+1] ) {
6210 if (VerifySuite(ssl, i)) {
6211 CYASSL_MSG("Verified suite validity");
6212 ssl->options.cipherSuite0 = ssl->suites.suites[i];
6213 ssl->options.cipherSuite = ssl->suites.suites[i+1];
6214 return SetCipherSpecs(ssl);
6217 CYASSL_MSG("Coult not verify suite validity, continue");
6221 return MATCH_SUITE_ERROR;
6225 /* process old style client hello, deprecate? */
6226 int ProcessOldClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
6227 word32 inSz, word16 sz)
6229 word32 idx = *inOutIdx;
6237 CYASSL_MSG("Got old format client hello");
6238 #ifdef CYASSL_CALLBACKS
6240 AddPacketName("ClientHello", &ssl->handShakeInfo);
6242 AddLateName("ClientHello", &ssl->timeoutInfo);
6245 /* manually hash input since different format */
6246 Md5Update(&ssl->hashMd5, input + idx, sz);
6247 ShaUpdate(&ssl->hashSha, input + idx, sz);
6249 if (IsAtLeastTLSv1_2(ssl))
6250 Sha256Update(&ssl->hashSha256, input + idx, sz);
6253 /* does this value mean client_hello? */
6257 pv.major = input[idx++];
6258 pv.minor = input[idx++];
6259 ssl->chVersion = pv; /* store */
6261 if (ssl->version.minor > pv.minor) {
6263 if (!ssl->options.downgrade) {
6264 CYASSL_MSG("Client trying to connect with lesser version");
6265 return VERSION_ERROR;
6267 if (pv.minor == SSLv3_MINOR) {
6269 CYASSL_MSG(" downgrading to SSLv3");
6270 ssl->options.tls = 0;
6271 ssl->options.tls1_1 = 0;
6272 ssl->version.minor = SSLv3_MINOR;
6274 else if (pv.minor == TLSv1_MINOR) {
6275 CYASSL_MSG(" downgrading to TLSv1");
6276 /* turn off tls 1.1+ */
6277 ssl->options.tls1_1 = 0;
6278 ssl->version.minor = TLSv1_MINOR;
6280 else if (pv.minor == TLSv1_1_MINOR) {
6281 CYASSL_MSG(" downgrading to TLSv1.1");
6282 ssl->version.minor = TLSv1_1_MINOR;
6285 havePSK = ssl->options.havePSK;
6288 InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
6289 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
6290 ssl->options.haveStaticECC, ssl->options.side);
6294 ato16(&input[idx], &clSuites.suiteSz);
6297 if (clSuites.suiteSz > MAX_SUITE_SZ)
6298 return BUFFER_ERROR;
6301 ato16(&input[idx], &sessionSz);
6304 if (sessionSz > ID_LEN)
6305 return BUFFER_ERROR;
6308 ato16(&input[idx], &randomSz);
6311 if (randomSz > RAN_LEN)
6312 return BUFFER_ERROR;
6315 for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
6316 byte first = input[idx++];
6317 if (!first) { /* implicit: skip sslv2 type */
6318 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
6323 clSuites.suiteSz = j;
6327 XMEMCPY(ssl->arrays.sessionID, input + idx, sessionSz);
6329 ssl->options.resuming = 1;
6333 if (randomSz < RAN_LEN)
6334 XMEMSET(ssl->arrays.clientRandom, 0, RAN_LEN - randomSz);
6335 XMEMCPY(&ssl->arrays.clientRandom[RAN_LEN - randomSz], input + idx,
6339 if (ssl->options.usingCompression)
6340 ssl->options.usingCompression = 0; /* turn off */
6342 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
6345 ssl->options.haveSessionId = 1;
6346 /* DoClientHello uses same resume code */
6347 while (ssl->options.resuming) { /* let's try */
6349 CYASSL_SESSION* session = GetSession(ssl, ssl->arrays.masterSecret);
6351 ssl->options.resuming = 0;
6352 break; /* session lookup failed */
6354 if (MatchSuite(ssl, &clSuites) < 0) {
6355 CYASSL_MSG("Unsupported cipher suite, OldClientHello");
6356 return UNSUPPORTED_SUITE;
6359 RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
6360 if (ssl->options.tls)
6361 ret = DeriveTlsKeys(ssl);
6363 ret = DeriveKeys(ssl);
6364 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
6369 return MatchSuite(ssl, &clSuites);
6373 static int DoClientHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
6374 word32 totalSz, word32 helloSz)
6379 word32 i = *inOutIdx;
6382 #ifdef CYASSL_CALLBACKS
6383 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
6384 if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
6386 /* make sure can read up to session */
6387 if (i + sizeof(pv) + RAN_LEN + ENUM_LEN > totalSz)
6388 return INCOMPLETE_DATA;
6390 XMEMCPY(&pv, input + i, sizeof(pv));
6391 ssl->chVersion = pv; /* store */
6393 if (ssl->version.minor > pv.minor) {
6395 if (!ssl->options.downgrade) {
6396 CYASSL_MSG("Client trying to connect with lesser version");
6397 return VERSION_ERROR;
6399 if (pv.minor == SSLv3_MINOR) {
6401 CYASSL_MSG(" downgrading to SSLv3");
6402 ssl->options.tls = 0;
6403 ssl->options.tls1_1 = 0;
6404 ssl->version.minor = SSLv3_MINOR;
6406 else if (pv.minor == TLSv1_MINOR) {
6407 /* turn off tls 1.1+ */
6408 CYASSL_MSG(" downgrading to TLSv1");
6409 ssl->options.tls1_1 = 0;
6410 ssl->version.minor = TLSv1_MINOR;
6412 else if (pv.minor == TLSv1_1_MINOR) {
6413 CYASSL_MSG(" downgrading to TLSv1.1");
6414 ssl->version.minor = TLSv1_1_MINOR;
6417 havePSK = ssl->options.havePSK;
6419 InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
6420 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
6421 ssl->options.haveStaticECC, ssl->options.side);
6424 XMEMCPY(ssl->arrays.clientRandom, input + i, RAN_LEN);
6430 printf("client random: ");
6431 for (j = 0; j < RAN_LEN; j++)
6432 printf("%02x", ssl->arrays.clientRandom[j]);
6439 if (i + ID_LEN > totalSz)
6440 return INCOMPLETE_DATA;
6441 XMEMCPY(ssl->arrays.sessionID, input + i, ID_LEN);
6443 ssl->options.resuming= 1; /* client wants to resume */
6444 CYASSL_MSG("Client wants to resume session");
6449 if (ssl->options.dtls) {
6452 byte cookie[MAX_COOKIE_LEN];
6455 if (b > MAX_COOKIE_LEN)
6456 return BUFFER_ERROR;
6457 if (i + b > totalSz)
6458 return INCOMPLETE_DATA;
6459 cookieSz = EmbedGenerateCookie(cookie, COOKIE_SZ, ssl);
6460 if ((b != cookieSz) || XMEMCMP(cookie, input + i, b) != 0)
6461 return COOKIE_ERROR;
6467 if (i + LENGTH_SZ > totalSz)
6468 return INCOMPLETE_DATA;
6470 ato16(&input[i], &clSuites.suiteSz);
6473 /* suites and comp len */
6474 if (i + clSuites.suiteSz + ENUM_LEN > totalSz)
6475 return INCOMPLETE_DATA;
6476 if (clSuites.suiteSz > MAX_SUITE_SZ)
6477 return BUFFER_ERROR;
6478 XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
6479 i += clSuites.suiteSz;
6481 b = input[i++]; /* comp len */
6482 if (i + b > totalSz)
6483 return INCOMPLETE_DATA;
6485 if (ssl->options.usingCompression) {
6488 byte comp = input[i++];
6489 if (comp == ZLIB_COMPRESSION)
6493 CYASSL_MSG("Not matching compression, turning off");
6494 ssl->options.usingCompression = 0; /* turn off */
6498 i += b; /* ignore, since we're not on */
6500 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
6503 if ( (i - begin) < helloSz)
6504 *inOutIdx = begin + helloSz; /* skip extensions */
6506 ssl->options.haveSessionId = 1;
6507 /* ProcessOld uses same resume code */
6508 while (ssl->options.resuming) { /* let's try */
6510 CYASSL_SESSION* session = GetSession(ssl, ssl->arrays.masterSecret);
6512 ssl->options.resuming = 0;
6513 CYASSL_MSG("Session lookup for resume failed");
6514 break; /* session lookup failed */
6516 if (MatchSuite(ssl, &clSuites) < 0) {
6517 CYASSL_MSG("Unsupported cipher suite, ClientHello");
6518 return UNSUPPORTED_SUITE;
6521 RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
6522 if (ssl->options.tls)
6523 ret = DeriveTlsKeys(ssl);
6525 ret = DeriveKeys(ssl);
6526 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
6530 return MatchSuite(ssl, &clSuites);
6534 static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutsz,
6538 word32 i = *inOutsz;
6539 int ret = VERIFY_CERT_ERROR; /* start in error state */
6544 #ifdef CYASSL_CALLBACKS
6546 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
6548 AddLateName("CertificateVerify", &ssl->timeoutInfo);
6550 if ( (i + VERIFY_HEADER) > totalSz)
6551 return INCOMPLETE_DATA;
6553 if (IsAtLeastTLSv1_2(ssl))
6555 ato16(&input[i], &sz);
6558 if ( (i + sz) > totalSz)
6559 return INCOMPLETE_DATA;
6561 if (sz > ENCRYPT_LEN)
6562 return BUFFER_ERROR;
6568 if (ssl->peerRsaKeyPresent != 0) {
6569 CYASSL_MSG("Doing RSA peer cert verify");
6571 outLen = RsaSSL_VerifyInline(sig, sz, &out, &ssl->peerRsaKey);
6573 if (IsAtLeastTLSv1_2(ssl)) {
6574 byte encodedSig[MAX_ENCODED_SIG_SZ];
6581 digest = ssl->certHashes.sha;
6583 digestSz = SHA_DIGEST_SIZE;
6585 sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
6587 if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,
6588 min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
6589 ret = 0; /* verified */
6592 if (outLen == sizeof(ssl->certHashes) && XMEMCMP(out,
6593 &ssl->certHashes, sizeof(ssl->certHashes)) == 0)
6594 ret = 0; /* verified */
6598 else if (ssl->peerEccDsaKeyPresent) {
6602 CYASSL_MSG("Doing ECC peer cert verify");
6604 err = ecc_verify_hash(sig, sz, ssl->certHashes.sha, SHA_DIGEST_SIZE,
6605 &verify, &ssl->peerEccDsaKey);
6607 if (err == 0 && verify == 1)
6608 ret = 0; /* verified */
6615 int SendServerHelloDone(CYASSL* ssl)
6618 int sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
6622 if (ssl->options.dtls)
6623 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
6625 /* check for avalaible size */
6626 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
6629 /* get ouput buffer */
6630 output = ssl->buffers.outputBuffer.buffer +
6631 ssl->buffers.outputBuffer.length;
6633 AddHeaders(output, 0, server_hello_done, ssl);
6635 HashOutput(ssl, output, sendSz, 0);
6636 #ifdef CYASSL_CALLBACKS
6638 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
6640 AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
6643 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
6645 ssl->buffers.outputBuffer.length += sendSz;
6647 return SendBuffered(ssl);
6651 int SendHelloVerifyRequest(CYASSL* ssl)
6654 byte cookieSz = COOKIE_SZ;
6655 int length = VERSION_SZ + ENUM_LEN + cookieSz;
6656 int idx = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
6657 int sendSz = length + idx;
6660 /* check for avalaible size */
6661 if ((ret = CheckAvalaibleSize(ssl, sendSz)) != 0)
6664 /* get ouput buffer */
6665 output = ssl->buffers.outputBuffer.buffer +
6666 ssl->buffers.outputBuffer.length;
6668 AddHeaders(output, length, hello_verify_request, ssl);
6670 XMEMCPY(output + idx, &ssl->chVersion, VERSION_SZ);
6673 output[idx++] = cookieSz;
6674 if ((ret = EmbedGenerateCookie(output + idx, cookieSz, ssl)) < 0)
6677 HashOutput(ssl, output, sendSz, 0);
6678 #ifdef CYASSL_CALLBACKS
6680 AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
6682 AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
6685 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
6687 ssl->buffers.outputBuffer.length += sendSz;
6689 return SendBuffered(ssl);
6693 static int DoClientKeyExchange(CYASSL* ssl, byte* input,
6700 if (ssl->options.verifyPeer && ssl->options.failNoCert)
6701 if (!ssl->options.havePeerCert) {
6702 CYASSL_MSG("client didn't present peer cert");
6703 return NO_PEER_CERT;
6706 #ifdef CYASSL_CALLBACKS
6708 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
6710 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
6712 if (ssl->specs.kea == rsa_kea) {
6717 InitRsaKey(&key, ssl->heap);
6719 if (ssl->buffers.key.buffer)
6720 ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
6721 ssl->buffers.key.length);
6723 return NO_PRIVATE_KEY;
6726 length = RsaEncryptSize(&key);
6727 ssl->arrays.preMasterSz = SECRET_LEN;
6729 if (ssl->options.tls)
6731 tmp = input + *inOutIdx;
6732 *inOutIdx += length;
6734 if (RsaPrivateDecryptInline(tmp, length, &out, &key) ==
6736 XMEMCPY(ssl->arrays.preMasterSecret, out, SECRET_LEN);
6737 if (ssl->arrays.preMasterSecret[0] != ssl->chVersion.major
6739 ssl->arrays.preMasterSecret[1] != ssl->chVersion.minor)
6741 ret = PMS_VERSION_ERROR;
6743 ret = MakeMasterSecret(ssl);
6746 ret = RSA_PRIVATE_ERROR;
6751 } else if (ssl->specs.kea == psk_kea) {
6752 byte* pms = ssl->arrays.preMasterSecret;
6755 ato16(&input[*inOutIdx], &ci_sz);
6756 *inOutIdx += LENGTH_SZ;
6757 if (ci_sz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR;
6759 XMEMCPY(ssl->arrays.client_identity, &input[*inOutIdx], ci_sz);
6761 ssl->arrays.client_identity[ci_sz] = 0;
6763 ssl->arrays.psk_keySz = ssl->options.server_psk_cb(ssl,
6764 ssl->arrays.client_identity, ssl->arrays.psk_key,
6766 if (ssl->arrays.psk_keySz == 0 ||
6767 ssl->arrays.psk_keySz > MAX_PSK_KEY_LEN) return PSK_KEY_ERROR;
6769 /* make psk pre master secret */
6770 /* length of key + length 0s + length of key + key */
6771 c16toa((word16)ssl->arrays.psk_keySz, pms);
6773 XMEMSET(pms, 0, ssl->arrays.psk_keySz);
6774 pms += ssl->arrays.psk_keySz;
6775 c16toa((word16)ssl->arrays.psk_keySz, pms);
6777 XMEMCPY(pms, ssl->arrays.psk_key, ssl->arrays.psk_keySz);
6778 ssl->arrays.preMasterSz = ssl->arrays.psk_keySz * 2 + 4;
6780 ret = MakeMasterSecret(ssl);
6783 } else if (ssl->specs.kea == ntru_kea) {
6786 word16 plainLen = sizeof(ssl->arrays.preMasterSecret);
6789 if (!ssl->buffers.key.buffer)
6790 return NO_PRIVATE_KEY;
6792 ato16(&input[*inOutIdx], &cipherLen);
6793 *inOutIdx += LENGTH_SZ;
6794 if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
6795 return NTRU_KEY_ERROR;
6797 tmp = input + *inOutIdx;
6798 rc = crypto_ntru_decrypt((word16)ssl->buffers.key.length,
6799 ssl->buffers.key.buffer, cipherLen, tmp, &plainLen,
6800 ssl->arrays.preMasterSecret);
6802 if (rc != NTRU_OK || plainLen != SECRET_LEN)
6803 return NTRU_DECRYPT_ERROR;
6804 *inOutIdx += cipherLen;
6806 ssl->arrays.preMasterSz = plainLen;
6807 ret = MakeMasterSecret(ssl);
6808 #endif /* HAVE_NTRU */
6810 } else if (ssl->specs.kea == ecc_diffie_hellman_kea) {
6812 word32 bLength = input[*inOutIdx]; /* one byte length */
6815 ret = ecc_import_x963(&input[*inOutIdx], bLength, &ssl->peerEccKey);
6817 return ECC_PEERKEY_ERROR;
6818 *inOutIdx += bLength;
6819 ssl->peerEccKeyPresent = 1;
6821 size = sizeof(ssl->arrays.preMasterSecret);
6822 if (ssl->specs.static_ecdh) {
6826 ecc_init(&staticKey);
6827 ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
6828 &staticKey, ssl->buffers.key.length);
6830 ret = ecc_shared_secret(&staticKey, &ssl->peerEccKey,
6831 ssl->arrays.preMasterSecret, &size);
6832 ecc_free(&staticKey);
6835 ret = ecc_shared_secret(&ssl->eccTempKey, &ssl->peerEccKey,
6836 ssl->arrays.preMasterSecret, &size);
6838 return ECC_SHARED_ERROR;
6839 ssl->arrays.preMasterSz = size;
6840 ret = MakeMasterSecret(ssl);
6841 #endif /* HAVE_ECC */
6842 #ifdef OPENSSL_EXTRA
6843 } else if (ssl->specs.kea == diffie_hellman_kea) {
6848 ato16(&input[*inOutIdx], &clientPubSz);
6849 *inOutIdx += LENGTH_SZ;
6851 clientPub = &input[*inOutIdx];
6852 *inOutIdx += clientPubSz;
6855 ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
6856 ssl->buffers.serverDH_P.length,
6857 ssl->buffers.serverDH_G.buffer,
6858 ssl->buffers.serverDH_G.length);
6860 ret = DhAgree(&dhKey, ssl->arrays.preMasterSecret,
6861 &ssl->arrays.preMasterSz,
6862 ssl->buffers.serverDH_Priv.buffer,
6863 ssl->buffers.serverDH_Priv.length,
6864 clientPub, clientPubSz);
6867 ret = MakeMasterSecret(ssl);
6868 #endif /* OPENSSL_EXTRA */
6872 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
6873 if (ssl->options.verifyPeer)
6874 BuildCertHashes(ssl, &ssl->certHashes);
6880 #endif /* NO_CYASSL_SERVER */
6883 #ifdef SINGLE_THREADED
6885 int InitMutex(CyaSSL_Mutex* m)
6891 int FreeMutex(CyaSSL_Mutex* m)
6897 int LockMutex(CyaSSL_Mutex* m)
6903 int UnLockMutex(CyaSSL_Mutex* m)
6908 #else /* MULTI_THREAD */
6910 #if defined(FREERTOS)
6912 int InitMutex(CyaSSL_Mutex* m)
6916 *m = ( CyaSSL_Mutex ) xSemaphoreCreateMutex();
6920 iReturn = BAD_MUTEX_ERROR;
6925 int FreeMutex(CyaSSL_Mutex* m)
6927 vSemaphoreDelete( *m );
6931 int LockMutex(CyaSSL_Mutex* m)
6933 /* Assume an infinite block, or should there be zero block? */
6934 xSemaphoreTake( *m, portMAX_DELAY );
6938 int UnLockMutex(CyaSSL_Mutex* m)
6940 xSemaphoreGive( *m );
6944 #elif defined(USE_WINDOWS_API)
6946 int InitMutex(CyaSSL_Mutex* m)
6948 InitializeCriticalSection(m);
6953 int FreeMutex(CyaSSL_Mutex* m)
6955 DeleteCriticalSection(m);
6960 int LockMutex(CyaSSL_Mutex* m)
6962 EnterCriticalSection(m);
6967 int UnLockMutex(CyaSSL_Mutex* m)
6969 LeaveCriticalSection(m);
6973 #elif defined(CYASSL_PTHREADS)
6975 int InitMutex(CyaSSL_Mutex* m)
6977 if (pthread_mutex_init(m, 0) == 0)
6980 return BAD_MUTEX_ERROR;
6984 int FreeMutex(CyaSSL_Mutex* m)
6986 if (pthread_mutex_destroy(m) == 0)
6989 return BAD_MUTEX_ERROR;
6993 int LockMutex(CyaSSL_Mutex* m)
6995 if (pthread_mutex_lock(m) == 0)
6998 return BAD_MUTEX_ERROR;
7002 int UnLockMutex(CyaSSL_Mutex* m)
7004 if (pthread_mutex_unlock(m) == 0)
7007 return BAD_MUTEX_ERROR;
7010 #elif defined(THREADX)
7012 int InitMutex(CyaSSL_Mutex* m)
7014 if (tx_mutex_create(m, "CyaSSL Mutex", TX_NO_INHERIT) == 0)
7017 return BAD_MUTEX_ERROR;
7021 int FreeMutex(CyaSSL_Mutex* m)
7023 if (tx_mutex_delete(m) == 0)
7026 return BAD_MUTEX_ERROR;
7030 int LockMutex(CyaSSL_Mutex* m)
7032 if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
7035 return BAD_MUTEX_ERROR;
7039 int UnLockMutex(CyaSSL_Mutex* m)
7041 if (tx_mutex_put(m) == 0)
7044 return BAD_MUTEX_ERROR;
7047 #elif defined(MICRIUM)
7049 int InitMutex(CyaSSL_Mutex* m)
7051 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
7052 if (NetSecure_OS_MutexCreate(m) == 0)
7055 return BAD_MUTEX_ERROR;
7062 int FreeMutex(CyaSSL_Mutex* m)
7064 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
7065 if (NetSecure_OS_FreeMutex(m) == 0)
7068 return BAD_MUTEX_ERROR;
7075 int LockMutex(CyaSSL_Mutex* m)
7077 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
7078 if (NetSecure_OS_LockMutex(m) == 0)
7081 return BAD_MUTEX_ERROR;
7088 int UnLockMutex(CyaSSL_Mutex* m)
7090 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
7091 if (NetSecure_OS_UnLockMutex(m) == 0)
7094 return BAD_MUTEX_ERROR;
7101 #endif /* USE_WINDOWS_API */
7102 #endif /* SINGLE_THREADED */