Prune finished labels from SSL3_ENC_METHOD.

There's not much point in putting those in the interface as the
final_finished_mac implementation is itself different between SSL 3.0
and TLS.

Change-Id: I76528a88d255c451ae008f1a34e51c3cb57d3073
Reviewed-on: https://boringssl-review.googlesource.com/6838
Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 2837c2e..7b311d6 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -380,10 +380,8 @@
           dtls1_start_timer(ssl);
         }
 
-        ret =
-            ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B,
-                               ssl->enc_method->client_finished_label,
-                               ssl->enc_method->client_finished_label_len);
+        ret = ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A,
+                                 SSL3_ST_CW_FINISHED_B);
         if (ret <= 0) {
           goto end;
         }
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 6e30cae..5c9624a 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -412,9 +412,7 @@
       case SSL3_ST_SW_FINISHED_A:
       case SSL3_ST_SW_FINISHED_B:
         ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A,
-                                 SSL3_ST_SW_FINISHED_B,
-                                 ssl->enc_method->server_finished_label,
-                                 ssl->enc_method->server_finished_label_len);
+                                 SSL3_ST_SW_FINISHED_B);
         if (ret <= 0) {
           goto end;
         }
diff --git a/ssl/internal.h b/ssl/internal.h
index 8a4f708..0057235 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -854,12 +854,8 @@
 struct ssl3_enc_method {
   int (*prf)(SSL *, uint8_t *, size_t, const uint8_t *, size_t, const char *,
              size_t, const uint8_t *, size_t, const uint8_t *, size_t);
-  int (*final_finish_mac)(SSL *, const char *, int, uint8_t *);
+  int (*final_finish_mac)(SSL *ssl, int from_server, uint8_t *out);
   int (*cert_verify_mac)(SSL *, int, uint8_t *);
-  const char *client_finished_label;
-  int client_finished_label_len;
-  const char *server_finished_label;
-  int server_finished_label_len;
   int (*alert_value)(int);
   /* Various flags indicating protocol version requirements */
   unsigned int enc_flags;
@@ -1060,7 +1056,7 @@
 int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len,
                           const EVP_MD **out_md, int pkey_type);
 
-int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen);
+int ssl3_send_finished(SSL *ssl, int a, int b);
 int ssl3_supports_cipher(const SSL_CIPHER *cipher);
 int ssl3_dispatch_alert(SSL *ssl);
 int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek);
@@ -1069,7 +1065,7 @@
 int ssl3_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek);
 int ssl3_write_app_data(SSL *ssl, const void *buf, int len);
 int ssl3_write_bytes(SSL *ssl, int type, const void *buf, int len);
-int ssl3_final_finish_mac(SSL *ssl, const char *sender, int slen, uint8_t *p);
+int ssl3_final_finish_mac(SSL *ssl, int from_server, uint8_t *out);
 int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p);
 int ssl3_output_cert_chain(SSL *ssl);
 const SSL_CIPHER *ssl3_choose_cipher(
@@ -1172,7 +1168,7 @@
 int tls1_change_cipher_state(SSL *ssl, int which);
 int tls1_setup_key_block(SSL *ssl);
 int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len);
-int tls1_final_finish_mac(SSL *ssl, const char *str, int slen, uint8_t *p);
+int tls1_final_finish_mac(SSL *ssl, int from_server, uint8_t *out);
 int tls1_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p);
 int tls1_generate_master_secret(SSL *ssl, uint8_t *out, const uint8_t *premaster,
                                 size_t premaster_len);
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index fcbe78d..3265609 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -156,14 +156,14 @@
   return 0;
 }
 
-int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen) {
+int ssl3_send_finished(SSL *ssl, int a, int b) {
   uint8_t *p;
   int n;
 
   if (ssl->state == a) {
     p = ssl_handshake_start(ssl);
 
-    n = ssl->enc_method->final_finish_mac(ssl, sender, slen,
+    n = ssl->enc_method->final_finish_mac(ssl, ssl->server,
                                           ssl->s3->tmp.finish_md);
     if (n == 0) {
       return 0;
@@ -202,25 +202,14 @@
 /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
  * so far. */
 static void ssl3_take_mac(SSL *ssl) {
-  const char *sender;
-  int slen;
-
   /* If no new cipher setup then return immediately: other functions will set
    * the appropriate error. */
   if (ssl->s3->tmp.new_cipher == NULL) {
     return;
   }
 
-  if (ssl->state & SSL_ST_CONNECT) {
-    sender = ssl->enc_method->server_finished_label;
-    slen = ssl->enc_method->server_finished_label_len;
-  } else {
-    sender = ssl->enc_method->client_finished_label;
-    slen = ssl->enc_method->client_finished_label_len;
-  }
-
   ssl->s3->tmp.peer_finish_md_len = ssl->enc_method->final_finish_mac(
-      ssl, sender, slen, ssl->s3->tmp.peer_finish_md);
+      ssl, !ssl->server, ssl->s3->tmp.peer_finish_md);
 }
 
 int ssl3_get_finished(SSL *ssl, int a, int b) {
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 2c1a32f..80c1b10 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -421,9 +421,7 @@
       case SSL3_ST_CW_FINISHED_A:
       case SSL3_ST_CW_FINISHED_B:
         ret = ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A,
-                                 SSL3_ST_CW_FINISHED_B,
-                                 ssl->enc_method->client_finished_label,
-                                 ssl->enc_method->client_finished_label_len);
+                                 SSL3_ST_CW_FINISHED_B);
         if (ret <= 0) {
           goto end;
         }
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index f5f847e..16c7dae 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -162,8 +162,8 @@
     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
 };
 
-static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
-                              uint8_t *p);
+static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender,
+                              size_t sender_len, uint8_t *p);
 
 int ssl3_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret,
              size_t secret_len, const char *label, size_t label_len,
