Remove non-CBC codepaths from e_tls.cc

RC4 and auth-only ciphers are long, long gone. Make this code not try to
do two things at once. While I'm here, replace `% block_size` with
`& (block_size - 1)`. The compiler doesn't know these are powers of 2,
but we do.

Change-Id: Id0307a03827410a90c02de46b0ab9fe294b83e1e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/85148
Reviewed-by: Rudolf Polzer <rpolzer@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Rudolf Polzer <rpolzer@google.com>
diff --git a/crypto/cipher/e_tls.cc b/crypto/cipher/e_tls.cc
index f6c8241..b0f3ab3 100644
--- a/crypto/cipher/e_tls.cc
+++ b/crypto/cipher/e_tls.cc
@@ -102,18 +102,14 @@
                                const size_t extra_in_len) {
   assert(extra_in_len == 0);
   const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state;
+  assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
 
   const size_t hmac_len = HMAC_size(tls_ctx->hmac_ctx);
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) {
-    // The NULL cipher.
-    return hmac_len;
-  }
-
   const size_t block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx);
   // An overflow of |in_len + hmac_len| doesn't affect the result mod
   // |block_size|, provided that |block_size| is a smaller power of two.
-  assert(block_size != 0 && (block_size & (block_size - 1)) == 0);
-  const size_t pad_len = block_size - (in_len + hmac_len) % block_size;
+  assert(block_size == 8 /*3DES*/ || block_size == 16 /*AES*/);
+  const size_t pad_len = block_size - ((in_len + hmac_len) & (block_size - 1));
   return hmac_len + pad_len;
 }
 
@@ -167,8 +163,8 @@
   }
 
   // Configure the explicit IV.
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
-      !tls_ctx->implicit_iv &&
+  assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
+  if (!tls_ctx->implicit_iv &&
       !EVP_EncryptInit_ex(&tls_ctx->cipher_ctx, nullptr, nullptr, nullptr,
                           nonce)) {
     return 0;
@@ -182,13 +178,13 @@
   }
 
   unsigned block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx);
+  assert(block_size == 8 /*3DES*/ || block_size == 16 /*AES*/);
 
   // Feed the MAC into the cipher in two steps. First complete the final partial
   // block from encrypting the input and split the result between |out| and
   // |out_tag|. Then feed the rest.
 
-  const size_t early_mac_len =
-      (block_size - (in_len % block_size)) % block_size;
+  const size_t early_mac_len = (block_size - in_len) & (block_size - 1);
   if (early_mac_len != 0) {
     assert(len + block_size - early_mac_len == in_len);
     uint8_t buf[EVP_MAX_BLOCK_LENGTH];
@@ -210,21 +206,15 @@
   }
   tag_len += len;
 
-  if (block_size > 1) {
-    assert(block_size <= 256);
-    assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
-
-    // Compute padding and feed that into the cipher.
-    uint8_t padding[256];
-    unsigned padding_len = block_size - ((in_len + mac_len) % block_size);
-    OPENSSL_memset(padding, padding_len - 1, padding_len);
-    if (!EVP_EncryptUpdate_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
-                              max_out_tag_len - tag_len, padding,
-                              padding_len)) {
-      return 0;
-    }
-    tag_len += len;
+  // Compute padding and feed that into the cipher.
+  uint8_t padding[256];
+  unsigned padding_len = block_size - ((in_len + mac_len) & (block_size - 1));
+  OPENSSL_memset(padding, padding_len - 1, padding_len);
+  if (!EVP_EncryptUpdate_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
+                            max_out_tag_len - tag_len, padding, padding_len)) {
+    return 0;
   }
+  tag_len += len;
 
   if (!EVP_EncryptFinal_ex2(&tls_ctx->cipher_ctx, out_tag + tag_len, &len,
                             max_out_tag_len - tag_len)) {
@@ -272,8 +262,8 @@
   }
 
   // Configure the explicit IV.
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
-      !tls_ctx->implicit_iv &&
+  assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
+  if (!tls_ctx->implicit_iv &&
       !EVP_DecryptInit_ex(&tls_ctx->cipher_ctx, nullptr, nullptr, nullptr,
                           nonce)) {
     return 0;
@@ -300,21 +290,13 @@
   // |padding_ok| and |data_plus_mac_len| for CBC ciphers.
   size_t data_plus_mac_len;
   crypto_word_t padding_ok;
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
-    if (!EVP_tls_cbc_remove_padding(
-            &padding_ok, &data_plus_mac_len, out, total,
-            EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx),
-            HMAC_size(tls_ctx->hmac_ctx))) {
-      // Publicly invalid. This can be rejected in non-constant time.
-      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
-      return 0;
-    }
-  } else {
-    padding_ok = CONSTTIME_TRUE_W;
-    data_plus_mac_len = total;
-    // |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has
-    // already been checked against the MAC size at the top of the function.
-    assert(data_plus_mac_len >= HMAC_size(tls_ctx->hmac_ctx));
+  if (!EVP_tls_cbc_remove_padding(
+          &padding_ok, &data_plus_mac_len, out, total,
+          EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx),
+          HMAC_size(tls_ctx->hmac_ctx))) {
+    // Publicly invalid. This can be rejected in non-constant time.
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
+    return 0;
   }
   size_t data_len = data_plus_mac_len - HMAC_size(tls_ctx->hmac_ctx);
 
@@ -333,37 +315,17 @@
   // Compute the MAC and extract the one in the record.
   uint8_t mac[EVP_MAX_MD_SIZE];
   size_t mac_len;
-  uint8_t record_mac_tmp[EVP_MAX_MD_SIZE];
-  uint8_t *record_mac;
-  if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
-      EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx->md)) {
-    if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx->md, mac, &mac_len,
-                                   ad_fixed, out, data_len, total,
-                                   tls_ctx->mac_key, tls_ctx->mac_key_len)) {
-      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
-      return 0;
-    }
-    assert(mac_len == HMAC_size(tls_ctx->hmac_ctx));
-
-    record_mac = record_mac_tmp;
-    EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total);
-  } else {
-    // We should support the constant-time path for all CBC-mode ciphers
-    // implemented.
-    assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE);
-
-    unsigned mac_len_u;
-    if (!HMAC_Init_ex(tls_ctx->hmac_ctx, nullptr, 0, nullptr, nullptr) ||
-        !HMAC_Update(tls_ctx->hmac_ctx, ad_fixed, ad_len) ||
-        !HMAC_Update(tls_ctx->hmac_ctx, out, data_len) ||
-        !HMAC_Final(tls_ctx->hmac_ctx, mac, &mac_len_u)) {
-      return 0;
-    }
-    mac_len = mac_len_u;
-
-    assert(mac_len == HMAC_size(tls_ctx->hmac_ctx));
-    record_mac = &out[data_len];
+  assert(EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx->md));
+  if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx->md, mac, &mac_len, ad_fixed,
+                                 out, data_len, total, tls_ctx->mac_key,
+                                 tls_ctx->mac_key_len)) {
+    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
+    return 0;
   }
+  assert(mac_len == HMAC_size(tls_ctx->hmac_ctx));
+
+  uint8_t record_mac[EVP_MAX_MD_SIZE];
+  EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total);
 
   // Perform the MAC check and the padding check in constant-time. It should be
   // safe to simply perform the padding check first, but it would not be under a