Add the PRF to SSL3_ENC_METHOD.
This lets us fold away the SSLv3-specific generate_master_secret. Once SSLv3
uses AEADs, others will fold away as well.
Change-Id: I27c1b75741823bc6db920d35f5dd5ce71b6fdbb3
Reviewed-on: https://boringssl-review.googlesource.com/2697
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 7385e7f..6cf8fb6 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -219,16 +219,10 @@
return ret;
}
-/* tls1_PRF computes the TLS PRF function as described in RFC 5246, section 5
- * and RFC 2246 section 5. It writes |out_len| bytes to |out|, using
- * |digest_mask| to select the hash functions, |secret| as the secret, and
- * |label| as the label. |seed1| and |seed2| are concatenated to form the seed
- * parameter. It returns one on success and zero on failure. */
-static int tls1_PRF(uint8_t *out, size_t out_len, long digest_mask,
- const uint8_t *secret, size_t secret_len,
- const char *label, size_t label_len,
- const uint8_t *seed1, size_t seed1_len,
- const uint8_t *seed2, size_t seed2_len) {
+int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
+ size_t secret_len, const char *label, size_t label_len,
+ const uint8_t *seed1, size_t seed1_len,
+ const uint8_t *seed2, size_t seed2_len) {
size_t idx, len, count, i;
const uint8_t *S1;
long m;
@@ -243,14 +237,14 @@
/* Allocate a temporary buffer. */
tmp = OPENSSL_malloc(out_len);
if (tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_PRF, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, tls1_prf, ERR_R_MALLOC_FAILURE);
return 0;
}
/* Count number of digests and partition |secret| evenly. */
count = 0;
for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
- if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) {
+ if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) {
count++;
}
}
@@ -265,7 +259,7 @@
S1 = secret;
memset(out, 0, out_len);
for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
- if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) {
+ if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) {
/* If |count| is 2 and |secret_len| is odd, |secret| is partitioned into
* two halves with an overlapping byte. */
if (!tls1_P_hash(tmp, out_len, md, S1, len + (secret_len & 1),
@@ -288,11 +282,13 @@
}
static int tls1_generate_key_block(SSL *s, uint8_t *out, size_t out_len) {
- return tls1_PRF(out, out_len, ssl_get_algorithm2(s),
- s->session->master_key, s->session->master_key_length,
- TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
- s->s3->server_random, SSL3_RANDOM_SIZE, s->s3->client_random,
- SSL3_RANDOM_SIZE);
+ return s->enc_method->prf(s, out, out_len, s->session->master_key,
+ s->session->master_key_length,
+ TLS_MD_KEY_EXPANSION_CONST,
+ TLS_MD_KEY_EXPANSION_CONST_SIZE,
+ s->s3->server_random, SSL3_RANDOM_SIZE,
+ s->s3->client_random,
+ SSL3_RANDOM_SIZE);
}
/* tls1_aead_ctx_init allocates |*aead_ctx|, if needed and returns 1. It
@@ -1046,9 +1042,9 @@
digests_len = 0;
}
- if (!tls1_PRF(out, 12, ssl_get_algorithm2(s), s->session->master_key,
- s->session->master_key_length, str, slen, buf, digests_len,
- NULL, 0)) {
+ if (!s->enc_method->prf(s, out, 12, s->session->master_key,
+ s->session->master_key_length, str, slen, buf,
+ digests_len, NULL, 0)) {
err = 1;
}
@@ -1165,18 +1161,18 @@
return 0;
}
- if (!tls1_PRF(out, SSL3_MASTER_SECRET_SIZE, ssl_get_algorithm2(s),
- premaster, premaster_len, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
- TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
- digests_len, NULL, 0)) {
+ if (!s->enc_method->prf(s, out, SSL3_MASTER_SECRET_SIZE, premaster,
+ premaster_len, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+ TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
+ digests_len, NULL, 0)) {
return 0;
}
} else {
- if (!tls1_PRF(out, SSL3_MASTER_SECRET_SIZE, ssl_get_algorithm2(s),
- premaster, premaster_len, TLS_MD_MASTER_SECRET_CONST,
- TLS_MD_MASTER_SECRET_CONST_SIZE, s->s3->client_random,
- SSL3_RANDOM_SIZE, s->s3->server_random,
- SSL3_RANDOM_SIZE)) {
+ if (!s->enc_method->prf(s, out, SSL3_MASTER_SECRET_SIZE, premaster,
+ premaster_len, TLS_MD_MASTER_SECRET_CONST,
+ TLS_MD_MASTER_SECRET_CONST_SIZE,
+ s->s3->client_random, SSL3_RANDOM_SIZE,
+ s->s3->server_random, SSL3_RANDOM_SIZE)) {
return 0;
}
}
@@ -1237,9 +1233,12 @@
goto err1;
}
- ret = tls1_PRF(out, olen, ssl_get_algorithm2(s), s->session->master_key,
- s->session->master_key_length, (const char *)val, vallen, NULL,
- 0, NULL, 0);
+ /* SSL_export_keying_material is not implemented for SSLv3, so passing
+ * everything through the label parameter works. */
+ assert(s->version != SSL3_VERSION);
+ ret = s->enc_method->prf(s, out, olen, s->session->master_key,
+ s->session->master_key_length, (const char *)val,
+ vallen, NULL, 0, NULL, 0);
goto out;
err1: