From 30bec6c19368774051740f6887c7707b980a13e9 Mon Sep 17 00:00:00 2001 From: toddouska Date: Fri, 28 Sep 2012 10:58:33 -0700 Subject: [PATCH 1/6] fix sniffer out of memory potential problem --- src/sniffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sniffer.c b/src/sniffer.c index 4ae300c84..142853232 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1666,8 +1666,8 @@ static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo, session->sslClient = SSL_new(session->context->ctx); if (session->sslClient == NULL) { if (session->sslServer) { - SSL_free(session->sslClient); - session->sslClient = 0; + SSL_free(session->sslServer); + session->sslServer= 0; } SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE); free(session); From dd421ebb7d9024b2a6afdd57600050e506f84a7f Mon Sep 17 00:00:00 2001 From: toddouska Date: Fri, 28 Sep 2012 11:04:20 -0700 Subject: [PATCH 2/6] cleaner sniffer mem fix --- src/sniffer.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sniffer.c b/src/sniffer.c index 142853232..fdb305f49 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1663,12 +1663,16 @@ static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo, } session->sslServer = SSL_new(session->context->ctx); + if (session->sslServer == NULL) { + SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE); + free(session); + return 0; + } session->sslClient = SSL_new(session->context->ctx); if (session->sslClient == NULL) { - if (session->sslServer) { - SSL_free(session->sslServer); - session->sslServer= 0; - } + SSL_free(session->sslServer); + session->sslServer = 0; + SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE); free(session); return 0; From 2c25481e7d52ab54d2a886bd209f291facfcb6bf Mon Sep 17 00:00:00 2001 From: toddouska Date: Fri, 28 Sep 2012 15:01:07 -0700 Subject: [PATCH 3/6] add AesSetKeyDirect for Ctr and Direct when also using aesni --- ctaocrypt/src/aes.c | 26 ++++++++++++++++++++++++++ cyassl/ctaocrypt/aes.h | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index f21e7a1a2..eabd0f4ee 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -1027,6 +1027,13 @@ static void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) CYASSL_MSG("AesEncrypt encountered improper key, set it up"); return; /* stop instead of segfaulting, set up your keys! */ } +#ifdef CYASSL_AESNI + if (haveAESNI) { + CYASSL_MSG("AesEncrypt encountered aesni keysetup, don't use direct"); + return; /* just stop now */ + } +#endif + /* * map byte array block to cipher state * and add initial round key: @@ -1165,6 +1172,13 @@ static void AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) CYASSL_MSG("AesDecrypt encountered improper key, set it up"); return; /* stop instead of segfaulting, set up your keys! */ } +#ifdef CYASSL_AESNI + if (haveAESNI) { + CYASSL_MSG("AesEncrypt encountered aesni keysetup, don't use direct"); + return; /* just stop now */ + } +#endif + /* * map byte array block to cipher state * and add initial round key: @@ -1381,6 +1395,18 @@ void AesDecryptDirect(Aes* aes, byte* out, const byte* in) #endif /* CYASSL_AES_DIRECT */ +#if defined(CYASSL_AES_DIRECT) || defined(CYASSL_AES_COUNTER) + +/* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */ +int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) +{ + return AesSetKeyLocal(aes, userKey, keylen, iv, dir); +} + +#endif /* CYASSL_AES_DIRECT || CYASSL_AES_COUNTER */ + + #ifdef CYASSL_AES_COUNTER /* Increment AES counter */ diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index 9ab625dfc..e8dc53312 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -87,7 +87,8 @@ CYASSL_API void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz); CYASSL_API void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); CYASSL_API void AesEncryptDirect(Aes* aes, byte* out, const byte* in); CYASSL_API void AesDecryptDirect(Aes* aes, byte* out, const byte* in); - +CYASSL_API int AesSetKeyDirect(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir); #ifdef HAVE_AESGCM CYASSL_API void AesGcmSetKey(Aes* aes, const byte* key, word32 len, const byte* implicitIV); From e5c04e70a7a1cbdb3f5c4e75b537d93fad3933c2 Mon Sep 17 00:00:00 2001 From: toddouska Date: Fri, 28 Sep 2012 15:10:35 -0700 Subject: [PATCH 4/6] make sure existing nonblocking users still work --- examples/client/client.c | 1 + src/io.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/client/client.c b/examples/client/client.c index 6e9c23f95..6fc1023d8 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -51,6 +51,7 @@ int timeout_count = CyaSSL_dtls_get_current_timeout(ssl) * 10; while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)) { + (void)timeout_count; if (error == SSL_ERROR_WANT_READ) printf("... client would read block\n"); else diff --git a/src/io.c b/src/io.c index a956f4396..d80848210 100644 --- a/src/io.c +++ b/src/io.c @@ -167,7 +167,7 @@ int EmbedReceive(CYASSL *ssl, char *buf, int sz, void *ctx) CYASSL_MSG("Embed Receive error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { - if (CyaSSL_get_using_nonblock(ssl)) { + if (!CyaSSL_dtls(ssl) || CyaSSL_get_using_nonblock(ssl)) { CYASSL_MSG(" Would block"); return IO_ERR_WANT_READ; } From e0413df92afe2037a34f0c0810f118b39bf7b206 Mon Sep 17 00:00:00 2001 From: toddouska Date: Mon, 1 Oct 2012 11:32:05 -0700 Subject: [PATCH 5/6] add key setup flag for malicious or misbehaving handshake messages with new memory system --- cyassl/internal.h | 1 + src/internal.c | 23 ++++++++++++++++++++--- src/keys.c | 12 ++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/cyassl/internal.h b/cyassl/internal.h index 51b5b2211..53c96c612 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1004,6 +1004,7 @@ typedef struct Ciphers { #ifdef BUILD_RABBIT Rabbit* rabbit; #endif + byte setup; /* have we set it up flag for detection */ } Ciphers; diff --git a/src/internal.c b/src/internal.c index 339b92da4..9b6101bcb 100644 --- a/src/internal.c +++ b/src/internal.c @@ -458,6 +458,8 @@ void InitCiphers(CYASSL* ssl) ssl->encrypt.rabbit = NULL; ssl->decrypt.rabbit = NULL; #endif + ssl->encrypt.setup = 0; + ssl->decrypt.setup = 0; } @@ -2657,8 +2659,13 @@ static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) } -static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) +static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) { + if (ssl->encrypt.setup == 0) { + CYASSL_MSG("Encrypt ciphers not setup"); + return ENCRYPT_ERROR; + } + switch (ssl->specs.bulk_cipher_algorithm) { #ifdef BUILD_ARC4 case rc4: @@ -2730,13 +2737,21 @@ static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) default: CYASSL_MSG("CyaSSL Encrypt programming error"); + return ENCRYPT_ERROR; } + + return 0; } static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, word32 sz) { + if (ssl->decrypt.setup == 0) { + CYASSL_MSG("Decrypt ciphers not setup"); + return DECRYPT_ERROR; + } + switch (ssl->specs.bulk_cipher_algorithm) { #ifdef BUILD_ARC4 case rc4: @@ -2800,6 +2815,7 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, default: CYASSL_MSG("CyaSSL Decrypt programming error"); + return DECRYPT_ERROR; } return 0; } @@ -3483,6 +3499,7 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, word32 headerSz = RECORD_HEADER_SZ; word16 size; byte iv[AES_BLOCK_SIZE]; /* max size */ + int ret = 0; #ifdef CYASSL_DTLS if (ssl->options.dtls) { @@ -3526,7 +3543,6 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, if (type == handshake) { #ifdef CYASSL_DTLS if (ssl->options.dtls) { - int ret; if ((ret = DtlsPoolSave(ssl, output, headerSz+inSz)) != 0) return ret; } @@ -3542,7 +3558,8 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, for (i = 0; i <= pad; i++) output[idx++] = (byte)pad; /* pad byte gets pad value too */ - Encrypt(ssl, output + headerSz, output + headerSz, size); + if ( (ret = Encrypt(ssl, output + headerSz, output + headerSz, size)) != 0) + return ret; return sz; } diff --git a/src/keys.c b/src/keys.c index 889739d8d..c40fb5f51 100644 --- a/src/keys.c +++ b/src/keys.c @@ -937,6 +937,8 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, Arc4SetKey(enc->arc4, keys->server_write_key, sz); Arc4SetKey(dec->arc4, keys->client_write_key, sz); } + enc->setup = 1; + dec->setup = 1; } #endif @@ -960,6 +962,8 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, Hc128_SetKey(dec->hc128, keys->client_write_key, keys->client_write_IV); } + enc->setup = 1; + dec->setup = 1; } #endif @@ -983,6 +987,8 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, RabbitSetKey(dec->rabbit, keys->client_write_key, keys->client_write_IV); } + enc->setup = 1; + dec->setup = 1; } #endif @@ -1006,6 +1012,8 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, Des3_SetKey(dec->des3, keys->client_write_key, keys->client_write_IV, DES_DECRYPTION); } + enc->setup = 1; + dec->setup = 1; } #endif @@ -1033,6 +1041,8 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, specs->key_size, keys->client_write_IV, AES_DECRYPTION); } + enc->setup = 1; + dec->setup = 1; } #endif @@ -1062,6 +1072,8 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, AesGcmSetKey(dec->aes, keys->client_write_key, specs->key_size, keys->client_write_IV); } + enc->setup = 1; + dec->setup = 1; } #endif From 36eeab927bf57080bf07becd7d2f78746142f372 Mon Sep 17 00:00:00 2001 From: toddouska Date: Mon, 1 Oct 2012 13:16:37 -0700 Subject: [PATCH 6/6] fix sniffer assert comparison on newer gcc --- src/sniffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sniffer.c b/src/sniffer.c index fdb305f49..b385c28aa 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -845,7 +845,7 @@ static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo) SnifferSession* session; word32 row = SessionHash(ipInfo, tcpInfo); - assert(row >= 0 && row <= HASH_SIZE); + assert(row <= HASH_SIZE); LockMutex(&SessionMutex); @@ -1585,7 +1585,7 @@ static void RemoveSession(SnifferSession* session, IpInfo* ipInfo, else haveLock = 1; - assert(row >= 0 && row <= HASH_SIZE); + assert(row <= HASH_SIZE); Trace(REMOVE_SESSION_STR); if (!haveLock)