Fix constant_time_conditional_memxor on some input lengths This wasn't called this way within the library, but fix it before it ever is. Thanks to Joe Birr-Pixton for catching this. Bug: 455606200 Change-Id: Ia6f4a63c595ca27822073188851f0bd62a6196ba Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/83367 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Lily Chen <chlily@google.com> Auto-Submit: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com> Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/constant_time_test.cc b/crypto/constant_time_test.cc index 77b6c7d..cc0f97f 100644 --- a/crypto/constant_time_test.cc +++ b/crypto/constant_time_test.cc
@@ -141,69 +141,77 @@ } TEST(ConstantTimeTest, MemCmov) { - for (int i = 0; i < 100; i++) { - uint8_t out[256], in[256]; - RAND_bytes(out, sizeof(out)); - RAND_bytes(in, sizeof(in)); + static constexpr size_t kMaxLen = 256; + uint8_t out[kMaxLen], in[kMaxLen]; + for (size_t len = 0; len <= kMaxLen; len++) { + SCOPED_TRACE(len); + for (int i = 0; i < 100; i++) { + RAND_bytes(out, len); + RAND_bytes(in, len); - uint8_t b = 0; - RAND_bytes(&b, 1); - b = constant_time_is_zero_8(b & 0xf); + uint8_t b = 0; + RAND_bytes(&b, 1); + b = constant_time_is_zero_8(b & 0xf); - uint8_t ref_in[256]; - OPENSSL_memcpy(ref_in, in, sizeof(in)); + uint8_t ref_in[256]; + OPENSSL_memcpy(ref_in, in, len); - uint8_t ref_out[256]; - OPENSSL_memcpy(ref_out, out, sizeof(out)); - if (b) { - OPENSSL_memcpy(ref_out, in, sizeof(in)); + uint8_t ref_out[256]; + OPENSSL_memcpy(ref_out, out, len); + if (b) { + OPENSSL_memcpy(ref_out, in, len); + } + + CONSTTIME_SECRET(out, len); + CONSTTIME_SECRET(in, len); + CONSTTIME_SECRET(&b, 1); + + constant_time_conditional_memcpy(out, in, len, b); + + CONSTTIME_DECLASSIFY(&in, len); + CONSTTIME_DECLASSIFY(&out, len); + + EXPECT_EQ(Bytes(in, len), Bytes(ref_in, len)); + EXPECT_EQ(Bytes(out, len), Bytes(ref_out, len)); } - - CONSTTIME_SECRET(out, sizeof(out)); - CONSTTIME_SECRET(in, sizeof(in)); - CONSTTIME_SECRET(&b, 1); - - constant_time_conditional_memcpy(out, in, sizeof(out), b); - - CONSTTIME_DECLASSIFY(&in, sizeof(in)); - CONSTTIME_DECLASSIFY(&out, sizeof(out)); - - EXPECT_EQ(Bytes(in), Bytes(ref_in)); - EXPECT_EQ(Bytes(out), Bytes(ref_out)); } } TEST(ConstantTimeTest, MemCxor) { - for (int i = 0; i < 100; i++) { - uint8_t out[256], in[256]; - RAND_bytes(out, sizeof(out)); - RAND_bytes(in, sizeof(in)); + static constexpr size_t kMaxLen = 256; + uint8_t out[kMaxLen], in[kMaxLen]; + for (size_t len = 0; len <= kMaxLen; len++) { + SCOPED_TRACE(len); + for (int i = 0; i < 100; i++) { + RAND_bytes(out, len); + RAND_bytes(in, len); - uint8_t b = 0; - RAND_bytes(&b, 1); - b = constant_time_is_zero_8(b & 0xf); + uint8_t b = 0; + RAND_bytes(&b, 1); + b = constant_time_is_zero_8(b & 0xf); - uint8_t ref_in[256]; - OPENSSL_memcpy(ref_in, in, sizeof(in)); + uint8_t ref_in[kMaxLen]; + OPENSSL_memcpy(ref_in, in, len); - uint8_t ref_out[256]; - OPENSSL_memcpy(ref_out, out, sizeof(out)); - if (b) { - for (size_t j = 0; j < sizeof(ref_out); ++j) { - ref_out[j] ^= in[j]; + uint8_t ref_out[kMaxLen]; + OPENSSL_memcpy(ref_out, out, len); + if (b) { + for (size_t j = 0; j < len; ++j) { + ref_out[j] ^= in[j]; + } } + + CONSTTIME_SECRET(out, len); + CONSTTIME_SECRET(in, len); + CONSTTIME_SECRET(&b, 1); + + constant_time_conditional_memxor(out, in, len, b); + + CONSTTIME_DECLASSIFY(&in, len); + CONSTTIME_DECLASSIFY(&out, len); + + EXPECT_EQ(Bytes(in, len), Bytes(ref_in, len)); + EXPECT_EQ(Bytes(out, len), Bytes(ref_out, len)); } - - CONSTTIME_SECRET(out, sizeof(out)); - CONSTTIME_SECRET(in, sizeof(in)); - CONSTTIME_SECRET(&b, 1); - - constant_time_conditional_memxor(out, in, sizeof(out), b); - - CONSTTIME_DECLASSIFY(&in, sizeof(in)); - CONSTTIME_DECLASSIFY(&out, sizeof(out)); - - EXPECT_EQ(Bytes(in), Bytes(ref_in)); - EXPECT_EQ(Bytes(out), Bytes(ref_out)); } }
diff --git a/crypto/internal.h b/crypto/internal.h index 633e4fa..1a22a94 100644 --- a/crypto/internal.h +++ b/crypto/internal.h
@@ -448,6 +448,7 @@ for (size_t i = 0; i < n_vec; i += 32) { *(v32u8 *)&out[i] ^= masks & *(v32u8 *)&in[i]; } + in += n_vec; out += n_vec; n -= n_vec; #endif