Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream merge 2025 01 02 #2090

Merged
merged 4 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -773,8 +773,6 @@ endif()

if(CONSTANT_TIME_VALIDATION)
add_definitions(-DBORINGSSL_CONSTANT_TIME_VALIDATION)
# Asserts will often test secret data.
add_definitions(-DNDEBUG)
endif()

# CMake's iOS support uses Apple's multiple-architecture toolchain. It takes an
Expand Down
4 changes: 2 additions & 2 deletions crypto/cipher_extra/tls_cbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in,
size_t mac_end = in_len;
size_t mac_start = mac_end - md_size;

assert(orig_len >= in_len);
assert(in_len >= md_size);
declassify_assert(orig_len >= in_len);
declassify_assert(in_len >= md_size);
assert(md_size <= EVP_MAX_MD_SIZE);
assert(md_size > 0);

Expand Down
84 changes: 52 additions & 32 deletions crypto/evp_extra/evp_extra_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1687,40 +1687,60 @@ static void ExpectECGroupAndKey(const EVP_PKEY *pkey, int nid) {
}

TEST(EVPExtraTest, ECKeygen) {
// |EVP_PKEY_paramgen| may be used as an extremely roundabout way to get an
// |EC_GROUP|.
bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
ASSERT_TRUE(ctx);
ASSERT_TRUE(EVP_PKEY_paramgen_init(ctx.get()));
ASSERT_TRUE(
EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx.get(), NID_X9_62_prime256v1));
EVP_PKEY *raw = nullptr;
ASSERT_TRUE(EVP_PKEY_paramgen(ctx.get(), &raw));
bssl::UniquePtr<EVP_PKEY> pkey(raw);
raw = nullptr;
ExpectECGroupOnly(pkey.get(), NID_X9_62_prime256v1);
for (bool copy : {false, true}) {
SCOPED_TRACE(copy);

// That resulting |EVP_PKEY| may be used as a template for key generation.
ctx.reset(EVP_PKEY_CTX_new(pkey.get(), nullptr));
ASSERT_TRUE(ctx);
ASSERT_TRUE(EVP_PKEY_keygen_init(ctx.get()));
raw = nullptr;
ASSERT_TRUE(EVP_PKEY_keygen(ctx.get(), &raw));
pkey.reset(raw);
raw = nullptr;
ExpectECGroupAndKey(pkey.get(), NID_X9_62_prime256v1);
auto maybe_copy = [&](bssl::UniquePtr<EVP_PKEY_CTX> *ctx) -> bool {
if (copy) {
ctx->reset(EVP_PKEY_CTX_dup(ctx->get()));
}
return *ctx != nullptr;
};

// |EVP_PKEY_paramgen| may also be skipped.
ctx.reset(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
ASSERT_TRUE(ctx);
ASSERT_TRUE(EVP_PKEY_keygen_init(ctx.get()));
ASSERT_TRUE(
EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx.get(), NID_X9_62_prime256v1));
raw = nullptr;
ASSERT_TRUE(EVP_PKEY_keygen(ctx.get(), &raw));
pkey.reset(raw);
raw = nullptr;
ExpectECGroupAndKey(pkey.get(), NID_X9_62_prime256v1);
// |EVP_PKEY_paramgen| may be used as an extremely roundabout way to get an
// |EC_GROUP|.
bssl::UniquePtr<EVP_PKEY_CTX> ctx(
EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
ASSERT_TRUE(ctx);
ASSERT_TRUE(maybe_copy(&ctx));
ASSERT_TRUE(EVP_PKEY_paramgen_init(ctx.get()));
ASSERT_TRUE(maybe_copy(&ctx));
ASSERT_TRUE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx.get(),
NID_X9_62_prime256v1));
ASSERT_TRUE(maybe_copy(&ctx));
EVP_PKEY *raw = nullptr;
ASSERT_TRUE(EVP_PKEY_paramgen(ctx.get(), &raw));
bssl::UniquePtr<EVP_PKEY> pkey(raw);
raw = nullptr;
ExpectECGroupOnly(pkey.get(), NID_X9_62_prime256v1);

