Pass a slightly smaller upper bound to TLS CBC MAC calculation When compute the MAC for TLS CBC ciphers, we need to be constant-time up to a range of data lens. The wider that range, the more blocks we run through the slower-constant-time path. Given a MAC length of M (20 bytes for SHA-1 and 32 bytes for SHA-256) and ciphertext length C (C a multiple of 16 and at least M+1 bytes), both public, the minimum plaintext length is C - M - 256. We use a maximum plaintext length of P_max = C, but the plaintext is actually upper-bounded at P_max = C - M. Switch to the more accurate estimate. This doesn't help for all inputs. For it to be a non-trivial improvement, we need to do one fewer hash block at C - M than we would have done with the weaker estimate. Computing the hash blocks is tricky because we're actually hashing L = 13 + P_max bytes. Additionally, SHA-1 and SHA-256 internally incorporate a length and padding into their final block. Hashing L bytes runs the compression function ceil((L + 9) / 64) times. In all, we run the compression function ceil((P_max + 22) / 64) times. Running those numbers, for SHA-1, we should expect an improvement when C mod 64 is 48. For SHA-256, it's when C mod 64 is 0 or 48. This matches the benchmarks below. Note that InputSize here is the actual plaintext. The corresponding ciphertext length is C = RoundUp(P + M + 1, 16). (Actually P_max = C - M - 1 would be an even more accurate upper bound, but that gets a little odd with how bad padding gets mapped to padding_length = 0 instead of padding_length = 1. It also wouldn't change the above.) Benchmark Time CPU Time Old Time New CPU Old CPU New ------------------------------------------------------------------------------------------------------------------------------------------------- BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:64 -0.0008 -0.0006 1101 1100 1101 1100 BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:72 -0.0053 -0.0054 1106 1100 1106 1100 BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:80 -0.1113 -0.1114 1297 1153 1297 1152 BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:88 -0.1121 -0.1122 1298 1152 1297 1152 BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:96 -0.0037 -0.0039 1346 1341 1346 1340 BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:104 -0.0032 -0.0032 1352 1347 1351 1347 BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:112 +0.0033 +0.0033 1391 1396 1391 1396 BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:120 +0.0013 +0.0013 1395 1396 1394 1396 BM_SpeedAEAD/open_aes_128_cbc_sha1/InputSize:128 +0.0030 +0.0029 1440 1444 1440 1444 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:64 -0.1168 -0.1171 1894 1673 1894 1672 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:72 -0.1171 -0.1171 1892 1670 1892 1670 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:80 -0.1130 -0.1137 1942 1723 1942 1721 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:88 -0.1130 -0.1140 1945 1725 1944 1722 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:96 +0.0036 +0.0019 2001 2008 2001 2005 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:104 +0.0033 +0.0021 2000 2007 1999 2003 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:112 -0.0087 -0.0102 2082 2064 2081 2060 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:120 +0.0059 +0.0042 2052 2064 2052 2061 BM_SpeedAEAD/open_aes_128_cbc_sha256/InputSize:128 -0.0918 -0.0927 2325 2111 2323 2108 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:64 +0.0019 +0.0003 1106 1108 1106 1106 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:72 -0.0016 -0.0022 1107 1105 1107 1105 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:80 -0.1060 -0.1060 1299 1161 1299 1161 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:88 -0.1076 -0.1077 1299 1159 1299 1159 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:96 -0.0020 -0.0020 1349 1346 1349 1346 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:104 -0.0021 -0.0020 1349 1347 1349 1346 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:112 -0.0002 -0.0004 1409 1408 1408 1408 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:120 -0.0007 -0.0011 1411 1410 1411 1409 BM_SpeedAEAD/open_aes_256_cbc_sha1/InputSize:128 +0.0043 +0.0027 1458 1464 1457 1461 Change-Id: I540febad01b02c8593343ebf8dadee3bd0e8b9ba Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/85647 Reviewed-by: Rudolf Polzer <rpolzer@google.com> Commit-Queue: David Benjamin <davidben@google.com>
BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.
Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.
Programs ship their own copies of BoringSSL when they use it and we update everything as needed when deciding to make API changes. This allows us to mostly avoid compromises in the name of compatibility. It works for us, but it may not work for you.
BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved in maintaining all these patches in multiple places was growing steadily.
Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the NDK) and a number of other apps/programs.
Project links:
To file a security issue, use the Chromium process and mention in the report this is for BoringSSL. You can ignore the parts of the process that are specific to Chromium/Chrome.
There are other files in this directory which might be helpful: