Replace enc_flags with normalized version checks. This removes the various non-PRF checks from SSL3_ENC_METHOD so that can have a clearer purpose. It also makes TLS 1.0 through 1.2's SSL3_ENC_METHOD tables identical and gives us an assert to ensure nothing accesses the version bits before version negotiation. Accordingly, ssl_needs_record_splitting was reordered slightly so we don't rely on enc_method being initialized to TLS 1.2 pre-version-negotiation. This leaves alert_value as the only part of SSL3_ENC_METHOD which may be accessed before version negotiation. Change-Id: If9e299e2ef5511b5fa442b2af654eed054c3e675 Reviewed-on: https://boringssl-review.googlesource.com/6842 Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/ssl/internal.h b/ssl/internal.h index c3982d0..8a5ebe9 100644 --- a/ssl/internal.h +++ b/ssl/internal.h
@@ -747,12 +747,6 @@ /* Check if an SSL structure is using DTLS */ #define SSL_IS_DTLS(ssl) (ssl->method->is_dtls) -/* See if we need explicit IV */ -#define SSL_USE_EXPLICIT_IV(ssl) \ - (ssl->enc_method->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) -/* See if we use signature algorithms extension and signature algorithm before - * signatures. */ -#define SSL_USE_SIGALGS(ssl) (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SIGALGS) /* From RFC4492, used in encoding the curve type in ECParameters */ #define NAMED_CURVE_TYPE 3 @@ -863,8 +857,6 @@ int (*final_finish_mac)(SSL *ssl, int from_server, uint8_t *out); int (*cert_verify_mac)(SSL *, int, uint8_t *); int (*alert_value)(int); - /* Various flags indicating protocol version requirements */ - unsigned int enc_flags; }; #define SSL_HM_HEADER_LENGTH(ssl) ssl->method->hhlen @@ -874,15 +866,6 @@ ssl->method->set_handshake_header(ssl, htype, len) #define ssl_do_write(ssl) ssl->method->do_write(ssl) -/* Values for enc_flags */ - -/* Uses explicit IV for CBC mode */ -#define SSL_ENC_FLAG_EXPLICIT_IV 0x1 -/* Uses signature algorithms extension */ -#define SSL_ENC_FLAG_SIGALGS 0x2 -/* Uses SHA256 default PRF */ -#define SSL_ENC_FLAG_SHA256_PRF 0x4 - /* lengths of messages */ #define DTLS1_COOKIE_LENGTH 256 @@ -975,8 +958,6 @@ } DTLS1_STATE; extern const SSL3_ENC_METHOD TLSv1_enc_data; -extern const SSL3_ENC_METHOD TLSv1_1_enc_data; -extern const SSL3_ENC_METHOD TLSv1_2_enc_data; extern const SSL3_ENC_METHOD SSLv3_enc_data; extern const SRTP_PROTECTION_PROFILE kSRTPProfiles[];
diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 3265609..1a91e0b 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c
@@ -434,7 +434,7 @@ /* For TLS v1.2 send signature algorithm and signature using * agreed digest and cached handshake records. Otherwise, use * SHA1 or MD5 + SHA1 depending on key type. */ - if (SSL_USE_SIGALGS(ssl)) { + if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { EVP_MD_CTX mctx; unsigned len;
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 10eaac8..ec7a50b 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c
@@ -874,7 +874,7 @@ /* If doing a full handshake with TLS 1.2, the server may request a client * certificate which requires hashing the handshake transcript under a * different hash. Otherwise, the handshake buffer may be released. */ - if (!SSL_USE_SIGALGS(ssl) || ssl->hit) { + if (ssl->hit || ssl3_protocol_version(ssl) < TLS1_2_VERSION) { ssl3_free_handshake_buffer(ssl); } @@ -1230,7 +1230,7 @@ } const EVP_MD *md = NULL; - if (SSL_USE_SIGALGS(ssl)) { + if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { uint8_t hash, signature; if (!CBS_get_u8(&server_key_exchange, &hash) || !CBS_get_u8(&server_key_exchange, &signature)) { @@ -1355,7 +1355,7 @@ goto err; } - if (SSL_USE_SIGALGS(ssl)) { + if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { CBS supported_signature_algorithms; if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) || !tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) { @@ -1790,7 +1790,7 @@ if (ssl->state == SSL3_ST_CW_CERT_VRFY_A) { /* Select and write out the digest type in TLS 1.2. */ const EVP_MD *md = NULL; - if (SSL_USE_SIGALGS(ssl)) { + if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { md = tls1_choose_signing_digest(ssl); if (!tls12_add_sigandhash(ssl, &cbb, md)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); @@ -1824,7 +1824,8 @@ /* Skip over the already written signature algorithm and retry the * signature. */ uint8_t *ptr; - if ((SSL_USE_SIGALGS(ssl) && !CBB_did_write(&cbb, 2)) || + if ((ssl3_protocol_version(ssl) >= TLS1_2_VERSION && + !CBB_did_write(&cbb, 2)) || !CBB_add_u16_length_prefixed(&cbb, &child) || !CBB_reserve(&child, &ptr, max_sig_len)) { goto err;
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 790867f..16c2a31 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c
@@ -491,5 +491,4 @@ ssl3_final_finish_mac, ssl3_cert_verify_mac, ssl3_alert_code, - 0, };
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 30fbfac..0d4a821 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c
@@ -568,8 +568,8 @@ * handshake macs if required. */ uint32_t ssl_get_algorithm_prf(const SSL *ssl) { uint32_t algorithm_prf = ssl->s3->tmp.new_cipher->algorithm_prf; - if (ssl->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF && - algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT) { + if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT && + ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { return SSL_HANDSHAKE_MAC_SHA256; } return algorithm_prf;
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 94f1ccb..bbe178f 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c
@@ -1077,7 +1077,8 @@ /* In TLS 1.2, client authentication requires hashing the handshake transcript * under a different hash. Otherwise, release the handshake buffer. */ - if (!SSL_USE_SIGALGS(ssl) || !ssl->s3->tmp.cert_request) { + if (!ssl->s3->tmp.cert_request || + ssl3_protocol_version(ssl) < TLS1_2_VERSION) { ssl3_free_handshake_buffer(ssl); } @@ -1297,7 +1298,7 @@ /* Determine signature algorithm. */ const EVP_MD *md; - if (SSL_USE_SIGALGS(ssl)) { + if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { md = tls1_choose_signing_digest(ssl); if (!tls12_add_sigandhash(ssl, &cbb, md)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); @@ -1397,7 +1398,7 @@ p += n; n++; - if (SSL_USE_SIGALGS(ssl)) { + if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { const uint8_t *psigs; nl = tls12_get_psigalgs(ssl, &psigs); s2n(nl, p); @@ -1764,7 +1765,7 @@ CBS_init(&certificate_verify, ssl->init_msg, n); /* Determine the digest type if needbe. */ - if (SSL_USE_SIGALGS(ssl)) { + if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { uint8_t hash, signature_type; if (!CBS_get_u8(&certificate_verify, &hash) || !CBS_get_u8(&certificate_verify, &signature_type)) {
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index fe3c173..8eba906 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c
@@ -2283,15 +2283,11 @@ return &SSLv3_enc_data; case TLS1_VERSION: - return &TLSv1_enc_data; - - case DTLS1_VERSION: case TLS1_1_VERSION: - return &TLSv1_1_enc_data; - - case DTLS1_2_VERSION: case TLS1_2_VERSION: - return &TLSv1_2_enc_data; + case DTLS1_VERSION: + case DTLS1_2_VERSION: + return &TLSv1_enc_data; default: return NULL;
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 25ff710..c728a0a 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c
@@ -658,21 +658,4 @@ tls1_final_finish_mac, tls1_cert_verify_mac, tls1_alert_code, - 0, -}; - -const SSL3_ENC_METHOD TLSv1_1_enc_data = { - tls1_prf, - tls1_final_finish_mac, - tls1_cert_verify_mac, - tls1_alert_code, - SSL_ENC_FLAG_EXPLICIT_IV, -}; - -const SSL3_ENC_METHOD TLSv1_2_enc_data = { - tls1_prf, - tls1_final_finish_mac, - tls1_cert_verify_mac, - tls1_alert_code, - SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF, };
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 346746a..7a336f1 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c
@@ -2646,7 +2646,7 @@ int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) { /* Extension ignored for inappropriate versions */ - if (!SSL_USE_SIGALGS(ssl)) { + if (ssl3_protocol_version(ssl) < TLS1_2_VERSION) { return 1; }
diff --git a/ssl/tls_record.c b/ssl/tls_record.c index 25d6e82..d53e1d7 100644 --- a/ssl/tls_record.c +++ b/ssl/tls_record.c
@@ -126,7 +126,8 @@ /* ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher * state needs record-splitting and zero otherwise. */ static int ssl_needs_record_splitting(const SSL *ssl) { - return !SSL_USE_EXPLICIT_IV(ssl) && ssl->s3->aead_write_ctx != NULL && + return ssl->s3->aead_write_ctx != NULL && + ssl3_protocol_version(ssl) < TLS1_1_VERSION && (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher); }