diff --git a/crypto/evp_extra/evp_extra_test.cc b/crypto/evp_extra/evp_extra_test.cc index 6d85556c3d..627151d56c 100644 --- a/crypto/evp_extra/evp_extra_test.cc +++ b/crypto/evp_extra/evp_extra_test.cc @@ -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 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 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 *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 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 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) { diff --git a/crypto/fipsmodule/evp/p_ec.c b/crypto/fipsmodule/evp/p_ec.c index 0138a3d5ac..d48bbaf3c4 100644 --- a/crypto/fipsmodule/evp/p_ec.c +++ b/crypto/fipsmodule/evp/p_ec.c @@ -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; }