Skip to content

Commit

Permalink
Fix EVP_PKEY_CTX_dup with EC generation
Browse files Browse the repository at this point in the history
gen_group wasn't copied over.

Change-Id: If5341dce69fe0297b6bd9a5fb7ed34d546201604
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/67167
Reviewed-by: Bob Beck <[email protected]>
Commit-Queue: David Benjamin <[email protected]>
(cherry picked from commit 8248baaf3e14895cc85255c009aace5fb92d0c95)
  • Loading branch information
davidben authored and nebeid committed Jan 2, 2025
1 parent c82b3d3 commit d9e7533
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 36 deletions.
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 @@ -1693,40 +1693,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
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

0 comments on commit d9e7533

Please sign in to comment.