// That resulting |EVP_PKEY| may be used as a template for key generation.
ctx.reset(EVP_PKEY_CTX_new(pkey.get(), nullptr));
ASSERT_TRUE(ctx);
ASSERT_TRUE(maybe_copy(&ctx));
ASSERT_TRUE(EVP_PKEY_keygen_init(ctx.get()));
ASSERT_TRUE(maybe_copy(&ctx));
raw = nullptr;
ASSERT_TRUE(EVP_PKEY_keygen(ctx.get(), &raw));
pkey.reset(raw);
raw = nullptr;
ExpectECGroupAndKey(pkey.get(), NID_X9_62_prime256v1);

// |EVP_PKEY_paramgen| may also be skipped.
ctx.reset(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
ASSERT_TRUE(ctx);
ASSERT_TRUE(maybe_copy(&ctx));
ASSERT_TRUE(EVP_PKEY_keygen_init(ctx.get()));
ASSERT_TRUE(maybe_copy(&ctx));
ASSERT_TRUE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx.get(),
NID_X9_62_prime256v1));
ASSERT_TRUE(maybe_copy(&ctx));
raw = nullptr;
ASSERT_TRUE(EVP_PKEY_keygen(ctx.get(), &raw));
pkey.reset(raw);
raw = nullptr;
ExpectECGroupAndKey(pkey.get(), NID_X9_62_prime256v1);
}
}

