evp_test: Fix MaybeReplaceWithCopy for EVP_MD_CTX

The corresponding EVP_PKEY_CTX pointer wasn't being updated. We actually
don't have an API to access the copied object, but OpenSSL 1.1.x added
EVP_MD_CTX_pkey_ctx, which seems fine enough.

I think this happened to work because none of the EVP_MD_CTX-based tests
set anything on the EVP_PKEY_CTX.

OpenSSL 3.x renamed it to EVP_MD_CTX_get_pkey_ctx, along with a host of
other such getters. I've stuck with the 1.1.x name for now, since we're
mostly not targetting the 3.x API yet.

Change-Id: Iefb325ae40beca843de5a03508d072119a9974ea
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/89127
Reviewed-by: Lily Chen <chlily@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/evp/evp_test.cc b/crypto/evp/evp_test.cc
index 613402f..85302c7 100644
--- a/crypto/evp/evp_test.cc
+++ b/crypto/evp/evp_test.cc
@@ -546,7 +546,8 @@
   return true;
 }
 
-bool MaybeReplaceWithCopy(bssl::UniquePtr<EVP_MD_CTX> *ctx, bool copy_ctx) {
+bool MaybeReplaceWithCopy(bssl::UniquePtr<EVP_MD_CTX> *ctx, EVP_PKEY_CTX **pctx,
+                          bool copy_ctx) {
   if (!copy_ctx) {
     return true;
   }
@@ -555,6 +556,7 @@
     return false;
   }
   *ctx = std::move(copy);
+  *pctx = EVP_MD_CTX_pkey_ctx(ctx->get());
   return true;
 }
 
@@ -674,9 +676,9 @@
     EVP_PKEY_CTX *pctx;
     if (ctx == nullptr ||  //
         !md_op_init(ctx.get(), &pctx, digest, nullptr, key) ||
-        !MaybeReplaceWithCopy(&ctx, copy_ctx) ||
+        !MaybeReplaceWithCopy(&ctx, &pctx, copy_ctx) ||
         !SetupContext(t, key_map, pctx) ||
-        !MaybeReplaceWithCopy(&ctx, copy_ctx)) {
+        !MaybeReplaceWithCopy(&ctx, &pctx, copy_ctx)) {
       return false;
     }
 
@@ -703,10 +705,9 @@
       if (verify_ctx == nullptr ||
           !EVP_DigestVerifyInit(verify_ctx.get(), &verify_pctx, digest, nullptr,
                                 key) ||
-
-          !MaybeReplaceWithCopy(&verify_ctx, copy_ctx) ||
+          !MaybeReplaceWithCopy(&verify_ctx, &verify_pctx, copy_ctx) ||
           !SetupContext(t, key_map, verify_pctx) ||
-          !MaybeReplaceWithCopy(&verify_ctx, copy_ctx)) {
+          !MaybeReplaceWithCopy(&verify_ctx, &verify_pctx, copy_ctx)) {
         return false;
       }
       EXPECT_TRUE(EVP_DigestVerify(verify_ctx.get(), actual.data(),
diff --git a/crypto/fipsmodule/digest/digest.cc.inc b/crypto/fipsmodule/digest/digest.cc.inc
index 0a073a1..49b067b 100644
--- a/crypto/fipsmodule/digest/digest.cc.inc
+++ b/crypto/fipsmodule/digest/digest.cc.inc
@@ -218,4 +218,6 @@
   return EVP_MD_type(EVP_MD_CTX_get0_md(ctx));
 }
 
+EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) { return ctx->pctx; }
+
 int EVP_add_digest(const EVP_MD *digest) { return 1; }
diff --git a/include/openssl/digest.h b/include/openssl/digest.h
index a86c189..4067023 100644
--- a/include/openssl/digest.h
+++ b/include/openssl/digest.h
@@ -201,6 +201,11 @@
 // |ctx|.
 OPENSSL_EXPORT int EVP_MD_CTX_type(const EVP_MD_CTX *ctx);
 
+// EVP_MD_CTX_pkey_ctx returns the |EVP_PKEY_CTX| used to configure additional
+// parameters on |ctx| if |ctx| is used for a sign or verify operation with
+// |EVP_DigestSignInit| or |EVP_DigestVerifyInit|. It returns NULL otherwise.
+OPENSSL_EXPORT EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx);
+
 
 // ASN.1 functions.
 //
diff --git a/include/openssl/prefix_symbols.h b/include/openssl/prefix_symbols.h
index 6b144db..75d1ecf 100644
--- a/include/openssl/prefix_symbols.h
+++ b/include/openssl/prefix_symbols.h
@@ -1067,6 +1067,7 @@
 #pragma redefine_extname EVP_MD_CTX_md BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_md))
 #pragma redefine_extname EVP_MD_CTX_move BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_move))
 #pragma redefine_extname EVP_MD_CTX_new BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_new))
+#pragma redefine_extname EVP_MD_CTX_pkey_ctx BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_pkey_ctx))
 #pragma redefine_extname EVP_MD_CTX_reset BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_reset))
 #pragma redefine_extname EVP_MD_CTX_set_flags BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_set_flags))
 #pragma redefine_extname EVP_MD_CTX_size BORINGSSL_SYMBOL(BORINGSSL_ADD_PREFIX(EVP_MD_CTX_size))
@@ -4126,6 +4127,7 @@
 #define EVP_MD_CTX_md BORINGSSL_ADD_PREFIX(EVP_MD_CTX_md)
 #define EVP_MD_CTX_move BORINGSSL_ADD_PREFIX(EVP_MD_CTX_move)
 #define EVP_MD_CTX_new BORINGSSL_ADD_PREFIX(EVP_MD_CTX_new)
+#define EVP_MD_CTX_pkey_ctx BORINGSSL_ADD_PREFIX(EVP_MD_CTX_pkey_ctx)
 #define EVP_MD_CTX_reset BORINGSSL_ADD_PREFIX(EVP_MD_CTX_reset)
 #define EVP_MD_CTX_set_flags BORINGSSL_ADD_PREFIX(EVP_MD_CTX_set_flags)
 #define EVP_MD_CTX_size BORINGSSL_ADD_PREFIX(EVP_MD_CTX_size)