Skip to content

Commit

Permalink
Merge pull request aws#1331 from dkostic/upstream-merge-2023-11-30
Browse files Browse the repository at this point in the history
Upstream merge 2023-11-30
  • Loading branch information
dkostic authored Dec 7, 2023
2 parents bb02d50 + 216aefb commit c7c418a
Show file tree
Hide file tree
Showing 19 changed files with 98 additions and 94 deletions.
12 changes: 6 additions & 6 deletions crypto/ec_extra/hash_to_curve.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,12 @@ static void map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z,
group->meth->felem_sqr;

EC_FELEM tv1, tv2, tv3, tv4, tv5, tv6, x, y, y1;
felem_sqr(group, &tv1, u); // 1. tv1 = u^2
felem_mul(group, &tv1, Z, &tv1); // 2. tv1 = Z * tv1
felem_sqr(group, &tv2, &tv1); // 3. tv2 = tv1^2
ec_felem_add(group, &tv2, &tv2, &tv1); // 4. tv2 = tv2 + tv1
ec_felem_add(group, &tv3, &tv2, &group->one); // 5. tv3 = tv2 + 1
felem_mul(group, &tv3, &group->b, &tv3); // 6. tv3 = B * tv3
felem_sqr(group, &tv1, u); // 1. tv1 = u^2
felem_mul(group, &tv1, Z, &tv1); // 2. tv1 = Z * tv1
felem_sqr(group, &tv2, &tv1); // 3. tv2 = tv1^2
ec_felem_add(group, &tv2, &tv2, &tv1); // 4. tv2 = tv2 + tv1
ec_felem_add(group, &tv3, &tv2, ec_felem_one(group)); // 5. tv3 = tv2 + 1
felem_mul(group, &tv3, &group->b, &tv3); // 6. tv3 = B * tv3

