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