@@ -313,16 +313,19 @@
   return ssl3_handshake_mac(ssl, md_nid, NULL, 0, p);
 }
 
-int ssl3_final_finish_mac(SSL *ssl, const char *sender, int len, uint8_t *p) {
+int ssl3_final_finish_mac(SSL *ssl, int from_server, uint8_t *out) {
+  const char *sender = from_server ? SSL3_MD_SERVER_FINISHED_CONST
+                                   : SSL3_MD_CLIENT_FINISHED_CONST;
+  const size_t sender_len = 4;
   int ret, sha1len;
-  ret = ssl3_handshake_mac(ssl, NID_md5, sender, len, p);
+  ret = ssl3_handshake_mac(ssl, NID_md5, sender, sender_len, out);
   if (ret == 0) {
     return 0;
   }
 
-  p += ret;
+  out += ret;
 
-  sha1len = ssl3_handshake_mac(ssl, NID_sha1, sender, len, p);
+  sha1len = ssl3_handshake_mac(ssl, NID_sha1, sender, sender_len, out);
   if (sha1len == 0) {
     return 0;
   }
@@ -331,8 +334,8 @@
   return ret;
 }
 
-static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len,
-                              uint8_t *p) {
+static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender,
+                              size_t sender_len, uint8_t *p) {
   unsigned int ret;
   size_t npad, n;
   unsigned int i;
@@ -360,7 +363,7 @@
 
   npad = (48 / n) * n;
   if (sender != NULL) {
-    EVP_DigestUpdate(&ctx, sender, len);
+    EVP_DigestUpdate(&ctx, sender, sender_len);
   }
   EVP_DigestUpdate(&ctx, ssl->session->master_key,
                    ssl->session->master_key_length);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 1e18e54..42e2854 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -167,8 +167,6 @@
     ssl3_prf,
     ssl3_final_finish_mac,
     ssl3_cert_verify_mac,
-    SSL3_MD_CLIENT_FINISHED_CONST, 4,
-    SSL3_MD_SERVER_FINISHED_CONST, 4,
     ssl3_alert_code,
     0,
 };
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index eee7b0c..94f1ccb 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -519,9 +519,7 @@
       case SSL3_ST_SW_FINISHED_A:
       case SSL3_ST_SW_FINISHED_B:
         ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A,
-                                 SSL3_ST_SW_FINISHED_B,
-                                 ssl->enc_method->server_finished_label,
-                                 ssl->enc_method->server_finished_label_len);
+                                 SSL3_ST_SW_FINISHED_B);
         if (ret <= 0) {
           goto end;
         }
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 92a8489..06dcf28 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -455,39 +455,39 @@
   return (int)(md5_len + len);
 }
 
-int tls1_final_finish_mac(SSL *ssl, const char *str, int slen, uint8_t *out) {
-  uint8_t buf[2 * EVP_MAX_MD_SIZE];
-  int err = 0;
-  int digests_len;
-
+int tls1_final_finish_mac(SSL *ssl, int from_server, uint8_t *out) {
   /* At this point, the handshake should have released the handshake buffer on
    * its own. */
   assert(ssl->s3->handshake_buffer == NULL);
 
-  digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf));
+  const char *label = TLS_MD_CLIENT_FINISH_CONST;
+  size_t label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
+  if (from_server) {
+    label = TLS_MD_SERVER_FINISH_CONST;
+    label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
+  }
+
+  uint8_t buf[EVP_MAX_MD_SIZE];
+  int digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf));
   if (digests_len < 0) {
-    err = 1;
-    digests_len = 0;
-  }
-
-  if (!ssl->enc_method->prf(ssl, out, 12, ssl->session->master_key,
-                            ssl->session->master_key_length, str, slen, buf,
-                            digests_len, NULL, 0)) {
-    err = 1;
-  }
-
-  if (err) {
     return 0;
-  } else {
-    return 12;
   }
+
+  static const size_t kFinishedLen = 12;
+  if (!ssl->enc_method->prf(ssl, out, kFinishedLen, ssl->session->master_key,
+                            ssl->session->master_key_length, label, label_len,
+                            buf, digests_len, NULL, 0)) {
+    return 0;
+  }
+
+  return (int)kFinishedLen;
 }
 
 int tls1_generate_master_secret(SSL *ssl, uint8_t *out,
                                 const uint8_t *premaster,
                                 size_t premaster_len) {
   if (ssl->s3->tmp.extended_master_secret) {
-    uint8_t digests[2 * EVP_MAX_MD_SIZE];
+    uint8_t digests[EVP_MAX_MD_SIZE];
     int digests_len = tls1_handshake_digest(ssl, digests, sizeof(digests));
     if (digests_len == -1) {
       return 0;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index d2fc8af..20115e8 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -134,8 +134,6 @@
     tls1_prf,
     tls1_final_finish_mac,
     tls1_cert_verify_mac,
-    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
-    TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
     tls1_alert_code,
     0,
 };
@@ -144,8 +142,6 @@
     tls1_prf,
     tls1_final_finish_mac,
     tls1_cert_verify_mac,
-    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
-    TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
     tls1_alert_code,
     SSL_ENC_FLAG_EXPLICIT_IV,
 };
@@ -154,8 +150,6 @@
     tls1_prf,
     tls1_final_finish_mac,
     tls1_cert_verify_mac,
-    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
-    TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
     tls1_alert_code,
     SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF,
 };