From d6a4ae97cdc118d2505a10acf613706c9ae32a54 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Thu, 6 Aug 2015 11:10:51 -0400 Subject: [PATCH] Simplify tls1_channel_id_hash. Rather than iterate over handshake_dgsts itself, it can just call tls1_handshake_digest. Change-Id: Ia518da540e47e65b13367eb1af184c0885908488 Reviewed-on: https://boringssl-review.googlesource.com/5617 Reviewed-by: Adam Langley --- ssl/internal.h | 6 +++++- ssl/s3_clnt.c | 6 ++---- ssl/s3_srvr.c | 13 +++-------- ssl/t1_lib.c | 58 +++++++++++++++++++++++++++----------------------- 4 files changed, 41 insertions(+), 42 deletions(-) diff --git a/ssl/internal.h b/ssl/internal.h index 1d6426b9..a898422b 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -1142,7 +1142,11 @@ int tls12_get_sigandhash(SSL *ssl, uint8_t *p, const EVP_MD *md); int tls12_get_sigid(int pkey_type); const EVP_MD *tls12_get_hash(uint8_t hash_alg); -int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s); +/* tls1_channel_id_hash computes the hash to be signed by Channel ID and writes + * it to |out|, which must contain at least |EVP_MAX_MD_SIZE| bytes. It returns + * one on success and zero on failure. */ +int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len); + int tls1_record_handshake_hashes_for_channel_id(SSL *s); int tls1_set_sigalgs_list(CERT *c, const char *str, int client); diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 6a3f1579..ef24316a 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -2210,10 +2210,8 @@ int ssl3_send_channel_id(SSL *s) { i2o_ECPublicKey(ec_key, &derp); uint8_t digest[EVP_MAX_MD_SIZE]; - unsigned digest_len; - if (!EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL) || - !tls1_channel_id_hash(&md_ctx, s) || - !EVP_DigestFinal_ex(&md_ctx, digest, &digest_len)) { + size_t digest_len; + if (!tls1_channel_id_hash(s, digest, &digest_len)) { goto err; } diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index fa9dc9a8..e45251be 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -2471,9 +2471,8 @@ int ssl3_get_next_proto(SSL *s) { int ssl3_get_channel_id(SSL *s) { int ret = -1, ok; long n; - EVP_MD_CTX md_ctx; - uint8_t channel_id_hash[SHA256_DIGEST_LENGTH]; - unsigned int channel_id_hash_len; + uint8_t channel_id_hash[EVP_MAX_MD_SIZE]; + size_t channel_id_hash_len; const uint8_t *p; uint16_t extension_type; EC_GROUP *p256 = NULL; @@ -2494,15 +2493,9 @@ int ssl3_get_channel_id(SSL *s) { /* Before incorporating the EncryptedExtensions message to the handshake * hash, compute the hash that should have been signed. */ - channel_id_hash_len = sizeof(channel_id_hash); - EVP_MD_CTX_init(&md_ctx); - if (!EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL) || - !tls1_channel_id_hash(&md_ctx, s) || - !EVP_DigestFinal(&md_ctx, channel_id_hash, &channel_id_hash_len)) { - EVP_MD_CTX_cleanup(&md_ctx); + if (!tls1_channel_id_hash(s, channel_id_hash, &channel_id_hash_len)) { return -1; } - EVP_MD_CTX_cleanup(&md_ctx); assert(channel_id_hash_len == SHA256_DIGEST_LENGTH); if (!ssl3_hash_current_message(s)) { diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 1dedb32a..d2f89830 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -113,6 +113,7 @@ #include #include +#include #include #include #include @@ -2923,42 +2924,45 @@ const EVP_MD *tls1_choose_signing_digest(SSL *ssl) { return EVP_sha1(); } -/* tls1_channel_id_hash calculates the signed data for a Channel ID on the - * given SSL connection and writes it to |md|. */ -int tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s) { +int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len) { + int ret = 0; EVP_MD_CTX ctx; - uint8_t temp_digest[EVP_MAX_MD_SIZE]; - unsigned temp_digest_len; - int i; - static const char kClientIDMagic[] = "TLS Channel ID signature"; - EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic)); + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL)) { + goto err; + } - if (s->hit) { + static const char kClientIDMagic[] = "TLS Channel ID signature"; + EVP_DigestUpdate(&ctx, kClientIDMagic, sizeof(kClientIDMagic)); + + if (ssl->hit) { static const char kResumptionMagic[] = "Resumption"; - EVP_DigestUpdate(md, kResumptionMagic, sizeof(kResumptionMagic)); - if (s->session->original_handshake_hash_len == 0) { - return 0; + EVP_DigestUpdate(&ctx, kResumptionMagic, sizeof(kResumptionMagic)); + if (ssl->session->original_handshake_hash_len == 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + goto err; } - EVP_DigestUpdate(md, s->session->original_handshake_hash, - s->session->original_handshake_hash_len); + EVP_DigestUpdate(&ctx, ssl->session->original_handshake_hash, + ssl->session->original_handshake_hash_len); } - EVP_MD_CTX_init(&ctx); - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i] == NULL) { - continue; - } - if (!EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst[i])) { - EVP_MD_CTX_cleanup(&ctx); - return 0; - } - EVP_DigestFinal_ex(&ctx, temp_digest, &temp_digest_len); - EVP_DigestUpdate(md, temp_digest, temp_digest_len); + uint8_t handshake_hash[EVP_MAX_MD_SIZE]; + int handshake_hash_len = tls1_handshake_digest(ssl, handshake_hash, + sizeof(handshake_hash)); + if (handshake_hash_len < 0) { + goto err; } - EVP_MD_CTX_cleanup(&ctx); + EVP_DigestUpdate(&ctx, handshake_hash, (size_t)handshake_hash_len); + unsigned len_u; + EVP_DigestFinal_ex(&ctx, out, &len_u); + *out_len = len_u; - return 1; + ret = 1; + +err: + EVP_MD_CTX_cleanup(&ctx); + return ret; } /* tls1_record_handshake_hashes_for_channel_id records the current handshake