Avoid some divisions in Lucky 13 fix.

data_plus_mac_size is secret. Values derived from it cannot quite be
safely divided by md_block_size because SHA-384 ciphers prevent that
field from being constant. We know the value is a power of two, so do
the strength reduction by hand.

Change-Id: Id62ab9e646f4e21d507a7059cfe84d49bbb986e6
Reviewed-on: https://boringssl-review.googlesource.com/27505
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/cipher_extra/tls_cbc.c b/crypto/cipher_extra/tls_cbc.c
index 6f95130..a24602b 100644
--- a/crypto/cipher_extra/tls_cbc.c
+++ b/crypto/cipher_extra/tls_cbc.c
@@ -271,7 +271,7 @@
   HASH_CTX md_state;
   void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out);
   void (*md_transform)(HASH_CTX *ctx, const uint8_t *block);
-  unsigned md_size, md_block_size = 64;
+  unsigned md_size, md_block_size = 64, md_block_shift = 6;
   // md_length_size is the number of bytes in the length field that terminates
   // the hash.
   unsigned md_length_size = 8;
@@ -305,6 +305,7 @@
       md_transform = tls1_sha512_transform;
       md_size = SHA384_DIGEST_LENGTH;
       md_block_size = 128;
+      md_block_shift = 7;
       md_length_size = 16;
       break;
 
@@ -318,6 +319,7 @@
 
   assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
   assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
+  assert(md_block_size == (1u << md_block_shift));
   assert(md_size <= EVP_MAX_MD_SIZE);
 
   static const size_t kHeaderLength = 13;
@@ -350,18 +352,16 @@
   // k is the starting byte offset into the conceptual header||data where
   // we start processing.
   size_t k = 0;
-  // mac_end_offset is the index just past the end of the data to be
-  // MACed.
+  // mac_end_offset is the index just past the end of the data to be MACed.
   size_t mac_end_offset = data_plus_mac_size + kHeaderLength - md_size;
-  // c is the index of the 0x80 byte in the final hash block that
-  // contains application data.
-  size_t c = mac_end_offset % md_block_size;
-  // index_a is the hash block number that contains the 0x80 terminating
-  // value.
-  size_t index_a = mac_end_offset / md_block_size;
-  // index_b is the hash block number that contains the 64-bit hash
-  // length, in bits.
-  size_t index_b = (mac_end_offset + md_length_size) / md_block_size;
+  // c is the index of the 0x80 byte in the final hash block that contains
+  // application data.
+  size_t c = mac_end_offset & (md_block_size - 1);
+  // index_a is the hash block number that contains the 0x80 terminating value.
+  size_t index_a = mac_end_offset >> md_block_shift;
+  // index_b is the hash block number that contains the 64-bit hash length, in
+  // bits.
+  size_t index_b = (mac_end_offset + md_length_size) >> md_block_shift;
 
   if (num_blocks > kVarianceBlocks) {
     num_starting_blocks = num_blocks - kVarianceBlocks;