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 <agl@google.com>
diff --git a/ssl/internal.h b/ssl/internal.h
index 1d6426b..a898422 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1142,7 +1142,11 @@
 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 6a3f157..ef24316 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -2210,10 +2210,8 @@
   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 fa9dc9a..e45251b 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -2471,9 +2471,8 @@
 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 @@
 
   /* 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 1dedb32..d2f8983 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -113,6 +113,7 @@
 #include <string.h>
 
 #include <openssl/bytestring.h>
+#include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
@@ -2923,42 +2924,45 @@
   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));
-
-  if (s->hit) {
-    static const char kResumptionMagic[] = "Resumption";
-    EVP_DigestUpdate(md, kResumptionMagic, sizeof(kResumptionMagic));
-    if (s->session->original_handshake_hash_len == 0) {
-      return 0;
-    }
-    EVP_DigestUpdate(md, s->session->original_handshake_hash,
-                     s->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);
+  if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL)) {
+    goto err;
   }
-  EVP_MD_CTX_cleanup(&ctx);
 
-  return 1;
+  static const char kClientIDMagic[] = "TLS Channel ID signature";
+  EVP_DigestUpdate(&ctx, kClientIDMagic, sizeof(kClientIDMagic));
+
+  if (ssl->hit) {
+    static const char kResumptionMagic[] = "Resumption";
+    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(&ctx, ssl->session->original_handshake_hash,
+                     ssl->session->original_handshake_hash_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_DigestUpdate(&ctx, handshake_hash, (size_t)handshake_hash_len);
+  unsigned len_u;
+  EVP_DigestFinal_ex(&ctx, out, &len_u);
+  *out_len = len_u;
+
+  ret = 1;
+
+err:
+  EVP_MD_CTX_cleanup(&ctx);
+  return ret;
 }
 
 /* tls1_record_handshake_hashes_for_channel_id records the current handshake