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