diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 43eafea04..a9f7518a8 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -760,8 +760,8 @@ static int DecryptKey(const char* password, int passwordSz, byte* salt, int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz) { word32 inOutIdx = 0, oid; - int first, second, length, iterations, saltSz, id; - int version; + int first, second, length, version, saltSz, id; + int iterations = 0; byte salt[MAX_SALT_SIZE]; byte cbcIv[MAX_IV_SIZE]; @@ -1375,6 +1375,7 @@ static int GetName(DecodedCert* cert, int nameType) cert->srcIdx += 2; id = cert->source[cert->srcIdx++]; b = cert->source[cert->srcIdx++]; /* strType */ + (void)b; /* may want to validate? */ if (GetLength(cert->source, &cert->srcIdx, &strLen, cert->maxIdx) < 0) diff --git a/ctaocrypt/src/integer.c b/ctaocrypt/src/integer.c index 72f443ffc..3bf4e7545 100644 --- a/ctaocrypt/src/integer.c +++ b/ctaocrypt/src/integer.c @@ -116,6 +116,9 @@ mp_clear (mp_int * a) { int i; + if (a == NULL) + return; + /* only do anything if a hasn't been freed previously */ if (a->dp != NULL) { /* first zero the digits */ diff --git a/ctaocrypt/src/pwdbased.c b/ctaocrypt/src/pwdbased.c index d493bfa31..3b5e2d134 100644 --- a/ctaocrypt/src/pwdbased.c +++ b/ctaocrypt/src/pwdbased.c @@ -236,6 +236,16 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, mp_int B1; if (hashType == MD5) { + Md5 md5; + + InitMd5(&md5); + Md5Update(&md5, buffer, totalLen); + Md5Final(&md5, Ai); + + for (i = 1; i < iterations; i++) { + Md5Update(&md5, Ai, u); + Md5Final(&md5, Ai); + } } else if (hashType == SHA) { Sha sha; @@ -251,10 +261,30 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, } #ifndef NO_SHA256 else if (hashType == SHA256) { + Sha256 sha256; + + InitSha256(&sha256); + Sha256Update(&sha256, buffer, totalLen); + Sha256Final(&sha256, Ai); + + for (i = 1; i < iterations; i++) { + Sha256Update(&sha256, Ai, u); + Sha256Final(&sha256, Ai); + } } #endif #ifdef CYASSL_SHA512 else if (hashType == SHA512) { + Sha512 sha512; + + InitSha512(&sha512); + Sha512Update(&sha512, buffer, totalLen); + Sha512Final(&sha512, Ai); + + for (i = 1; i < iterations; i++) { + Sha512Update(&sha512, Ai, u); + Sha512Final(&sha512, Ai); + } } #endif diff --git a/ctaocrypt/src/rabbit.c b/ctaocrypt/src/rabbit.c index 79f5b3e92..008dffe2e 100644 --- a/ctaocrypt/src/rabbit.c +++ b/ctaocrypt/src/rabbit.c @@ -210,7 +210,7 @@ void RabbitProcess(Rabbit* ctx, byte* output, const byte* input, word32 msglen) U32V(ctx->workCtx.x[1]<<16)); /* Increment pointers and decrement length */ - input += 16; + input += 16; output += 16; msglen -= 16; } @@ -219,25 +219,25 @@ void RabbitProcess(Rabbit* ctx, byte* output, const byte* input, word32 msglen) if (msglen) { word32 i; - word32 tmp[4]; - byte* buffer = (byte*)tmp; + byte buffer[16]; /* Iterate the system */ RABBIT_next_state(&(ctx->workCtx)); /* Generate 16 bytes of pseudo-random data */ - tmp[0] = LITTLE32(ctx->workCtx.x[0] ^ + *(word32*)(buffer+ 0) = LITTLE32(ctx->workCtx.x[0] ^ (ctx->workCtx.x[5]>>16) ^ U32V(ctx->workCtx.x[3]<<16)); - tmp[1] = LITTLE32(ctx->workCtx.x[2] ^ + *(word32*)(buffer+ 4) = LITTLE32(ctx->workCtx.x[2] ^ (ctx->workCtx.x[7]>>16) ^ U32V(ctx->workCtx.x[5]<<16)); - tmp[2] = LITTLE32(ctx->workCtx.x[4] ^ + *(word32*)(buffer+ 8) = LITTLE32(ctx->workCtx.x[4] ^ (ctx->workCtx.x[1]>>16) ^ U32V(ctx->workCtx.x[7]<<16)); - tmp[3] = LITTLE32(ctx->workCtx.x[6] ^ + *(word32*)(buffer+12) = LITTLE32(ctx->workCtx.x[6] ^ (ctx->workCtx.x[3]>>16) ^ U32V(ctx->workCtx.x[1]<<16)); /* Encrypt/decrypt the data */ for (i=0; i - #define XMALLOC(s, h, t) CyaSSL_Malloc((s)) + #define XMALLOC(s, h, t) ((void)h, (void)t, CyaSSL_Malloc((s))) #define XFREE(p, h, t) {void* xp = (p); if((xp)) CyaSSL_Free((xp));} #define XREALLOC(p, n, h, t) CyaSSL_Realloc((p), (n)) #endif @@ -215,7 +215,10 @@ enum { DYNAMIC_TYPE_CRL_MONITOR = 26, DYNAMIC_TYPE_OCSP_STATUS = 27, DYNAMIC_TYPE_OCSP_ENTRY = 28, - DYNAMIC_TYPE_ALTNAME = 29 + DYNAMIC_TYPE_ALTNAME = 29, + DYNAMIC_TYPE_SUITES = 30, + DYNAMIC_TYPE_CIPHER = 31, + DYNAMIC_TYPE_RNG = 32 }; /* stack protection */ diff --git a/cyassl/error.h b/cyassl/error.h index 82df03500..d9d35ff75 100644 --- a/cyassl/error.h +++ b/cyassl/error.h @@ -103,6 +103,7 @@ enum CyaSSL_ErrorCodes { MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */ COOKIE_ERROR = -269, /* dtls cookie error */ SEQUENCE_ERROR = -270, /* dtls sequence error */ + SUITES_ERROR = -271, /* suites pointer error */ /* add strings to SetErrorString !!!!! */ /* begin negotiation parameter errors */ diff --git a/cyassl/internal.h b/cyassl/internal.h index 967aa0c67..a6af3e2fa 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -474,6 +474,14 @@ enum Misc { }; +/* don't use extra 3/4k stack space unless need to */ +#ifdef HAVE_NTRU + #define MAX_ENCRYPT_SZ MAX_NTRU_ENCRYPT_SZ +#else + #define MAX_ENCRYPT_SZ ENCRYPT_LEN +#endif + + /* states */ enum states { NULL_STATE = 0, @@ -965,29 +973,34 @@ typedef struct Keys { word32 encryptSz; /* last size of encrypted data */ byte encryptionOn; /* true after change cipher spec */ + byte decryptedCur; /* only decrypt current record once */ } Keys; /* cipher for now */ -typedef union { +typedef struct Ciphers { #ifdef BUILD_ARC4 - Arc4 arc4; + Arc4* arc4; #endif #ifdef BUILD_DES3 - Des3 des3; + Des3* des3; #endif #ifdef BUILD_AES - Aes aes; + Aes* aes; #endif #ifdef HAVE_HC128 - HC128 hc128; + HC128* hc128; #endif #ifdef BUILD_RABBIT - Rabbit rabbit; + Rabbit* rabbit; #endif } Ciphers; +CYASSL_LOCAL void InitCiphers(CYASSL* ssl); +CYASSL_LOCAL void FreeCiphers(CYASSL* ssl); + + /* hashes type */ typedef struct Hashes { byte md5[MD5_DIGEST_SIZE]; @@ -1203,7 +1216,7 @@ struct CYASSL { int error; ProtocolVersion version; /* negotiated version */ ProtocolVersion chVersion; /* client hello version */ - Suites suites; + Suites* suites; /* only need during handshake */ Ciphers encrypt; Ciphers decrypt; CipherSpecs specs; @@ -1214,7 +1227,7 @@ struct CYASSL { CYASSL_BIO* biowr; /* socket bio write to free/close */ void* IOCB_ReadCtx; void* IOCB_WriteCtx; - RNG rng; + RNG* rng; Md5 hashMd5; /* md5 hash of handshake msgs */ Sha hashSha; /* sha hash of handshake msgs */ #ifndef NO_SHA256 @@ -1440,6 +1453,7 @@ CYASSL_LOCAL int StoreKeys(CYASSL* ssl, const byte* keyData); CYASSL_LOCAL int IsTLS(const CYASSL* ssl); CYASSL_LOCAL int IsAtLeastTLSv1_2(const CYASSL* ssl); +CYASSL_LOCAL void FreeHandshakeResources(CYASSL* ssl); CYASSL_LOCAL void ShrinkInputBuffer(CYASSL* ssl, int forcedFree); CYASSL_LOCAL void ShrinkOutputBuffer(CYASSL* ssl); CYASSL_LOCAL Signer* GetCA(void* cm, byte* hash); diff --git a/cyassl/sniffer_error.h b/cyassl/sniffer_error.h index 4882c7dd8..e6883f2dd 100644 --- a/cyassl/sniffer_error.h +++ b/cyassl/sniffer_error.h @@ -99,6 +99,7 @@ #define BAD_DECRYPT_TYPE 65 #define BAD_FINISHED_MSG 66 #define BAD_COMPRESSION_STR 67 +#define BAD_DERIVE_STR 68 /* !!!! also add to msgTable in sniffer.c and .rc file !!!! */ diff --git a/cyassl/sniffer_error.rc b/cyassl/sniffer_error.rc index f4af8ee5b..307efbf29 100644 --- a/cyassl/sniffer_error.rc +++ b/cyassl/sniffer_error.rc @@ -81,5 +81,6 @@ STRINGTABLE 66, "Bad Finished Message Processing" 67, "Bad Compression Type" + 68, "Bad DeriveKeys Error" } diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 3ce8ed412..0ccc4dd4a 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -780,6 +780,7 @@ enum { CYASSL_CHAIN_CA = 2 /* added to cache from trusted chain */ }; +CYASSL_API int CyaSSL_GetObjectSize(void); /* object size based on build */ CYASSL_API int CyaSSL_SetVersion(CYASSL* ssl, int version); CYASSL_API int CyaSSL_KeyPemToDer(const unsigned char*, int sz, unsigned char*, int, const char*); diff --git a/examples/client/client.c b/examples/client/client.c index 512612673..3ed70b481 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -263,9 +263,10 @@ void client_test(void* args) #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC) /* don't use EDH, can't sniff tmp keys */ - if (cipherList == NULL) + if (cipherList == NULL) { if (CyaSSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS) err_sys("can't set cipher list"); + } #endif #ifdef USER_CA_CB diff --git a/examples/server/server.c b/examples/server/server.c index a33a4efb9..e16f74b50 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -262,8 +262,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC) /* don't use EDH, can't sniff tmp keys */ - if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS) - err_sys("can't set cipher list"); + if (cipherList == NULL) { + if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS) + err_sys("can't set cipher list"); + } #endif ssl = SSL_new(ctx); diff --git a/src/crl.c b/src/crl.c index 40759a4f1..681d0ee9a 100644 --- a/src/crl.c +++ b/src/crl.c @@ -123,7 +123,6 @@ int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert) { CRL_Entry* crle; int foundEntry = 0; - int revoked = 0; int ret = 0; CYASSL_ENTER("CheckCertCRL"); @@ -157,7 +156,6 @@ int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert) while (rc) { if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) { CYASSL_MSG("Cert revoked"); - revoked = 1; ret = CRL_CERT_REVOKED; break; } diff --git a/src/internal.c b/src/internal.c index e22e32dac..3ab2a1324 100644 --- a/src/internal.c +++ b/src/internal.c @@ -434,7 +434,59 @@ void FreeSSL_Ctx(CYASSL_CTX* ctx) } } - + +/* Set cipher pointers to null */ +void InitCiphers(CYASSL* ssl) +{ +#ifdef BUILD_ARC4 + ssl->encrypt.arc4 = NULL; + ssl->decrypt.arc4 = NULL; +#endif +#ifdef BUILD_DES3 + ssl->encrypt.des3 = NULL; + ssl->decrypt.des3 = NULL; +#endif +#ifdef BUILD_AES + ssl->encrypt.aes = NULL; + ssl->decrypt.aes = NULL; +#endif +#ifdef HAVE_HC128 + ssl->encrypt.hc128 = NULL; + ssl->decrypt.hc128 = NULL; +#endif +#ifdef BUILD_RABBIT + ssl->encrypt.rabbit = NULL; + ssl->decrypt.rabbit = NULL; +#endif +} + + +/* Free ciphers */ +void FreeCiphers(CYASSL* ssl) +{ +#ifdef BUILD_ARC4 + XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER); +#endif +#ifdef BUILD_DES3 + XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER); +#endif +#ifdef BUILD_AES + XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER); +#endif +#ifdef HAVE_HC128 + XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER); +#endif +#ifdef BUILD_RABBIT + XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER); +#endif +} + + void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK, byte haveNTRU, byte haveECDSAsig, byte haveStaticECC, int side) { @@ -449,7 +501,11 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK, (void)havePSK; (void)haveNTRU; (void)haveStaticECC; - (void)haveRSAsig; + + if (suites == NULL) { + CYASSL_MSG("InitSuites pointer error"); + return; + } if (suites->setSuites) return; /* trust user settings, don't override */ @@ -457,8 +513,10 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK, if (side == SERVER_END && haveStaticECC) haveRSA = 0; /* can't do RSA with ECDSA key */ - if (side == SERVER_END && haveECDSAsig) - haveRSAsig = 0; /* can't have RSA sig if signed by ECDSA */ + if (side == SERVER_END && haveECDSAsig) { + haveRSAsig = 0; /* can't have RSA sig if signed by ECDSA */ + (void)haveRSAsig; /* non ecc builds won't read */ + } #ifdef CYASSL_DTLS if (pv.major == DTLS_MAJOR && pv.minor == DTLS_MINOR) @@ -814,7 +872,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->ctx = ctx; /* only for passing to calls, options could change */ ssl->version = ctx->method->version; - ssl->suites = ctx->suites; + ssl->suites = NULL; #ifdef HAVE_LIBZ ssl->didStreamInit = 0; @@ -926,6 +984,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->dtls_timeout = 2; #endif ssl->keys.encryptionOn = 0; /* initially off */ + ssl->keys.decryptedCur = 0; /* initially off */ ssl->options.sessionCacheOff = ctx->sessionCacheOff; ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff; @@ -997,6 +1056,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->arrays.server_hint[0] = 0; #endif /* NO_PSK */ + ssl->rng = NULL; + InitCiphers(ssl); /* all done with init, now can return errors, call other stuff */ /* increment CTX reference count */ @@ -1007,9 +1068,23 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ctx->refCount++; UnLockMutex(&ctx->countMutex); - if ( (ret = InitRng(&ssl->rng)) != 0) + ssl->rng = (RNG*)XMALLOC(sizeof(RNG), ssl->heap, DYNAMIC_TYPE_RNG); + if (ssl->rng == NULL) { + CYASSL_MSG("RNG Memory error"); + return MEMORY_E; + } + + if ( (ret = InitRng(ssl->rng)) != 0) return ret; + ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, + DYNAMIC_TYPE_SUITES); + if (ssl->suites == NULL) { + CYASSL_MSG("Suites Memory error"); + return MEMORY_E; + } + *ssl->suites = ctx->suites; + /* make sure server has cert and key unless using PSK */ if (ssl->options.side == SERVER_END && !havePSK) if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) { @@ -1019,11 +1094,11 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) /* make sure server has DH parms, and add PSK if there, add NTRU too */ if (ssl->options.side == SERVER_END) - InitSuites(&ssl->suites, ssl->version,ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version,ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); else - InitSuites(&ssl->suites, ssl->version, TRUE, havePSK, + InitSuites(ssl->suites, ssl->version, TRUE, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -1034,6 +1109,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) /* In case holding SSL object in array and don't want to free actual ssl */ void SSL_ResourceFree(CYASSL* ssl) { + FreeCiphers(ssl); + XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG); + XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES); XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH); XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH); /* parameters (p,g) may be owned by ctx */ @@ -1078,6 +1156,25 @@ void SSL_ResourceFree(CYASSL* ssl) } +/* Free any handshake resources no longer needed */ +void FreeHandshakeResources(CYASSL* ssl) +{ + /* input buffer */ + if (ssl->buffers.inputBuffer.dynamicFlag) + ShrinkInputBuffer(ssl, NO_FORCED_FREE); + + /* suites */ + XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES); + ssl->suites = NULL; + + /* RNG */ + if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) { + XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG); + ssl->rng = NULL; + } +} + + void FreeSSL(CYASSL* ssl) { FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */ @@ -1584,6 +1681,9 @@ static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx, return UNKNOWN_RECORD_TYPE; } + /* haven't decrypted this record yet */ + ssl->keys.decryptedCur = 0; + return 0; } @@ -2364,13 +2464,13 @@ static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) switch (ssl->specs.bulk_cipher_algorithm) { #ifdef BUILD_ARC4 case rc4: - Arc4Process(&ssl->encrypt.arc4, out, input, sz); + Arc4Process(ssl->encrypt.arc4, out, input, sz); break; #endif #ifdef BUILD_DES3 case triple_des: - Des3_CbcEncrypt(&ssl->encrypt.des3, out, input, sz); + Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz); break; #endif @@ -2380,12 +2480,12 @@ static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) if ((word)input % 16) { byte buffer[MAX_RECORD_SIZE + MAX_COMP_EXTRA+MAX_MSG_EXTRA]; XMEMCPY(buffer, input, sz); - AesCbcEncrypt(&ssl->encrypt.aes, buffer, buffer, sz); + AesCbcEncrypt(ssl->encrypt.aes, buffer, buffer, sz); XMEMCPY(out, buffer, sz); break; } #endif - AesCbcEncrypt(&ssl->encrypt.aes, out, input, sz); + AesCbcEncrypt(ssl->encrypt.aes, out, input, sz); break; #endif @@ -2408,25 +2508,25 @@ static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) * IV length minus the authentication tag size. */ c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, additional + AEAD_LEN_OFFSET); - AesGcmEncrypt(&ssl->encrypt.aes, + AesGcmEncrypt(ssl->encrypt.aes, out + AES_GCM_EXP_IV_SZ, input + AES_GCM_EXP_IV_SZ, sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ, additional, AEAD_AUTH_DATA_SZ); - AesGcmIncExpIV(&ssl->encrypt.aes); + AesGcmIncExpIV(ssl->encrypt.aes); } break; #endif #ifdef HAVE_HC128 case hc128: - Hc128_Process(&ssl->encrypt.hc128, out, input, sz); + Hc128_Process(ssl->encrypt.hc128, out, input, sz); break; #endif #ifdef BUILD_RABBIT case rabbit: - RabbitProcess(&ssl->encrypt.rabbit, out, input, sz); + RabbitProcess(ssl->encrypt.rabbit, out, input, sz); break; #endif @@ -2442,19 +2542,19 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, switch (ssl->specs.bulk_cipher_algorithm) { #ifdef BUILD_ARC4 case rc4: - Arc4Process(&ssl->decrypt.arc4, plain, input, sz); + Arc4Process(ssl->decrypt.arc4, plain, input, sz); break; #endif #ifdef BUILD_DES3 case triple_des: - Des3_CbcDecrypt(&ssl->decrypt.des3, plain, input, sz); + Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz); break; #endif #ifdef BUILD_AES case aes: - AesCbcDecrypt(&ssl->decrypt.aes, plain, input, sz); + AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz); break; #endif @@ -2463,7 +2563,7 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, { byte additional[AES_BLOCK_SIZE]; - AesGcmSetExpIV(&ssl->decrypt.aes, input); + AesGcmSetExpIV(ssl->decrypt.aes, input); XMEMSET(additional, 0, AES_BLOCK_SIZE); /* sequence number field is 64-bits, we only use 32-bits */ @@ -2475,7 +2575,7 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, additional + AEAD_LEN_OFFSET); - if (AesGcmDecrypt(&ssl->decrypt.aes, + if (AesGcmDecrypt(ssl->decrypt.aes, plain + AES_GCM_EXP_IV_SZ, input + AES_GCM_EXP_IV_SZ, sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, @@ -2490,13 +2590,13 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, #ifdef HAVE_HC128 case hc128: - Hc128_Process(&ssl->decrypt.hc128, plain, input, sz); + Hc128_Process(ssl->decrypt.hc128, plain, input, sz); break; #endif #ifdef BUILD_RABBIT case rabbit: - RabbitProcess(&ssl->decrypt.rabbit, plain, input, sz); + RabbitProcess(ssl->decrypt.rabbit, plain, input, sz); break; #endif @@ -2514,7 +2614,9 @@ static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx) if (decryptResult == 0) { - ssl->keys.encryptSz = sz; + ssl->keys.encryptSz = sz; + ssl->keys.decryptedCur = 1; + if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) *idx += ssl->specs.block_size; /* go past TLSv1.1 IV */ if (ssl->specs.cipher_type == aead) @@ -2858,7 +2960,7 @@ int ProcessReply(CYASSL* ssl) /* the record layer is here */ case runProcessingOneMessage: - if (ssl->keys.encryptionOn) + if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0) if (DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx, ssl->curSize, @@ -2902,6 +3004,11 @@ int ProcessReply(CYASSL* ssl) AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo); } #endif + + if (ssl->curSize != 1) { + CYASSL_MSG("Malicious or corrupted ChangeCipher msg"); + return LENGTH_ERROR; + } ssl->buffers.inputBuffer.idx++; ssl->keys.encryptionOn = 1; @@ -3185,7 +3292,7 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, if (ssl->options.tls1_1) { ivSz = blockSz; sz += ivSz; - RNG_GenerateBlock(&ssl->rng, iv, ivSz); + RNG_GenerateBlock(ssl->rng, iv, ivSz); } sz += 1; /* pad byte */ pad = (sz - headerSz) % blockSz; @@ -3197,7 +3304,7 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, if (ssl->specs.cipher_type == aead) { ivSz = AES_GCM_EXP_IV_SZ; sz += (ivSz + 16 - digestSz); - AesGcmGetExpIV(&ssl->encrypt.aes, iv); + AesGcmGetExpIV(ssl->encrypt.aes, iv); } #endif size = (word16)(sz - headerSz); /* include mac and digest */ @@ -3356,7 +3463,8 @@ int SendCertificate(CYASSL* ssl) if (ssl->buffers.certChain.buffer) { XMEMCPY(output + i, ssl->buffers.certChain.buffer, ssl->buffers.certChain.length); - i += ssl->buffers.certChain.length; + /* if add more to output adjust i + i += ssl->buffers.certChain.length; */ } } HashOutput(ssl, output, sendSz, 0); @@ -3425,7 +3533,8 @@ int SendCertificateRequest(CYASSL* ssl) } c16toa(0, &output[i]); /* auth's */ - i += REQ_HEADER_SZ; + /* if add more to output, adjust i + i += REQ_HEADER_SZ; */ HashOutput(ssl, output, sendSz, 0); @@ -3952,6 +4061,10 @@ void SetErrorString(int error, char* str) XSTRNCPY(str, "DTLS Sequence Error", max); break; + case SUITES_ERROR: + XSTRNCPY(str, "Suites Pointer Error", max); + break; + default : XSTRNCPY(str, "unknown error number", max); } @@ -4373,6 +4486,11 @@ int SetCipherList(Suites* s, const char* list) const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]); int idx = 0; + if (s == NULL) { + CYASSL_MSG("SetCipherList suite pointer error"); + return 0; + } + if (!list) return 0; @@ -4572,9 +4690,14 @@ int SetCipherList(Suites* s, const char* list) int idSz = ssl->options.resuming ? ID_LEN : 0; int ret; + if (ssl->suites == NULL) { + CYASSL_MSG("Bad suites pointer in SendClientHello"); + return SUITES_ERROR; + } + length = sizeof(ProtocolVersion) + RAN_LEN + idSz + ENUM_LEN - + ssl->suites.suiteSz + SUITE_LEN + + ssl->suites->suiteSz + SUITE_LEN + COMP_LEN + ENUM_LEN; if (IsAtLeastTLSv1_2(ssl)) @@ -4608,7 +4731,7 @@ int SetCipherList(Suites* s, const char* list) /* then random */ if (ssl->options.connectState == CONNECT_BEGIN) { - RNG_GenerateBlock(&ssl->rng, output + idx, RAN_LEN); + RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN); /* store random */ XMEMCPY(ssl->arrays.clientRandom, output + idx, RAN_LEN); @@ -4640,10 +4763,10 @@ int SetCipherList(Suites* s, const char* list) } #endif /* then cipher suites */ - c16toa(ssl->suites.suiteSz, output + idx); + c16toa(ssl->suites->suiteSz, output + idx); idx += 2; - XMEMCPY(output + idx, &ssl->suites.suites, ssl->suites.suiteSz); - idx += ssl->suites.suiteSz; + XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz); + idx += ssl->suites->suiteSz; /* last, compression */ output[idx++] = COMP_LEN; @@ -5081,13 +5204,13 @@ int SetCipherList(Suites* s, const char* list) int SendClientKeyExchange(CYASSL* ssl) { - byte encSecret[MAX_NTRU_ENCRYPT_SZ]; + byte encSecret[MAX_ENCRYPT_SZ]; word32 encSz = 0; word32 idx = 0; int ret = 0; if (ssl->specs.kea == rsa_kea) { - RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret, + RNG_GenerateBlock(ssl->rng, ssl->arrays.preMasterSecret, SECRET_LEN); ssl->arrays.preMasterSecret[0] = ssl->chVersion.major; ssl->arrays.preMasterSecret[1] = ssl->chVersion.minor; @@ -5098,7 +5221,7 @@ int SetCipherList(Suites* s, const char* list) ret = RsaPublicEncrypt(ssl->arrays.preMasterSecret, SECRET_LEN, encSecret, sizeof(encSecret), &ssl->peerRsaKey, - &ssl->rng); + ssl->rng); if (ret > 0) { encSz = ret; ret = 0; /* set success to 0 */ @@ -5121,7 +5244,7 @@ int SetCipherList(Suites* s, const char* list) serverG.buffer, serverG.length); if (ret == 0) /* for DH, encSecret is Yc, agree is pre-master */ - ret = DhGenerateKeyPair(&key, &ssl->rng, priv, &privSz, + ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz, encSecret, &encSz); if (ret == 0) ret = DhAgree(&key, ssl->arrays.preMasterSecret, @@ -5163,7 +5286,7 @@ int SetCipherList(Suites* s, const char* list) 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U' }; - RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret, + RNG_GenerateBlock(ssl->rng, ssl->arrays.preMasterSecret, SECRET_LEN); ssl->arrays.preMasterSz = SECRET_LEN; @@ -5205,7 +5328,7 @@ int SetCipherList(Suites* s, const char* list) } ecc_init(&myKey); - ret = ecc_make_key(&ssl->rng, peerKey->dp->size, &myKey); + ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey); if (ret != 0) return ECC_MAKEKEY_ERROR; @@ -5266,7 +5389,8 @@ int SetCipherList(Suites* s, const char* list) idx += 2; } XMEMCPY(output + idx, encSecret, encSz); - idx += encSz; + /* if add more to output, adjust idx + idx += encSz; */ HashOutput(ssl, output, sendSz, 0); @@ -5371,7 +5495,7 @@ int SetCipherList(Suites* s, const char* list) word32 localSz = sigOutSz; ret = ecc_sign_hash(signBuffer + MD5_DIGEST_SIZE, SHA_DIGEST_SIZE, verify + extraSz + VERIFY_HEADER, - &localSz, &ssl->rng, &eccKey); + &localSz, ssl->rng, &eccKey); #endif } else { @@ -5390,7 +5514,7 @@ int SetCipherList(Suites* s, const char* list) } ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz + - VERIFY_HEADER, ENCRYPT_LEN, &key, &ssl->rng); + VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng); if (ret > 0) ret = 0; /* RSA reset */ @@ -5476,7 +5600,7 @@ int SetCipherList(Suites* s, const char* list) /* then random */ if (!ssl->options.resuming) - RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN); + RNG_GenerateBlock(ssl->rng, ssl->arrays.serverRandom, RAN_LEN); XMEMCPY(output + idx, ssl->arrays.serverRandom, RAN_LEN); idx += RAN_LEN; @@ -5492,7 +5616,7 @@ int SetCipherList(Suites* s, const char* list) /* then session id */ output[idx++] = ID_LEN; if (!ssl->options.resuming) - RNG_GenerateBlock(&ssl->rng, ssl->arrays.sessionID, ID_LEN); + RNG_GenerateBlock(ssl->rng, ssl->arrays.sessionID, ID_LEN); XMEMCPY(output + idx, ssl->arrays.sessionID, ID_LEN); idx += ID_LEN; @@ -5758,7 +5882,7 @@ int SetCipherList(Suites* s, const char* list) signBuffer = encodedSig; } ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz, - &rsaKey, &ssl->rng); + &rsaKey, ssl->rng); FreeRsaKey(&rsaKey); ecc_free(&dsaKey); if (ret > 0) @@ -5770,7 +5894,7 @@ int SetCipherList(Suites* s, const char* list) word32 sz = sigSz; ret = ecc_sign_hash(&hash[MD5_DIGEST_SIZE], SHA_DIGEST_SIZE, - output + idx, &sz, &ssl->rng, &dsaKey); + output + idx, &sz, ssl->rng, &dsaKey); FreeRsaKey(&rsaKey); ecc_free(&dsaKey); if (ret < 0) return ret; @@ -5832,7 +5956,7 @@ int SetCipherList(Suites* s, const char* list) ssl->buffers.serverDH_G.buffer, ssl->buffers.serverDH_G.length); if (ret == 0) - ret = DhGenerateKeyPair(&dhKey, &ssl->rng, + ret = DhGenerateKeyPair(&dhKey, ssl->rng, ssl->buffers.serverDH_Priv.buffer, &ssl->buffers.serverDH_Priv.length, ssl->buffers.serverDH_Pub.buffer, @@ -5960,11 +6084,9 @@ int SetCipherList(Suites* s, const char* list) signBuffer = encodedSig; } ret = RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz, - &rsaKey, &ssl->rng); + &rsaKey, ssl->rng); FreeRsaKey(&rsaKey); - if (ret > 0) - ret = 0; /* reset on success */ - else + if (ret <= 0) return ret; } } @@ -6295,11 +6417,19 @@ int SetCipherList(Suites* s, const char* list) { int haveRSA = !ssl->options.haveStaticECC; int havePSK = 0; - byte first = ssl->suites.suites[idx]; - byte second = ssl->suites.suites[idx+1]; + byte first; + byte second; CYASSL_ENTER("VerifySuite"); + if (ssl->suites == NULL) { + CYASSL_MSG("Suites pointer error"); + return 0; + } + + first = ssl->suites->suites[idx]; + second = ssl->suites->suites[idx+1]; + #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif @@ -6379,16 +6509,19 @@ int SetCipherList(Suites* s, const char* list) if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1) return MATCH_SUITE_ERROR; + if (ssl->suites == NULL) + return SUITES_ERROR; + /* start with best, if a match we are good */ - for (i = 0; i < ssl->suites.suiteSz; i += 2) + for (i = 0; i < ssl->suites->suiteSz; i += 2) for (j = 0; j < peerSuites->suiteSz; j += 2) - if (ssl->suites.suites[i] == peerSuites->suites[j] && - ssl->suites.suites[i+1] == peerSuites->suites[j+1] ) { + if (ssl->suites->suites[i] == peerSuites->suites[j] && + ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) { if (VerifySuite(ssl, i)) { CYASSL_MSG("Verified suite validity"); - ssl->options.cipherSuite0 = ssl->suites.suites[i]; - ssl->options.cipherSuite = ssl->suites.suites[i+1]; + ssl->options.cipherSuite0 = ssl->suites->suites[i]; + ssl->options.cipherSuite = ssl->suites->suites[i+1]; return SetCipherSpecs(ssl); } else { @@ -6463,7 +6596,7 @@ int SetCipherList(Suites* s, const char* list) havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } @@ -6534,7 +6667,7 @@ int SetCipherList(Suites* s, const char* list) return UNSUPPORTED_SUITE; } - RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN); + RNG_GenerateBlock(ssl->rng, ssl->arrays.serverRandom, RAN_LEN); if (ssl->options.tls) ret = DeriveTlsKeys(ssl); else @@ -6594,7 +6727,7 @@ int SetCipherList(Suites* s, const char* list) #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } @@ -6696,7 +6829,7 @@ int SetCipherList(Suites* s, const char* list) return UNSUPPORTED_SUITE; } - RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN); + RNG_GenerateBlock(ssl->rng, ssl->arrays.serverRandom, RAN_LEN); if (ssl->options.tls) ret = DeriveTlsKeys(ssl); else diff --git a/src/keys.c b/src/keys.c index 0e4bc0474..cfab8c685 100644 --- a/src/keys.c +++ b/src/keys.c @@ -918,34 +918,46 @@ static int SetPrefix(byte* sha_input, int idx) static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, - byte side) + byte side, void* heap, RNG* rng) { #ifdef BUILD_ARC4 word32 sz = specs->key_size; if (specs->bulk_cipher_algorithm == rc4) { + enc->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER); + if (enc->arc4 == NULL) + return MEMORY_E; + dec->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER); + if (dec->arc4 == NULL) + return MEMORY_E; if (side == CLIENT_END) { - Arc4SetKey(&enc->arc4, keys->client_write_key, sz); - Arc4SetKey(&dec->arc4, keys->server_write_key, sz); + Arc4SetKey(enc->arc4, keys->client_write_key, sz); + Arc4SetKey(dec->arc4, keys->server_write_key, sz); } else { - Arc4SetKey(&enc->arc4, keys->server_write_key, sz); - Arc4SetKey(&dec->arc4, keys->client_write_key, sz); + Arc4SetKey(enc->arc4, keys->server_write_key, sz); + Arc4SetKey(dec->arc4, keys->client_write_key, sz); } } #endif #ifdef HAVE_HC128 if (specs->bulk_cipher_algorithm == hc128) { + enc->hc128 = (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER); + if (enc->hc128 == NULL) + return MEMORY_E; + dec->hc128 = (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER); + if (dec->hc128 == NULL) + return MEMORY_E; if (side == CLIENT_END) { - Hc128_SetKey(&enc->hc128, keys->client_write_key, + Hc128_SetKey(enc->hc128, keys->client_write_key, keys->client_write_IV); - Hc128_SetKey(&dec->hc128, keys->server_write_key, + Hc128_SetKey(dec->hc128, keys->server_write_key, keys->server_write_IV); } else { - Hc128_SetKey(&enc->hc128, keys->server_write_key, + Hc128_SetKey(enc->hc128, keys->server_write_key, keys->server_write_IV); - Hc128_SetKey(&dec->hc128, keys->client_write_key, + Hc128_SetKey(dec->hc128, keys->client_write_key, keys->client_write_IV); } } @@ -953,16 +965,22 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #ifdef BUILD_RABBIT if (specs->bulk_cipher_algorithm == rabbit) { + enc->rabbit = (Rabbit*)XMALLOC(sizeof(Rabbit),heap,DYNAMIC_TYPE_CIPHER); + if (enc->rabbit == NULL) + return MEMORY_E; + dec->rabbit = (Rabbit*)XMALLOC(sizeof(Rabbit),heap,DYNAMIC_TYPE_CIPHER); + if (dec->rabbit == NULL) + return MEMORY_E; if (side == CLIENT_END) { - RabbitSetKey(&enc->rabbit, keys->client_write_key, + RabbitSetKey(enc->rabbit, keys->client_write_key, keys->client_write_IV); - RabbitSetKey(&dec->rabbit, keys->server_write_key, + RabbitSetKey(dec->rabbit, keys->server_write_key, keys->server_write_IV); } else { - RabbitSetKey(&enc->rabbit, keys->server_write_key, + RabbitSetKey(enc->rabbit, keys->server_write_key, keys->server_write_IV); - RabbitSetKey(&dec->rabbit, keys->client_write_key, + RabbitSetKey(dec->rabbit, keys->client_write_key, keys->client_write_IV); } } @@ -970,16 +988,22 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #ifdef BUILD_DES3 if (specs->bulk_cipher_algorithm == triple_des) { + enc->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER); + if (enc->des3 == NULL) + return MEMORY_E; + dec->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER); + if (dec->des3 == NULL) + return MEMORY_E; if (side == CLIENT_END) { - Des3_SetKey(&enc->des3, keys->client_write_key, + Des3_SetKey(enc->des3, keys->client_write_key, keys->client_write_IV, DES_ENCRYPTION); - Des3_SetKey(&dec->des3, keys->server_write_key, + Des3_SetKey(dec->des3, keys->server_write_key, keys->server_write_IV, DES_DECRYPTION); } else { - Des3_SetKey(&enc->des3, keys->server_write_key, + Des3_SetKey(enc->des3, keys->server_write_key, keys->server_write_IV, DES_ENCRYPTION); - Des3_SetKey(&dec->des3, keys->client_write_key, + Des3_SetKey(dec->des3, keys->client_write_key, keys->client_write_IV, DES_DECRYPTION); } } @@ -987,19 +1011,25 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #ifdef BUILD_AES if (specs->bulk_cipher_algorithm == aes) { + enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); + if (enc->aes == NULL) + return MEMORY_E; + dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); + if (dec->aes == NULL) + return MEMORY_E; if (side == CLIENT_END) { - AesSetKey(&enc->aes, keys->client_write_key, + AesSetKey(enc->aes, keys->client_write_key, specs->key_size, keys->client_write_IV, AES_ENCRYPTION); - AesSetKey(&dec->aes, keys->server_write_key, + AesSetKey(dec->aes, keys->server_write_key, specs->key_size, keys->server_write_IV, AES_DECRYPTION); } else { - AesSetKey(&enc->aes, keys->server_write_key, + AesSetKey(enc->aes, keys->server_write_key, specs->key_size, keys->server_write_IV, AES_ENCRYPTION); - AesSetKey(&dec->aes, keys->client_write_key, + AesSetKey(dec->aes, keys->client_write_key, specs->key_size, keys->client_write_IV, AES_DECRYPTION); } @@ -1008,16 +1038,28 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #ifdef BUILD_AESGCM if (specs->bulk_cipher_algorithm == aes_gcm) { + byte iv[AES_GCM_EXP_IV_SZ]; + enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); + if (enc->aes == NULL) + return MEMORY_E; + dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); + if (dec->aes == NULL) + return MEMORY_E; + + /* Initialize the AES-GCM explicit IV to a random number. */ + RNG_GenerateBlock(rng, iv, sizeof(iv)); + AesGcmSetExpIV(enc->aes, iv); + if (side == CLIENT_END) { - AesGcmSetKey(&enc->aes, keys->client_write_key, specs->key_size, + AesGcmSetKey(enc->aes, keys->client_write_key, specs->key_size, keys->client_write_IV); - AesGcmSetKey(&dec->aes, keys->server_write_key, specs->key_size, + AesGcmSetKey(dec->aes, keys->server_write_key, specs->key_size, keys->server_write_IV); } else { - AesGcmSetKey(&enc->aes, keys->server_write_key, specs->key_size, + AesGcmSetKey(enc->aes, keys->server_write_key, specs->key_size, keys->server_write_IV); - AesGcmSetKey(&dec->aes, keys->client_write_key, specs->key_size, + AesGcmSetKey(dec->aes, keys->client_write_key, specs->key_size, keys->client_write_IV); } } @@ -1026,6 +1068,7 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, keys->sequence_number = 0; keys->peer_sequence_number = 0; keys->encryptionOn = 0; + (void)rng; return 0; } @@ -1043,16 +1086,6 @@ int StoreKeys(CYASSL* ssl, const byte* keyData) XMEMCPY(ssl->keys.server_write_MAC_secret,&keyData[i], sz); i += sz; } -#ifdef BUILD_AESGCM - else if (ssl->specs.bulk_cipher_algorithm == aes_gcm) { - byte iv[AES_GCM_EXP_IV_SZ]; - - /* Initialize the AES-GCM explicit IV to a random number. */ - RNG_GenerateBlock(&ssl->rng, iv, sizeof(iv)); - AesGcmSetExpIV(&ssl->encrypt.aes, iv); - } -#endif - sz = ssl->specs.key_size; XMEMCPY(ssl->keys.client_write_key, &keyData[i], sz); i += sz; @@ -1065,7 +1098,7 @@ int StoreKeys(CYASSL* ssl, const byte* keyData) XMEMCPY(ssl->keys.server_write_IV, &keyData[i], sz); return SetKeys(&ssl->encrypt, &ssl->decrypt, &ssl->keys, &ssl->specs, - ssl->options.side); + ssl->options.side, ssl->heap, ssl->rng); } @@ -1103,7 +1136,6 @@ int DeriveKeys(CYASSL* ssl) XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN); idx += RAN_LEN; XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN); - idx += RAN_LEN; ShaUpdate(&sha, shaInput, sizeof(shaInput) - KEY_PREFIX + j); ShaFinal(&sha, shaOutput); @@ -1124,7 +1156,7 @@ static void CleanPreMaster(CYASSL* ssl) for (i = 0; i < sz; i++) ssl->arrays.preMasterSecret[i] = 0; - RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret, sz); + RNG_GenerateBlock(ssl->rng, ssl->arrays.preMasterSecret, sz); for (i = 0; i < sz; i++) ssl->arrays.preMasterSecret[i] = 0; @@ -1133,7 +1165,7 @@ static void CleanPreMaster(CYASSL* ssl) /* Create and store the master secret see page 32, 6.1 */ -int MakeMasterSecret(CYASSL* ssl) +static int MakeSslMasterSecret(CYASSL* ssl) { byte shaOutput[SHA_DIGEST_SIZE]; byte md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE]; @@ -1155,10 +1187,6 @@ int MakeMasterSecret(CYASSL* ssl) } #endif -#ifndef NO_TLS - if (ssl->options.tls) return MakeTlsMasterSecret(ssl); -#endif - InitMd5(&md5); InitSha(&sha); @@ -1206,3 +1234,14 @@ int MakeMasterSecret(CYASSL* ssl) return ret; } + +/* Master wrapper, doesn't use SSL stack space in TLS mode */ +int MakeMasterSecret(CYASSL* ssl) +{ +#ifndef NO_TLS + if (ssl->options.tls) return MakeTlsMasterSecret(ssl); +#endif + + return MakeSslMasterSecret(ssl); +} + diff --git a/src/sniffer.c b/src/sniffer.c index 037d52896..abeeb4dc4 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -217,7 +217,8 @@ static const char* const msgTable[] = /* 66 */ "Bad Finished Message Processing", - "Bad Compression Type" + "Bad Compression Type", + "Bad DeriveKeys Error" }; @@ -1205,6 +1206,7 @@ static int ProcessServerHello(const byte* input, int* sslBytes, } if (doResume ) { + int ret = 0; SSL_SESSION* resume = GetSession(session->sslServer, session->sslServer->arrays.masterSecret); if (resume == NULL) { @@ -1228,12 +1230,16 @@ static int ProcessServerHello(const byte* input, int* sslBytes, } if (session->sslServer->options.tls) { - DeriveTlsKeys(session->sslServer); - DeriveTlsKeys(session->sslClient); + ret = DeriveTlsKeys(session->sslServer); + ret += DeriveTlsKeys(session->sslClient); } else { - DeriveKeys(session->sslServer); - DeriveKeys(session->sslClient); + ret = DeriveKeys(session->sslServer); + ret += DeriveKeys(session->sslClient); + } + if (ret != 0) { + SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE); + return -1; } } #ifdef SHOW_SECRETS @@ -1517,31 +1523,31 @@ static void Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz) switch (ssl->specs.bulk_cipher_algorithm) { #ifdef BUILD_ARC4 case rc4: - Arc4Process(&ssl->decrypt.arc4, output, input, sz); + Arc4Process(ssl->decrypt.arc4, output, input, sz); break; #endif #ifdef BUILD_DES3 case triple_des: - Des3_CbcDecrypt(&ssl->decrypt.des3, output, input, sz); + Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz); break; #endif #ifdef BUILD_AES case aes: - AesCbcDecrypt(&ssl->decrypt.aes, output, input, sz); + AesCbcDecrypt(ssl->decrypt.aes, output, input, sz); break; #endif #ifdef HAVE_HC128 case hc128: - Hc128_Process(&ssl->decrypt.hc128, output, input, sz); + Hc128_Process(ssl->decrypt.hc128, output, input, sz); break; #endif #ifdef BUILD_RABBIT case rabbit: - RabbitProcess(&ssl->decrypt.rabbit, output, input, sz); + RabbitProcess(ssl->decrypt.rabbit, output, input, sz); break; #endif diff --git a/src/ssl.c b/src/ssl.c index 6c6f0dcca..867fc9ff3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -216,6 +216,34 @@ int CyaSSL_negotiate(CYASSL* ssl) } +/* object size based on build */ +int CyaSSL_GetObjectSize(void) +{ +#ifdef SHOW_SIZES + printf("sizeof suites = %lu\n", sizeof(Suites)); + printf("sizeof ciphers(2) = %lu\n", sizeof(Ciphers)); + printf("\tsizeof arc4 = %lu\n", sizeof(Arc4)); + printf("\tsizeof aes = %lu\n", sizeof(Aes)); + printf("\tsizeof des3 = %lu\n", sizeof(Des3)); + printf("\tsizeof rabbit = %lu\n", sizeof(Rabbit)); + printf("sizeof cipher specs = %lu\n", sizeof(CipherSpecs)); + printf("sizeof keys = %lu\n", sizeof(Keys)); + printf("sizeof MD5 = %lu\n", sizeof(Md5)); + printf("sizeof SHA = %lu\n", sizeof(Sha)); + printf("sizeof SHA256 = %lu\n", sizeof(Sha256)); + printf("sizeof Hashes(2) = %lu\n", sizeof(Hashes)); + printf("sizeof Buffers = %lu\n", sizeof(Buffers)); + printf("sizeof Options = %lu\n", sizeof(Options)); + printf("sizeof Arrays = %lu\n", sizeof(Arrays)); + printf("sizeof Session = %lu\n", sizeof(CYASSL_SESSION)); + printf("sizeof peerKey = %lu\n", sizeof(RsaKey)); + printf("sizeof CYASSL_CIPHER = %lu\n", sizeof(CYASSL_CIPHER)); +#endif + + return sizeof(CYASSL); +} + + /* server Diffie-Hellman parameters */ int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz, const unsigned char* g, int gSz) @@ -256,7 +284,7 @@ int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz, #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -542,7 +570,7 @@ int CyaSSL_SetVersion(CYASSL* ssl, int version) havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -729,7 +757,6 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) (void)heap; (void)dynamicType; - (void)pkcs8Enc; if (type == CERT_TYPE || type == CA_TYPE) { XSTRNCPY(header, "-----BEGIN CERTIFICATE-----", sizeof(header)); @@ -766,8 +793,10 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) sizeof(footer)); headerEnd = XSTRNSTR((char*)buff, header, sz); - if (headerEnd) + if (headerEnd) { pkcs8Enc = 1; + (void)pkcs8Enc; /* only opensslextra will read */ + } } } if (!headerEnd && type == PRIVATEKEY_TYPE) { /* may be ecc */ @@ -876,7 +905,7 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) int passwordSz; char password[80]; - if (!info->ctx || !info->ctx->passwd_cb) + if (!info || !info->ctx || !info->ctx->passwd_cb) return SSL_BAD_FILE; /* no callback error */ passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0, info->ctx->userdata); @@ -943,7 +972,7 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) CYASSL_MSG("Growing Tmp Chain Buffer"); bufferSz = sz - consumed; /* will shrink to actual size */ chainBuffer = (byte*)XMALLOC(bufferSz, ctx->heap, - DYNAMIC_FILE_TYPE); + DYNAMIC_TYPE_FILE); if (chainBuffer == NULL) { XFREE(der.buffer, ctx->heap, dynamicType); return MEMORY_E; @@ -1393,6 +1422,7 @@ int CyaSSL_CertManagerVerifyBuffer(CYASSL_CERT_MANAGER* cm, const byte* buff, CYASSL_ENTER("CyaSSL_CertManagerVerifyBuffer"); der.buffer = NULL; + der.length = 0; if (format == SSL_FILETYPE_PEM) { EncryptedInfo info; @@ -2164,14 +2194,14 @@ int CyaSSL_CTX_set_cipher_list(CYASSL_CTX* ctx, const char* list) int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list) { CYASSL_ENTER("CyaSSL_set_cipher_list"); - if (SetCipherList(&ssl->suites, list)) { + if (SetCipherList(ssl->suites, list)) { byte havePSK = 0; #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -2413,8 +2443,7 @@ void CyaSSL_dtls_got_timeout(CYASSL* ssl) CYASSL_MSG("connect state: SECOND_REPLY_DONE"); case SECOND_REPLY_DONE: - if (ssl->buffers.inputBuffer.dynamicFlag) - ShrinkInputBuffer(ssl, NO_FORCED_FREE); + FreeHandshakeResources(ssl); CYASSL_LEAVE("SSL_connect()", SSL_SUCCESS); return SSL_SUCCESS; @@ -2490,7 +2519,7 @@ void CyaSSL_dtls_got_timeout(CYASSL* ssl) #ifdef HAVE_ECC /* in case used set_accept_state after init */ if (ssl->eccTempKeyPresent == 0) { - if (ecc_make_key(&ssl->rng, ssl->eccTempKeySz, + if (ecc_make_key(ssl->rng, ssl->eccTempKeySz, &ssl->eccTempKey) != 0) { ssl->error = ECC_MAKEKEY_ERROR; CYASSL_ERROR(ssl->error); @@ -2650,8 +2679,7 @@ void CyaSSL_dtls_got_timeout(CYASSL* ssl) CYASSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE"); case ACCEPT_THIRD_REPLY_DONE : - if (ssl->buffers.inputBuffer.dynamicFlag) - ShrinkInputBuffer(ssl, NO_FORCED_FREE); + FreeHandshakeResources(ssl); CYASSL_LEAVE("SSL_accept()", SSL_SUCCESS); return SSL_SUCCESS; @@ -3221,7 +3249,7 @@ int CyaSSL_set_compression(CYASSL* ssl) ssl->options.havePSK = 1; ssl->options.client_psk_cb = cb; - InitSuites(&ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU, + InitSuites(ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } @@ -3242,7 +3270,7 @@ int CyaSSL_set_compression(CYASSL* ssl) ssl->options.havePSK = 1; ssl->options.server_psk_cb = cb; - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, TRUE, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, TRUE, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } @@ -3467,7 +3495,7 @@ int CyaSSL_set_compression(CYASSL* ssl) #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } diff --git a/src/tls.c b/src/tls.c index f5ef46007..4904a9157 100644 --- a/src/tls.c +++ b/src/tls.c @@ -120,9 +120,8 @@ static void p_hash(byte* result, word32 resLen, const byte* secret, /* compute TLSv1 PRF (pseudo random function using HMAC) */ -static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, - const byte* label, word32 labLen, const byte* seed, word32 seedLen, - int useAtLeastSha256, int hash_type) +static void doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, + const byte* label, word32 labLen, const byte* seed, word32 seedLen) { word32 half = (secLen + 1) / 2; @@ -145,21 +144,38 @@ static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, XMEMCPY(labelSeed, label, labLen); XMEMCPY(labelSeed + labLen, seed, seedLen); + p_hash(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen, + md5_mac); + p_hash(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen, + sha_mac); + get_xor(digest, digLen, md5_result, sha_result); +} + + +/* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack + use */ +static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, + const byte* label, word32 labLen, const byte* seed, word32 seedLen, + int useAtLeastSha256, int hash_type) +{ if (useAtLeastSha256) { + byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ + + if (labLen + seedLen > MAX_PRF_LABSEED) + return; + + XMEMCPY(labelSeed, label, labLen); + XMEMCPY(labelSeed + labLen, seed, seedLen); + /* If a cipher suite wants an algorithm better than sha256, it * should use better. */ if (hash_type < sha256_mac) hash_type = sha256_mac; p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen, hash_type); - return; } - - p_hash(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen, - md5_mac); - p_hash(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen, - sha_mac); - get_xor(digest, digLen, md5_result, sha_result); + else + doPRF(digest, digLen, secret, secLen, label, labLen, seed, seedLen); }