update main-with-bazel from master branch

This commit is contained in:
BoringSSL Robot
2023-06-06 18:17:03 +00:00
9 changed files with 2603 additions and 6979 deletions
+19 -1
View File
@@ -91,7 +91,25 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
}
#endif
ChaCha20_ctr32(out, in, in_len, key_ptr, counter_nonce);
while (in_len > 0) {
// The assembly functions do not have defined overflow behavior. While
// overflow is almost always a bug in the caller, we prefer our functions to
// behave the same across platforms, so divide into multiple calls to avoid
// this case.
uint64_t todo = 64 * ((UINT64_C(1) << 32) - counter_nonce[0]);
if (todo > in_len) {
todo = in_len;
}
ChaCha20_ctr32(out, in, (size_t)todo, key_ptr, counter_nonce);
in += todo;
out += todo;
in_len -= todo;
// We're either done and will next break out of the loop, or we stopped at
// the wraparound point and the counter should continue at zero.
counter_nonce[0] = 0;
}
}
#else
+110
View File
@@ -218,8 +218,102 @@ static const uint8_t kOutput[] = {
0x8f, 0x40, 0xcf, 0x4a,
};
static uint32_t kOverflowCounter = 0xffffffff;
static const uint8_t kOverflowOutput[] = {
0x37, 0x64, 0x38, 0xcb, 0x25, 0x69, 0x2c, 0xf5, 0x88, 0x8a, 0xfe, 0x6d,
0x3b, 0x10, 0x07, 0x3c, 0x77, 0xac, 0xcd, 0x1c, 0x0c, 0xa7, 0x17, 0x31,
0x1d, 0xc3, 0x81, 0xd1, 0xa5, 0x20, 0x55, 0xea, 0xd3, 0x00, 0xc9, 0x84,
0xde, 0xe2, 0xe5, 0x5e, 0x7b, 0x28, 0x28, 0x59, 0x73, 0x3a, 0x8e, 0x57,
0x62, 0x18, 0x50, 0x55, 0x97, 0xca, 0x50, 0x3e, 0x8a, 0x84, 0x61, 0x28,
0x4c, 0x22, 0x93, 0x50, 0x48, 0x7e, 0x65, 0x78, 0x06, 0x5a, 0xcd, 0x2b,
0x11, 0xf7, 0x10, 0xfd, 0x6f, 0x41, 0x92, 0x82, 0x7c, 0x3a, 0x71, 0x07,
0x67, 0xd0, 0x7e, 0xb7, 0xdf, 0xdc, 0xfc, 0xee, 0xe6, 0x55, 0xdd, 0x6f,
0x79, 0x23, 0xf3, 0xae, 0xb1, 0x21, 0x96, 0xbe, 0xea, 0x0e, 0x1b, 0x58,
0x0b, 0x3f, 0x63, 0x51, 0xd4, 0xce, 0x98, 0xfe, 0x1a, 0xc7, 0xa7, 0x43,
0x7f, 0x0c, 0xe8, 0x62, 0xcf, 0x78, 0x3f, 0x4e, 0x31, 0xbf, 0x2b, 0x76,
0x91, 0xcd, 0x19, 0x80, 0x0d, 0x7f, 0x11, 0x8b, 0x76, 0xef, 0x43, 0x3c,
0x4f, 0x61, 0x86, 0xc5, 0x64, 0xa8, 0xc2, 0x73, 0xc2, 0x64, 0x39, 0xa0,
0x8b, 0xe6, 0x7f, 0xf6, 0x26, 0xd4, 0x47, 0x4f, 0xe4, 0x46, 0xe2, 0xf5,
0x9e, 0xe6, 0xc7, 0x76, 0x6c, 0xa9, 0x0f, 0x1d, 0x1b, 0x22, 0xa5, 0x62,
0x0a, 0x88, 0x3e, 0x8c, 0xf0, 0xbc, 0x4c, 0x11, 0x3f, 0x0d, 0xf7, 0x85,
0x67, 0x0b, 0x4c, 0xa3, 0x3f, 0xa8, 0xf1, 0x2a, 0x65, 0x2e, 0x00, 0x03,
0xc9, 0x49, 0x91, 0x48, 0xb7, 0xc8, 0x29, 0x28, 0x2f, 0x46, 0x8e, 0x8b,
0xd6, 0x73, 0x19, 0x06, 0x3e, 0x6f, 0x92, 0xc8, 0x3d, 0x3f, 0x4d, 0x68,
0xbc, 0x02, 0xc0, 0x8f, 0x71, 0x46, 0x0d, 0x28, 0x63, 0xfe, 0xad, 0x14,
0x81, 0x04, 0xb7, 0x23, 0xfd, 0x21, 0x0a, 0xf0, 0x6f, 0xcd, 0x47, 0x0b,
0x0e, 0x93, 0xa3, 0xa8, 0x44, 0x15, 0xd6, 0xae, 0x06, 0x44, 0x6b, 0xbc,
0xff, 0x8a, 0x56, 0x60, 0x3c, 0x38, 0xd6, 0xed, 0x03, 0x2d, 0x79, 0x2a,
0xe9, 0x15, 0xef, 0xfc, 0x92, 0x1f, 0x83, 0xa4, 0x60, 0x8f, 0xc9, 0x29,
0xb2, 0xb4, 0x9e, 0x3f, 0xa9, 0xe8, 0xfb, 0xa2, 0x62, 0x20, 0x2e, 0xc9,
0x43, 0xb2, 0xd1, 0x36, 0x85, 0x1e, 0xa4, 0xb3, 0x4f, 0x8c, 0x9e, 0x81,
0x75, 0x68, 0xbc, 0xf1, 0x52, 0xd5, 0x03, 0x22, 0xcf, 0xdf, 0x64, 0xb0,
0x28, 0xd2, 0x45, 0x18, 0x38, 0x8c, 0xd0, 0xf6, 0x30, 0x3c, 0x04, 0xd9,
0x8d, 0xb6, 0xb2, 0x57, 0x2a, 0xee, 0x28, 0xeb, 0x5f, 0x1a, 0x10, 0x6e,
0x88, 0x79, 0x08, 0x23, 0x19, 0x84, 0xf8, 0x80, 0x1a, 0x7d, 0x6f, 0x8b,
0xc1, 0x8e, 0x5f, 0x5f, 0x54, 0x14, 0x2a, 0xdc, 0x41, 0x5d, 0xeb, 0x00,
0xf2, 0x50, 0xae, 0xd3, 0x55, 0x32, 0xf6, 0xd9, 0x34, 0xf4, 0xb2, 0xf2,
0xf5, 0x90, 0x05, 0x8a, 0x9c, 0xc7, 0x94, 0x5d, 0x2d, 0x5a, 0x0f, 0xdd,
0x03, 0xde, 0xbe, 0x18, 0xb3, 0xe3, 0x07, 0x6b, 0x57, 0xfa, 0x1b, 0x7b,
0x75, 0xcb, 0xc2, 0x4d, 0xf7, 0x88, 0xfe, 0xf9, 0xc0, 0x6c, 0xdb, 0x5f,
0xf6, 0x48, 0x00, 0x4a, 0x5d, 0x75, 0xfa, 0x6b, 0x45, 0x43, 0xc4, 0x7f,
0x97, 0x31, 0x22, 0xb4, 0x9c, 0xa3, 0xee, 0x2f, 0x27, 0xa9, 0x9f, 0x0e,
0xdc, 0x40, 0x67, 0x17, 0x2e, 0xcb, 0xfd, 0x9e, 0xe7, 0xb2, 0x85, 0xcd,
0x49, 0x24, 0xc8, 0x8a, 0x59, 0x6b, 0x1f, 0xec, 0x72, 0x89, 0xf8, 0x30,
0xdf, 0x82, 0x61, 0x3b, 0x8b, 0xc9, 0x80, 0xe4, 0x27, 0x0d, 0xfe, 0x42,
0x27, 0x6c, 0xaf, 0x62, 0x3e, 0x2f, 0x1d, 0x38, 0xb6, 0x88, 0x8f, 0x71,
0x5a, 0x54, 0x6c, 0x68, 0x57, 0x40, 0x49, 0x7a, 0xb2, 0xe8, 0xb6, 0x97,
0xab, 0xd6, 0x3c, 0x35, 0xf3, 0x95, 0x12, 0xde, 0xa2, 0x39, 0x54, 0x52,
0x8c, 0x38, 0x2a, 0x2b, 0xe7, 0x21, 0x38, 0x63, 0xb0, 0xd6, 0xad, 0x94,
0x44, 0xaf, 0x49, 0x5d, 0xfc, 0x49, 0x6b, 0x30, 0xdf, 0xe9, 0x19, 0x1e,
0xed, 0x98, 0x0d, 0x4a, 0x3d, 0x56, 0x5e, 0x74, 0xad, 0x13, 0x8b, 0x68,
0x45, 0x08, 0xbe, 0x0e, 0x6c, 0xb4, 0x62, 0x93, 0x27, 0x8b, 0x4f, 0xab,
0x3e, 0xba, 0xe1, 0xe5, 0xff, 0xa8, 0x5d, 0x33, 0x32, 0xff, 0x34, 0xf9,
0x8d, 0x67, 0x24, 0x4a, 0xbb, 0x2c, 0x60, 0xb5, 0x88, 0x96, 0x1b, 0xcc,
0x53, 0xfb, 0x2e, 0x05, 0x1d, 0x8b, 0xc2, 0xa0, 0xde, 0x21, 0x41, 0x5e,
0x11, 0x1b, 0x96, 0xd9, 0xa6, 0xae, 0xbd, 0xf0, 0x91, 0xad, 0x69, 0x2b,
0xd2, 0x3f, 0xe4, 0x3d, 0x16, 0x69, 0xa6, 0xb2, 0x9c, 0xbe, 0x59, 0x7b,
0x87, 0x79, 0xf5, 0xc2, 0x5a, 0xcc, 0xdf, 0xfe, 0x7f, 0xf9, 0xa6, 0x52,
0xde, 0x5f, 0x46, 0x91, 0x21, 0x2c, 0x2c, 0x49, 0x25, 0x00, 0xd5, 0xe4,
0x81, 0x6b, 0x85, 0xad, 0x98, 0xaf, 0x06, 0x4a, 0x83, 0xb2, 0xe3, 0x42,
0x39, 0x31, 0x50, 0xe1, 0x2d, 0x22, 0xe6, 0x07, 0x24, 0x65, 0x29, 0x3f,
0x4c, 0xbd, 0x14, 0x8d, 0xfa, 0x31, 0xfa, 0xa4, 0xb5, 0x99, 0x04, 0xa2,
0xa5, 0xcc, 0x3b, 0x12, 0xb1, 0xaa, 0x6a, 0x17, 0x78, 0x8b, 0xb3, 0xe4,
0x3c, 0x4c, 0xc5, 0xaa, 0x79, 0x12, 0x17, 0xe0, 0x22, 0x4d, 0xf4, 0xa9,
0xd5, 0xd0, 0xed, 0xf8, 0xfe, 0x0a, 0x45, 0x80, 0x9f, 0x3b, 0x74, 0xa0,
0xb1, 0xda, 0x18, 0xfa, 0xc2, 0x7d, 0xf6, 0x18, 0x2e, 0xa9, 0x2b, 0x7e,
0x69, 0x06, 0x43, 0x2d, 0x62, 0x09, 0x42, 0x10, 0x9f, 0x83, 0xad, 0xd9,
0xdd, 0xcd, 0xcb, 0x1b, 0x33, 0x32, 0x3e, 0x1f, 0xf6, 0xac, 0x3b, 0xa3,
0x29, 0xd7, 0xc0, 0x88, 0xf9, 0xb7, 0x4c, 0xcd, 0x0a, 0x1f, 0xb8, 0x0f,
0xe6, 0xf7, 0xd7, 0x4d, 0x5f, 0x06, 0x12, 0x8a, 0x12, 0xa6, 0x2d, 0xbe,
0x5c, 0x57, 0xf8, 0x7f, 0x54, 0x3f, 0x90, 0x83, 0x2c, 0x0a, 0xc5, 0x3d,
0x03, 0x78, 0x8a, 0x68, 0xf0, 0xbd, 0xa5, 0x3e, 0xe7, 0x07, 0xab, 0xc8,
0x58, 0x2f, 0x5c, 0xfd, 0xb5, 0x39, 0xe3, 0xc6, 0x1c, 0x27, 0xf9, 0x0b,
0xc7, 0x4c, 0xcc, 0x67, 0x62, 0xe6, 0x79, 0xe8, 0xc1, 0x0a, 0x86, 0x8a,
0xb2, 0x32, 0x7b, 0x90, 0x36, 0x50, 0x92, 0x1f, 0x3e, 0x68, 0x39, 0x1c,
0x4d, 0x5d, 0xf8, 0x2b, 0xe8, 0x7d, 0xe2, 0x34, 0x61, 0x9e, 0xc3, 0x77,
0xb9, 0x4c, 0x34, 0x08, 0xda, 0x31, 0xc9, 0x1d, 0xbd, 0x3b, 0x7b, 0xf1,
0x14, 0xba, 0x3a, 0x34, 0x13, 0xaa, 0x5e, 0xa8, 0x36, 0xf6, 0xfe, 0xed,
0x5b, 0xef, 0xaf, 0x24, 0x42, 0xba, 0xfc, 0xc9, 0x30, 0x84, 0xec, 0x49,
0x14, 0xab, 0x58, 0x71, 0xfe, 0x4b, 0x6d, 0x7b, 0x9f, 0xbb, 0x3c, 0x83,
0xdf, 0x3a, 0xfb, 0x54, 0xff, 0x36, 0xaa, 0x6c, 0x47, 0x94, 0xc0, 0xde,
0x89, 0x2e, 0xac, 0x68, 0xee, 0xe8, 0xf4, 0xae, 0xa3, 0xe0, 0x91, 0x55,
0x0b, 0x0c, 0xd7, 0xf4, 0x33, 0xb5, 0xf9, 0xf2, 0x9e, 0xda, 0x78, 0xe5,
0x75, 0xec, 0xdb, 0xf6, 0xed, 0x27, 0x9f, 0x44, 0x19, 0x9f, 0xb7, 0xf0,
0xac, 0x1b, 0x3a, 0xf5, 0x77, 0xc7, 0x76, 0x1e, 0x3f, 0x78, 0x12, 0x48,
0x1d, 0xb8, 0xe0, 0x30, 0x29, 0x9a, 0x8c, 0x8f, 0x21, 0x44, 0x9c, 0x89,
0xec, 0x8e, 0xd0, 0x81, 0xf5, 0x6a, 0xd0, 0xac, 0x5e, 0xf0, 0x0f, 0x88,
0x86, 0x31, 0x2e, 0x15, 0x1e, 0x0d, 0x2d, 0xeb, 0x56, 0x30, 0x27, 0x02,
0x93, 0xf4, 0x07, 0x07, 0xba, 0xf7, 0xbd, 0xe8, 0x27, 0x4f, 0xc6, 0xd9,
0x57, 0x10, 0x3b, 0xf0, 0xff, 0x2f, 0x2d, 0x6b, 0xd0, 0x17, 0xb3, 0x49,
0xeb, 0xc2, 0x49, 0xdb,
};
static_assert(sizeof(kInput) == sizeof(kOutput),
"Input and output lengths don't match.");
static_assert(sizeof(kInput) == sizeof(kOverflowOutput),
"Input and output lengths don't match.");
TEST(ChaChaTest, TestVector) {
// Run the test with the test vector at all lengths.
@@ -237,6 +331,22 @@ TEST(ChaChaTest, TestVector) {
}
}
TEST(ChaChaTest, CounterOverflow) {
// Run the test with the test vector at all lengths.
for (size_t len = 0; len <= sizeof(kInput); len++) {
SCOPED_TRACE(len);
std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
CRYPTO_chacha_20(buf.get(), kInput, len, kKey, kNonce, kOverflowCounter);
EXPECT_EQ(Bytes(kOverflowOutput, len), Bytes(buf.get(), len));
// Test the in-place version.
OPENSSL_memcpy(buf.get(), kInput, len);
CRYPTO_chacha_20(buf.get(), buf.get(), len, kKey, kNonce, kOverflowCounter);
EXPECT_EQ(Bytes(kOverflowOutput, len), Bytes(buf.get(), len));
}
}
#if defined(CHACHA20_ASM) && defined(SUPPORTS_ABI_TEST)
TEST(ChaChaTest, ABI) {
uint32_t key[8];
+8 -1
View File
@@ -32,7 +32,14 @@ void CRYPTO_hchacha20(uint8_t out[32], const uint8_t key[32],
defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
#define CHACHA20_ASM
// ChaCha20_ctr32 is defined in asm/chacha-*.pl.
// ChaCha20_ctr32 encrypts |in_len| bytes from |in| and writes the result to
// |out|. If |in| and |out| alias, they must be equal.
//
// |counter[0]| is the initial 32-bit block counter, and the remainder is the
// 96-bit nonce. If the counter overflows, the output is undefined. The function
// will produce output, but the output may vary by machine and may not be
// self-consistent. (On some architectures, the assembly implements a mix of
// 64-bit and 32-bit counters.)
void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len,
const uint32_t key[8], const uint32_t counter[4]);
#endif
+69
View File
@@ -52,6 +52,7 @@
#include <limits>
#include <gtest/gtest.h>
#include "test/test_util.h"
#include <openssl/mem.h>
#include <openssl/rand.h>
@@ -169,3 +170,71 @@ TEST(ConstantTimeTest, ValueBarrier) {
EXPECT_EQ(u64, value_barrier_u64(u64));
}
}
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));
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_out[256];
OPENSSL_memcpy(ref_out, out, sizeof(out));
if (b) {
OPENSSL_memcpy(ref_out, in, sizeof(in));
}
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));
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_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];
}
}
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));
}
}
+30 -44
View File
@@ -315,11 +315,6 @@ static void fe_copy_lt(fe_loose *h, const fe *f) {
static_assert(sizeof(fe_loose) == sizeof(fe), "fe and fe_loose mismatch");
OPENSSL_memmove(h, f, sizeof(fe));
}
#if !defined(OPENSSL_SMALL)
static void fe_copy_ll(fe_loose *h, const fe_loose *f) {
OPENSSL_memmove(h, f, sizeof(fe_loose));
}
#endif // !defined(OPENSSL_SMALL)
static void fe_loose_invert(fe *out, const fe_loose *z) {
fe t0;
@@ -698,16 +693,6 @@ void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
fe_add(&r->T, &trZ, &trT);
}
static uint8_t equal(signed char b, signed char c) {
uint8_t ub = b;
uint8_t uc = c;
uint8_t x = ub ^ uc; // 0: yes; 1..255: no
uint32_t y = x; // 0: yes; 1..255: no
y -= 1; // 4294967295: yes; 0..254: no
y >>= 31; // 1: yes; 0: no
return y;
}
static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) {
fe_cmov(&t->yplusx, &u->yplusx, b);
fe_cmov(&t->yminusx, &u->yminusx, b);
@@ -754,7 +739,7 @@ void x25519_ge_scalarmult_small_precomp(
ge_precomp_0(&e);
for (j = 1; j < 16; j++) {
cmov(&e, &multiples[j-1], equal(index, j));
cmov(&e, &multiples[j-1], 1&constant_time_eq_w(index, j));
}
ge_cached cached;
@@ -776,35 +761,36 @@ void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) {
#else
static uint8_t negative(signed char b) {
uint32_t x = b;
x >>= 31; // 1: yes; 0: no
return x;
}
static void table_select(ge_precomp *t, const int pos, const signed char b) {
uint8_t bnegative = constant_time_msb_w(b);
uint8_t babs = b - ((bnegative & b) << 1);
uint8_t t_bytes[3][32] = {
{constant_time_is_zero_w(b) & 1}, {constant_time_is_zero_w(b) & 1}, {0}};
#if defined(__clang__) // materialize for vectorization, 6% speedup
__asm__("" : "+m" (t_bytes) : /*no inputs*/);
#endif
static_assert(sizeof(t_bytes) == sizeof(k25519Precomp[pos][0]), "");
for (int i = 0; i < 8; i++) {
constant_time_conditional_memxor(t_bytes, k25519Precomp[pos][i],
sizeof(t_bytes),
constant_time_eq_w(babs, 1 + i));
}
fe yplusx, yminusx, xy2d;
fe_frombytes_strict(&yplusx, t_bytes[0]);
fe_frombytes_strict(&yminusx, t_bytes[1]);
fe_frombytes_strict(&xy2d, t_bytes[2]);
fe_copy_lt(&t->yplusx, &yplusx);
fe_copy_lt(&t->yminusx, &yminusx);
fe_copy_lt(&t->xy2d, &xy2d);
static void table_select(ge_precomp *t, int pos, signed char b) {
ge_precomp minust;
uint8_t bnegative = negative(b);
uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1);
ge_precomp_0(t);
cmov(t, &k25519Precomp[pos][0], equal(babs, 1));
cmov(t, &k25519Precomp[pos][1], equal(babs, 2));
cmov(t, &k25519Precomp[pos][2], equal(babs, 3));
cmov(t, &k25519Precomp[pos][3], equal(babs, 4));
cmov(t, &k25519Precomp[pos][4], equal(babs, 5));
cmov(t, &k25519Precomp[pos][5], equal(babs, 6));
cmov(t, &k25519Precomp[pos][6], equal(babs, 7));
cmov(t, &k25519Precomp[pos][7], equal(babs, 8));
fe_copy_ll(&minust.yplusx, &t->yminusx);
fe_copy_ll(&minust.yminusx, &t->yplusx);
// NOTE: the input table is canonical, but types don't encode it
fe tmp;
fe_carry(&tmp, &t->xy2d);
fe_neg(&minust.xy2d, &tmp);
cmov(t, &minust, bnegative);
fe_copy_lt(&minust.yplusx, &yminusx);
fe_copy_lt(&minust.yminusx, &yplusx);
fe_neg(&minust.xy2d, &xy2d);
cmov(t, &minust, bnegative>>7);
}
// h = a * B
@@ -916,7 +902,7 @@ void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) {
ge_cached selected;
ge_cached_0(&selected);
for (j = 0; j < 16; j++) {
cmov_cached(&selected, &Ai[j], equal(j, index));
cmov_cached(&selected, &Ai[j], 1&constant_time_eq_w(index, j));
}
x25519_ge_add(&t, &u, &selected);
File diff suppressed because it is too large Load Diff
+10 -12
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# coding=utf-8
# Copyright (c) 2020, Google Inc.
#
@@ -14,7 +14,7 @@
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import StringIO
from io import StringIO
import subprocess
# Base field Z_p
@@ -76,12 +76,7 @@ def point_mul(s, P):
return Q
def to_bytes(x):
ret = bytearray(32)
for i in range(len(ret)):
ret[i] = x % 256
x >>= 8
assert x == 0
return ret
return x.to_bytes(32, "little")
def to_ge_precomp(P):
# typedef struct {
@@ -109,6 +104,9 @@ def to_base_51(x):
assert x == 0
return ret
def to_bytes_literal(x):
return "{" + ", ".join(map(hex, to_bytes(x))) + "}"
def to_literal(x):
ret = "{{\n#if defined(OPENSSL_64_BIT)\n"
ret += ", ".join(map(str, to_base_51(x)))
@@ -140,7 +138,7 @@ def main():
bi_precomp.append(to_ge_precomp(P))
buf = StringIO.StringIO()
buf = StringIO()
buf.write("""/* Copyright (c) 2020, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -190,14 +188,14 @@ static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = {""")
#else
// k25519Precomp[i][j] = (j+1)*256^i*B
static const ge_precomp k25519Precomp[32][8] = {
static const uint8_t k25519Precomp[32][8][3][32] = {
""")
for child in large_precomp:
buf.write("{\n")
for val in child:
buf.write("{\n")
for term in val:
buf.write(to_literal(term) + ",\n")
buf.write(to_bytes_literal(term) + ",\n")
buf.write("},\n")
buf.write("},\n")
buf.write("""};
@@ -216,7 +214,7 @@ static const ge_precomp Bi[8] = {
""")
proc = subprocess.Popen(["clang-format"], stdin=subprocess.PIPE)
proc.communicate(buf.getvalue())
proc.communicate(buf.getvalue().encode("utf8"))
if __name__ == "__main__":
main()
+46 -8
View File
@@ -265,15 +265,15 @@ OPENSSL_INLINE void OPENSSL_reset_malloc_counter_for_testing(void) {}
// Pointer utility functions.
// buffers_alias returns one if |a| and |b| alias and zero otherwise.
static inline int buffers_alias(const uint8_t *a, size_t a_len,
const uint8_t *b, size_t b_len) {
static inline int buffers_alias(const void *a, size_t a_bytes,
const void *b, size_t b_bytes) {
// Cast |a| and |b| to integers. In C, pointer comparisons between unrelated
// objects are undefined whereas pointer to integer conversions are merely
// implementation-defined. We assume the implementation defined it in a sane
// way.
uintptr_t a_u = (uintptr_t)a;
uintptr_t b_u = (uintptr_t)b;
return a_u + a_len > b_u && b_u + b_len > a_u;
return a_u + a_bytes > b_u && b_u + b_bytes > a_u;
}
// align_pointer returns |ptr|, advanced to |alignment|. |alignment| must be a
@@ -360,6 +360,9 @@ static inline uint64_t value_barrier_u64(uint64_t a) {
return a;
}
// |value_barrier_u8| could be defined as above, but compilers other than
// clang seem to still materialize 0x00..00MM instead of reusing 0x??..??MM.
// constant_time_msb_w returns the given value with the MSB copied to all the
// other bits.
static inline crypto_word_t constant_time_msb_w(crypto_word_t a) {
@@ -476,16 +479,23 @@ static inline crypto_word_t constant_time_select_w(crypto_word_t mask,
// to a cmov, it sometimes further transforms it into a branch, which we do
// not want.
//
// Adding barriers to both |mask| and |~mask| breaks the relationship between
// the two, which makes the compiler stick with bitmasks.
return (value_barrier_w(mask) & a) | (value_barrier_w(~mask) & b);
// Hiding the value of the mask from the compiler evades this transformation.
mask = value_barrier_w(mask);
return (mask & a) | (~mask & b);
}
// constant_time_select_8 acts like |constant_time_select| but operates on
// 8-bit values.
static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a,
static inline uint8_t constant_time_select_8(crypto_word_t mask, uint8_t a,
uint8_t b) {
return (uint8_t)(constant_time_select_w(mask, a, b));
// |mask| is a word instead of |uint8_t| to avoid materializing 0x000..0MM
// Making both |mask| and its value barrier |uint8_t| would allow the compiler
// to materialize 0x????..?MM instead, but only clang is that clever.
// However, vectorization of bitwise operations seems to work better on
// |uint8_t| than a mix of |uint64_t| and |uint8_t|, so |m| is cast to
// |uint8_t| after the value barrier but before the bitwise operations.
uint8_t m = value_barrier_w(mask);
return (m & a) | (~m & b);
}
// constant_time_select_int acts like |constant_time_select| but operates on
@@ -495,6 +505,34 @@ static inline int constant_time_select_int(crypto_word_t mask, int a, int b) {
(crypto_word_t)(b)));
}
// constant_time_conditional_memcpy copies |n| bytes from |src| to |dst| if
// |mask| is 0xff..ff and does nothing if |mask| is 0. The |n|-byte memory
// ranges at |dst| and |src| must not overlap, as when calling |memcpy|.
static inline void constant_time_conditional_memcpy(void *dst, const void *src,
const size_t n,
const crypto_word_t mask) {
assert(!buffers_alias(dst, n, src, n));
uint8_t *out = (uint8_t *)dst;
const uint8_t *in = (const uint8_t *)src;
for (size_t i = 0; i < n; i++) {
out[i] = constant_time_select_8(mask, in[i], out[i]);
}
}
// constant_time_conditional_memxor xors |n| bytes from |src| to |dst| if
// |mask| is 0xff..ff and does nothing if |mask| is 0. The |n|-byte memory
// ranges at |dst| and |src| must not overlap, as when calling |memcpy|.
static inline void constant_time_conditional_memxor(void *dst, const void *src,
const size_t n,
const crypto_word_t mask) {
assert(!buffers_alias(dst, n, src, n));
uint8_t *out = (uint8_t *)dst;
const uint8_t *in = (const uint8_t *)src;
for (size_t i = 0; i < n; i++) {
out[i] ^= value_barrier_w(mask) & in[i];
}
}
#if defined(BORINGSSL_CONSTANT_TIME_VALIDATION)
// CONSTTIME_SECRET takes a pointer and a number of bytes and marks that region
+6
View File
@@ -29,6 +29,12 @@ extern "C" {
// CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and
// nonce and writes the result to |out|. If |in| and |out| alias, they must be
// equal. The initial block counter is specified by |counter|.
//
// This function implements a 32-bit block counter as in RFC 8439. On overflow,
// the counter wraps. Reusing a key, nonce, and block counter combination is not
// secure, so wrapping is usually a bug in the caller. While it is possible to
// wrap without reuse with a large initial block counter, this is not
// recommended and may not be portable to other ChaCha20 implementations.
OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in,
size_t in_len, const uint8_t key[32],
const uint8_t nonce[12], uint32_t counter);