diff options
author | Rich Salz <rsalz@openssl.org> | 2017-08-03 10:24:03 -0400 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2017-08-03 10:24:03 -0400 |
commit | ae3947de09522206d61c0206a733517b10a910f8 (patch) | |
tree | 7044411af55af40f9f5f5adad685ccc70d155998 /ssl | |
parent | 75e2c877650444fb829547bdb58d46eb1297bc1a (diff) |
Add a DRBG to each SSL object
Give each SSL object it's own DRBG, chained to the parent global
DRBG which is used only as a source of randomness into the per-SSL
DRBG. This is used for all session, ticket, and pre-master secret keys.
It is NOT used for ECDH key generation which use only the global
DRBG. (Doing that without changing the API is tricky, if not impossible.)
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/4050)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/record/ssl3_record.c | 2 | ||||
-rw-r--r-- | ssl/s3_lib.c | 6 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 27 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 2 | ||||
-rw-r--r-- | ssl/ssl_sess.c | 4 | ||||
-rw-r--r-- | ssl/statem/statem_clnt.c | 4 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 6 | ||||
-rw-r--r-- | ssl/tls_srp.c | 4 |
8 files changed, 38 insertions, 17 deletions
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index afb03fde5b..ae485046a4 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -892,7 +892,7 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) */ SSLerr(SSL_F_TLS1_ENC, ERR_R_INTERNAL_ERROR); return -1; - } else if (RAND_bytes(recs[ctr].input, ivlen) <= 0) { + } else if (ssl_randbytes(s, recs[ctr].input, ivlen) <= 0) { SSLerr(SSL_F_TLS1_ENC, ERR_R_INTERNAL_ERROR); return -1; } diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index a2959a3896..e36eb93ca7 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -4213,11 +4213,11 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len, if (send_time) { unsigned long Time = (unsigned long)time(NULL); unsigned char *p = result; + l2n(Time, p); - /* TODO(size_t): Convert this */ - ret = RAND_bytes(p, (int)(len - 4)); + ret = ssl_randbytes(s, p, len - 4); } else { - ret = RAND_bytes(result, (int)len); + ret = ssl_randbytes(s, result, len); } #ifndef OPENSSL_NO_TLS13DOWNGRADE if (ret) { diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 048669c451..3abb27140b 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -21,6 +21,7 @@ #include <openssl/async.h> #include <openssl/ct.h> #include "internal/cryptlib.h" +#include "internal/rand.h" const char SSL_version_str[] = OPENSSL_VERSION_TEXT; @@ -619,10 +620,20 @@ SSL *SSL_new(SSL_CTX *ctx) goto err; s->lock = CRYPTO_THREAD_lock_new(); - if (s->lock == NULL) { - SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE); - OPENSSL_free(s); - return NULL; + if (s->lock == NULL) + goto err; + + /* + * If not using the standard RAND (say for fuzzing), then don't use a + * chained DRBG. + */ + if (RAND_get_rand_method() == RAND_OpenSSL()) { + s->drbg = RAND_DRBG_new(NID_aes_128_ctr, RAND_DRBG_FLAG_CTR_USE_DF, + RAND_DRBG_get0_global()); + if (s->drbg == NULL) { + CRYPTO_THREAD_lock_free(s->lock); + goto err; + } } RECORD_LAYER_init(&s->rlayer, s); @@ -1130,6 +1141,7 @@ void SSL_free(SSL *s) sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); #endif + RAND_DRBG_free(s->drbg); CRYPTO_THREAD_lock_free(s->lock); OPENSSL_free(s); @@ -5081,3 +5093,10 @@ uint32_t SSL_get_max_early_data(const SSL *s) { return s->max_early_data; } + +int ssl_randbytes(SSL *s, unsigned char *rnd, size_t size) +{ + if (s->drbg != NULL) + return RAND_DRBG_generate(s->drbg, rnd, size, 0, NULL, 0); + return RAND_bytes(rnd, (int)size); +} diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index ce678a66db..c78c28fe45 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1322,6 +1322,7 @@ struct ssl_st { size_t block_padding; CRYPTO_RWLOCK *lock; + RAND_DRBG *drbg; }; /* @@ -2122,6 +2123,7 @@ __owur int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags); __owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref); +__owur int ssl_randbytes(SSL *s, unsigned char *buf, size_t num); __owur int ssl_security(const SSL *s, int op, int bits, int nid, void *other); __owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other); diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 805a3d75f4..8cd4355cc6 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -277,12 +277,12 @@ unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s) */ #define MAX_SESS_ID_ATTEMPTS 10 -static int def_generate_session_id(const SSL *ssl, unsigned char *id, +static int def_generate_session_id(SSL *ssl, unsigned char *id, unsigned int *id_len) { unsigned int retry = 0; do - if (RAND_bytes(id, *id_len) <= 0) + if (ssl_randbytes(ssl, id, *id_len) <= 0) return 0; while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)) ; diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 5f6c6b0382..5f2855bcf4 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -2816,7 +2816,7 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt, int *al) pms[0] = s->client_version >> 8; pms[1] = s->client_version & 0xff; /* TODO(size_t): Convert this function */ - if (RAND_bytes(pms + 2, (int)(pmslen - 2)) <= 0) { + if (ssl_randbytes(s, pms + 2, (int)(pmslen - 2)) <= 0) { goto err; } @@ -3006,7 +3006,7 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt, int *al) /* Generate session key * TODO(size_t): Convert this function */ - || RAND_bytes(pms, (int)pmslen) <= 0) { + || ssl_randbytes(s, pms, (int)pmslen) <= 0) { *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_INTERNAL_ERROR); goto err; diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 9d3c387dcd..fad339adb2 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -2671,7 +2671,7 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt, int *al) * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - if (RAND_bytes(rand_premaster_secret, sizeof(rand_premaster_secret)) <= 0) + if (ssl_randbytes(s, rand_premaster_secret, sizeof(rand_premaster_secret)) <= 0) goto err; /* @@ -3378,7 +3378,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) } age_add_u; if (SSL_IS_TLS13(s)) { - if (RAND_bytes(age_add_u.age_add_c, sizeof(age_add_u)) <= 0) + if (ssl_randbytes(s, age_add_u.age_add_c, sizeof(age_add_u)) <= 0) goto err; s->session->ext.tick_age_add = age_add_u.age_add; /* @@ -3487,7 +3487,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) const EVP_CIPHER *cipher = EVP_aes_256_cbc(); iv_len = EVP_CIPHER_iv_length(cipher); - if (RAND_bytes(iv, iv_len) <= 0) + if (ssl_randbytes(s, iv, iv_len) <= 0) goto err; if (!EVP_EncryptInit_ex(ctx, cipher, NULL, tctx->ext.tick_aes_key, iv)) diff --git a/ssl/tls_srp.c b/ssl/tls_srp.c index bfdbdf5874..368cacee3d 100644 --- a/ssl/tls_srp.c +++ b/ssl/tls_srp.c @@ -153,7 +153,7 @@ int SSL_srp_server_param_with_username(SSL *s, int *ad) (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) return SSL3_AL_FATAL; - if (RAND_bytes(b, sizeof(b)) <= 0) + if (ssl_randbytes(s, b, sizeof(b)) <= 0) return SSL3_AL_FATAL; s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); OPENSSL_cleanse(b, sizeof(b)); @@ -343,7 +343,7 @@ int SRP_Calc_A_param(SSL *s) { unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; - if (RAND_bytes(rnd, sizeof(rnd)) <= 0) + if (ssl_randbytes(s, rnd, sizeof(rnd)) <= 0) return 0; s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); OPENSSL_cleanse(rnd, sizeof(rnd)); |