From d9e753399c8afcfb632398e9139bbe4fd6ab57a6 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sun, 17 Mar 2024 17:17:59 +1000 Subject: [PATCH] Fix EVP_PKEY_CTX_dup with EC generation gen_group wasn't copied over. Change-Id: If5341dce69fe0297b6bd9a5fb7ed34d546201604 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/67167 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 8248baaf3e14895cc85255c009aace5fb92d0c95) --- crypto/evp_extra/evp_extra_test.cc | 84 ++++++++++++++++++------------ crypto/fipsmodule/evp/p_ec.c | 7 ++- 2 files changed, 55 insertions(+), 36 deletions(-) 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; }