[openssl] openssl-3.0 update

2022-01-10 Thread Dr . Paul Dale
The branch openssl-3.0 has been updated
   via  576cc3ecb34a8909bf549798430de95fc0fb4042 (commit)
  from  afaa7755aa3e577348e1267d5ad34da695292917 (commit)


- Log -
commit 576cc3ecb34a8909bf549798430de95fc0fb4042
Author: Peiwei Hu 
Date:   Wed Jan 5 23:17:53 2022 +0800

Fix: some patches related to error exiting

Signed-off-by: Peiwei Hu 

Reviewed-by: Tomas Mraz 
Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17443)

---

Summary of changes:
 apps/verify.c| 1 +
 crypto/ec/ec_lib.c   | 4 ++--
 crypto/x509/v3_crld.c| 1 +
 crypto/x509/v3_sxnet.c   | 8 +---
 ssl/statem/statem_clnt.c | 2 +-
 test/evp_test.c  | 2 +-
 6 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/apps/verify.c b/apps/verify.c
index acf80c65c4..a403f301fc 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -263,6 +263,7 @@ static int check(X509_STORE *ctx, const char *file,
 if (x509_ctrl_string(x, opt) <= 0) {
 BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
 ERR_print_errors(bio_err);
+X509_free(x);
 return 0;
 }
 }
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 3d3cf96962..2d85d4f23a 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -1710,8 +1710,8 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM 
params[],
 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING);
 if (ptmp != NULL
 && !ossl_ec_encoding_param2id(ptmp, _flag)) {
-ECerr(0, EC_R_INVALID_ENCODING);
-return 0;
+ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+goto err;
 }
 if (encoding_flag == OPENSSL_EC_NAMED_CURVE) {
 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c
index bc755f5f0d..e704d419f7 100644
--- a/crypto/x509/v3_crld.c
+++ b/crypto/x509/v3_crld.c
@@ -83,6 +83,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, 
X509V3_CTX *ctx,
 return -1;
 dnsect = X509V3_get_section(ctx, cnf->value);
 if (!dnsect) {
+X509_NAME_free(nm);
 ERR_raise(ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND);
 return -1;
 }
diff --git a/crypto/x509/v3_sxnet.c b/crypto/x509/v3_sxnet.c
index 3e5ae048be..4c925900dd 100644
--- a/crypto/x509/v3_sxnet.c
+++ b/crypto/x509/v3_sxnet.c
@@ -167,11 +167,12 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, 
const char *user,
 goto err;
 if (!ASN1_INTEGER_set(sx->version, 0))
 goto err;
-*psx = sx;
 } else
 sx = *psx;
 if (SXNET_get_id_INTEGER(sx, zone)) {
 ERR_raise(ERR_LIB_X509V3, X509V3_R_DUPLICATE_ZONE_ID);
+if (*psx == NULL)
+SXNET_free(sx);
 return 0;
 }
 
@@ -185,13 +186,14 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, 
const char *user,
 if (!sk_SXNETID_push(sx->ids, id))
 goto err;
 id->zone = zone;
+*psx = sx;
 return 1;
 
  err:
 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
 SXNETID_free(id);
-SXNET_free(sx);
-*psx = NULL;
+if (*psx == NULL)
+SXNET_free(sx);
 return 0;
 }
 
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 435888db21..f4e2c15600 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -2926,7 +2926,7 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt)
 encoded_pub_len = EVP_PKEY_get1_encoded_public_key(ckey, _pub);
 if (encoded_pub_len == 0) {
 SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-EVP_PKEY_free(skey);
+EVP_PKEY_free(ckey);
 return EXT_RETURN_FAIL;
 }
 
diff --git a/test/evp_test.c b/test/evp_test.c
index eda8c827f9..47d4e6c878 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -2516,7 +2516,7 @@ static int rand_test_run(EVP_TEST *t)
 item->pr_entropyB_len);
 params[1] = OSSL_PARAM_construct_end();
 if (!TEST_true(EVP_RAND_CTX_set_params(expected->parent, params)))
