Prevent false positive in constant time checks An optimization around the array access of in made valgrind think this loop was non-constant time, while in fact it is. Prevent this optimization by adding a value barrier. See bug for more details. Test: cmake -DCONSTANT_TIME_VALIDATION=1 -DCMAKE_BUILD_TYPE=Release \ -GNinja -B build && \ ninja -C build && \ valgrind ./build/crypto_test \ --gtest_filter=*PerAEADTest.UnalignedInput/AES_128_CBC_SHA1_TLS* Test: cmake -DCMAKE_BUILD_TYPE=Release -GNinja -B build && \ ninja -C build && ./build/crypto_test Bug: 436788086 Change-Id: I3f00d06c71cb3b30146dde890f157078915ea1f4 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/81867 Reviewed-by: David Benjamin <davidben@google.com> Auto-Submit: Miriam Polzer <mpolzer@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/cipher/tls_cbc.cc b/crypto/cipher/tls_cbc.cc index d34d2d6..31d3218 100644 --- a/crypto/cipher/tls_cbc.cc +++ b/crypto/cipher/tls_cbc.cc
@@ -53,7 +53,10 @@ for (size_t i = 0; i < to_check; i++) { uint8_t mask = constant_time_ge_8(padding_length, i); - uint8_t b = in[in_len - 1 - i]; + // The value barrier on |(in_len - 1 - i)| isn't needed to enforce + // constant-time. It is just there to prevent a false positive in + // constant-time checks by valgrind. + uint8_t b = in[value_barrier_w(in_len - 1 - i)]; // The final |padding_length+1| bytes should all have the value // |padding_length|. Therefore the XOR should be zero. good &= ~(mask & (padding_length ^ b));