Ensure all EVP calls have their returns checked where appropriate
There are lots of calls to EVP functions from within libssl There were
various places where we should probably check the return value but don't.
This adds these checks.
Reviewed-by: Richard Levitte <levitte@openssl.org>
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index 359d247..381872d 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -846,33 +846,36 @@
header[j++] = rec->length & 0xff;
/* Final param == is SSLv3 */
- ssl3_cbc_digest_record(hash,
- md, &md_size,
- header, rec->input,
- rec->length + md_size, rec->orig_len,
- mac_sec, md_size, 1);
+ if (ssl3_cbc_digest_record(hash,
+ md, &md_size,
+ header, rec->input,
+ rec->length + md_size, rec->orig_len,
+ mac_sec, md_size, 1) <= 0)
+ return -1;
} else {
unsigned int md_size_u;
/* Chop the digest off the end :-) */
EVP_MD_CTX_init(&md_ctx);
- EVP_MD_CTX_copy_ex(&md_ctx, hash);
- EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
- EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad);
- EVP_DigestUpdate(&md_ctx, seq, 8);
rec_char = rec->type;
- EVP_DigestUpdate(&md_ctx, &rec_char, 1);
p = md;
s2n(rec->length, p);
- EVP_DigestUpdate(&md_ctx, md, 2);
- EVP_DigestUpdate(&md_ctx, rec->input, rec->length);
- EVP_DigestFinal_ex(&md_ctx, md, NULL);
-
- EVP_MD_CTX_copy_ex(&md_ctx, hash);
- EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
- EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad);
- EVP_DigestUpdate(&md_ctx, md, md_size);
- EVP_DigestFinal_ex(&md_ctx, md, &md_size_u);
+ if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
+ || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
+ || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0
+ || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0
+ || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0
+ || EVP_DigestUpdate(&md_ctx, md, 2) <= 0
+ || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0
+ || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0
+ || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
+ || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
+ || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0
+ || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0
+ || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) {
+ EVP_MD_CTX_cleanup(&md_ctx);
+ return -1;
+ }
md_size = md_size_u;
EVP_MD_CTX_cleanup(&md_ctx);
@@ -944,18 +947,24 @@
* are hashing because that gives an attacker a timing-oracle.
*/
/* Final param == not SSLv3 */
- ssl3_cbc_digest_record(mac_ctx,
- md, &md_size,
- header, rec->input,
- rec->length + md_size, rec->orig_len,
- ssl->s3->read_mac_secret,
- ssl->s3->read_mac_secret_size, 0);
- } else {
- EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
- EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
- t = EVP_DigestSignFinal(mac_ctx, md, &md_size);
- if (t <= 0)
+ if (ssl3_cbc_digest_record(mac_ctx,
+ md, &md_size,
+ header, rec->input,
+ rec->length + md_size, rec->orig_len,
+ ssl->s3->read_mac_secret,
+ ssl->s3->read_mac_secret_size, 0) <= 0) {
+ if (!stream_mac)
+ EVP_MD_CTX_cleanup(&hmac);
return -1;
+ }
+ } else {
+ if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
+ || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
+ || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
+ if (!stream_mac)
+ EVP_MD_CTX_cleanup(&hmac);
+ return -1;
+ }
if (!send && !SSL_USE_ETM(ssl) && FIPS_mode())
tls_fips_digest_extra(ssl->enc_read_ctx,
mac_ctx, rec->input,
@@ -964,6 +973,7 @@
if (!stream_mac)
EVP_MD_CTX_cleanup(&hmac);
+
#ifdef TLS_DEBUG
fprintf(stderr, "seq=");
{
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index f7997ea..5225222 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -172,8 +172,9 @@
* functions, above, we know that data_plus_mac_size is large enough to contain
* a padding byte and MAC. (If the padding was invalid, it might contain the
* padding too. )
+ * Returns 1 on success or 0 on error
*/
-void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
unsigned char *md_out,
size_t *md_out_size,
const unsigned char header[13],
@@ -217,7 +218,8 @@
switch (EVP_MD_CTX_type(ctx)) {
case NID_md5:
- MD5_Init((MD5_CTX *)md_state.c);
+ if (MD5_Init((MD5_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_md5_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))MD5_Transform;
@@ -226,28 +228,32 @@
length_is_big_endian = 0;
break;
case NID_sha1:
- SHA1_Init((SHA_CTX *)md_state.c);
+ if (SHA1_Init((SHA_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha1_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA1_Transform;
md_size = 20;
break;
case NID_sha224:
- SHA224_Init((SHA256_CTX *)md_state.c);
+ if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha256_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
md_size = 224 / 8;
break;
case NID_sha256:
- SHA256_Init((SHA256_CTX *)md_state.c);
+ if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha256_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
md_size = 32;
break;
case NID_sha384:
- SHA384_Init((SHA512_CTX *)md_state.c);
+ if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha512_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
@@ -256,7 +262,8 @@
md_length_size = 16;
break;
case NID_sha512:
- SHA512_Init((SHA512_CTX *)md_state.c);
+ if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha512_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
@@ -272,7 +279,7 @@
OPENSSL_assert(0);
if (md_out_size)
*md_out_size = -1;
- return;
+ return 0;
}
OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
@@ -410,7 +417,7 @@
*/
if (header_length <= md_block_size) {
/* Should never happen */
- return;
+ return 0;
}
overhang = header_length - md_block_size;
md_transform(md_state.c, header);
@@ -491,26 +498,34 @@
}
EVP_MD_CTX_init(&md_ctx);
- EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ );
+ if (EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ ) <= 0)
+ goto err;
if (is_sslv3) {
/* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
memset(hmac_pad, 0x5c, sslv3_pad_length);
- EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
- EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
- EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+ if (EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length) <= 0
+ || EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length) <= 0
+ || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0)
+ goto err;
} else {
/* Complete the HMAC in the standard manner. */
for (i = 0; i < md_block_size; i++)
hmac_pad[i] ^= 0x6a;
- EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
- EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+ if (EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size) <= 0
+ || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0)
+ goto err;
}
ret = EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
if (ret && md_out_size)
*md_out_size = md_out_size_u;
EVP_MD_CTX_cleanup(&md_ctx);
+
+ return 1;
+err:
+ EVP_MD_CTX_cleanup(&md_ctx);
+ return 0;
}
/*
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 02e07ba..1a5aaec 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -253,7 +253,7 @@
EVP_CIPHER_CTX_init(s->enc_read_ctx);
dd = s->enc_read_ctx;
- if (!ssl_replace_hash(&s->read_hash, m)) {
+ if (ssl_replace_hash(&s->read_hash, m) == NULL) {
SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
goto err2;
}
@@ -286,7 +286,7 @@
*/
EVP_CIPHER_CTX_init(s->enc_write_ctx);
dd = s->enc_write_ctx;
- if (!ssl_replace_hash(&s->write_hash, m)) {
+ if (ssl_replace_hash(&s->write_hash, m) == NULL) {
SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
goto err2;
}
@@ -617,19 +617,21 @@
return 0;
npad = (48 / n) * n;
- if (sender != NULL)
- EVP_DigestUpdate(&ctx, sender, len);
- EVP_DigestUpdate(&ctx, s->session->master_key,
- s->session->master_key_length);
- EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
- EVP_DigestFinal_ex(&ctx, md_buf, &i);
+ if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0)
+ || EVP_DigestUpdate(&ctx, s->session->master_key,
+ s->session->master_key_length) <= 0
+ || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0
+ || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0
- EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL);
- EVP_DigestUpdate(&ctx, s->session->master_key,
- s->session->master_key_length);
- EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
- EVP_DigestUpdate(&ctx, md_buf, i);
- EVP_DigestFinal_ex(&ctx, p, &ret);
+ || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0
+ || EVP_DigestUpdate(&ctx, s->session->master_key,
+ s->session->master_key_length) <= 0
+ || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0
+ || EVP_DigestUpdate(&ctx, md_buf, i) <= 0
+ || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) {
+ SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR);
+ ret = 0;
+ }
EVP_MD_CTX_cleanup(&ctx);
@@ -660,24 +662,31 @@
EVP_MD_CTX_init(&ctx);
for (i = 0; i < 3; i++) {
- EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL);
- EVP_DigestUpdate(&ctx, salt[i], strlen((const char *)salt[i]));
- EVP_DigestUpdate(&ctx, p, len);
- EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE);
- EVP_DigestFinal_ex(&ctx, buf, &n);
+ if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0
+ || EVP_DigestUpdate(&ctx, salt[i],
+ strlen((const char *)salt[i])) <= 0
+ || EVP_DigestUpdate(&ctx, p, len) <= 0
+ || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0
- EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL);
- EVP_DigestUpdate(&ctx, p, len);
- EVP_DigestUpdate(&ctx, buf, n);
- EVP_DigestFinal_ex(&ctx, out, &n);
+ || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0
+ || EVP_DigestUpdate(&ctx, p, len) <= 0
+ || EVP_DigestUpdate(&ctx, buf, n) <= 0
+ || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) {
+ SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
+ ret = 0;
+ break;
+ }
out += n;
ret += n;
}
EVP_MD_CTX_cleanup(&ctx);
#ifdef OPENSSL_SSL_TRACE_CRYPTO
- if (s->msg_callback) {
+ if (ret > 0 && s->msg_callback) {
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
p, len, s, s->msg_callback_arg);
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 580178e..fe30ab4 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -439,10 +439,11 @@
const EVP_PKEY_ASN1_METHOD *ameth;
int pkey_id = 0;
ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1);
- if (ameth) {
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+ if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+ ameth) > 0) {
+ return pkey_id;
}
- return pkey_id;
+ return 0;
}
#else
@@ -454,7 +455,9 @@
int pkey_id = 0;
ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1);
if (ameth) {
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+ if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+ ameth) <= 0)
+ pkey_id = 0;
}
if (tmpeng)
ENGINE_finish(tmpeng);
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index b66ebc4..82fb614 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -140,6 +140,8 @@
"ssl3_do_change_cipher_spec"},
{ERR_FUNC(SSL_F_SSL3_ENC), "ssl3_enc"},
{ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "ssl3_generate_key_block"},
+ {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET),
+ "ssl3_generate_master_secret"},
{ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST),
"ssl3_get_certificate_request"},
{ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "ssl3_get_cert_status"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index d8d2244..1c3b726 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3165,8 +3165,11 @@
{
ssl_clear_hash_ctx(hash);
*hash = EVP_MD_CTX_create();
- if (md)
- EVP_DigestInit_ex(*hash, md, NULL);
+ if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
+ EVP_MD_CTX_destroy(*hash);
+ *hash = NULL;
+ return NULL;
+ }
return *hash;
}
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 1295b7b..6ccdbe4 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -2114,15 +2114,15 @@
/* s3_cbc.c */
__owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
-void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
- unsigned char *md_out,
- size_t *md_out_size,
- const unsigned char header[13],
- const unsigned char *data,
- size_t data_plus_mac_size,
- size_t data_plus_mac_plus_padding_size,
- const unsigned char *mac_secret,
- unsigned mac_secret_length, char is_sslv3);
+__owur int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+ unsigned char *md_out,
+ size_t *md_out_size,
+ const unsigned char header[13],
+ const unsigned char *data,
+ size_t data_plus_mac_size,
+ size_t data_plus_mac_plus_padding_size,
+ const unsigned char *mac_secret,
+ unsigned mac_secret_length, char is_sslv3);
void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx,
EVP_MD_CTX *mac_ctx, const unsigned char *data,
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index be552c1..96353c1 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -157,7 +157,10 @@
}
RSA_up_ref(rsa);
- EVP_PKEY_assign_RSA(pkey, rsa);
+ if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
+ RSA_free(rsa);
+ return 0;
+ }
ret = ssl_set_pkey(ssl->cert, pkey);
EVP_PKEY_free(pkey);
@@ -192,6 +195,15 @@
if (c->pkeys[i].x509 != NULL) {
EVP_PKEY *pktmp;
pktmp = X509_get_pubkey(c->pkeys[i].x509);
+ if (pktmp == NULL) {
+ SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE);
+ EVP_PKEY_free(pktmp);
+ return 0;
+ }
+ /*
+ * The return code from EVP_PKEY_copy_parameters is deliberately
+ * ignored. Some EVP_PKEY types cannot do this.
+ */
EVP_PKEY_copy_parameters(pktmp, pkey);
EVP_PKEY_free(pktmp);
ERR_clear_error();
@@ -386,6 +398,10 @@
}
if (c->pkeys[i].privatekey != NULL) {
+ /*
+ * The return code from EVP_PKEY_copy_parameters is deliberately
+ * ignored. Some EVP_PKEY types cannot do this.
+ */
EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
ERR_clear_error();
@@ -498,7 +514,10 @@
}
RSA_up_ref(rsa);
- EVP_PKEY_assign_RSA(pkey, rsa);
+ if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
+ RSA_free(rsa);
+ return 0;
+ }
ret = ssl_set_pkey(ctx->cert, pkey);
EVP_PKEY_free(pkey);
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index f6b95d6..7b7fc22 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1961,15 +1961,21 @@
q = md_buf;
for (num = 2; num > 0; num--) {
EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- EVP_DigestInit_ex(&md_ctx, (num == 2)
- ? s->ctx->md5 : s->ctx->sha1, NULL);
- EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, PACKET_data(¶ms),
- PACKET_remaining(¶ms));
- EVP_DigestFinal_ex(&md_ctx, q, &size);
+ if (EVP_DigestInit_ex(&md_ctx,
+ (num == 2) ? s->ctx->md5 : s->ctx->sha1,
+ NULL) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&md_ctx, PACKET_data(¶ms),
+ PACKET_remaining(¶ms)) <= 0
+ || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) {
+ SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
q += size;
j += size;
}
@@ -1990,13 +1996,17 @@
} else
#endif
{
- EVP_VerifyInit_ex(&md_ctx, md, NULL);
- EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_VerifyUpdate(&md_ctx, PACKET_data(¶ms),
- PACKET_remaining(¶ms));
+ if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0
+ || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_VerifyUpdate(&md_ctx, PACKET_data(¶ms),
+ PACKET_remaining(¶ms)) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
+ goto f_err;
+ }
if (EVP_VerifyFinal(&md_ctx, PACKET_data(&signature),
PACKET_remaining(&signature), pkey) <= 0) {
/* bad signature */
@@ -2786,16 +2796,16 @@
}
/*
* If we have send a certificate, and certificate key
- *
- * * parameters match those of server certificate, use
+ * parameters match those of server certificate, use
* certificate key for key exchange
*/
/* Otherwise, generate ephemeral key pair */
- EVP_PKEY_encrypt_init(pkey_ctx);
- /* Generate session key */
- if (RAND_bytes(pms, pmslen) <= 0) {
+ if (pkey_ctx == NULL
+ || EVP_PKEY_encrypt_init(pkey_ctx) <= 0
+ /* Generate session key */
+ || RAND_bytes(pms, pmslen) <= 0) {
EVP_PKEY_CTX_free(pkey_ctx);
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
@@ -2819,13 +2829,18 @@
* data
*/
ukm_hash = EVP_MD_CTX_create();
- EVP_DigestInit(ukm_hash,
- EVP_get_digestbynid(NID_id_GostR3411_94));
- EVP_DigestUpdate(ukm_hash, s->s3->client_random,
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(ukm_hash, s->s3->server_random,
- SSL3_RANDOM_SIZE);
- EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len);
+ if (EVP_DigestInit(ukm_hash,
+ EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0
+ || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
+ EVP_MD_CTX_destroy(ukm_hash);
+ SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
EVP_MD_CTX_destroy(ukm_hash);
if (EVP_PKEY_CTX_ctrl
(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8,
@@ -2840,7 +2855,7 @@
*/
*(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
msglen = 255;
- if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) < 0) {
+ if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
SSL_R_LIBRARY_BUG);
goto err;
@@ -3006,7 +3021,10 @@
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
- EVP_PKEY_sign_init(pctx);
+ if (EVP_PKEY_sign_init(pctx) <= 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) {
if (!SSL_USE_SIGALGS(s))
s->method->ssl3_enc->cert_verify_mac(s,
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index c418787..a7498d8 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -2109,14 +2109,20 @@
for (num = 2; num > 0; num--) {
EVP_MD_CTX_set_flags(&md_ctx,
EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- EVP_DigestInit_ex(&md_ctx, (num == 2)
- ? s->ctx->md5 : s->ctx->sha1, NULL);
- EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, d, n);
- EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i);
+ if (EVP_DigestInit_ex(&md_ctx, (num == 2)
+ ? s->ctx->md5 : s->ctx->sha1, NULL) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&md_ctx, d, n) <= 0
+ || EVP_DigestFinal_ex(&md_ctx, q,
+ (unsigned int *)&i) <= 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+ ERR_LIB_EVP);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
q += i;
j += i;
}
@@ -2144,16 +2150,17 @@
#ifdef SSL_DEBUG
fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
#endif
- EVP_SignInit_ex(&md_ctx, md, NULL);
- EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_SignUpdate(&md_ctx, d, n);
- if (!EVP_SignFinal(&md_ctx, &(p[2]),
- (unsigned int *)&i, pkey)) {
+ if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0
+ || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_SignUpdate(&md_ctx, d, n) <= 0
+ || EVP_SignFinal(&md_ctx, &(p[2]),
+ (unsigned int *)&i, pkey) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
- goto err;
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
}
s2n(i, p);
n += i + 2;
@@ -2812,7 +2819,11 @@
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto f_err;
}
- EVP_PKEY_decrypt_init(pkey_ctx);
+ if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
/*
* If client certificate is present and is of the same type, maybe
* use it for key exchange. Don't mind errors from
@@ -2829,12 +2840,13 @@
if (!PACKET_get_bytes(pkt, &data, sess_key_len)) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
+ goto gerr;
}
if (ASN1_get_object ((const unsigned char **)&data, &Tlen, &Ttag,
&Tclass, sess_key_len) != V_ASN1_CONSTRUCTED
|| Ttag != V_ASN1_SEQUENCE
|| Tclass != V_ASN1_UNIVERSAL) {
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
goto gerr;
@@ -2852,7 +2864,7 @@
sizeof(premaster_secret), 0)) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
+ goto gerr;
}
/* Check if pubkey from client certificate was used */
if (EVP_PKEY_CTX_ctrl
@@ -2865,7 +2877,7 @@
gerr:
EVP_PKEY_free(client_pub_pkey);
EVP_PKEY_CTX_free(pkey_ctx);
- goto err;
+ goto f_err;
} else {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE);
@@ -3150,7 +3162,11 @@
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
goto f_err;
}
- EVP_PKEY_verify_init(pctx);
+ if (EVP_PKEY_verify_init(pctx) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
if (len != 64) {
fprintf(stderr, "GOST signature length is %d", len);
}
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 1f539aa..729cecc 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -353,6 +353,8 @@
EVP_CIPHER_CTX_init(s->enc_read_ctx);
dd = s->enc_read_ctx;
mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
+ if (mac_ctx == NULL)
+ goto err;
#ifndef OPENSSL_NO_COMP
COMP_CTX_free(s->expand);
s->expand = NULL;
@@ -386,11 +388,14 @@
dd = s->enc_write_ctx;
if (SSL_IS_DTLS(s)) {
mac_ctx = EVP_MD_CTX_create();
- if (!mac_ctx)
+ if (mac_ctx == NULL)
goto err;
s->write_hash = mac_ctx;
- } else
+ } else {
mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
+ if (mac_ctx == NULL)
+ goto err;
+ }
#ifndef OPENSSL_NO_COMP
COMP_CTX_free(s->compress);
s->compress = NULL;
@@ -463,7 +468,12 @@
if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
mac_secret, *mac_secret_size);
- EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key);
+ if (mac_key == NULL
+ || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) {
+ EVP_PKEY_free(mac_key);
+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ goto err2;
+ }
EVP_PKEY_free(mac_key);
}
#ifdef TLS_DEBUG
@@ -711,8 +721,9 @@
}
EVP_MD_CTX_init(&ctx);
- EVP_MD_CTX_copy_ex(&ctx, d);
- EVP_DigestFinal_ex(&ctx, out, &ret);
+ if (EVP_MD_CTX_copy_ex(&ctx, d) <=0
+ || EVP_DigestFinal_ex(&ctx, out, &ret) <= 0)
+ ret = 0;
EVP_MD_CTX_cleanup(&ctx);
return ((int)ret);
}
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index ffc95d8..1439eaa 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -3079,10 +3079,13 @@
/* Check key name matches */
if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
return 2;
- HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
- EVP_sha256(), NULL);
- EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- tctx->tlsext_tick_aes_key, etick + 16);
+ if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+ EVP_sha256(), NULL) <= 0
+ || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+ tctx->tlsext_tick_aes_key,
+ etick + 16) <= 0) {
+ goto err;
+ }
}
/*
* Attempt to process session ticket, first conduct sanity and integrity
@@ -3090,13 +3093,14 @@
*/
mlen = HMAC_size(&hctx);
if (mlen < 0) {
- EVP_CIPHER_CTX_cleanup(&ctx);
- return -1;
+ goto err;
}
eticklen -= mlen;
/* Check HMAC of encrypted ticket */
- HMAC_Update(&hctx, etick, eticklen);
- HMAC_Final(&hctx, tick_hmac, NULL);
+ if (HMAC_Update(&hctx, etick, eticklen) <= 0
+ || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) {
+ goto err;
+ }
HMAC_CTX_cleanup(&hctx);
if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
EVP_CIPHER_CTX_cleanup(&ctx);
@@ -3107,11 +3111,11 @@
p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
sdec = OPENSSL_malloc(eticklen);
- if (sdec == NULL) {
+ if (sdec == NULL
+ || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
EVP_CIPHER_CTX_cleanup(&ctx);
return -1;
}
- EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
EVP_CIPHER_CTX_cleanup(&ctx);
OPENSSL_free(sdec);
@@ -3144,6 +3148,10 @@
* For session parse failure, indicate that we need to send a new ticket.
*/
return 2;
+err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ HMAC_CTX_cleanup(&hctx);
+ return -1;
}
/* Tables to translate from NIDs to TLS v1.2 ids */