-return 0;
+goto err;
 }
 if (!TEST_true(EVP_RAND_generate
(expected->ctx, got, got_len,


Coverity Scan: Analysis completed for openssl/openssl

2022-01-10 Thread scan-admin


Your request for analysis of openssl/openssl has been completed 
successfully.
The results are available at 
https://u15810271.ct.sendgrid.net/ls/click?upn=HRESupC-2F2Czv4BOaCWWCy7my0P0qcxCbhZ31OYv50yoN-2BQSVjTtaSz8wS4wOr7HlekBtV1P4YRtWclMVkCdvAA-3D-3Dxy9E_MulOTlHne1IxTRELXXnGni8d68xSVF-2BUCe3a7Ux-2BjeF-2BKAOObPXjHENogK3W3gArNgzf5eU9txBld1wIVZkTKD4M2xDiyi6ppjZPyltan2cq5I4f85OxwP8oU4PkBOs3-2Fr4yAL69wjltsoj62uzMGJ7ZkaXhX47yvuYeiXBuzWzl60UFGdnWjNHSZBZ4rqHc6a-2Bw3pKOpuyp7YghbYXVdEr8NX3d3ekCX1-2FxSzU5P5o-3D

Build ID: 429133

Analysis Summary:
   New defects found: 0
   Defects eliminated: 0



[openssl] openssl-3.0 update

2022-01-10 Thread Matt Caswell
The branch openssl-3.0 has been updated
   via  afaa7755aa3e577348e1267d5ad34da695292917 (commit)
   via  fa2029250e38947ebd68a9b5861bedaa2384d85d (commit)
   via  43927f81a5d1ea1d32508430eee2df85736ba105 (commit)
  from  617203e64f17371b95fc8d64fc7fde9f8bc6e9db (commit)


- Log -
commit afaa7755aa3e577348e1267d5ad34da695292917
Author: Matt Caswell 
Date:   Wed Dec 29 16:39:11 2021 +

Add a test for a custom digest created via EVP_MD_meth_new()

We check that the init and cleanup functions for the custom method are
called as expected.

Based on an original reproducer by Dmitry Belyavsky from issue #17149.

Reviewed-by: Dmitry Belyavskiy 
(Merged from https://github.com/openssl/openssl/pull/17255)

(cherry picked from commit fbbe7202eba9fba243c18513f4f0316dafb3496d)

commit fa2029250e38947ebd68a9b5861bedaa2384d85d
Author: Matt Caswell 
Date:   Fri Dec 10 17:17:27 2021 +

Fix a leak in EVP_DigestInit_ex()

If an EVP_MD_CTX is reused then memory allocated and stored in md_data
can be leaked unless the EVP_MD's cleanup function is called.

Fixes #17149

Reviewed-by: Dmitry Belyavskiy 
(Merged from https://github.com/openssl/openssl/pull/17255)

(cherry picked from commit 357bccc8ba64ec8a5f587b04b5d6b6ca9e8dcbdc)

commit 43927f81a5d1ea1d32508430eee2df85736ba105
Author: Matt Caswell 
Date:   Fri Dec 10 16:53:02 2021 +

Ensure that MDs created via EVP_MD_meth_new() go down the legacy route

MDs created via EVP_MD_meth_new() are inherently legacy and therefore
need to go down the legacy route when they are used.

Reviewed-by: Dmitry Belyavskiy 
(Merged from https://github.com/openssl/openssl/pull/17255)

(cherry picked from commit d9ad5b16b32172df6f7d02cfb1c339cc85d0db01)

---

Summary of changes:
 crypto/evp/digest.c   | 34 -
 test/evp_extra_test.c | 85 +++
 2 files changed, 104 insertions(+), 15 deletions(-)

diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index d92059cbcc..eb6ccfaca2 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -25,6 +25,19 @@
 #include "crypto/evp.h"
 #include "evp_local.h"
 
+static void cleanup_old_md_data(EVP_MD_CTX *ctx, int force)
+{
+if (ctx->digest != NULL) {
+if (ctx->digest->cleanup != NULL
+&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+ctx->digest->cleanup(ctx);
+if (ctx->md_data != NULL && ctx->digest->ctx_size > 0
+&& (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)
+|| force))
+OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+ctx->md_data = NULL;
+}
+}
 
 void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
 {
@@ -41,12 +54,7 @@ void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
  * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
  * sometimes only copies of the context are ever finalised.
  */
-if (ctx->digest && ctx->digest->cleanup
-&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
-ctx->digest->cleanup(ctx);
-if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
-&& (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE) || force))
-OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+cleanup_old_md_data(ctx, force);
 if (force)
 ctx->digest = NULL;
 
@@ -207,7 +215,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const 
EVP_MD *type,
 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
 || tmpimpl != NULL
 #endif
-|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) {
+|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0
+|| type->origin == EVP_ORIG_METH) {
 if (ctx->digest == ctx->fetched_digest)
 ctx->digest = NULL;
 EVP_MD_free(ctx->fetched_digest);
@@ -215,10 +224,7 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const 
EVP_MD *type,
 goto legacy;
 }
 
-if (ctx->digest != NULL && ctx->digest->ctx_size > 0) {
-OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-ctx->md_data = NULL;
-}
+cleanup_old_md_data(ctx, 1);
 
 /* Start of non-legacy code below */
 
@@ -307,10 +313,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const 
EVP_MD *type,
 }
 #endif
 if (ctx->digest != type) {
-if (ctx->digest && ctx->digest->ctx_size) {
-OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-ctx->md_data = NULL;
-}
+cleanup_old_md_data(ctx, 1);
+
 ctx->digest = type;
 if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
 ctx->update = type->update;

[openssl] master update

2022-01-10 Thread Matt Caswell
The branch master has been updated
   via  fbbe7202eba9fba243c18513f4f0316dafb3496d (commit)
   via  357bccc8ba64ec8a5f587b04b5d6b6ca9e8dcbdc (commit)
   via  d9ad5b16b32172df6f7d02cfb1c339cc85d0db01 (commit)
  from  64a8f6008acce93d0bf184559c63e66c0cc0e23d (commit)


- Log -
commit fbbe7202eba9fba243c18513f4f0316dafb3496d
Author: Matt Caswell 
Date:   Wed Dec 29 16:39:11 2021 +

Add a test for a custom digest created via EVP_MD_meth_new()

We check that the init and cleanup functions for the custom method are
called as expected.

Based on an original reproducer by Dmitry Belyavsky from issue #17149.

Reviewed-by: Dmitry Belyavskiy 
(Merged from https://github.com/openssl/openssl/pull/17255)

commit 357bccc8ba64ec8a5f587b04b5d6b6ca9e8dcbdc
Author: Matt Caswell 
Date:   Fri Dec 10 17:17:27 2021 +

Fix a leak in EVP_DigestInit_ex()

If an EVP_MD_CTX is reused then memory allocated and stored in md_data
can be leaked unless the EVP_MD's cleanup function is called.

Fixes #17149

Reviewed-by: Dmitry Belyavskiy 
(Merged from https://github.com/openssl/openssl/pull/17255)

commit d9ad5b16b32172df6f7d02cfb1c339cc85d0db01
Author: Matt Caswell 
Date:   Fri Dec 10 16:53:02 2021 +

Ensure that MDs created via EVP_MD_meth_new() go down the legacy route

MDs created via EVP_MD_meth_new() are inherently legacy and therefore
need to go down the legacy route when they are used.

Reviewed-by: Dmitry Belyavskiy 
(Merged from https://github.com/openssl/openssl/pull/17255)

---

Summary of changes:
 crypto/evp/digest.c   | 34 -
 test/evp_extra_test.c | 85 +++
 2 files changed, 104 insertions(+), 15 deletions(-)

diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 322cfe7646..cdcb60092e 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -25,6 +25,19 @@
 #include "crypto/evp.h"
 #include "evp_local.h"
 
+static void cleanup_old_md_data(EVP_MD_CTX *ctx, int force)
+{
+if (ctx->digest != NULL) {
+if (ctx->digest->cleanup != NULL
+&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+ctx->digest->cleanup(ctx);
+if (ctx->md_data != NULL && ctx->digest->ctx_size > 0
+&& (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)
+|| force))
+OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+ctx->md_data = NULL;
+}
+}
 
 void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
 {
@@ -41,12 +54,7 @@ void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
  * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
  * sometimes only copies of the context are ever finalised.
  */
-if (ctx->digest && ctx->digest->cleanup
-&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
-ctx->digest->cleanup(ctx);
-if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
-&& (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE) || force))
-OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+cleanup_old_md_data(ctx, force);
 if (force)
 ctx->digest = NULL;
 
@@ -208,7 +216,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const 
EVP_MD *type,
 || tmpimpl != NULL
 # endif
 #endif
-|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) {
+|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0
+|| type->origin == EVP_ORIG_METH) {
 if (ctx->digest == ctx->fetched_digest)
 ctx->digest = NULL;
 EVP_MD_free(ctx->fetched_digest);
@@ -216,10 +225,7 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const 
EVP_MD *type,
 goto legacy;
 }
 
-if (ctx->digest != NULL && ctx->digest->ctx_size > 0) {
-OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-ctx->md_data = NULL;
-}
+cleanup_old_md_data(ctx, 1);
 
 /* Start of non-legacy code below */
 
@@ -308,10 +314,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const 
EVP_MD *type,
 }
 #endif
 if (ctx->digest != type) {
-if (ctx->digest && ctx->digest->ctx_size) {
-OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-ctx->md_data = NULL;
-}
+cleanup_old_md_data(ctx, 1);
+
 ctx->digest = type;
 if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
 ctx->update = type->update;
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 7f191c43a9..05af89379f 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -4179,6 +4179,90 @@ static int test_evp_md_cipher_meth(void)
 return testresult;
 }
 
+typedef struct {
+int data;
+} 

[openssl] openssl-3.0 update

2022-01-10 Thread tomas
The branch openssl-3.0 has been updated
   via  617203e64f17371b95fc8d64fc7fde9f8bc6e9db (commit)
  from  7e1ec537a91d1f33c50e8f70dff82a4ed6668e9a (commit)


- Log -
commit 617203e64f17371b95fc8d64fc7fde9f8bc6e9db
Author: Tomas Mraz 
Date:   Wed Jan 5 16:50:00 2022 +0100

EVP_PKEY_derive_set_peer_ex: Export the peer key to proper keymgmt

The peer key has to be exported to the operation's keymgmt
not the ctx->pkey's keymgmt.

Fixes #17424

Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17425)

(cherry picked from commit 64a8f6008acce93d0bf184559c63e66c0cc0e23d)

---

Summary of changes:
 crypto/evp/exchange.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c
index e2ca30c94d..bd97a047c5 100644
--- a/crypto/evp/exchange.c
+++ b/crypto/evp/exchange.c
@@ -306,7 +306,7 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const 
OSSL_PARAM params[])
 /*
  * Ensure that the key is provided, either natively, or as a cached
  * export.  We start by fetching the keymgmt with the same name as
- * |ctx->pkey|, but from the provider of the exchange method, using
+ * |ctx->keymgmt|, but from the provider of the exchange method, using
  * the same property query as when fetching the exchange method.
  * With the keymgmt we found (if we did), we try to export |ctx->pkey|
  * to it (evp_pkey_export_to_provider() is smart enough to only 
actually
@@ -380,6 +380,7 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY 
*peer,
 int ret = 0, check;
 void *provkey = NULL;
 EVP_PKEY_CTX *check_ctx = NULL;
+EVP_KEYMGMT *tmp_keymgmt = NULL, *tmp_keymgmt_tofree = NULL;
 
 if (ctx == NULL) {
 ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
@@ -404,8 +405,25 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, 
EVP_PKEY *peer,
 return -1;
 }
 
-provkey = evp_pkey_export_to_provider(peer, ctx->libctx, >keymgmt,
-  ctx->propquery);
+/*
+ * Ensure that the |peer| is provided, either natively, or as a cached
+ * export.  We start by fetching the keymgmt with the same name as
+ * |ctx->keymgmt|, but from the provider of the exchange method, using
+ * the same property query as when fetching the exchange method.
+ * With the keymgmt we found (if we did), we try to export |peer|
+ * to it (evp_pkey_export_to_provider() is smart enough to only actually
+ * export it if |tmp_keymgmt| is different from |peer|'s keymgmt)
+ */
+tmp_keymgmt_tofree = tmp_keymgmt =
+evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)
+
EVP_KEYEXCH_get0_provider(ctx->op.kex.exchange),
+EVP_KEYMGMT_get0_name(ctx->keymgmt),
+ctx->propquery);
+if (tmp_keymgmt != NULL)
+provkey = evp_pkey_export_to_provider(peer, ctx->libctx,
+  _keymgmt, ctx->propquery);
+EVP_KEYMGMT_free(tmp_keymgmt_tofree);
+
 /*
  * If making the key provided wasn't possible, legacy may be able to pick
  * it up


[openssl] master update

2022-01-10 Thread tomas
The branch master has been updated
   via  64a8f6008acce93d0bf184559c63e66c0cc0e23d (commit)
  from  328bf5adf9e23da523d4195db309083aa02403c4 (commit)


- Log -
commit 64a8f6008acce93d0bf184559c63e66c0cc0e23d
Author: Tomas Mraz 
Date:   Wed Jan 5 16:50:00 2022 +0100

EVP_PKEY_derive_set_peer_ex: Export the peer key to proper keymgmt

The peer key has to be exported to the operation's keymgmt
not the ctx->pkey's keymgmt.

Fixes #17424

Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17425)

---

Summary of changes:
 crypto/evp/exchange.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c
index e2ca30c94d..bd97a047c5 100644
--- a/crypto/evp/exchange.c
+++ b/crypto/evp/exchange.c
@@ -306,7 +306,7 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const 
OSSL_PARAM params[])
 /*
  * Ensure that the key is provided, either natively, or as a cached
  * export.  We start by fetching the keymgmt with the same name as
- * |ctx->pkey|, but from the provider of the exchange method, using
+ * |ctx->keymgmt|, but from the provider of the exchange method, using
  * the same property query as when fetching the exchange method.
  * With the keymgmt we found (if we did), we try to export |ctx->pkey|
  * to it (evp_pkey_export_to_provider() is smart enough to only 
actually
@@ -380,6 +380,7 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY 
*peer,
 int ret = 0, check;
 void *provkey = NULL;
 EVP_PKEY_CTX *check_ctx = NULL;
+EVP_KEYMGMT *tmp_keymgmt = NULL, *tmp_keymgmt_tofree = NULL;
 
 if (ctx == NULL) {
 ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
@@ -404,8 +405,25 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, 
EVP_PKEY *peer,
 return -1;
 }
 
-provkey = evp_pkey_export_to_provider(peer, ctx->libctx, >keymgmt,
-  ctx->propquery);
+/*
+ * Ensure that the |peer| is provided, either natively, or as a cached
+ * export.  We start by fetching the keymgmt with the same name as
+ * |ctx->keymgmt|, but from the provider of the exchange method, using
+ * the same property query as when fetching the exchange method.
+ * With the keymgmt we found (if we did), we try to export |peer|
+ * to it (evp_pkey_export_to_provider() is smart enough to only actually
+ * export it if |tmp_keymgmt| is different from |peer|'s keymgmt)
+ */
+tmp_keymgmt_tofree = tmp_keymgmt =
+evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)
+
EVP_KEYEXCH_get0_provider(ctx->op.kex.exchange),
+EVP_KEYMGMT_get0_name(ctx->keymgmt),
+ctx->propquery);
+if (tmp_keymgmt != NULL)
+provkey = evp_pkey_export_to_provider(peer, ctx->libctx,
+  _keymgmt, ctx->propquery);
+EVP_KEYMGMT_free(tmp_keymgmt_tofree);
+
 /*
  * If making the key provided wasn't possible, legacy may be able to pick
  * it up