// 7. tv4 = CMOV(Z, -tv2, tv2 != 0)
const BN_ULONG tv2_non_zero = ec_felem_non_zero_mask(group, &tv2);
Expand Down
16 changes: 10 additions & 6 deletions crypto/err/err.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,13 @@ struct err_error_st {

// ERR_STATE contains the per-thread, error queue.
typedef struct err_state_st {
// errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring
// buffer.
// errors contains up to ERR_NUM_ERRORS - 1 most recent errors, organised as a
// ring buffer.
struct err_error_st errors[ERR_NUM_ERRORS];
// top contains the index one past the most recent error. If |top| equals
// |bottom| then the queue is empty.
// top contains the index of the most recent error. If |top| equals |bottom|
// then the queue is empty.
unsigned top;
// bottom contains the index of the last error in the queue.
// bottom contains the index before the least recent error in the queue.
unsigned bottom;

// to_free, if not NULL, contains a pointer owned by this structure that was
Expand Down Expand Up @@ -875,6 +875,10 @@ void ERR_restore_state(const ERR_SAVE_STATE *state) {
return;
}

if (state->num_errors >= ERR_NUM_ERRORS) {
abort();
}

ERR_STATE *const dst = err_get_state();
if (dst == NULL) {
return;
Expand All @@ -883,6 +887,6 @@ void ERR_restore_state(const ERR_SAVE_STATE *state) {
for (size_t i = 0; i < state->num_errors; i++) {
err_copy(&dst->errors[i], &state->errors[i]);
}
dst->top = state->num_errors - 1;
dst->top = (unsigned)(state->num_errors - 1);
dst->bottom = ERR_NUM_ERRORS - 1;
}
45 changes: 17 additions & 28 deletions crypto/fipsmodule/ec/ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,8 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth, const BIGNUM *p, const BIGNUM *a,
bn_mont_ctx_init(&ret->field);
bn_mont_ctx_init(&ret->order);

ret->generator.group = ret;

if (!ec_GFp_simple_group_set_curve(ret, p, a, b, ctx)) {
EC_GROUP_free(ret);
return NULL;
Expand All @@ -347,19 +349,9 @@ static int ec_group_set_generator(EC_GROUP *group, const EC_AFFINE *generator,
}

group->field_greater_than_order = BN_cmp(&group->field.N, order) > 0;
group->generator = EC_POINT_new(group);
if (group->generator == NULL) {
return 0;
}
ec_affine_to_jacobian(group, &group->generator->raw, generator);
assert(ec_felem_equal(group, &group->one, &group->generator->raw.Z));

// Avoid a reference cycle. |group->generator| does not maintain an owning
// pointer to |group|.
int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references);

assert(!is_zero);
(void)is_zero;
group->generator.raw.X = generator->X;
group->generator.raw.Y = generator->Y;
// |raw.Z| was set to 1 by |ec_GFp_simple_group_set_curve|.
group->has_order = 1;
return 1;
}
Expand Down Expand Up @@ -404,7 +396,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,

int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
const BIGNUM *order, const BIGNUM *cofactor) {
if (group->curve_name != NID_undef || group->generator != NULL ||
if (group->curve_name != NID_undef || group->has_order ||
generator->group != group) {
// |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
// |EC_GROUP_new_curve_GFp| and may only used once on each group.
Expand Down Expand Up @@ -568,7 +560,6 @@ void EC_GROUP_free(EC_GROUP *group) {
return;
}

ec_point_free(group->generator, /*free_group=*/0);
bn_mont_ctx_cleanup(&group->order);
bn_mont_ctx_cleanup(&group->field);
OPENSSL_free(group);
Expand Down Expand Up @@ -605,18 +596,17 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
// structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes,
// custom curve construction is sadly done in two parts) but otherwise not the
// same object, we consider them always unequal.
return a->meth != b->meth ||
a->generator == NULL ||
b->generator == NULL ||
return a->meth != b->meth || //
!a->has_order || !b->has_order ||
BN_cmp(&a->order.N, &b->order.N) != 0 ||
BN_cmp(&a->field.N, &b->field.N) != 0 ||
!ec_felem_equal(a, &a->a, &b->a) ||
!ec_felem_equal(a, &a->a, &b->a) || //
!ec_felem_equal(a, &a->b, &b->b) ||
!ec_GFp_simple_points_equal(a, &a->generator->raw, &b->generator->raw);
!ec_GFp_simple_points_equal(a, &a->generator.raw, &b->generator.raw);
}

const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
return group->generator;
return group->has_order ? &group->generator : NULL;
}

const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
Expand Down Expand Up @@ -811,7 +801,7 @@ void ec_affine_to_jacobian(const EC_GROUP *group, EC_JACOBIAN *out,
const EC_AFFINE *p) {
out->X = p->X;
out->Y = p->Y;
out->Z = group->one;
out->Z = *ec_felem_one(group);
}

int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out,
Expand Down Expand Up @@ -849,10 +839,9 @@ int ec_point_set_affine_coordinates(const EC_GROUP *group, EC_AFFINE *out,
// return value by setting a known safe value. Note this may not be possible
// if the caller is in the process of constructing an arbitrary group and
// the generator is missing.
if (group->generator != NULL) {
assert(ec_felem_equal(group, &group->one, &group->generator->raw.Z));
out->X = group->generator->raw.X;
out->Y = group->generator->raw.Y;
if (group->has_order) {
out->X = group->generator.raw.X;
out->Y = group->generator.raw.Y;
}
return 0;
}
Expand Down Expand Up @@ -1229,8 +1218,8 @@ int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out,
}

void ec_set_to_safe_point(const EC_GROUP *group, EC_JACOBIAN *out) {
if (group->generator != NULL) {
ec_GFp_simple_point_copy(out, &group->generator->raw);
if (group->has_order) {
ec_GFp_simple_point_copy(out, &group->generator.raw);
} else {
// The generator can be missing if the caller is in the process of
// constructing an arbitrary group. In this case, we give up and use the
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/ec/ec_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ int EC_KEY_check_fips(const EC_KEY *key) {
// ec_felem_to_bignum() calls BN_bin2bn() which sets the `neg` flag to 0.
EC_POINT *pub_key = key->pub_key;
EC_GROUP *group = key->pub_key->group;
if(ec_felem_equal(group, &group->one, &pub_key->raw.Z)) {
if(ec_felem_equal(group, ec_felem_one(group), &pub_key->raw.Z)) {
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
int check_ret = 1;
Expand Down
5 changes: 5 additions & 0 deletions crypto/fipsmodule/ec/felem.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
#include "../../internal.h"


const EC_FELEM *ec_felem_one(const EC_GROUP *group) {
// We reuse generator.Z as a cache for 1 in the field.
return &group->generator.raw.Z;
}

int ec_bignum_to_felem(const EC_GROUP *group, EC_FELEM *out, const BIGNUM *in) {
uint8_t bytes[EC_MAX_BYTES];
size_t len = BN_num_bytes(&group->field.N);
Expand Down
31 changes: 17 additions & 14 deletions crypto/fipsmodule/ec/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ typedef struct {
BN_ULONG words[EC_MAX_WORDS];
} EC_FELEM;

// ec_felem_one returns one in |group|'s field.
const EC_FELEM *ec_felem_one(const EC_GROUP *group);

// ec_bignum_to_felem converts |in| to an |EC_FELEM|. It returns one on success
// and zero if |in| is out of range.
int ec_bignum_to_felem(const EC_GROUP *group, EC_FELEM *out, const BIGNUM *in);
Expand Down Expand Up @@ -603,19 +606,30 @@ struct ec_method_st {

const EC_METHOD *EC_GFp_mont_method(void);

struct ec_point_st {
// group is an owning reference to |group|, unless this is
// |group->generator|.
EC_GROUP *group;
// raw is the group-specific point data. Functions that take |EC_POINT|
// typically check consistency with |EC_GROUP| while functions that take
// |EC_JACOBIAN| do not. Thus accesses to this field should be externally
// checked for consistency.
EC_JACOBIAN raw;
} /* EC_POINT */;

struct ec_group_st {
const EC_METHOD *meth;

// Unlike all other |EC_POINT|s, |generator| does not own |generator->group|
// to avoid a reference cycle. Additionally, Z is guaranteed to be one, so X
// and Y are suitable for use as an |EC_AFFINE|.
EC_POINT *generator;
// and Y are suitable for use as an |EC_AFFINE|. Before |has_order| is set, Z
// is one, but X and Y are uninitialized.
EC_POINT generator;

BN_MONT_CTX order;
BN_MONT_CTX field;

EC_FELEM a, b; // Curve coefficients.
EC_FELEM one; // The value one.

int curve_name; // optional NID for named curve

Expand All @@ -633,17 +647,6 @@ struct ec_group_st {
CRYPTO_refcount_t references;
} /* EC_GROUP */;

struct ec_point_st {
// group is an owning reference to |group|, unless this is
// |group->generator|.
EC_GROUP *group;
// raw is the group-specific point data. Functions that take |EC_POINT|
// typically check consistency with |EC_GROUP| while functions that take
// |EC_JACOBIAN| do not. Thus accesses to this field should be externally
// checked for consistency.
EC_JACOBIAN raw;
} /* EC_POINT */;

EC_GROUP *ec_group_new(const EC_METHOD *meth, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx);

Expand Down
3 changes: 2 additions & 1 deletion crypto/fipsmodule/ec/simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
if (!BN_MONT_CTX_set(&group->field, p, ctx) ||
!ec_bignum_to_felem(group, &group->a, a) ||
!ec_bignum_to_felem(group, &group->b, b) ||
!ec_bignum_to_felem(group, &group->one, BN_value_one())) {
// Reuse Z from the generator to cache the value one.
!ec_bignum_to_felem(group, &group->generator.raw.Z, BN_value_one())) {
goto err;
}

Expand Down
4 changes: 2 additions & 2 deletions crypto/fipsmodule/ec/simple_mul.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r,

void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_JACOBIAN *r,
const EC_SCALAR *scalar) {
ec_GFp_mont_mul(group, r, &group->generator->raw, scalar);
ec_GFp_mont_mul(group, r, &group->generator.raw, scalar);
}

static void ec_GFp_mont_batch_precomp(const EC_GROUP *group, EC_JACOBIAN *out,
Expand Down Expand Up @@ -234,7 +234,7 @@ static void ec_GFp_mont_get_comb_window(const EC_GROUP *group,
ec_felem_select(group, &out->Y, match, &precomp->comb[j].Y, &out->Y);
}
BN_ULONG is_infinity = constant_time_is_zero_w(window);
ec_felem_select(group, &out->Z, is_infinity, &out->Z, &group->one);
ec_felem_select(group, &out->Z, is_infinity, &out->Z, ec_felem_one(group));
}

void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_JACOBIAN *r,
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/ec/wnaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r,
int8_t g_wNAF[EC_MAX_BYTES * 8 + 1];
EC_JACOBIAN g_precomp[EC_WNAF_TABLE_SIZE];
assert(wNAF_len <= OPENSSL_ARRAY_SIZE(g_wNAF));
const EC_JACOBIAN *g = &group->generator->raw;
const EC_JACOBIAN *g = &group->generator.raw;
if (g_scalar != NULL) {
ec_compute_wNAF(group, g_wNAF, g_scalar, bits, EC_WNAF_WINDOW_BITS);
compute_precomp(group, g_precomp, g, EC_WNAF_TABLE_SIZE);
Expand Down
7 changes: 3 additions & 4 deletions crypto/fipsmodule/ecdsa/ecdsa_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,15 @@ TEST(ECDSATest, BuiltinCurves) {

// Test ASN.1-encoded signatures.
// Create a signature.
unsigned sig_len = ECDSA_size(eckey.get());
std::vector<uint8_t> signature(sig_len);
std::vector<uint8_t> signature(ECDSA_size(eckey.get()));
unsigned sig_len;
ASSERT_TRUE(
ECDSA_sign(0, digest, 20, signature.data(), &sig_len, eckey.get()));
signature.resize(sig_len);

// ECDSA signing should be non-deterministic. This does not verify k is
// generated securely but at least checks it was randomized at all.
sig_len = ECDSA_size(eckey.get());
std::vector<uint8_t> signature2(sig_len);
std::vector<uint8_t> signature2(ECDSA_size(eckey.get()));
ASSERT_TRUE(
ECDSA_sign(0, digest, 20, signature2.data(), &sig_len, eckey.get()));
signature2.resize(sig_len);
Expand Down
6 changes: 3 additions & 3 deletions crypto/fipsmodule/pbkdf/pbkdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@


int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len,
const uint8_t *salt, size_t salt_len, unsigned iterations,
const uint8_t *salt, size_t salt_len, uint32_t iterations,
const EVP_MD *digest, size_t key_len, uint8_t *out_key) {
// See RFC 8018, section 5.2.
int ret = 0;
Expand Down Expand Up @@ -103,7 +103,7 @@ int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len,
}

OPENSSL_memcpy(out_key, digest_tmp, todo);
for (unsigned j = 1; j < iterations; j++) {
for (uint32_t j = 1; j < iterations; j++) {
// Compute the remaining U_* values and XOR.
if (!HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL) ||
!HMAC_Update(&hctx, digest_tmp, md_len) ||
Expand Down Expand Up @@ -148,7 +148,7 @@ int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len,

int PKCS5_PBKDF2_HMAC_SHA1(const char *password, size_t password_len,
const uint8_t *salt, size_t salt_len,
unsigned iterations, size_t key_len,
uint32_t iterations, size_t key_len,
uint8_t *out_key) {
return PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, iterations,
EVP_sha1(), key_len, out_key);
Expand Down
6 changes: 3 additions & 3 deletions crypto/pkcs8/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm,
// key material to |out| and returns one. Otherwise, it returns zero. |id|
// should be one of the |PKCS12_*_ID| values.
int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt,
size_t salt_len, uint8_t id, unsigned iterations,
size_t salt_len, uint8_t id, uint32_t iterations,
size_t out_len, uint8_t *out, const EVP_MD *md);

// pkcs12_pbe_encrypt_init configures |ctx| for encrypting with a PBES1 scheme
// defined in PKCS#12. It writes the corresponding AlgorithmIdentifier to |out|.
int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg,
unsigned iterations, const char *pass,
uint32_t iterations, const char *pass,
size_t pass_len, const uint8_t *salt,
size_t salt_len);

Expand Down Expand Up @@ -121,7 +121,7 @@ int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx,
// as defined in RFC 2998, with the specified parameters. It writes the
// corresponding AlgorithmIdentifier to |out|.
int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx,
const EVP_CIPHER *cipher, unsigned iterations,
const EVP_CIPHER *cipher, uint32_t iterations,
const char *pass, size_t pass_len,
const uint8_t *salt, size_t salt_len);

Expand Down
6 changes: 3 additions & 3 deletions crypto/pkcs8/p5_pbev2.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ static int add_cipher_oid(CBB *out, int nid) {
}

static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const EVP_MD *pbkdf2_md, unsigned iterations,
const EVP_MD *pbkdf2_md, uint32_t iterations,
const char *pass, size_t pass_len,
const uint8_t *salt, size_t salt_len,
const uint8_t *iv, size_t iv_len, int enc) {
Expand All @@ -162,7 +162,7 @@ static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
}

int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx,
const EVP_CIPHER *cipher, unsigned iterations,
const EVP_CIPHER *cipher, uint32_t iterations,
const char *pass, size_t pass_len,
const uint8_t *salt, size_t salt_len) {
int cipher_nid = EVP_CIPHER_nid(cipher);
Expand Down Expand Up @@ -310,7 +310,7 @@ int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx,
return 0;
}

return pkcs5_pbe2_cipher_init(ctx, cipher, md, (unsigned)iterations, pass,
return pkcs5_pbe2_cipher_init(ctx, cipher, md, (uint32_t)iterations, pass,
pass_len, CBS_data(&salt), CBS_len(&salt),
CBS_data(&iv), CBS_len(&iv), 0 /* decrypt */);
}
Loading

0 comments on commit c7c418a

Please sign in to comment.