From 50a00d4ff08707bb645f20a77283c8c5d68a6d66 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Tue, 21 Oct 2014 15:43:43 -0600 Subject: [PATCH 01/13] add PicoTCP support --- cyassl/ctaocrypt/settings.h | 24 ++++++++++++++++++++++++ src/io.c | 14 +++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/cyassl/ctaocrypt/settings.h b/cyassl/ctaocrypt/settings.h index 36141a6bc..89c7abd33 100644 --- a/cyassl/ctaocrypt/settings.h +++ b/cyassl/ctaocrypt/settings.h @@ -93,6 +93,12 @@ /* Uncomment next line if using TI-RTOS settings */ /* #define CYASSL_TIRTOS */ +/* Uncomment next line if building with PicoTCP */ +/* #define CYASSL_PICOTCP */ + +/* Uncomment next line if building for PicoTCP demo bundle */ +/* #define CYASSL_PICOTCP_DEMO */ + #include #ifdef IPHONE @@ -228,6 +234,24 @@ #define NO_MAIN_DRIVER #endif +#ifdef CYASSL_PICOTCP + #define errno pico_err + #include "pico_defines.h" + #include "pico_stack.h" + #include "pico_constants.h" + #include "pico_bsd_sockets.h" + #define CUSTOM_RAND_GENERATE pico_rand +#endif + +#ifdef CYASSL_PICOTCP_DEMO + #define CYASSL_STM32 + #define FREERTOS + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define XMALLOC(s, h, type) pvPortMalloc((s)) + #define XFREE(p, h, type) vPortFree((p)) +#endif + #ifdef FREERTOS_WINSIM #define FREERTOS #define USE_WINDOWS_API diff --git a/src/io.c b/src/io.c index 10e18fb17..d0645875c 100644 --- a/src/io.c +++ b/src/io.c @@ -80,7 +80,8 @@ #include #endif #include - #if !(defined(DEVKITPRO) || defined(HAVE_RTP_SYS) || defined(EBSNET)) + #if !(defined(DEVKITPRO) || defined(HAVE_RTP_SYS) || defined(EBSNET)) \ + || defined(CYASSL_PICOTCP) #include #include #include @@ -153,6 +154,14 @@ #define SOCKET_ECONNREFUSED SCK_ERROR #define SOCKET_ECONNABORTED SCK_ERROR #endif +#elif defined(CYASSL_PICOTCP) + #define SOCKET_EWOULDBLOCK PICO_ERR_EAGAIN + #define SOCKET_EAGAIN PICO_ERR_EAGAIN + #define SOCKET_ECONNRESET PICO_ERR_ECONNRESET + #define SOCKET_EINTR PICO_ERR_EINTR + #define SOCKET_EPIPE PICO_ERR_EIO + #define SOCKET_ECONNREFUSED PICO_ERR_ECONNREFUSED + #define SOCKET_ECONNABORTED PICO_ERR_ESHUTDOWN #else #define SOCKET_EWOULDBLOCK EWOULDBLOCK #define SOCKET_EAGAIN EAGAIN @@ -173,6 +182,9 @@ #elif defined(CYASSL_LWIP) #define SEND_FUNCTION lwip_send #define RECV_FUNCTION lwip_recv +#elif defined(CYASSL_PICOTCP) + #define SEND_FUNCTION pico_send + #define RECV_FUNCTION pico_recv #else #define SEND_FUNCTION send #define RECV_FUNCTION recv From 37c16272343f756d43b283bae61bf241348e57a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Fri, 17 Oct 2014 15:04:22 -0300 Subject: [PATCH 02/13] internal.c: refactoring BuildFinished to reduce stack usage: --- variable md5 moved to the heap (sizeof(Md5) saved) --- variable sha moved to the heap (sizeof(Sha) saved) --- variable sha256 moved to the heap (sizeof(Sha256) saved) --- variable sha384 moved to the heap (sizeof(Sha384) saved) --- src/internal.c | 106 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 11 deletions(-) diff --git a/src/internal.c b/src/internal.c index cb6429094..a44bbfc60 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3187,24 +3187,91 @@ static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender) static int BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) { + int ret = 0; +#ifdef CYASSL_SMALL_STACK + #ifndef NO_OLD_TLS + #ifndef NO_MD5 + Md5* md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifndef NO_SHA + Sha* sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #endif + #ifndef NO_SHA256 + Sha256* sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + Sha384* sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif +#else + #ifndef NO_OLD_TLS + #ifndef NO_MD5 + Md5 md5[1]; + #endif + #ifndef NO_SHA + Sha sha[1]; + #endif + #endif + #ifndef NO_SHA256 + Sha256 sha256[1]; + #endif + #ifdef CYASSL_SHA384 + Sha384 sha384[1]; + #endif +#endif + +#ifdef CYASSL_SMALL_STACK + if (ssl == NULL + #ifndef NO_OLD_TLS + #ifndef NO_MD5 + || md5 == NULL + #endif + #ifndef NO_SHA + || sha == NULL + #endif + #endif + #ifndef NO_SHA256 + || sha256 == NULL + #endif + #ifdef CYASSL_SHA384 + || sha384 == NULL + #endif + ) { + #ifndef NO_OLD_TLS + #ifndef NO_MD5 + XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifndef NO_SHA + XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #endif + #ifndef NO_SHA256 + XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return MEMORY_E; + } +#endif + /* store current states, building requires get_digest which resets state */ #ifndef NO_OLD_TLS #ifndef NO_MD5 - Md5 md5 = ssl->hashMd5; + md5[0] = ssl->hashMd5; #endif #ifndef NO_SHA - Sha sha = ssl->hashSha; -#endif + sha[0] = ssl->hashSha; + #endif #endif #ifndef NO_SHA256 - Sha256 sha256 = ssl->hashSha256; + sha256[0] = ssl->hashSha256; #endif #ifdef CYASSL_SHA384 - Sha384 sha384 = ssl->hashSha384; + sha384[0] = ssl->hashSha384; #endif - int ret = 0; - #ifndef NO_TLS if (ssl->options.tls) { ret = BuildTlsFinished(ssl, hashes, sender); @@ -3220,21 +3287,38 @@ static int BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) /* restore */ #ifndef NO_OLD_TLS #ifndef NO_MD5 - ssl->hashMd5 = md5; + ssl->hashMd5 = md5[0]; #endif #ifndef NO_SHA - ssl->hashSha = sha; + ssl->hashSha = sha[0]; #endif #endif if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 - ssl->hashSha256 = sha256; + ssl->hashSha256 = sha256[0]; #endif #ifdef CYASSL_SHA384 - ssl->hashSha384 = sha384; + ssl->hashSha384 = sha384[0]; #endif } +#ifdef CYASSL_SMALL_STACK +#ifndef NO_OLD_TLS +#ifndef NO_MD5 + XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif +#ifndef NO_SHA + XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif +#endif +#ifndef NO_SHA256 + XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif +#ifdef CYASSL_SHA384 + XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif +#endif + return ret; } From 5ef9a21eaab9a626e72f89b8deda1a805ba58093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Fri, 17 Oct 2014 16:16:50 -0300 Subject: [PATCH 03/13] internal.c: refactoring DoCertificate to reduce stack usage: --- variable domain moved to the heap (256 bytes saved) --- variable dCert moved to the heap (sizeof(DecodedCert) saved) --- variable store moved to the heap (sizeof(CYASSL_X509_STORE_CTX) saved) --- src/internal.c | 177 ++++++++++++++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 68 deletions(-) diff --git a/src/internal.c b/src/internal.c index a44bbfc60..4546c143d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4035,14 +4035,24 @@ int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert) static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, word32 size) { - word32 listSz, begin = *inOutIdx; + word32 listSz; + word32 begin = *inOutIdx; int ret = 0; int anyError = 0; int totalCerts = 0; /* number of certs in certs buffer */ int count; - char domain[ASN_NAME_MAX]; buffer certs[MAX_CHAIN_DEPTH]; +#ifdef CYASSL_SMALL_STACK + char* domain = NULL; + DecodedCert* dCert = NULL; + CYASSL_X509_STORE_CTX* store = NULL; +#else + char domain[ASN_NAME_MAX]; + DecodedCert dCert[1]; + CYASSL_X509_STORE_CTX store[1]; +#endif + #ifdef CYASSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo); if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo); @@ -4109,22 +4119,28 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, count = totalCerts; +#ifdef CYASSL_SMALL_STACK + dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (dCert == NULL) + return MEMORY_E; +#endif + /* verify up to peer's first */ while (count > 1) { buffer myCert = certs[count - 1]; - DecodedCert dCert; byte* subjectHash; - InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap); - ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone, + InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap); + ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone, ssl->ctx->cm); #ifndef NO_SKID - subjectHash = dCert.extSubjKeyId; + subjectHash = dCert->extSubjKeyId; #else - subjectHash = dCert.subjectHash; + subjectHash = dCert->subjectHash; #endif - if (ret == 0 && dCert.isCA == 0) { + if (ret == 0 && dCert->isCA == 0) { CYASSL_MSG("Chain cert is not a CA, not adding as one"); } else if (ret == 0 && ssl->options.verifyNone) { @@ -4155,7 +4171,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_CRL if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) { CYASSL_MSG("Doing Non Leaf CRL check"); - ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert); + ret = CheckCertCRL(ssl->ctx->cm->crl, dCert); if (ret != 0) { CYASSL_MSG("\tCRL check not ok"); @@ -4166,20 +4182,19 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, if (ret != 0 && anyError == 0) anyError = ret; /* save error from last time */ - FreeDecodedCert(&dCert); + FreeDecodedCert(dCert); count--; } /* peer's, may not have one if blank client cert sent by TLSv1.2 */ if (count) { buffer myCert = certs[0]; - DecodedCert dCert; - int fatal = 0; + int fatal = 0; CYASSL_MSG("Verifying Peer's cert"); - InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap); - ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone, + InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap); + ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone, ssl->ctx->cm); if (ret == 0) { CYASSL_MSG("Verified Peer's cert"); @@ -4207,7 +4222,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, if (ssl->keys.encryptionOn) { /* compare against previous time */ - if (XMEMCMP(dCert.subjectHash, + if (XMEMCMP(dCert->subjectHash, ssl->secure_renegotiation->subject_hash, SHA_DIGEST_SIZE) != 0) { CYASSL_MSG("Peer sent different cert during scr, fatal"); @@ -4219,14 +4234,14 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, /* cache peer's hash */ if (fatal == 0) { XMEMCPY(ssl->secure_renegotiation->subject_hash, - dCert.subjectHash, SHA_DIGEST_SIZE); + dCert->subjectHash, SHA_DIGEST_SIZE); } } #endif #ifdef HAVE_OCSP if (fatal == 0 && ssl->ctx->cm->ocspEnabled) { - ret = CheckCertOCSP(ssl->ctx->cm->ocsp, &dCert); + ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert); if (ret != 0) { CYASSL_MSG("\tOCSP Lookup not ok"); fatal = 0; @@ -4246,7 +4261,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, if (doCrlLookup) { CYASSL_MSG("Doing Leaf CRL check"); - ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert); + ret = CheckCertCRL(ssl->ctx->cm->crl, dCert); if (ret != 0) { CYASSL_MSG("\tCRL check not ok"); @@ -4260,37 +4275,37 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, #ifdef KEEP_PEER_CERT { /* set X509 format for peer cert even if fatal */ - int copyRet = CopyDecodedToX509(&ssl->peerCert, &dCert); + int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert); if (copyRet == MEMORY_E) fatal = 1; } #endif #ifndef IGNORE_KEY_EXTENSIONS - if (dCert.extKeyUsageSet) { + if (dCert->extKeyUsageSet) { if ((ssl->specs.kea == rsa_kea) && - (dCert.extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) { + (dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) { ret = KEYUSE_ENCIPHER_E; } if ((ssl->specs.sig_algo == rsa_sa_algo || (ssl->specs.sig_algo == ecc_dsa_sa_algo && !ssl->specs.static_ecdh)) && - (dCert.extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) { + (dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) { CYASSL_MSG("KeyUse Digital Sig not set"); ret = KEYUSE_SIGNATURE_E; } } - if (dCert.extExtKeyUsageSet) { + if (dCert->extExtKeyUsageSet) { if (ssl->options.side == CYASSL_CLIENT_END) { - if ((dCert.extExtKeyUsage & + if ((dCert->extExtKeyUsage & (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) { CYASSL_MSG("ExtKeyUse Server Auth not set"); ret = EXTKEYUSE_AUTH_E; } } else { - if ((dCert.extExtKeyUsage & + if ((dCert->extExtKeyUsage & (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) { CYASSL_MSG("ExtKeyUse Client Auth not set"); ret = EXTKEYUSE_AUTH_E; @@ -4300,25 +4315,36 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, #endif /* IGNORE_KEY_EXTENSIONS */ if (fatal) { - FreeDecodedCert(&dCert); + FreeDecodedCert(dCert); + #ifdef CYASSL_SMALL_STACK + XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif ssl->error = ret; return ret; } ssl->options.havePeerCert = 1; +#ifdef CYASSL_SMALL_STACK + domain = (char*)XMALLOC(ASN_NAME_MAX, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (domain == NULL) { + FreeDecodedCert(dCert); + XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif /* store for callback use */ - if (dCert.subjectCNLen < ASN_NAME_MAX) { - XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen); - domain[dCert.subjectCNLen] = '\0'; + if (dCert->subjectCNLen < ASN_NAME_MAX) { + XMEMCPY(domain, dCert->subjectCN, dCert->subjectCNLen); + domain[dCert->subjectCNLen] = '\0'; } else domain[0] = '\0'; if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) { - if (MatchDomainName(dCert.subjectCN, dCert.subjectCNLen, + if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen, (char*)ssl->buffers.domainName.buffer) == 0) { CYASSL_MSG("DomainName match on common name failed"); - if (CheckAltNames(&dCert, + if (CheckAltNames(dCert, (char*)ssl->buffers.domainName.buffer) == 0 ) { CYASSL_MSG("DomainName match on alt names failed too"); ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */ @@ -4327,7 +4353,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, } /* decode peer key */ - switch (dCert.keyOID) { + switch (dCert->keyOID) { #ifndef NO_RSA case RSAk: { @@ -4340,8 +4366,8 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, keyRet = InitRsaKey(ssl->peerRsaKey, ssl->heap); } - if (keyRet != 0 || RsaPublicKeyDecode(dCert.publicKey, &idx, - ssl->peerRsaKey, dCert.pubKeySize) != 0) { + if (keyRet != 0 || RsaPublicKeyDecode(dCert->publicKey, + &idx, ssl->peerRsaKey, dCert->pubKeySize) != 0) { ret = PEER_KEY_ERROR; } else { @@ -4349,15 +4375,15 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_PK_CALLBACKS #ifndef NO_RSA ssl->buffers.peerRsaKey.buffer = - XMALLOC(dCert.pubKeySize, + XMALLOC(dCert->pubKeySize, ssl->heap, DYNAMIC_TYPE_RSA); if (ssl->buffers.peerRsaKey.buffer == NULL) ret = MEMORY_ERROR; else { XMEMCPY(ssl->buffers.peerRsaKey.buffer, - dCert.publicKey, dCert.pubKeySize); + dCert->publicKey, dCert->pubKeySize); ssl->buffers.peerRsaKey.length = - dCert.pubKeySize; + dCert->pubKeySize; } #endif /* NO_RSA */ #endif /*HAVE_PK_CALLBACKS */ @@ -4368,12 +4394,13 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_NTRU case NTRUk: { - if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) { + if (dCert->pubKeySize > sizeof(ssl->peerNtruKey)) { ret = PEER_KEY_ERROR; } else { - XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize); - ssl->peerNtruKeyLen = (word16)dCert.pubKeySize; + XMEMCPY(ssl->peerNtruKey, dCert->publicKey, + dCert->pubKeySize); + ssl->peerNtruKeyLen = (word16)dCert->pubKeySize; ssl->peerNtruKeyPresent = 1; } } @@ -4387,7 +4414,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, ssl->peerEccDsaKeyPresent = 0; ecc_init(ssl->peerEccDsaKey); } - if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize, + if (ecc_import_x963(dCert->publicKey, dCert->pubKeySize, ssl->peerEccDsaKey) != 0) { ret = PEER_KEY_ERROR; } @@ -4396,15 +4423,15 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_PK_CALLBACKS #ifdef HAVE_ECC ssl->buffers.peerEccDsaKey.buffer = - XMALLOC(dCert.pubKeySize, + XMALLOC(dCert->pubKeySize, ssl->heap, DYNAMIC_TYPE_ECC); if (ssl->buffers.peerEccDsaKey.buffer == NULL) ret = MEMORY_ERROR; else { XMEMCPY(ssl->buffers.peerEccDsaKey.buffer, - dCert.publicKey, dCert.pubKeySize); + dCert->publicKey, dCert->pubKeySize); ssl->buffers.peerEccDsaKey.length = - dCert.pubKeySize; + dCert->pubKeySize; } #endif /* HAVE_ECC */ #endif /*HAVE_PK_CALLBACKS */ @@ -4416,42 +4443,52 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, break; } - FreeDecodedCert(&dCert); + FreeDecodedCert(dCert); } +#ifdef CYASSL_SMALL_STACK + XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + store = (CYASSL_X509_STORE_CTX*)XMALLOC(sizeof(CYASSL_X509_STORE_CTX), + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (store == NULL) { + XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif + if (anyError != 0 && ret == 0) ret = anyError; - if (ret != 0) { if (!ssl->options.verifyNone) { int why = bad_certificate; + if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E) why = certificate_expired; if (ssl->verifyCallback) { - int ok; - CYASSL_X509_STORE_CTX store; + int ok; - store.error = ret; - store.error_depth = totalCerts; - store.discardSessionCerts = 0; - store.domain = domain; - store.userCtx = ssl->verifyCbCtx; + store->error = ret; + store->error_depth = totalCerts; + store->discardSessionCerts = 0; + store->domain = domain; + store->userCtx = ssl->verifyCbCtx; #ifdef KEEP_PEER_CERT - store.current_cert = &ssl->peerCert; + store->current_cert = &ssl->peerCert; #else - store.current_cert = NULL; + store->current_cert = NULL; #endif #ifdef FORTRESS - store.ex_data = ssl; + store->ex_data = ssl; #endif - ok = ssl->verifyCallback(0, &store); + ok = ssl->verifyCallback(0, store); if (ok) { CYASSL_MSG("Verify callback overriding error!"); ret = 0; } #ifdef SESSION_CERTS - if (store.discardSessionCerts) { + if (store->discardSessionCerts) { CYASSL_MSG("Verify callback requested discard sess certs"); ssl->session.chain.count = 0; } @@ -4468,19 +4505,18 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, else { if (ssl->verifyCallback) { int ok; - CYASSL_X509_STORE_CTX store; - store.error = ret; - store.error_depth = totalCerts; - store.discardSessionCerts = 0; - store.domain = domain; - store.userCtx = ssl->verifyCbCtx; + store->error = ret; + store->error_depth = totalCerts; + store->discardSessionCerts = 0; + store->domain = domain; + store->userCtx = ssl->verifyCbCtx; #ifdef KEEP_PEER_CERT - store.current_cert = &ssl->peerCert; + store->current_cert = &ssl->peerCert; #endif - store.ex_data = ssl; + store->ex_data = ssl; - ok = ssl->verifyCallback(1, &store); + ok = ssl->verifyCallback(1, store); if (!ok) { CYASSL_MSG("Verify callback overriding valid certificate!"); ret = -1; @@ -4488,7 +4524,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, ssl->options.isClosed = 1; } #ifdef SESSION_CERTS - if (store.discardSessionCerts) { + if (store->discardSessionCerts) { CYASSL_MSG("Verify callback requested discard sess certs"); ssl->session.chain.count = 0; } @@ -4510,6 +4546,11 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, *inOutIdx += ssl->keys.padSz; } +#ifdef CYASSL_SMALL_STACK + XFREE(store, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; } From a7e585b63dff0836d5623d273e4a8196212f3332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Fri, 17 Oct 2014 16:31:09 -0300 Subject: [PATCH 04/13] internal.c: refactoring BuildMessage to reduce stack usage: --- variable hmac moved to the heap (up to 64 bytes saved) --- src/internal.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index 4546c143d..4ccda921a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6928,11 +6928,26 @@ static int BuildMessage(CYASSL* ssl, byte* output, int outSz, if (ssl->specs.cipher_type != aead) { #ifdef HAVE_TRUNCATED_HMAC if (ssl->truncated_hmac && ssl->specs.hash_size > digestSz) { - byte hmac[MAX_DIGEST_SIZE]; + #ifdef CYASSL_SMALL_STACK + byte* hmac = NULL; + #else + byte hmac[MAX_DIGEST_SIZE]; + #endif + + #ifdef CYASSL_SMALL_STACK + hmac = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (hmac == NULL) + return MEMORY_E; + #endif ret = ssl->hmac(ssl, hmac, output + headerSz + ivSz, inSz, - type, 0); + type, 0); XMEMCPY(output + idx, hmac, digestSz); + + #ifdef CYASSL_SMALL_STACK + XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif } else #endif ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, From 845e49781f07882f063f9c444a490db362d6458b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Fri, 17 Oct 2014 16:44:42 -0300 Subject: [PATCH 05/13] internal.c: refactoring DoServerHello to reduce stack usage: --- variable clSuites removed (sizeof(Suites) saved) ps.: TLSX_Parse() does not requires the suites parameter at client side. --- src/internal.c | 3 +-- src/tls.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index 4ccda921a..85f817fe3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9275,7 +9275,6 @@ static void PickHashSigAlgo(CYASSL* ssl, if (TLSX_SupportExtensions(ssl)) { int ret = 0; word16 totalExtSz; - Suites clSuites; /* just for compatibility right now */ if ((i - begin) + OPAQUE16_LEN > helloSz) return BUFFER_ERROR; @@ -9287,7 +9286,7 @@ static void PickHashSigAlgo(CYASSL* ssl, return BUFFER_ERROR; if ((ret = TLSX_Parse(ssl, (byte *) input + i, - totalExtSz, 0, &clSuites))) + totalExtSz, 0, NULL))) return ret; i += totalExtSz; diff --git a/src/tls.c b/src/tls.c index 93e8dcf32..6b67711e6 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2149,7 +2149,7 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest, int ret = 0; word16 offset = 0; - if (!ssl || !input || !suites) + if (!ssl || !input || (isRequest && !suites)) return BAD_FUNC_ARG; while (ret == 0 && offset < length) { From 9368c8d1e82c71ffa06b1dfbafe47a371c9d829f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Sat, 18 Oct 2014 14:31:14 -0300 Subject: [PATCH 06/13] internal.c: refactoring SendCertificateVerify to reduce stack usage: --- variable encodedSig moved to the heap (512 bytes saved) --- src/internal.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 85f817fe3..c48fb26a9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10388,8 +10388,27 @@ static void PickHashSigAlgo(CYASSL* ssl, byte* signBuffer = NULL; #endif word32 signSz = FINISHED_SZ; - byte encodedSig[MAX_ENCODED_SIG_SZ]; word32 extraSz = 0; /* tls 1.2 hash/sig */ +#ifdef CYASSL_SMALL_STACK + byte* encodedSig = NULL; +#else + byte encodedSig[MAX_ENCODED_SIG_SZ]; +#endif + +#ifdef CYASSL_SMALL_STACK + encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encodedSig == NULL) { + #ifndef NO_RSA + if (initRsaKey) + FreeRsaKey(&key); + #endif + #ifdef HAVE_ECC + ecc_free(&eccKey); + #endif + return MEMORY_E; + } +#endif (void)encodedSig; (void)signSz; @@ -10541,6 +10560,10 @@ static void PickHashSigAlgo(CYASSL* ssl, ret = 0; /* RSA reset */ } #endif +#ifdef CYASSL_SMALL_STACK + XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + if (ret == 0) { AddHeaders(output, length + extraSz + VERIFY_HEADER, certificate_verify, ssl); From 949094cfbc3e7a583ce94dfb36c0dd7d32093bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Sat, 18 Oct 2014 14:38:57 -0300 Subject: [PATCH 07/13] internal.c: refactoring DoCertificateVerify to reduce stack usage: --- variable encodedSig moved to the heap (512 bytes saved) --- src/internal.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/internal.c b/src/internal.c index c48fb26a9..81e3ed203 100644 --- a/src/internal.c +++ b/src/internal.c @@ -12333,12 +12333,23 @@ int DoSessionTicket(CYASSL* ssl, } if (IsAtLeastTLSv1_2(ssl)) { +#ifdef CYASSL_SMALL_STACK + byte* encodedSig = NULL; +#else byte encodedSig[MAX_ENCODED_SIG_SZ]; +#endif word32 sigSz; byte* digest = ssl->certHashes.sha; int typeH = SHAh; int digestSz = SHA_DIGEST_SIZE; +#ifdef CYASSL_SMALL_STACK + encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encodedSig == NULL) + return MEMORY_E; +#endif + if (sigAlgo != rsa_sa_algo) { CYASSL_MSG("Oops, peer sent RSA key but not in verify"); } @@ -12363,6 +12374,10 @@ int DoSessionTicket(CYASSL* ssl, if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig, min(sigSz, MAX_ENCODED_SIG_SZ)) == 0) ret = 0; /* verified */ + +#ifdef CYASSL_SMALL_STACK + XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif } else { if (outLen == FINISHED_SZ && out && XMEMCMP(out, From 7f836cd6b30c42d631ecf91c22a03990ec69a4cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Sat, 18 Oct 2014 15:21:40 -0300 Subject: [PATCH 08/13] internal.c: refactoring SendClientKeyExchange to reduce stack usage: --- variable encSecret moved to the heap (1027 bytes saved) --- variables priv moved to the heap (1024 bytes saved) --- src/internal.c | 208 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 174 insertions(+), 34 deletions(-) diff --git a/src/internal.c b/src/internal.c index 81e3ed203..4ccb45f63 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9942,7 +9942,11 @@ static void PickHashSigAlgo(CYASSL* ssl, int SendClientKeyExchange(CYASSL* ssl) { +#ifdef CYASSL_SMALL_STACK + byte* encSecret = NULL; +#else byte encSecret[MAX_ENCRYPT_SZ]; +#endif word32 encSz = 0; word32 idx = 0; int ret = 0; @@ -9950,32 +9954,47 @@ static void PickHashSigAlgo(CYASSL* ssl, (void)doUserRsa; - #ifdef HAVE_PK_CALLBACKS - #ifndef NO_RSA - if (ssl->ctx->RsaEncCb) - doUserRsa = 1; - #endif /* NO_RSA */ - #endif /*HAVE_PK_CALLBACKS */ +#ifdef HAVE_PK_CALLBACKS + #ifndef NO_RSA + if (ssl->ctx->RsaEncCb) + doUserRsa = 1; + #endif /* NO_RSA */ +#endif /*HAVE_PK_CALLBACKS */ + + #ifdef CYASSL_SMALL_STACK + encSecret = (byte*)XMALLOC(MAX_ENCRYPT_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encSecret == NULL) + return MEMORY_E; + #endif switch (ssl->specs.kea) { #ifndef NO_RSA case rsa_kea: ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, SECRET_LEN); - if (ret != 0) + if (ret != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; + } ssl->arrays->preMasterSecret[0] = ssl->chVersion.major; ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor; ssl->arrays->preMasterSz = SECRET_LEN; - if (ssl->peerRsaKeyPresent == 0) + if (ssl->peerRsaKeyPresent == 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } if (doUserRsa) { #ifdef HAVE_PK_CALLBACKS #ifndef NO_RSA - encSz = sizeof(encSecret); + encSz = MAX_ENCRYPT_SZ; ret = ssl->ctx->RsaEncCb(ssl, ssl->arrays->preMasterSecret, SECRET_LEN, @@ -9988,7 +10007,7 @@ static void PickHashSigAlgo(CYASSL* ssl, } else { ret = RsaPublicEncrypt(ssl->arrays->preMasterSecret, - SECRET_LEN, encSecret, sizeof(encSecret), + SECRET_LEN, encSecret, MAX_ENCRYPT_SZ, ssl->peerRsaKey, ssl->rng); if (ret > 0) { encSz = ret; @@ -10003,13 +10022,30 @@ static void PickHashSigAlgo(CYASSL* ssl, buffer serverP = ssl->buffers.serverDH_P; buffer serverG = ssl->buffers.serverDH_G; buffer serverPub = ssl->buffers.serverDH_Pub; + #ifdef CYASSL_SMALL_STACK + byte* priv = NULL; + #else byte priv[ENCRYPT_LEN]; + #endif word32 privSz = 0; DhKey key; if (serverP.buffer == 0 || serverG.buffer == 0 || - serverPub.buffer == 0) + serverPub.buffer == 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } + + #ifdef CYASSL_SMALL_STACK + priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (priv == NULL) { + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + #endif InitDhKey(&key); ret = DhSetKey(&key, serverP.buffer, serverP.length, @@ -10022,6 +10058,9 @@ static void PickHashSigAlgo(CYASSL* ssl, ret = DhAgree(&key, ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, priv, privSz, serverPub.buffer, serverPub.length); + #ifdef CYASSL_SMALL_STACK + XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif FreeDhKey(&key); } break; @@ -10035,10 +10074,19 @@ static void PickHashSigAlgo(CYASSL* ssl, ssl->arrays->server_hint, ssl->arrays->client_identity, MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); if (ssl->arrays->psk_keySz == 0 || - ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return PSK_KEY_ERROR; + } encSz = (word32)XSTRLEN(ssl->arrays->client_identity); - if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR; + if (encSz > MAX_PSK_ID_LEN) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return CLIENT_ID_ERROR; + } XMEMCPY(encSecret, ssl->arrays->client_identity, encSz); /* make psk pre master secret */ @@ -10064,26 +10112,51 @@ static void PickHashSigAlgo(CYASSL* ssl, buffer serverP = ssl->buffers.serverDH_P; buffer serverG = ssl->buffers.serverDH_G; buffer serverPub = ssl->buffers.serverDH_Pub; + #ifdef CYASSSL_SMALL_STACK + byte* priv = NULL; + #else byte priv[ENCRYPT_LEN]; + #endif word32 privSz = 0; word32 pubSz = 0; word32 esSz = 0; DhKey key; if (serverP.buffer == 0 || serverG.buffer == 0 || - serverPub.buffer == 0) + serverPub.buffer == 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, ssl->arrays->server_hint, ssl->arrays->client_identity, MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); if (ssl->arrays->psk_keySz == 0 || - ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return PSK_KEY_ERROR; + } esSz = (word32)XSTRLEN(ssl->arrays->client_identity); - if (esSz > MAX_PSK_ID_LEN) + if (esSz > MAX_PSK_ID_LEN) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return CLIENT_ID_ERROR; + } + + #ifdef CYASSL_SMALL_STACK + priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (priv == NULL) { + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + #endif c16toa((word16)esSz, es); es += OPAQUE16_LEN; XMEMCPY(es, ssl->arrays->client_identity, esSz); @@ -10102,8 +10175,15 @@ static void PickHashSigAlgo(CYASSL* ssl, &ssl->arrays->preMasterSz, priv, privSz, serverPub.buffer, serverPub.length); FreeDhKey(&key); - if (ret != 0) + #ifdef CYASSL_SMALL_STACK + XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + if (ret != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; + } c16toa((word16)pubSz, es); encSz += pubSz + OPAQUE16_LEN; @@ -10127,7 +10207,7 @@ static void PickHashSigAlgo(CYASSL* ssl, case ntru_kea: { word32 rc; - word16 cipherLen = sizeof(encSecret); + word16 cipherLen = MAX_ENCRYPT_SZ; DRBG_HANDLE drbg; static uint8_t const cyasslStr[] = { 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U' @@ -10135,19 +10215,31 @@ static void PickHashSigAlgo(CYASSL* ssl, ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, SECRET_LEN); - if (ret != 0) + if (ret != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; + } ssl->arrays->preMasterSz = SECRET_LEN; - if (ssl->peerNtruKeyPresent == 0) + if (ssl->peerNtruKeyPresent == 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } rc = ntru_crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr, sizeof(cyasslStr), GetEntropy, &drbg); - if (rc != DRBG_OK) - return NTRU_DRBG_ERROR; + if (rc != DRBG_OK) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return NTRU_DRBG_ERROR; + } rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen, ssl->peerNtruKey, @@ -10155,8 +10247,12 @@ static void PickHashSigAlgo(CYASSL* ssl, ssl->arrays->preMasterSecret, &cipherLen, encSecret); ntru_crypto_drbg_uninstantiate(drbg); - if (rc != NTRU_OK) + if (rc != NTRU_OK) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NTRU_ENCRYPT_ERROR; + } encSz = cipherLen; ret = 0; @@ -10168,27 +10264,44 @@ static void PickHashSigAlgo(CYASSL* ssl, { ecc_key myKey; ecc_key* peerKey = NULL; - word32 size = sizeof(encSecret); + word32 size = MAX_ENCRYPT_SZ; if (ssl->specs.static_ecdh) { /* TODO: EccDsa is really fixed Ecc change naming */ - if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey->dp) + if (!ssl->peerEccDsaKeyPresent || + !ssl->peerEccDsaKey->dp) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } peerKey = ssl->peerEccDsaKey; } else { - if (!ssl->peerEccKeyPresent || !ssl->peerEccKey->dp) + if (!ssl->peerEccKeyPresent || !ssl->peerEccKey->dp) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } peerKey = ssl->peerEccKey; } - if (peerKey == NULL) + if (peerKey == NULL) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } ecc_init(&myKey); ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey); - if (ret != 0) + if (ret != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ECC_MAKEKEY_ERROR; + } /* precede export with 1 byte length */ ret = ecc_export_x963(&myKey, encSecret + 1, &size); @@ -10211,6 +10324,9 @@ static void PickHashSigAlgo(CYASSL* ssl, break; #endif /* HAVE_ECC */ default: + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ALGO_ID_E; /* unsupported kea */ } @@ -10240,8 +10356,12 @@ static void PickHashSigAlgo(CYASSL* ssl, sendSz += MAX_MSG_EXTRA; /* check for available size */ - if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) + if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; + } /* get ouput buffer */ output = ssl->buffers.outputBuffer.buffer + @@ -10262,25 +10382,41 @@ static void PickHashSigAlgo(CYASSL* ssl, input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (input == NULL) + if (input == NULL) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return MEMORY_E; + } XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); sendSz = BuildMessage(ssl, output, sendSz, input, inputSz, handshake); XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (sendSz < 0) + if (sendSz < 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return sendSz; + } } else { ret = HashOutput(ssl, output, sendSz, 0); - if (ret != 0) + if (ret != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; + } } #ifdef CYASSL_DTLS if (ssl->options.dtls) { - if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) + if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; + } } #endif @@ -10299,7 +10435,11 @@ static void PickHashSigAlgo(CYASSL* ssl, else ret = SendBuffered(ssl); } - + + #ifdef CYASSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + if (ret == 0 || ret == WANT_WRITE) { int tmpRet = MakeMasterSecret(ssl); if (tmpRet != 0) From 0447bf755130c8f5ca6d4e3ba259ec2290470ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Sat, 18 Oct 2014 16:08:52 -0300 Subject: [PATCH 09/13] internal.c: refactoring DoServerKeyExchange to reduce stack usage: --- variable md5 moved to the heap (sizeof(Md5) saved) --- variable sha moved to the heap (sizeof(Sha) saved) --- variable sha256 moved to the heap (sizeof(Sha256) saved) --- variable sha384 moved to the heap (sizeof(Sha384) saved) --- src/internal.c | 131 +++++++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 48 deletions(-) diff --git a/src/internal.c b/src/internal.c index 4ccb45f63..0e38196a5 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9687,22 +9687,35 @@ static void PickHashSigAlgo(CYASSL* ssl, ssl->specs.kea == diffie_hellman_kea) { #ifndef NO_OLD_TLS - Md5 md5; - Sha sha; +#ifdef CYASSL_SMALL_STACK + Md5* md5; + Sha* sha; +#else + Md5 md5[0]; + Sha sha[0]; +#endif #endif #ifndef NO_SHA256 - Sha256 sha256; - byte hash256[SHA256_DIGEST_SIZE]; +#ifdef CYASSL_SMALL_STACK + Sha256* sha256; +#else + Sha256 sha256[0]; +#endif + byte hash256[SHA256_DIGEST_SIZE]; #endif #ifdef CYASSL_SHA384 - Sha384 sha384; - byte hash384[SHA384_DIGEST_SIZE]; +#ifdef CYASSL_SMALL_STACK + Sha384* sha384; +#else + Sha384 sha384[0]; #endif - byte hash[FINISHED_SZ]; - byte messageVerify[MAX_DH_SZ]; - byte hashAlgo = sha_mac; - byte sigAlgo = ssl->specs.sig_algo; - word16 verifySz = (word16) (*inOutIdx - begin); + byte hash384[SHA384_DIGEST_SIZE]; +#endif + byte hash[FINISHED_SZ]; + byte messageVerify[MAX_DH_SZ]; + byte hashAlgo = sha_mac; + byte sigAlgo = ssl->specs.sig_algo; + word16 verifySz = (word16) (*inOutIdx - begin); /* save message for hash verify */ if (verifySz > sizeof(messageVerify)) @@ -9733,54 +9746,76 @@ static void PickHashSigAlgo(CYASSL* ssl, /* verify signature */ #ifndef NO_OLD_TLS /* md5 */ - InitMd5(&md5); - Md5Update(&md5, ssl->arrays->clientRandom, RAN_LEN); - Md5Update(&md5, ssl->arrays->serverRandom, RAN_LEN); - Md5Update(&md5, messageVerify, verifySz); - Md5Final(&md5, hash); + #ifdef CYASSL_SMALL_STACK + md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (md5 == NULL) + return MEMORY_E; + #endif + InitMd5(md5); + Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN); + Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN); + Md5Update(md5, messageVerify, verifySz); + Md5Final(md5, hash); + #ifdef CYASSL_SMALL_STACK + XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif /* sha */ - ret = InitSha(&sha); - if (ret != 0) + #ifdef CYASSL_SMALL_STACK + sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sha == NULL) + return MEMORY_E; + #endif + ret = InitSha(sha); + if (ret != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; - ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN); - ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN); - ShaUpdate(&sha, messageVerify, verifySz); - ShaFinal(&sha, hash + MD5_DIGEST_SIZE); + } + ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN); + ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN); + ShaUpdate(sha, messageVerify, verifySz); + ShaFinal(sha, hash + MD5_DIGEST_SIZE); + #ifdef CYASSL_SMALL_STACK + XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif #endif #ifndef NO_SHA256 - ret = InitSha256(&sha256); - if (ret != 0) - return ret; - ret = Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN); - if (ret != 0) - return ret; - ret = Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN); - if (ret != 0) - return ret; - ret = Sha256Update(&sha256, messageVerify, verifySz); - if (ret != 0) - return ret; - ret = Sha256Final(&sha256, hash256); + #ifdef CYASSL_SMALL_STACK + sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sha256 == NULL) + return MEMORY_E; + #endif + if (!(ret = InitSha256(sha256)) + && !(ret = Sha256Update(sha256, ssl->arrays->clientRandom, RAN_LEN)) + && !(ret = Sha256Update(sha256, ssl->arrays->serverRandom, RAN_LEN)) + && !(ret = Sha256Update(sha256, messageVerify, verifySz))) + ret = Sha256Final(sha256, hash256); + #ifdef CYASSL_SMALL_STACK + XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif if (ret != 0) return ret; #endif #ifdef CYASSL_SHA384 - ret = InitSha384(&sha384); - if (ret != 0) - return ret; - ret = Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN); - if (ret != 0) - return ret; - ret = Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN); - if (ret != 0) - return ret; - ret = Sha384Update(&sha384, messageVerify, verifySz); - if (ret != 0) - return ret; - ret = Sha384Final(&sha384, hash384); + #ifdef CYASSL_SMALL_STACK + sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sha384 == NULL) + return MEMORY_E; + #endif + if (!(ret = InitSha384(sha384)) + && !(ret = Sha384Update(sha384, ssl->arrays->clientRandom, RAN_LEN)) + && !(ret = Sha384Update(sha384, ssl->arrays->serverRandom, RAN_LEN)) + && !(ret = Sha384Update(sha384, messageVerify, verifySz))) + ret = Sha384Final(sha384, hash384); + #ifdef CYASSL_SMALL_STACK + XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif if (ret != 0) return ret; #endif From 5056ebe8293f854237ea72a16e0592f94e7ac9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Mon, 20 Oct 2014 16:44:44 -0300 Subject: [PATCH 10/13] internal.c: refactoring DoServerKeyExchange to reduce stack usage: --- variable hash256 moved to the heap (32 bytes saved) --- variable hash384 moved to the heap (48 bytes saved) --- variable hash moved to the heap (36 bytes saved) --- variable messageVerify moved to the heap (612 bytes saved) --- variable encodedSig moved to the heap (512 bytes saved) --- src/internal.c | 223 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 198 insertions(+), 25 deletions(-) diff --git a/src/internal.c b/src/internal.c index 0e38196a5..8446f944e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9688,8 +9688,8 @@ static void PickHashSigAlgo(CYASSL* ssl, { #ifndef NO_OLD_TLS #ifdef CYASSL_SMALL_STACK - Md5* md5; - Sha* sha; + Md5* md5 = NULL; + Sha* sha = NULL; #else Md5 md5[0]; Sha sha[0]; @@ -9697,59 +9697,96 @@ static void PickHashSigAlgo(CYASSL* ssl, #endif #ifndef NO_SHA256 #ifdef CYASSL_SMALL_STACK - Sha256* sha256; + Sha256* sha256 = NULL; + byte* hash256 = NULL; #else Sha256 sha256[0]; -#endif byte hash256[SHA256_DIGEST_SIZE]; #endif +#endif #ifdef CYASSL_SHA384 #ifdef CYASSL_SMALL_STACK - Sha384* sha384; + Sha384* sha384 = NULL; + byte* hash384 = NULL; #else Sha384 sha384[0]; -#endif byte hash384[SHA384_DIGEST_SIZE]; #endif +#endif +#ifdef CYASSL_SMALL_STACK + byte* hash = NULL; + byte* messageVerify = NULL; +#else byte hash[FINISHED_SZ]; byte messageVerify[MAX_DH_SZ]; +#endif byte hashAlgo = sha_mac; byte sigAlgo = ssl->specs.sig_algo; word16 verifySz = (word16) (*inOutIdx - begin); /* save message for hash verify */ - if (verifySz > sizeof(messageVerify)) + if (verifySz > MAX_DH_SZ) return BUFFER_ERROR; + #ifdef CYASSL_SMALL_STACK + messageVerify = (byte*)XMALLOC(MAX_DH_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (messageVerify == NULL) + return MEMORY_E; + #endif + XMEMCPY(messageVerify, input + begin, verifySz); if (IsAtLeastTLSv1_2(ssl)) { - if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size) + if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size) { + #ifdef CYASSL_SMALL_STACK + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return BUFFER_ERROR; + } hashAlgo = input[(*inOutIdx)++]; sigAlgo = input[(*inOutIdx)++]; } /* signature */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { + #ifdef CYASSL_SMALL_STACK + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return BUFFER_ERROR; + } ato16(input + *inOutIdx, &length); *inOutIdx += OPAQUE16_LEN; - if ((*inOutIdx - begin) + length > size) + if ((*inOutIdx - begin) + length > size) { + #ifdef CYASSL_SMALL_STACK + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return BUFFER_ERROR; + } /* inOutIdx updated at the end of the function */ /* verify signature */ + #ifdef CYASSL_SMALL_STACK + hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (hash == NULL) { + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } + #endif + #ifndef NO_OLD_TLS /* md5 */ #ifdef CYASSL_SMALL_STACK md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (md5 == NULL) + if (md5 == NULL) { + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; + } #endif InitMd5(md5); Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN); @@ -9763,13 +9800,18 @@ static void PickHashSigAlgo(CYASSL* ssl, /* sha */ #ifdef CYASSL_SMALL_STACK sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sha == NULL) + if (sha == NULL) { + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; + } #endif ret = InitSha(sha); if (ret != 0) { #ifdef CYASSL_SMALL_STACK - XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; } @@ -9786,8 +9828,15 @@ static void PickHashSigAlgo(CYASSL* ssl, #ifdef CYASSL_SMALL_STACK sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sha256 == NULL) + hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sha256 == NULL || hash256 == NULL) { + XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; + } #endif if (!(ret = InitSha256(sha256)) && !(ret = Sha256Update(sha256, ssl->arrays->clientRandom, RAN_LEN)) @@ -9797,16 +9846,32 @@ static void PickHashSigAlgo(CYASSL* ssl, #ifdef CYASSL_SMALL_STACK XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - if (ret != 0) + if (ret != 0) { + #ifdef CYASSL_SMALL_STACK + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; + } #endif #ifdef CYASSL_SHA384 #ifdef CYASSL_SMALL_STACK sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sha384 == NULL) + hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sha384 == NULL || hash384 == NULL) { + XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; + } #endif if (!(ret = InitSha384(sha384)) && !(ret = Sha384Update(sha384, ssl->arrays->clientRandom, RAN_LEN)) @@ -9816,10 +9881,23 @@ static void PickHashSigAlgo(CYASSL* ssl, #ifdef CYASSL_SMALL_STACK XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - if (ret != 0) + if (ret != 0) { + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ret; + } #endif + #ifdef CYASSL_SMALL_STACK + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifndef NO_RSA /* rsa */ if (sigAlgo == rsa_sa_algo) @@ -9832,8 +9910,18 @@ static void PickHashSigAlgo(CYASSL* ssl, doUserRsa = 1; #endif /*HAVE_PK_CALLBACKS */ - if (!ssl->peerRsaKeyPresent) + if (!ssl->peerRsaKeyPresent) { + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } if (doUserRsa) { #ifdef HAVE_PK_CALLBACKS @@ -9850,7 +9938,6 @@ static void PickHashSigAlgo(CYASSL* ssl, } if (IsAtLeastTLSv1_2(ssl)) { - byte encodedSig[MAX_ENCODED_SIG_SZ]; word32 encSigSz; #ifndef NO_OLD_TLS byte* digest = &hash[MD5_DIGEST_SIZE]; @@ -9861,6 +9948,11 @@ static void PickHashSigAlgo(CYASSL* ssl, int typeH = SHA256h; int digestSz = SHA256_DIGEST_SIZE; #endif +#ifdef CYASSL_SMALL_STACK + byte* encodedSig = NULL; +#else + byte encodedSig[MAX_ENCODED_SIG_SZ]; +#endif if (hashAlgo == sha_mac) { #ifndef NO_SHA @@ -9884,16 +9976,57 @@ static void PickHashSigAlgo(CYASSL* ssl, #endif } + #ifdef CYASSL_SMALL_STACK + encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encodedSig == NULL) { + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return MEMORY_E; + } + #endif encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH); if (encSigSz != (word32)ret || !out || XMEMCMP(out, encodedSig, - min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) + min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) { + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return VERIFY_SIGN_ERROR; + } + + #ifdef CYASSL_SMALL_STACK + XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif } else { - if (ret != sizeof(hash) || !out || XMEMCMP(out, - hash, sizeof(hash)) != 0) + if (ret != FINISHED_SZ || !out || XMEMCMP(out, + hash, FINISHED_SZ) != 0) { + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return VERIFY_SIGN_ERROR; + } } } else #endif @@ -9915,8 +10048,18 @@ static void PickHashSigAlgo(CYASSL* ssl, doUserEcc = 1; #endif - if (!ssl->peerEccDsaKeyPresent) + if (!ssl->peerEccDsaKeyPresent) { + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return NO_PEER_KEY; + } if (IsAtLeastTLSv1_2(ssl)) { if (hashAlgo == sha_mac) { @@ -9951,17 +10094,47 @@ static void PickHashSigAlgo(CYASSL* ssl, ret = ecc_verify_hash(input + *inOutIdx, length, digest, digestSz, &verify, ssl->peerEccDsaKey); } - if (ret != 0 || verify == 0) + if (ret != 0 || verify == 0) { + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return VERIFY_SIGN_ERROR; + } } - else + else { #endif /* HAVE_ECC */ + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return ALGO_ID_E; + } /* signature length */ *inOutIdx += length; ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE; + + #ifdef CYASSL_SMALL_STACK + #ifndef NO_SHA256 + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef CYASSL_SHA384 + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif } if (ssl->keys.encryptionOn) { From a60332d9a37f8678cf39bddbd2ac7c7bf72fad66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Tue, 21 Oct 2014 12:39:02 -0300 Subject: [PATCH 11/13] internal.c: refactoring DoServerKeyExchange to reduce stack usage: --- using goto to centralize resources deallocation. --- src/internal.c | 278 +++++++++++++------------------------------------ 1 file changed, 75 insertions(+), 203 deletions(-) diff --git a/src/internal.c b/src/internal.c index 8446f944e..6e660714f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9457,6 +9457,7 @@ static void PickHashSigAlgo(CYASSL* ssl, word16 length = 0; word32 begin = *inOutIdx; int ret = 0; + #define ERROR_OUT(err, exit) do { ret = err; goto exit; } while(0) (void)length; /* shut up compiler warnings */ (void)begin; @@ -9691,8 +9692,8 @@ static void PickHashSigAlgo(CYASSL* ssl, Md5* md5 = NULL; Sha* sha = NULL; #else - Md5 md5[0]; - Sha sha[0]; + Md5 md5[1]; + Sha sha[1]; #endif #endif #ifndef NO_SHA256 @@ -9700,7 +9701,7 @@ static void PickHashSigAlgo(CYASSL* ssl, Sha256* sha256 = NULL; byte* hash256 = NULL; #else - Sha256 sha256[0]; + Sha256 sha256[1]; byte hash256[SHA256_DIGEST_SIZE]; #endif #endif @@ -9709,7 +9710,7 @@ static void PickHashSigAlgo(CYASSL* ssl, Sha384* sha384 = NULL; byte* hash384 = NULL; #else - Sha384 sha384[0]; + Sha384 sha384[1]; byte hash384[SHA384_DIGEST_SIZE]; #endif #endif @@ -9726,102 +9727,70 @@ static void PickHashSigAlgo(CYASSL* ssl, /* save message for hash verify */ if (verifySz > MAX_DH_SZ) - return BUFFER_ERROR; + ERROR_OUT(BUFFER_ERROR, done); #ifdef CYASSL_SMALL_STACK messageVerify = (byte*)XMALLOC(MAX_DH_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (messageVerify == NULL) - return MEMORY_E; + ERROR_OUT(MEMORY_E, done); #endif XMEMCPY(messageVerify, input + begin, verifySz); if (IsAtLeastTLSv1_2(ssl)) { - if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size) { - #ifdef CYASSL_SMALL_STACK - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return BUFFER_ERROR; - } + if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size) + ERROR_OUT(BUFFER_ERROR, done); hashAlgo = input[(*inOutIdx)++]; sigAlgo = input[(*inOutIdx)++]; } /* signature */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - #ifdef CYASSL_SMALL_STACK - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return BUFFER_ERROR; - } + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) + ERROR_OUT(BUFFER_ERROR, done); ato16(input + *inOutIdx, &length); *inOutIdx += OPAQUE16_LEN; - if ((*inOutIdx - begin) + length > size) { - #ifdef CYASSL_SMALL_STACK - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return BUFFER_ERROR; - } + if ((*inOutIdx - begin) + length > size) + ERROR_OUT(BUFFER_ERROR, done); /* inOutIdx updated at the end of the function */ /* verify signature */ #ifdef CYASSL_SMALL_STACK hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (hash == NULL) { - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } + if (hash == NULL) + ERROR_OUT(MEMORY_E, done); #endif #ifndef NO_OLD_TLS /* md5 */ #ifdef CYASSL_SMALL_STACK md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (md5 == NULL) { - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } + if (md5 == NULL) + ERROR_OUT(MEMORY_E, done); #endif InitMd5(md5); Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN); Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN); Md5Update(md5, messageVerify, verifySz); Md5Final(md5, hash); - #ifdef CYASSL_SMALL_STACK - XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif /* sha */ #ifdef CYASSL_SMALL_STACK sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sha == NULL) { - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } + if (sha == NULL) + ERROR_OUT(MEMORY_E, done); #endif ret = InitSha(sha); - if (ret != 0) { - #ifdef CYASSL_SMALL_STACK - XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } + if (ret != 0) + goto done; ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN); ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN); ShaUpdate(sha, messageVerify, verifySz); ShaFinal(sha, hash + MD5_DIGEST_SIZE); - #ifdef CYASSL_SMALL_STACK - XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif #endif #ifndef NO_SHA256 @@ -9830,30 +9799,16 @@ static void PickHashSigAlgo(CYASSL* ssl, DYNAMIC_TYPE_TMP_BUFFER); hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sha256 == NULL || hash256 == NULL) { - XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } + if (sha256 == NULL || hash256 == NULL) + ERROR_OUT(MEMORY_E, done); #endif if (!(ret = InitSha256(sha256)) && !(ret = Sha256Update(sha256, ssl->arrays->clientRandom, RAN_LEN)) && !(ret = Sha256Update(sha256, ssl->arrays->serverRandom, RAN_LEN)) && !(ret = Sha256Update(sha256, messageVerify, verifySz))) ret = Sha256Final(sha256, hash256); - #ifdef CYASSL_SMALL_STACK - XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - if (ret != 0) { - #ifdef CYASSL_SMALL_STACK - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } + if (ret != 0) + goto done; #endif #ifdef CYASSL_SHA384 @@ -9862,80 +9817,47 @@ static void PickHashSigAlgo(CYASSL* ssl, DYNAMIC_TYPE_TMP_BUFFER); hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sha384 == NULL || hash384 == NULL) { - XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } + if (sha384 == NULL || hash384 == NULL) + ERROR_OUT(MEMORY_E, done); #endif if (!(ret = InitSha384(sha384)) && !(ret = Sha384Update(sha384, ssl->arrays->clientRandom, RAN_LEN)) && !(ret = Sha384Update(sha384, ssl->arrays->serverRandom, RAN_LEN)) && !(ret = Sha384Update(sha384, messageVerify, verifySz))) ret = Sha384Final(sha384, hash384); - #ifdef CYASSL_SMALL_STACK - XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - if (ret != 0) { - #ifdef CYASSL_SMALL_STACK - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } + if (ret != 0) + goto done; #endif - #ifdef CYASSL_SMALL_STACK - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifndef NO_RSA /* rsa */ if (sigAlgo == rsa_sa_algo) { - byte* out = NULL; - byte doUserRsa = 0; + byte* out = NULL; + byte doUserRsa = 0; + word32 verifiedSz = 0; #ifdef HAVE_PK_CALLBACKS if (ssl->ctx->RsaVerifyCb) doUserRsa = 1; #endif /*HAVE_PK_CALLBACKS */ - if (!ssl->peerRsaKeyPresent) { - #ifdef CYASSL_SMALL_STACK - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifdef CYASSL_SHA384 - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } + if (!ssl->peerRsaKeyPresent) + ERROR_OUT(NO_PEER_KEY, done); if (doUserRsa) { #ifdef HAVE_PK_CALLBACKS - ret = ssl->ctx->RsaVerifyCb(ssl, (byte *) input + *inOutIdx, - length, &out, - ssl->buffers.peerRsaKey.buffer, - ssl->buffers.peerRsaKey.length, - ssl->RsaVerifyCtx); + verifiedSz = ssl->ctx->RsaVerifyCb(ssl, + (byte *)input + *inOutIdx, + length, &out, + ssl->buffers.peerRsaKey.buffer, + ssl->buffers.peerRsaKey.length, + ssl->RsaVerifyCtx); #endif /*HAVE_PK_CALLBACKS */ } - else { - ret = RsaSSL_VerifyInline((byte *) input + *inOutIdx, length, - &out, ssl->peerRsaKey); - } + else + verifiedSz = RsaSSL_VerifyInline((byte *)input + *inOutIdx, + length, &out, ssl->peerRsaKey); if (IsAtLeastTLSv1_2(ssl)) { word32 encSigSz; @@ -9979,55 +9901,25 @@ static void PickHashSigAlgo(CYASSL* ssl, #ifdef CYASSL_SMALL_STACK encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (encodedSig == NULL) { - #ifdef CYASSL_SMALL_STACK - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifdef CYASSL_SHA384 - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return MEMORY_E; - } + if (encodedSig == NULL) + ERROR_OUT(MEMORY_E, done); #endif + encSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH); - if (encSigSz != (word32)ret || !out || XMEMCMP(out, encodedSig, - min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) { - #ifdef CYASSL_SMALL_STACK - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifdef CYASSL_SHA384 - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return VERIFY_SIGN_ERROR; - } + if (encSigSz != verifiedSz || !out || XMEMCMP(out, encodedSig, + min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) + ret = VERIFY_SIGN_ERROR; #ifdef CYASSL_SMALL_STACK XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif + if (ret != 0) + goto done; } - else { - if (ret != FINISHED_SZ || !out || XMEMCMP(out, - hash, FINISHED_SZ) != 0) { - #ifdef CYASSL_SMALL_STACK - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifdef CYASSL_SHA384 - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return VERIFY_SIGN_ERROR; - } - } + else if (verifiedSz != FINISHED_SZ || !out || XMEMCMP(out, + hash, FINISHED_SZ) != 0) + ERROR_OUT(VERIFY_SIGN_ERROR, done); } else #endif #ifdef HAVE_ECC @@ -10048,18 +9940,8 @@ static void PickHashSigAlgo(CYASSL* ssl, doUserEcc = 1; #endif - if (!ssl->peerEccDsaKeyPresent) { - #ifdef CYASSL_SMALL_STACK - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifdef CYASSL_SHA384 - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } + if (!ssl->peerEccDsaKeyPresent) + ERROR_OUT(NO_PEER_KEY, done); if (IsAtLeastTLSv1_2(ssl)) { if (hashAlgo == sha_mac) { @@ -10094,47 +9976,37 @@ static void PickHashSigAlgo(CYASSL* ssl, ret = ecc_verify_hash(input + *inOutIdx, length, digest, digestSz, &verify, ssl->peerEccDsaKey); } - if (ret != 0 || verify == 0) { - #ifdef CYASSL_SMALL_STACK - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifdef CYASSL_SHA384 - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return VERIFY_SIGN_ERROR; - } + if (ret != 0 || verify == 0) + ERROR_OUT(VERIFY_SIGN_ERROR, done); } - else { + else #endif /* HAVE_ECC */ - #ifdef CYASSL_SMALL_STACK - #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifdef CYASSL_SHA384 - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ALGO_ID_E; - } + ERROR_OUT(ALGO_ID_E, done); /* signature length */ *inOutIdx += length; ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE; - #ifdef CYASSL_SMALL_STACK + done: +#ifdef CYASSL_SMALL_STACK + #ifndef NO_OLD_TLS + XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif #ifndef NO_SHA256 - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif #ifdef CYASSL_SHA384 - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif + XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + if (ret != 0) + return ret; } if (ssl->keys.encryptionOn) { From fde4d568457c1673bcf77e51f0f95003658fcd3d Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Wed, 22 Oct 2014 12:11:31 +0200 Subject: [PATCH 12/13] Updated picoTCP support, based on newer HTTPS demo --- cyassl/ctaocrypt/settings.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cyassl/ctaocrypt/settings.h b/cyassl/ctaocrypt/settings.h index 89c7abd33..29b820b72 100644 --- a/cyassl/ctaocrypt/settings.h +++ b/cyassl/ctaocrypt/settings.h @@ -239,17 +239,20 @@ #include "pico_defines.h" #include "pico_stack.h" #include "pico_constants.h" - #include "pico_bsd_sockets.h" #define CUSTOM_RAND_GENERATE pico_rand #endif #ifdef CYASSL_PICOTCP_DEMO #define CYASSL_STM32 - #define FREERTOS #define USE_FAST_MATH #define TFM_TIMING_RESISTANT - #define XMALLOC(s, h, type) pvPortMalloc((s)) - #define XFREE(p, h, type) vPortFree((p)) + #define XMALLOC(s, h, type) PICO_ZALLOC((s)) + #define XFREE(p, h, type) PICO_FREE((p)) + #define SINGLE_THREADED + #define NO_WRITEV + #define CYASSL_USER_IO + #define NO_DEV_RANDOM + #define NO_FILESYSTEM #endif #ifdef FREERTOS_WINSIM From 6108f9cd454b4b597606b9a6f2c106025937b60f Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 22 Oct 2014 14:26:20 -0600 Subject: [PATCH 13/13] add LICENSING file --- LICENSING | 11 +++++++++++ Makefile.am | 2 ++ 2 files changed, 13 insertions(+) create mode 100644 LICENSING diff --git a/LICENSING b/LICENSING new file mode 100644 index 000000000..e43bb9f39 --- /dev/null +++ b/LICENSING @@ -0,0 +1,11 @@ + +CyaSSL and wolfCrypt are either licensed for use under the GPLv2 or a +standard commercial license. For our users who cannot use CyaSSL under +GPLv2, a commercial license to CyaSSL and wolfCrypt is available. +Please contact wolfSSL Inc. directly at: + +Email: licensing@wolfssl.com +Phone: +1 425 245-8247 + +More information can be found on the wolfSSL website at www.wolfssl.com. + diff --git a/Makefile.am b/Makefile.am index 48a5621e1..8688d878e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -56,6 +56,8 @@ EXTRA_DIST+= cyassl64.sln EXTRA_DIST+= valgrind-error.sh EXTRA_DIST+= gencertbuf.pl EXTRA_DIST+= IDE +EXTRA_DIST+= README.md +EXTRA_DIST+= LICENSING include cyassl/include.am include certs/include.am