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,
};