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>kris/onging/CECPQ3_patch15
@@ -380,10 +380,8 @@ int dtls1_connect(SSL *ssl) { | |||
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; | |||
} | |||
@@ -412,9 +412,7 @@ int dtls1_accept(SSL *ssl) { | |||
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; | |||
} | |||
@@ -854,12 +854,8 @@ struct ssl_protocol_method_st { | |||
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_hash_current_message(SSL *ssl); | |||
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 @@ void ssl3_read_close_notify(SSL *ssl); | |||
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_prf(SSL *ssl, uint8_t *out, size_t out_len, const uint8_t *secret, | |||
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); | |||
@@ -156,14 +156,14 @@ int ssl3_do_write(SSL *ssl, int type) { | |||
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 @@ int ssl3_send_finished(SSL *ssl, int a, int b, const char *sender, int slen) { | |||
/* 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) { | |||
@@ -421,9 +421,7 @@ int ssl3_connect(SSL *ssl) { | |||
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; | |||
} | |||
@@ -162,8 +162,8 @@ static const uint8_t ssl3_pad_2[48] = { | |||
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 @@ int ssl3_cert_verify_mac(SSL *ssl, int md_nid, uint8_t *p) { | |||
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 @@ int ssl3_final_finish_mac(SSL *ssl, const char *sender, int len, uint8_t *p) { | |||
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 @@ static int ssl3_handshake_mac(SSL *ssl, int md_nid, const char *sender, int len, | |||
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); | |||
@@ -167,8 +167,6 @@ const SSL3_ENC_METHOD SSLv3_enc_data = { | |||
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, | |||
}; | |||
@@ -519,9 +519,7 @@ int ssl3_accept(SSL *ssl) { | |||
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; | |||
} | |||
@@ -455,39 +455,39 @@ int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len) { | |||
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)); | |||
if (digests_len < 0) { | |||
err = 1; | |||
digests_len = 0; | |||
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; | |||
} | |||
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; | |||
uint8_t buf[EVP_MAX_MD_SIZE]; | |||
int digests_len = tls1_handshake_digest(ssl, buf, sizeof(buf)); | |||
if (digests_len < 0) { | |||
return 0; | |||
} | |||
if (err) { | |||
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; | |||
} else { | |||
return 12; | |||
} | |||
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; | |||
@@ -134,8 +134,6 @@ const SSL3_ENC_METHOD TLSv1_enc_data = { | |||
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 @@ const SSL3_ENC_METHOD TLSv1_1_enc_data = { | |||
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 @@ const SSL3_ENC_METHOD TLSv1_2_enc_data = { | |||
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, | |||
}; | |||