TEST(EVPExtraTest, DHKeygen) {
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/bn/bytes.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ void bn_assert_fits_in_bytes(const BIGNUM *bn, size_t num) {
void bn_words_to_big_endian(uint8_t *out, size_t out_len, const BN_ULONG *in,
size_t in_len) {
// The caller should have selected an output length without truncation.
assert(fits_in_bytes(in, in_len, out_len));
declassify_assert(fits_in_bytes(in, in_len, out_len));
size_t num_bytes = in_len * sizeof(BN_ULONG);
if (out_len < num_bytes) {
num_bytes = out_len;
Expand Down
6 changes: 3 additions & 3 deletions crypto/fipsmodule/bn/div.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ BN_ULONG bn_reduce_once(BN_ULONG *r, const BN_ULONG *a, BN_ULONG carry,
//
// Although |carry| may be one if it was one on input and |bn_sub_words|
// returns zero, this would give |r| > |m|, violating our input assumptions.
assert(carry == 0 || carry == (BN_ULONG)-1);
declassify_assert(carry + 1 <= 1);
bn_select_words(r, carry, a /* r < 0 */, r /* r >= 0 */, num);
return carry;
}
Expand All @@ -434,7 +434,7 @@ BN_ULONG bn_reduce_once_in_place(BN_ULONG *r, BN_ULONG carry, const BN_ULONG *m,
BN_ULONG *tmp, size_t num) {
// See |bn_reduce_once| for why this logic works.
carry -= bn_sub_words(tmp, r, m, num);
assert(carry == 0 || carry == (BN_ULONG)-1);
declassify_assert(carry + 1 <= 1);
bn_select_words(r, carry, r /* tmp < 0 */, tmp /* tmp >= 0 */, num);
return carry;
}
Expand Down Expand Up @@ -504,7 +504,7 @@ int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder,
// |divisor_min_bits| bits, the top |divisor_min_bits - 1| can be incorporated
// without reductions. This significantly speeds up |RSA_check_key|. For
// simplicity, we round down to a whole number of words.
assert(divisor_min_bits <= BN_num_bits(divisor));
declassify_assert(divisor_min_bits <= BN_num_bits(divisor));
int initial_words = 0;
if (divisor_min_bits > 0) {
initial_words = (divisor_min_bits - 1) / BN_BITS2;
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/bn/div_extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static uint16_t mod_u16(uint32_t n, uint16_t d, uint32_t p, uint32_t m) {

// Multiply and subtract to get the remainder.
n -= d * t;
assert(n < d);
declassify_assert(n < d);
return n;
}

Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/bn/exponentiation.c
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,

// Prepare a^1 in the Montgomery domain.
assert(!a->neg);
assert(BN_ucmp(a, m) < 0);
declassify_assert(BN_ucmp(a, m) < 0);
if (!BN_to_montgomery(&am, a, mont, ctx) ||
!bn_resize_words(&am, top)) {
goto err;
Expand Down
8 changes: 4 additions & 4 deletions crypto/fipsmodule/bn/gcd_extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static int bn_gcd_consttime(BIGNUM *r, unsigned *out_shift, const BIGNUM *x,
// At least one of |u| and |v| is now even.
BN_ULONG u_is_odd = word_is_odd_mask(u->d[0]);
BN_ULONG v_is_odd = word_is_odd_mask(v->d[0]);
assert(!(u_is_odd & v_is_odd));
declassify_assert(!(u_is_odd & v_is_odd));

// If both are even, the final GCD gains a factor of two.
shift += 1 & (~u_is_odd & ~v_is_odd);
Expand All @@ -106,7 +106,7 @@ static int bn_gcd_consttime(BIGNUM *r, unsigned *out_shift, const BIGNUM *x,
// One of |u| or |v| is zero at this point. The algorithm usually makes |u|
// zero, unless |y| was already zero on input. Fix this by combining the
// values.
assert(BN_is_zero(u) || BN_is_zero(v));
declassify_assert(BN_is_zero(u) | BN_is_zero(v));
for (size_t i = 0; i < width; i++) {
v->d[i] |= u->d[i];
}
Expand Down Expand Up @@ -289,7 +289,7 @@ int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a,
// and |v| is now even.
BN_ULONG u_is_even = ~word_is_odd_mask(u->d[0]);
BN_ULONG v_is_even = ~word_is_odd_mask(v->d[0]);
assert(u_is_even != v_is_even);
declassify_assert(u_is_even != v_is_even);

// Halve the even one and adjust the corresponding coefficient.
maybe_rshift1_words(u->d, u_is_even, tmp->d, n_width);
Expand All @@ -313,7 +313,7 @@ int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a,
maybe_rshift1_words_carry(D->d, D_carry, v_is_even, tmp->d, a_width);
}

assert(BN_is_zero(v));
declassify_assert(BN_is_zero(v));
// While the inputs and output are secret, this function considers whether the
// input was invertible to be public. It is used as part of RSA key
// generation, where inputs are chosen to already be invertible.
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/bn/montgomery_inv.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ static uint64_t bn_neg_inv_mod_r_u64(uint64_t n) {

// The invariant now shows that u*r - v*n == 1 since r == 2 * alpha.
#if BN_BITS2 == 64 && defined(BN_ULLONG)
assert(1 == ((BN_ULLONG)u * 2 * alpha) - ((BN_ULLONG)v * beta));
declassify_assert(1 == ((BN_ULLONG)u * 2 * alpha) - ((BN_ULLONG)v * beta));
#endif

return v;
Expand Down
4 changes: 2 additions & 2 deletions crypto/fipsmodule/bn/mul.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static void bn_mul_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
}

// The product should fit without carries.
assert(c == 0);
declassify_assert(c == 0);
}

// bn_mul_part_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r|
Expand Down Expand Up @@ -407,7 +407,7 @@ static void bn_mul_part_recursive(BN_ULONG *r, const BN_ULONG *a,
}

// The product should fit without carries.
assert(c == 0);
declassify_assert(c == 0);
}

// bn_mul_impl implements |BN_mul| and |bn_mul_consttime|. Note this function
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/bn/prime.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ int BN_primality_test(int *out_is_probably_prime, const BIGNUM *w, int checks,
}
}

assert(uniform_iterations >= (crypto_word_t)checks);
declassify_assert(uniform_iterations >= (crypto_word_t)checks);
*out_is_probably_prime = 1;
ret = 1;

Expand Down
3 changes: 2 additions & 1 deletion crypto/fipsmodule/bn/random.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive,
// If the value is not in range, force it to be in range.
r->d[0] |= constant_time_select_w(in_range, 0, min_inclusive);
r->d[words - 1] &= constant_time_select_w(in_range, BN_MASK2, mask >> 1);
assert(bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words));
declassify_assert(
bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words));

r->neg = 0;
r->width = (int)words;
Expand Down
14 changes: 7 additions & 7 deletions crypto/fipsmodule/curve25519/curve25519_nohw.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ typedef uint64_t fe_limb_t;
#define assert_fe(f) \
do { \
for (unsigned _assert_fe_i = 0; _assert_fe_i < 5; _assert_fe_i++) { \
assert(f[_assert_fe_i] <= UINT64_C(0x8cccccccccccc)); \
declassify_assert(f[_assert_fe_i] <= UINT64_C(0x8cccccccccccc)); \
} \
} while (0)

Expand All @@ -94,7 +94,7 @@ typedef uint64_t fe_limb_t;
#define assert_fe_loose(f) \
do { \
for (unsigned _assert_fe_i = 0; _assert_fe_i < 5; _assert_fe_i++) { \
assert(f[_assert_fe_i] <= UINT64_C(0x1a666666666664)); \
declassify_assert(f[_assert_fe_i] <= UINT64_C(0x1a666666666664)); \
} \
} while (0)

Expand All @@ -116,8 +116,8 @@ typedef uint32_t fe_limb_t;
#define assert_fe(f) \
do { \
for (unsigned _assert_fe_i = 0; _assert_fe_i < 10; _assert_fe_i++) { \
assert(f[_assert_fe_i] <= \
((_assert_fe_i & 1) ? 0x2333333u : 0x4666666u)); \
declassify_assert(f[_assert_fe_i] <= \
((_assert_fe_i & 1) ? 0x2333333u : 0x4666666u)); \
} \
} while (0)

Expand All @@ -134,8 +134,8 @@ typedef uint32_t fe_limb_t;
#define assert_fe_loose(f) \
do { \
for (unsigned _assert_fe_i = 0; _assert_fe_i < 10; _assert_fe_i++) { \
assert(f[_assert_fe_i] <= \
((_assert_fe_i & 1) ? 0x6999999u : 0xd333332u)); \
declassify_assert(f[_assert_fe_i] <= \
((_assert_fe_i & 1) ? 0x6999999u : 0xd333332u)); \
} \
} while (0)

Expand All @@ -146,7 +146,7 @@ OPENSSL_STATIC_ASSERT(sizeof(fe) == sizeof(fe_limb_t) * FE_NUM_LIMBS,

static void fe_frombytes_strict(fe *h, const uint8_t s[32]) {
// |fiat_25519_from_bytes| requires the top-most bit be clear.
assert((s[31] & 0x80) == 0);
declassify_assert((s[31] & 0x80) == 0);
fiat_25519_from_bytes(h->v, s);
assert_fe(h->v);
}
Expand Down
7 changes: 3 additions & 4 deletions crypto/fipsmodule/evp/p_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,14 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx) {
}

static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
EC_PKEY_CTX *dctx, *sctx;
if (!pkey_ec_init(dst)) {
return 0;
}
sctx = src->data;
dctx = dst->data;

const EC_PKEY_CTX *sctx = src->data;
EC_PKEY_CTX *dctx = dst->data;
dctx->md = sctx->md;

dctx->gen_group = sctx->gen_group;
return 1;
}

Expand Down
4 changes: 2 additions & 2 deletions crypto/fipsmodule/rsa/rsa_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {

// This is a pre-condition for |mod_montgomery|. It was already checked by the
// caller.
assert(BN_ucmp(I, n) < 0);
declassify_assert(BN_ucmp(I, n) < 0);

if (!mod_montgomery(r1, I, q, rsa->mont_q, p, ctx) ||
!mod_montgomery(r2, I, p, rsa->mont_p, q, ctx) ||
Expand Down Expand Up @@ -773,7 +773,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
// bound the width slightly higher, so fix it. This trips constant-time checks
// because a naive data flow analysis does not realize the excess words are
// publicly zero.
assert(BN_cmp(r0, n) < 0);
declassify_assert(BN_cmp(r0, n) < 0);
bn_assert_fits_in_bytes(r0, BN_num_bytes(n));
if (!bn_resize_words(r0, n->width)) {
goto err;
Expand Down
Loading
Loading