[openssl] master update

Matt Caswell matt at openssl.org
Wed Nov 18 14:35:14 UTC 2020


The branch master has been updated
       via  d3d2c0dc68e6eebbfe7b1fc2ea653225a9f37a94 (commit)
       via  3105d8469379642c4a0060077d460ef920c035be (commit)
       via  b6ae56fd2778632a45c8f8d4be2c8d62767b951a (commit)
       via  1b2a55ffa2e6acde6fb9909276936cc1c61c89b1 (commit)
       via  33c39a0659de257dde8ce28496f0ce6c16954430 (commit)
       via  0437309fdf544492e272943e892523653df2f189 (commit)
       via  1072041b17adc9618644c813ea95e85cf54deced (commit)
       via  13c453728c076d5c1a65a5fd9424e15a9964d755 (commit)
       via  163f6dc1f70f30de46a68137c36e70cae4d95cd8 (commit)
       via  9912be1b33bf2a65672d70ad75e07e0d63d33df3 (commit)
       via  8b7df247b7538e97133c50aaf27813d30677f729 (commit)
       via  936d5657680bba3315aec6d7cdc04ea8cab9050e (commit)
       via  184280971c4db38d7001983569bacca2a50b50f1 (commit)
       via  cb5a427acf0617798099321032421d1242930402 (commit)
       via  1b2b475517054d26a555269acacdb0ab7072bc6e (commit)
       via  1ee22dc26873e68b73b693ffb5d99a6e9644b45f (commit)
       via  091f6074c554a14bd9d37186e40ff9d556e4b216 (commit)
      from  2b93900e28b330e6066a993278fabd4d560936f9 (commit)


- Log -----------------------------------------------------------------
commit d3d2c0dc68e6eebbfe7b1fc2ea653225a9f37a94
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Nov 2 16:59:15 2020 +0000

    Adapt ssltest_old to not use deprecated DH APIs
    
    There are non-deprecated replacements so we should use those instead.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 3105d8469379642c4a0060077d460ef920c035be
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Oct 29 17:18:54 2020 +0000

    Extend the auto DH testing to check DH sizes
    
    Check that the size of the DH parameters we select changes according to
    the size of the certificate key or symmetric cipher (if no certificate).
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit b6ae56fd2778632a45c8f8d4be2c8d62767b951a
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Oct 29 16:46:56 2020 +0000

    Add some additional test certificates/keys
    
    Add certs with 1024, 3072, 4096 and 8192 bit RSA keys
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 1b2a55ffa2e6acde6fb9909276936cc1c61c89b1
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Oct 23 16:44:35 2020 +0100

    Add a CHANGES.md entry for the "tmp_dh" functions/macros
    
    Describe the tmp_dh deprecations, and what applications should do instead.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 33c39a0659de257dde8ce28496f0ce6c16954430
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 21 16:00:48 2020 +0100

    Add a test for the various ways of setting temporary DH params
    
    We support a number of different ways of setting temporary DH params. We
    should test that they all work correctly.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 0437309fdf544492e272943e892523653df2f189
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 21 15:07:01 2020 +0100

    Document some SSL DH related functions/macros
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 1072041b17adc9618644c813ea95e85cf54deced
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 21 15:06:28 2020 +0100

    Return sensible values for some SSL ctrls
    
    Some ctrls were always returning 0 even if they were successful.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 13c453728c076d5c1a65a5fd9424e15a9964d755
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Oct 16 16:35:44 2020 +0100

    Only disabled what we need to in a no-dh build
    
    no-dh disables the low level API for DH. However, since we're now using
    the high level EVP API in most places we don't need to disable quite so
    much.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 163f6dc1f70f30de46a68137c36e70cae4d95cd8
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Oct 15 16:45:54 2020 +0100

    Implement a replacement for SSL_set_tmp_dh()
    
    The old function took a DH as a parameter. In the new version we pass
    an EVP_PKEY instead. Similarly for the SSL_CTX version of this function.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 9912be1b33bf2a65672d70ad75e07e0d63d33df3
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 14 17:30:17 2020 +0100

    Remove deprecated functionality from s_server
    
    This will be added back in by a later commit
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 8b7df247b7538e97133c50aaf27813d30677f729
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 14 17:13:45 2020 +0100

    Disable the DHParameters config option in a no-deprecated build
    
    This option calls SSL_set_tmp_dh() which does not exist in a no-deprecated
    build. We need to implement an alternative.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 936d5657680bba3315aec6d7cdc04ea8cab9050e
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 14 16:19:16 2020 +0100

    Remove DH usage from tls_process_cke_dhe
    
    We instead set the encoded public key directly in the EVP_PKEY object.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 184280971c4db38d7001983569bacca2a50b50f1
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 14 16:12:05 2020 +0100

    Remove DH usage in tls_construct_server_key_exchange()
    
    We get DH related parameters directly from the EVP_PKEY instead of
    downgrading to a DH object first.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit cb5a427acf0617798099321032421d1242930402
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 14 16:01:56 2020 +0100

    Avoid the use of a DH object in tls_construct_cke_dhe()
    
    There is no need for us to downgrade the EVP_PKEY into a DH object
    for this function so we rewrite things to avoid it.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 1b2b475517054d26a555269acacdb0ab7072bc6e
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 14 15:06:28 2020 +0100

    Deprecate SSL_CTRL_SET_TMP_DH and other related ctrls
    
    These ctrls pass around a DH object which is now deprecated, so we
    deprecate the ctrls themselves.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 1ee22dc26873e68b73b693ffb5d99a6e9644b45f
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 14 13:41:32 2020 +0100

    Convert TLS ServerKeyExchange processing to use an EVP_PKEY
    
    Previously we were constructing a DH object and then assigning it to an
    EVP_PKEY. Instead we construct an EVP_PKEY directly.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

commit 091f6074c554a14bd9d37186e40ff9d556e4b216
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Oct 14 09:25:35 2020 +0100

    Convert TLS auto DH parameters to use EVP_PKEY
    
    Previously a DH object was constructed and then assigned to an EVP_PKEY.
    Instead we now construct the EVP_PKEY directly instead.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13368)

-----------------------------------------------------------------------

Summary of changes:
 CHANGES.md                               |  15 ++
 apps/s_server.c                          |  80 +++----
 crypto/bn/bn_dh.c                        |   3 -
 crypto/bn/build.info                     |   8 +-
 doc/man3/SSL_CTX_set_tmp_dh_callback.pod | 142 ++++++------
 include/openssl/bn.h                     |   2 -
 include/openssl/ssl.h.in                 |  23 +-
 ssl/s3_lib.c                             |  68 ++----
 ssl/ssl_cert.c                           |   7 +-
 ssl/ssl_conf.c                           |  47 ++--
 ssl/ssl_lib.c                            |  34 ++-
 ssl/ssl_local.h                          |   9 +-
 ssl/statem/statem_clnt.c                 | 120 +++++------
 ssl/statem/statem_srvr.c                 |  69 +++---
 ssl/t1_lib.c                             |  51 +++--
 ssl/tls_depr.c                           |  17 ++
 test/certs/ee-cert-1024.pem              |  16 ++
 test/certs/ee-cert-3072.pem              |  22 ++
 test/certs/ee-cert-4096.pem              |  25 +++
 test/certs/ee-cert-8192.pem              |  35 +++
 test/certs/ee-key-1024.pem               |  16 ++
 test/certs/ee-key-3072.pem               |  40 ++++
 test/certs/ee-key-4096.pem               |  52 +++++
 test/certs/ee-key-8192.pem               | 100 +++++++++
 test/certs/setup.sh                      |  12 ++
 test/dtlstest.c                          |   3 +
 test/sslapitest.c                        | 359 ++++++++++++++++++++++++++++++-
 test/sslcorrupttest.c                    |   3 +-
 test/ssltest_old.c                       | 158 ++++++--------
 test/ssltestlib.c                        |   4 -
 util/libcrypto.num                       |  16 +-
 util/libssl.num                          |   6 +-
 util/missingmacro.txt                    |   2 -
 util/missingmacro111.txt                 |   2 -
 util/other.syms                          |   2 +
 35 files changed, 1122 insertions(+), 446 deletions(-)
 create mode 100644 test/certs/ee-cert-1024.pem
 create mode 100644 test/certs/ee-cert-3072.pem
 create mode 100644 test/certs/ee-cert-4096.pem
 create mode 100644 test/certs/ee-cert-8192.pem
 create mode 100644 test/certs/ee-key-1024.pem
 create mode 100644 test/certs/ee-key-3072.pem
 create mode 100644 test/certs/ee-key-4096.pem
 create mode 100644 test/certs/ee-key-8192.pem

diff --git a/CHANGES.md b/CHANGES.md
index 6e275f1d73..ca4e096ed2 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -23,6 +23,21 @@ OpenSSL 3.0
 
 ### Changes between 1.1.1 and 3.0 [xx XXX xxxx]
 
+ * The functions SSL_CTX_set_tmp_dh_callback and SSL_set_tmp_dh_callback, as
+   well as the macros SSL_CTX_set_tmp_dh() and SSL_set_tmp_dh() have been
+   deprecated. These are used to set the Diffie-Hellman (DH) parameters that
+   are to be used by servers requiring ephemeral DH keys. Instead applications
+   should consider using the built-in DH parameters that are available by
+   calling SSL_CTX_set_dh_auto() or SSL_set_dh_auto(). If custom parameters are
+   necessary then applications can use the alternative functions
+   SSL_CTX_set0_tmp_dh_pkey() and SSL_set0_tmp_dh_pkey(). There is no direct
+   replacement for the "callback" functions. The callback was originally useful
+   in order to have different parameters for export and non-export ciphersuites.
+   Export ciphersuites are no longer supported by OpenSSL. Use of the callback
+   functions should be replaced by one of the other methods described above.
+
+   *Matt Caswell*
+
  * The -crypt option to the passwd command line tool has been removed.
 
    *Paul Dale*
diff --git a/apps/s_server.c b/apps/s_server.c
index cd76ababe0..1e4bb4f639 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -21,6 +21,7 @@
 #include <openssl/e_os2.h>
 #include <openssl/async.h>
 #include <openssl/ssl.h>
+#include <openssl/decoder.h>
 
 #ifndef OPENSSL_NO_SOCK
 
@@ -71,9 +72,6 @@ static int generate_session_id(SSL *ssl, unsigned char *id,
                                unsigned int *id_len);
 static void init_session_cache_ctx(SSL_CTX *sctx);
 static void free_sessions(void);
-#ifndef OPENSSL_NO_DH
-static DH *load_dh_param(const char *dhfile);
-#endif
 static void print_connection_info(SSL *con);
 
 static const int bufsize = 16 * 1024;
@@ -982,9 +980,7 @@ const OPTIONS s_server_options[] = {
     {"use_srtp", OPT_SRTP_PROFILES, 's',
      "Offer SRTP key management with a colon-separated profile list"},
 #endif
-#ifndef OPENSSL_NO_DH
     {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"},
-#endif
 #ifndef OPENSSL_NO_NEXTPROTONEG
     {"nextprotoneg", OPT_NEXTPROTONEG, 's',
      "Set the advertised protocols for the NPN extension (comma-separated list)"},
@@ -1030,10 +1026,8 @@ int s_server_main(int argc, char *argv[])
 #endif
     do_server_cb server_cb;
     int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0;
-#ifndef OPENSSL_NO_DH
     char *dhfile = NULL;
     int no_dhe = 0;
-#endif
     int nocert = 0, ret = 1;
     int noCApath = 0, noCAfile = 0, noCAstore = 0;
     int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
@@ -1442,9 +1436,7 @@ int s_server_main(int argc, char *argv[])
             s_quiet = s_brief = verify_args.quiet = 1;
             break;
         case OPT_NO_DHE:
-#ifndef OPENSSL_NO_DH
             no_dhe = 1;
-#endif
             break;
         case OPT_NO_RESUME_EPHEMERAL:
             no_resume_ephemeral = 1;
@@ -2030,54 +2022,67 @@ int s_server_main(int argc, char *argv[])
     if (alpn_ctx.data)
         SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
 
-#ifndef OPENSSL_NO_DH
     if (!no_dhe) {
-        DH *dh = NULL;
+        EVP_PKEY *dhpkey = NULL;
 
         if (dhfile != NULL)
-            dh = load_dh_param(dhfile);
+            dhpkey = load_keyparams(dhfile, 0, "DH", "DH parameters");
         else if (s_cert_file != NULL)
-            dh = load_dh_param(s_cert_file);
+            dhpkey = load_keyparams(s_cert_file, 0, "DH", "DH parameters");
 
-        if (dh != NULL) {
+        if (dhpkey != NULL) {
             BIO_printf(bio_s_out, "Setting temp DH parameters\n");
         } else {
             BIO_printf(bio_s_out, "Using default temp DH parameters\n");
         }
         (void)BIO_flush(bio_s_out);
 
-        if (dh == NULL) {
+        if (dhpkey == NULL) {
             SSL_CTX_set_dh_auto(ctx, 1);
-        } else if (!SSL_CTX_set_tmp_dh(ctx, dh)) {
-            BIO_puts(bio_err, "Error setting temp DH parameters\n");
-            ERR_print_errors(bio_err);
-            DH_free(dh);
-            goto end;
+        } else {
+            /*
+             * We need 2 references: one for use by ctx and one for use by
+             * ctx2
+             */
+            if (!EVP_PKEY_up_ref(dhpkey)) {
+                EVP_PKEY_free(dhpkey);
+                goto end;
+            }
+            if (!SSL_CTX_set0_tmp_dh_pkey(ctx, dhpkey)) {
+                BIO_puts(bio_err, "Error setting temp DH parameters\n");
+                ERR_print_errors(bio_err);
+                /* Free 2 references */
+                EVP_PKEY_free(dhpkey);
+                EVP_PKEY_free(dhpkey);
+                goto end;
+            }
         }
 
         if (ctx2 != NULL) {
-            if (!dhfile) {
-                DH *dh2 = load_dh_param(s_cert_file2);
-                if (dh2 != NULL) {
+            if (dhfile != NULL) {
+                EVP_PKEY *dhpkey2 = load_keyparams(s_cert_file2, 0, "DH",
+                                                   "DH parameters");
+
+                if (dhpkey2 != NULL) {
                     BIO_printf(bio_s_out, "Setting temp DH parameters\n");
                     (void)BIO_flush(bio_s_out);
 
-                    DH_free(dh);
-                    dh = dh2;
+                    EVP_PKEY_free(dhpkey);
+                    dhpkey = dhpkey2;
                 }
             }
-            if (dh == NULL) {
+            if (dhpkey == NULL) {
                 SSL_CTX_set_dh_auto(ctx2, 1);
-            } else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) {
+            } else if (!SSL_CTX_set0_tmp_dh_pkey(ctx2, dhpkey)) {
                 BIO_puts(bio_err, "Error setting temp DH parameters\n");
                 ERR_print_errors(bio_err);
-                DH_free(dh);
+                EVP_PKEY_free(dhpkey);
                 goto end;
             }
+            dhpkey = NULL;
         }
-        DH_free(dh);
+        EVP_PKEY_free(dhpkey);
     }
-#endif
 
     if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
         goto end;
@@ -3003,21 +3008,6 @@ static void print_connection_info(SSL *con)
     (void)BIO_flush(bio_s_out);
 }
 
-#ifndef OPENSSL_NO_DH
-static DH *load_dh_param(const char *dhfile)
-{
-    DH *ret = NULL;
-    BIO *bio;
-
-    if ((bio = BIO_new_file(dhfile, "r")) == NULL)
-        goto err;
-    ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
- err:
-    BIO_free(bio);
-    return ret;
-}
-#endif
-
 static int www_body(int s, int stype, int prot, unsigned char *context)
 {
     char *buf = NULL;
diff --git a/crypto/bn/bn_dh.c b/crypto/bn/bn_dh.c
index 74ce024004..9f5b80cb8e 100644
--- a/crypto/bn/bn_dh.c
+++ b/crypto/bn/bn_dh.c
@@ -10,7 +10,6 @@
 #include "bn_local.h"
 #include "internal/nelem.h"
 
-#ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 # include "crypto/bn_dh.h"
 
@@ -1051,5 +1050,3 @@ make_dh_bn(modp_6144_p)
 make_dh_bn(modp_6144_q)
 make_dh_bn(modp_8192_p)
 make_dh_bn(modp_8192_q)
-
-#endif /* OPENSSL_NO_DH */
diff --git a/crypto/bn/build.info b/crypto/bn/build.info
index 093cbcc7f1..6164bba8c7 100644
--- a/crypto/bn/build.info
+++ b/crypto/bn/build.info
@@ -101,18 +101,12 @@ IF[{- !$disabled{asm} -}]
   ENDIF
 ENDIF
 
-IF[{- !$disabled{dh} -}]
-  $BNDH=bn_const.c
-ELSE
-  $BNDH=
-ENDIF
-
 $COMMON=bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c \
         bn_mod.c bn_conv.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
         bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_sqr.c \
         bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
         bn_x931p.c bn_intern.c bn_dh.c \
-        bn_rsa_fips186_4.c $BNDH
+        bn_rsa_fips186_4.c bn_const.c
 SOURCE[../../libcrypto]=$COMMON $BNASM bn_print.c bn_err.c bn_srp.c
 IF[{- !$disabled{'deprecated-3.0'} -}]
   SOURCE[../../libcrypto]=bn_depr.c
diff --git a/doc/man3/SSL_CTX_set_tmp_dh_callback.pod b/doc/man3/SSL_CTX_set_tmp_dh_callback.pod
index fe159bef1b..ac8dd391b2 100644
--- a/doc/man3/SSL_CTX_set_tmp_dh_callback.pod
+++ b/doc/man3/SSL_CTX_set_tmp_dh_callback.pod
@@ -2,7 +2,8 @@
 
 =head1 NAME
 
-SSL_CTX_set_tmp_dh_callback, SSL_CTX_set_tmp_dh,
+SSL_CTX_set_dh_auto, SSL_set_dh_auto, SSL_CTX_set0_tmp_dh_pkey,
+SSL_set0_tmp_dh_pkey, SSL_CTX_set_tmp_dh_callback, SSL_CTX_set_tmp_dh,
 SSL_set_tmp_dh_callback, SSL_set_tmp_dh
 - handle DH keys for ephemeral key exchange
 
@@ -10,6 +11,15 @@ SSL_set_tmp_dh_callback, SSL_set_tmp_dh
 
  #include <openssl/ssl.h>
 
+ long SSL_CTX_set_dh_auto(SSL *s, int onoff);
+ long SSL_set_dh_auto(SSL *s, int onoff);
+ int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey);
+ int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey);
+
+Deprecated since OpenSSL 3.0, can be hidden entirely by defining
+B<OPENSSL_API_COMPAT> with a suitable version value, see
+L<openssl_user_macros(7)>:
+
  void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
                                   DH *(*tmp_dh_callback)(SSL *ssl, int is_export,
                                                          int keylength));
@@ -22,33 +32,19 @@ SSL_set_tmp_dh_callback, SSL_set_tmp_dh
 
 =head1 DESCRIPTION
 
-SSL_CTX_set_tmp_dh_callback() sets the callback function for B<ctx> to be
-used when a DH parameters are required to B<tmp_dh_callback>.
-The callback is inherited by all B<ssl> objects created from B<ctx>.
-
-SSL_CTX_set_tmp_dh() sets DH parameters to be used to be B<dh>.
-The key is inherited by all B<ssl> objects created from B<ctx>.
-
-SSL_set_tmp_dh_callback() sets the callback only for B<ssl>.
+The functions described on this page are relevant for servers only.
 
-SSL_set_tmp_dh() sets the parameters only for B<ssl>.
+Some ciphersuites may use ephemeral Diffie-Hellman (DH) key exchange. In these
+cases, the session data is negotiated using the ephemeral/temporary DH key and
+the key supplied and certified by the certificate chain is only used for
+signing. Anonymous ciphers (without a permanent server key) also use ephemeral
+DH keys.
 
-These functions apply to SSL/TLS servers only.
-
-=head1 NOTES
-
-When using a cipher with RSA authentication, an ephemeral DH key exchange
-can take place. Ciphers with DSA keys always use ephemeral DH keys as well.
-In these cases, the session data are negotiated using the
-ephemeral/temporary DH key and the key supplied and certified
-by the certificate chain is only used for signing.
-Anonymous ciphers (without a permanent server key) also use ephemeral DH keys.
-
-Using ephemeral DH key exchange yields forward secrecy, as the connection
-can only be decrypted, when the DH key is known. By generating a temporary
+Using ephemeral DH key exchange yields forward secrecy as the connection
+can only be decrypted when the DH key is known. By generating a temporary
 DH key inside the server application that is lost when the application
 is left, it becomes impossible for an attacker to decrypt past sessions,
-even if he gets hold of the normal (certified) key, as this key was
+even if they get hold of the normal (certified) key, as this key was
 only used for signing.
 
 In order to perform a DH key exchange the server must use a DH group
@@ -56,59 +52,57 @@ In order to perform a DH key exchange the server must use a DH group
 a new DH key during the negotiation.
 
 As generating DH parameters is extremely time consuming, an application
-should not generate the parameters on the fly but supply the parameters.
-DH parameters can be reused, as the actual key is newly generated during
-the negotiation. The risk in reusing DH parameters is that an attacker
-may specialize on a very often used DH group. Applications should therefore
-generate their own DH parameters during the installation process using the
-openssl L<openssl-dhparam(1)> application. This application
-guarantees that "strong" primes are used.
-
-An application may either directly specify the DH parameters or
-can supply the DH parameters via a callback function.
-
-Previous versions of the callback used B<is_export> and B<keylength>
-parameters to control parameter generation for export and non-export
-cipher suites. Modern servers that do not support export cipher suites
-are advised to either use SSL_CTX_set_tmp_dh() or alternatively, use
-the callback but ignore B<keylength> and B<is_export> and simply
-supply at least 2048-bit parameters in the callback.
+should not generate the parameters on the fly. DH parameters can be reused, as
+the actual key is newly generated during the negotiation.
+
+Typically applications should use well know DH parameters that have built-in
+support in OpenSSL. The macros SSL_CTX_set_dh_auto() and SSL_set_dh_auto()
+configure OpenSSL to use the default built-in DH parameters for the B<SSL_CTX>
+and B<SSL> objects respectively. Passing a value of 1 in the I<onoff> parameter
+switches the feature on, and passing a value of 0 switches it off. The default
+setting is off.
+
+If "auto" DH parameters are switched on then the parameters will be selected to
+be consistent with the size of the key associated with the server's certificate.
+If there is no certificate (e.g. for PSK ciphersuites), then it it will be
+consistent with the size of the negotiated symmetric cipher key.
+
+Applications may supply their own DH parameters instead of using the built-in
+values. This approach is discouraged and applications should in preference use
+the built-in parameter support described above. Applications wishing to supply
+their own DH parameters should call SSL_CTX_set0_tmp_dh_pkey() or
+SSL_set0_tmp_dh_pkey() to supply the parameters for the B<SSL_CTX> or B<SSL>
+respectively. The parameters should be supplied in the I<dhpkey> argument as
+an B<EVP_PKEY> containg DH parameters. Ownership of the I<dhpkey> value is
+passed to the B<SSL_CTX> or B<SSL> object as a result of this call, and so the
+caller should not free it if the function call is succesful.
+
+The deprecated macros SSL_CTX_set_tmp_dh() and SSL_set_tmp_dh() do the same
+thing as SSL_CTX_set0_tmp_dh_pkey() and SSL_set0_tmp_dh_pkey() except that the
+DH parameters are supplied in a B<DH> object instead in the I<dh> argument, and
+ownership of the B<DH> object is retained by the application. Applications
+should use "auto" parameters instead, or call SSL_CTX_set0_tmp_dh_pkey() or
+SSL_set0_tmp_dh_pkey() as appropriate.
+
+An application may instead specify the DH parameters via a callback function
+using the functions SSL_CTX_set_tmp_dh_callback() or SSL_set_tmp_dh_callback()
+to set the callback for the B<SSL_CTX> or B<SSL> object respectively. These
+functions are deprecated. Applications should instead use "auto" parameters, or
+specify the parameters via SSL_CTX_set0_tmp_dh_pkey() or SSL_set0_tmp_dh_pkey()
+as appropriate.
+
+The callback will be invoked during a connection when DH parameters are
+required. The B<SSL> object for the current connection is supplied as an
+argument. Previous versions of OpenSSL used the B<is_export> and B<keylength>
+arguments to control parameter generation for export and non-export
+cipher suites. Modern OpenSSL does not support export ciphersuites and so these
+arguments are unused and can be ignored by the callback. The callback should
+return the parameters to be used in a DH object. Ownership of the DH object is
+retained by the application and should later be freed.
 
 =head1 RETURN VALUES
 
-SSL_CTX_set_tmp_dh_callback() and SSL_set_tmp_dh_callback() do not return
-diagnostic output.
-
-SSL_CTX_set_tmp_dh() and SSL_set_tmp_dh() do return 1 on success and 0
-on failure. Check the error queue to find out the reason of failure.
-
-=head1 EXAMPLES
-
-Setup DH parameters with a key length of 2048 bits. (Error handling
-partly left out.)
-
-Command-line parameter generation:
-
- $ openssl dhparam -out dh_param_2048.pem 2048
-
-Code for setting up parameters during server initialization:
-
- SSL_CTX ctx = SSL_CTX_new();
-
- DH *dh_2048 = NULL;
- FILE *paramfile = fopen("dh_param_2048.pem", "r");
-
- if (paramfile) {
-     dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
-     fclose(paramfile);
- } else {
-     /* Error. */
- }
- if (dh_2048 == NULL)
-     /* Error. */
- if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1)
-     /* Error. */
- ...
+All of these functions/macros return 1 for success or 0 on error.
 
 =head1 SEE ALSO
 
diff --git a/include/openssl/bn.h b/include/openssl/bn.h
index f3c8ab956b..9f019ba86e 100644
--- a/include/openssl/bn.h
+++ b/include/openssl/bn.h
@@ -527,7 +527,6 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
                           const BIGNUM *priv, const unsigned char *message,
                           size_t message_len, BN_CTX *ctx);
 
-# ifndef OPENSSL_NO_DH
 /* Primes from RFC 2409 */
 BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn);
 BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn);
@@ -550,7 +549,6 @@ BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn);
 #   define get_rfc3526_prime_6144 BN_get_rfc3526_prime_6144
 #   define get_rfc3526_prime_8192 BN_get_rfc3526_prime_8192
 #  endif
-# endif
 
 int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
 
diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in
index 8a86e2d24f..a02227be0c 100644
--- a/include/openssl/ssl.h.in
+++ b/include/openssl/ssl.h.in
@@ -1225,9 +1225,13 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 # define SSL_ERROR_WANT_ASYNC            9
 # define SSL_ERROR_WANT_ASYNC_JOB       10
 # define SSL_ERROR_WANT_CLIENT_HELLO_CB 11
-# define SSL_CTRL_SET_TMP_DH                     3
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+#  define SSL_CTRL_SET_TMP_DH                    3
+# endif
 # define SSL_CTRL_SET_TMP_ECDH                   4
-# define SSL_CTRL_SET_TMP_DH_CB                  6
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+#  define SSL_CTRL_SET_TMP_DH_CB                 6
+# endif
 # define SSL_CTRL_GET_CLIENT_CERT_REQUEST        9
 # define SSL_CTRL_GET_NUM_RENEGOTIATIONS         10
 # define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS       11
@@ -1351,14 +1355,18 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
         SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
 # define SSL_total_renegotiations(ssl) \
         SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
-# define SSL_CTX_set_tmp_dh(ctx,dh) \
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+#  define SSL_CTX_set_tmp_dh(ctx,dh) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh))
+# endif
 # define SSL_CTX_set_dh_auto(ctx, onoff) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL)
 # define SSL_set_dh_auto(s, onoff) \
         SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL)
-# define SSL_set_tmp_dh(ssl,dh) \
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+#  define SSL_set_tmp_dh(ssl,dh) \
         SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)(dh))
+# endif
 # ifndef OPENSSL_NO_DEPRECATED_3_0
 #  define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh))
@@ -1497,6 +1505,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 # define SSL_get_server_tmp_key(s, pk) \
          SSL_get_peer_tmp_key(s, pk)
 
+int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey);
+int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey);
+
 /*
  * The following symbol names are old and obsolete. They are kept
  * for compatibility reasons only and should not be used anymore.
@@ -2129,13 +2140,17 @@ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len);
 void SSL_set_default_read_buffer_len(SSL *s, size_t len);
 
 # ifndef OPENSSL_NO_DH
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
 /* NB: the |keylength| is only applicable when is_export is true */
+OSSL_DEPRECATEDIN_3_0
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
                                  DH *(*dh) (SSL *ssl, int is_export,
                                             int keylength));
+OSSL_DEPRECATEDIN_3_0
 void SSL_set_tmp_dh_callback(SSL *ssl,
                              DH *(*dh) (SSL *ssl, int is_export,
                                         int keylength));
+#  endif
 # endif
 
 __owur const COMP_METHOD *SSL_get_current_compression(const SSL *s);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 69949202a2..c2bdef6eae 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3451,29 +3451,20 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
     case SSL_CTRL_GET_FLAGS:
         ret = (int)(s->s3.flags);
         break;
-#ifndef OPENSSL_NO_DH
+#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
     case SSL_CTRL_SET_TMP_DH:
         {
-            DH *dh = (DH *)parg;
             EVP_PKEY *pkdh = NULL;
-            if (dh == NULL) {
+            if (parg == NULL) {
                 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
                 return 0;
             }
-            pkdh = ssl_dh_to_pkey(dh);
+            pkdh = ssl_dh_to_pkey(parg);
             if (pkdh == NULL) {
                 ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
                 return 0;
             }
-            if (!ssl_security(s, SSL_SECOP_TMP_DH,
-                              EVP_PKEY_security_bits(pkdh), 0, pkdh)) {
-                ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL);
-                EVP_PKEY_free(pkdh);
-                return 0;
-            }
-            EVP_PKEY_free(s->cert->dh_tmp);
-            s->cert->dh_tmp = pkdh;
-            return 1;
+            return SSL_set0_tmp_dh_pkey(s, pkdh);
         }
         break;
     case SSL_CTRL_SET_TMP_DH_CB:
@@ -3481,10 +3472,10 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
             ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return ret;
         }
+# endif
     case SSL_CTRL_SET_DH_AUTO:
         s->cert->dh_tmp_auto = larg;
         return 1;
-#endif
 #ifndef OPENSSL_NO_EC
     case SSL_CTRL_SET_TMP_ECDH:
         {
@@ -3776,22 +3767,21 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
     int ret = 0;
 
     switch (cmd) {
-#ifndef OPENSSL_NO_DH
+#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
     case SSL_CTRL_SET_TMP_DH_CB:
-        {
-            s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
-        }
+        s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
+        ret = 1;
         break;
 #endif
     case SSL_CTRL_SET_TLSEXT_DEBUG_CB:
         s->ext.debug_cb = (void (*)(SSL *, int, int,
                                     const unsigned char *, int, void *))fp;
+        ret = 1;
         break;
 
     case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
-        {
-            s->not_resumable_session_cb = (int (*)(SSL *, int))fp;
-        }
+        s->not_resumable_session_cb = (int (*)(SSL *, int))fp;
+        ret = 1;
         break;
     default:
         break;
@@ -3802,39 +3792,30 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
 long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
 {
     switch (cmd) {
-#ifndef OPENSSL_NO_DH
+#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
     case SSL_CTRL_SET_TMP_DH:
         {
-            DH *dh = (DH *)parg;
             EVP_PKEY *pkdh = NULL;
-            if (dh == NULL) {
+            if (parg == NULL) {
                 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
                 return 0;
             }
-            pkdh = ssl_dh_to_pkey(dh);
+            pkdh = ssl_dh_to_pkey(parg);
             if (pkdh == NULL) {
                 ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
                 return 0;
             }
-            if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
-                                  EVP_PKEY_security_bits(pkdh), 0, pkdh)) {
-                ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL);
-                EVP_PKEY_free(pkdh);
-                return 0;
-            }
-            EVP_PKEY_free(ctx->cert->dh_tmp);
-            ctx->cert->dh_tmp = pkdh;
-            return 1;
+            return SSL_CTX_set0_tmp_dh_pkey(ctx, pkdh);
         }
     case SSL_CTRL_SET_TMP_DH_CB:
         {
             ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return 0;
         }
+#endif
     case SSL_CTRL_SET_DH_AUTO:
         ctx->cert->dh_tmp_auto = larg;
         return 1;
-#endif
 #ifndef OPENSSL_NO_EC
     case SSL_CTRL_SET_TMP_ECDH:
         {
@@ -4046,7 +4027,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
 long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
 {
     switch (cmd) {
-#ifndef OPENSSL_NO_DH
+#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
     case SSL_CTRL_SET_TMP_DH_CB:
         {
             ctx->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
@@ -5009,18 +4990,3 @@ int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey,
     EVP_PKEY_CTX_free(pctx);
     return rv;
 }
-
-#ifndef OPENSSL_NO_DH
-EVP_PKEY *ssl_dh_to_pkey(DH *dh)
-{
-    EVP_PKEY *ret;
-    if (dh == NULL)
-        return NULL;
-    ret = EVP_PKEY_new();
-    if (EVP_PKEY_set1_DH(ret, dh) <= 0) {
-        EVP_PKEY_free(ret);
-        return NULL;
-    }
-    return ret;
-}
-#endif
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index ee56e681b4..4f085dd7e6 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -90,14 +90,15 @@ CERT *ssl_cert_dup(CERT *cert)
         OPENSSL_free(ret);
         return NULL;
     }
-#ifndef OPENSSL_NO_DH
+
     if (cert->dh_tmp != NULL) {
         ret->dh_tmp = cert->dh_tmp;
         EVP_PKEY_up_ref(ret->dh_tmp);
     }
+#ifndef OPENSSL_NO_DH
     ret->dh_tmp_cb = cert->dh_tmp_cb;
-    ret->dh_tmp_auto = cert->dh_tmp_auto;
 #endif
+    ret->dh_tmp_auto = cert->dh_tmp_auto;
 
     for (i = 0; i < SSL_PKEY_NUM; i++) {
         CERT_PKEY *cpk = cert->pkeys + i;
@@ -232,9 +233,7 @@ void ssl_cert_free(CERT *c)
         return;
     REF_ASSERT_ISNT(i < 0);
 
-#ifndef OPENSSL_NO_DH
     EVP_PKEY_free(c->dh_tmp);
-#endif
 
     ssl_cert_clear_certs(c);
     OPENSSL_free(c->conf_sigalgs);
diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c
index 96fddfd4cc..2e8240c73b 100644
--- a/ssl/ssl_conf.c
+++ b/ssl/ssl_conf.c
@@ -11,7 +11,8 @@
 #include "ssl_local.h"
 #include <openssl/conf.h>
 #include <openssl/objects.h>
-#include <openssl/dh.h>
+#include <openssl/decoder.h>
+#include <openssl/core_dispatch.h>
 #include "internal/nelem.h"
 
 /*
@@ -574,33 +575,51 @@ static int cmd_ClientCAStore(SSL_CONF_CTX *cctx, const char *value)
     return cmd_RequestCAStore(cctx, value);
 }
 
-#ifndef OPENSSL_NO_DH
 static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
 {
     int rv = 0;
-    DH *dh = NULL;
+    EVP_PKEY *dhpkey = NULL;
     BIO *in = NULL;
-    if (cctx->ctx || cctx->ssl) {
+    SSL_CTX *sslctx = (cctx->ssl != NULL) ? cctx->ssl->ctx : cctx->ctx;
+    OSSL_DECODER_CTX *decoderctx = NULL;
+
+    if (cctx->ctx != NULL || cctx->ssl != NULL) {
         in = BIO_new(BIO_s_file());
         if (in == NULL)
             goto end;
         if (BIO_read_filename(in, value) <= 0)
             goto end;
-        dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
-        if (dh == NULL)
+
+        decoderctx
+            = OSSL_DECODER_CTX_new_by_EVP_PKEY(&dhpkey, "PEM", NULL, "DH",
+                                               OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                                               sslctx->libctx, sslctx->propq);
+        if (decoderctx == NULL
+                || !OSSL_DECODER_from_bio(decoderctx, in)) {
+            OSSL_DECODER_CTX_free(decoderctx);
+            goto end;
+        }
+        OSSL_DECODER_CTX_free(decoderctx);
+
+        if (dhpkey == NULL)
             goto end;
-    } else
+    } else {
         return 1;
-    if (cctx->ctx)
-        rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
-    if (cctx->ssl)
-        rv = SSL_set_tmp_dh(cctx->ssl, dh);
+    }
+
+    if (cctx->ctx != NULL) {
+        if ((rv = SSL_CTX_set0_tmp_dh_pkey(cctx->ctx, dhpkey)) > 0)
+            dhpkey = NULL;
+    }
+    if (cctx->ssl != NULL) {
+        if ((rv = SSL_set0_tmp_dh_pkey(cctx->ssl, dhpkey)) > 0)
+            dhpkey = NULL;
+    }
  end:
-    DH_free(dh);
+    EVP_PKEY_free(dhpkey);
     BIO_free(in);
     return rv > 0;
 }
-#endif
 
 static int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value)
 {
@@ -726,11 +745,9 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
     SSL_CONF_CMD(ClientCAStore, NULL,
                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
                  SSL_CONF_TYPE_STORE),
-#ifndef OPENSSL_NO_DH
     SSL_CONF_CMD(DHParameters, "dhparam",
                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
                  SSL_CONF_TYPE_FILE),
-#endif
     SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
     SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER),
 };
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index d82baa5497..bb0eec9b5f 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3504,11 +3504,11 @@ void ssl_set_masks(SSL *s)
     if (c == NULL)
         return;
 
+    dh_tmp = (c->dh_tmp != NULL
 #ifndef OPENSSL_NO_DH
-    dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL || c->dh_tmp_auto);
-#else
-    dh_tmp = 0;
+              || c->dh_tmp_cb != NULL
 #endif
+              || c->dh_tmp_auto);
 
     rsa_enc = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID;
     rsa_sign = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID;
@@ -4487,7 +4487,7 @@ int SSL_want(const SSL *s)
  * \param dh the callback
  */
 
-#ifndef OPENSSL_NO_DH
+#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
                                  DH *(*dh) (SSL *ssl, int is_export,
                                             int keylength))
@@ -5955,3 +5955,29 @@ void ssl_evp_md_free(const EVP_MD *md)
         EVP_MD_free((EVP_MD *)md);
     }
 }
+
+int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey)
+{
+    if (!ssl_security(s, SSL_SECOP_TMP_DH,
+                      EVP_PKEY_security_bits(dhpkey), 0, dhpkey)) {
+        SSLerr(0, SSL_R_DH_KEY_TOO_SMALL);
+        EVP_PKEY_free(dhpkey);
+        return 0;
+    }
+    EVP_PKEY_free(s->cert->dh_tmp);
+    s->cert->dh_tmp = dhpkey;
+    return 1;
+}
+
+int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey)
+{
+    if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
+                          EVP_PKEY_security_bits(dhpkey), 0, dhpkey)) {
+        SSLerr(0, SSL_R_DH_KEY_TOO_SMALL);
+        EVP_PKEY_free(dhpkey);
+        return 0;
+    }
+    EVP_PKEY_free(ctx->cert->dh_tmp);
+    ctx->cert->dh_tmp = dhpkey;
+    return 1;
+}
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 5e47320d62..a14d97b8e9 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -2004,11 +2004,12 @@ typedef struct cert_st {
      * an index, not a pointer.
      */
     CERT_PKEY *key;
-# ifndef OPENSSL_NO_DH
+
     EVP_PKEY *dh_tmp;
+#ifndef OPENSSL_NO_DH
     DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize);
+#endif
     int dh_tmp_auto;
-# endif
     /* Flags related to certificates */
     uint32_t cert_flags;
     CERT_PKEY pkeys[SSL_PKEY_NUM];
@@ -2692,9 +2693,7 @@ void tls1_set_cert_validity(SSL *s);
 __owur int ssl_validate_ct(SSL *s);
 #  endif
 
-#  ifndef OPENSSL_NO_DH
-__owur DH *ssl_get_auto_dh(SSL *s);
-#  endif
+__owur EVP_PKEY *ssl_get_auto_dh(SSL *s);
 
 __owur int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee);
 __owur int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *ex,
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index eb88c37c5b..5b7b7cd5f5 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -23,6 +23,8 @@
 #include <openssl/bn.h>
 #include <openssl/engine.h>
 #include <openssl/trace.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
 #include <internal/cryptlib.h>
 
 static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt);
@@ -2010,14 +2012,13 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
 
 static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
 {
-#ifndef OPENSSL_NO_DH
     PACKET prime, generator, pub_key;
     EVP_PKEY *peer_tmp = NULL;
-
-    DH *dh = NULL;
     BIGNUM *p = NULL, *g = NULL, *bnpub_key = NULL;
-
-    int check_bits = 0;
+    EVP_PKEY_CTX *pctx = NULL;
+    OSSL_PARAM *params = NULL;
+    OSSL_PARAM_BLD *tmpl = NULL;
+    int ret = 0;
 
     if (!PACKET_get_length_prefixed_2(pkt, &prime)
         || !PACKET_get_length_prefixed_2(pkt, &generator)
@@ -2026,14 +2027,6 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
         return 0;
     }
 
-    peer_tmp = EVP_PKEY_new();
-    dh = DH_new();
-
-    if (peer_tmp == NULL || dh == NULL) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
-        goto err;
-    }
-
     /* TODO(size_t): Convert these calls */
     p = BN_bin2bn(PACKET_data(&prime), (int)PACKET_remaining(&prime), NULL);
     g = BN_bin2bn(PACKET_data(&generator), (int)PACKET_remaining(&generator),
@@ -2045,34 +2038,36 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
         goto err;
     }
 
-    /* test non-zero pubkey */
-    if (BN_is_zero(bnpub_key)) {
-        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE);
-        goto err;
-    }
-
-    if (!DH_set0_pqg(dh, p, NULL, g)) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BN_LIB);
+    tmpl = OSSL_PARAM_BLD_new();
+    if (tmpl == NULL
+            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
+            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g)
+            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
+                                       bnpub_key)
+            || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
         goto err;
     }
-    p = g = NULL;
 
-    if (DH_check_params(dh, &check_bits) == 0 || check_bits != 0) {
-        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE);
+    pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq);
+    if (pctx == NULL) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
         goto err;
     }
-
-    if (!DH_set0_key(dh, bnpub_key, NULL)) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BN_LIB);
+    if (EVP_PKEY_key_fromdata_init(pctx) <= 0
+            || EVP_PKEY_fromdata(pctx, &peer_tmp, params) <= 0) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_DH_VALUE);
         goto err;
     }
-    bnpub_key = NULL;
 
-    if (EVP_PKEY_assign_DH(peer_tmp, dh) == 0) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
+    EVP_PKEY_CTX_free(pctx);
+    pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, peer_tmp, s->ctx->propq);
+    if (pctx == NULL
+            || EVP_PKEY_param_check(pctx) != 1
+            || EVP_PKEY_public_check(pctx) != 1) {
+        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE);
         goto err;
     }
-    dh = NULL;
 
     if (!ssl_security(s, SSL_SECOP_TMP_DH, EVP_PKEY_security_bits(peer_tmp),
                       0, peer_tmp)) {
@@ -2081,6 +2076,7 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
     }
 
     s->s3.peer_tmp = peer_tmp;
+    peer_tmp = NULL;
 
     /*
      * FIXME: This makes assumptions about which ciphersuites come with
@@ -2090,20 +2086,18 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
         *pkey = X509_get0_pubkey(s->session->peer);
     /* else anonymous DH, so no certificate or pkey. */
 
-    return 1;
+    ret = 1;
 
  err:
+    OSSL_PARAM_BLD_free(tmpl);
+    OSSL_PARAM_BLD_free_params(params);
+    EVP_PKEY_free(peer_tmp);
+    EVP_PKEY_CTX_free(pctx);
     BN_free(p);
     BN_free(g);
     BN_free(bnpub_key);
-    DH_free(dh);
-    EVP_PKEY_free(peer_tmp);
 
-    return 0;
-#else
-    SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-    return 0;
-#endif
+    return ret;
 }
 
 static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
@@ -2899,11 +2893,12 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt)
 
 static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt)
 {
-#ifndef OPENSSL_NO_DH
-    DH *dh_clnt = NULL;
     EVP_PKEY *ckey = NULL, *skey = NULL;
     unsigned char *keybytes = NULL;
     int prime_len;
+    unsigned char *encoded_pub = NULL;
+    size_t encoded_pub_len, pad_len;
+    int ret = 0;
 
     skey = s->s3.peer_tmp;
     if (skey == NULL) {
@@ -2917,41 +2912,46 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt)
         goto err;
     }
 
-    dh_clnt = EVP_PKEY_get0_DH(ckey);
-
-    if (dh_clnt == NULL) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-        goto err;
-    }
-
     if (ssl_derive(s, ckey, skey, 0) == 0) {
         /* SSLfatal() already called */
         goto err;
     }
 
     /* send off the data */
-    prime_len = BN_num_bytes(DH_get0_p(dh_clnt));
+
+    /* Generate encoding of server key */
+    encoded_pub_len = EVP_PKEY_get1_encoded_public_key(ckey, &encoded_pub);
+    if (encoded_pub_len == 0) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+        EVP_PKEY_free(skey);
+        return EXT_RETURN_FAIL;
+    }
+
     /*
      * For interoperability with some versions of the Microsoft TLS
      * stack, we need to zero pad the DHE pub key to the same length
-     * as the prime, so use the length of the prime here.
+     * as the prime.
      */
-    if (!WPACKET_sub_allocate_bytes_u16(pkt, prime_len, &keybytes)
-            || BN_bn2binpad(DH_get0_pub_key(dh_clnt), keybytes, prime_len) < 0) {
+    prime_len = EVP_PKEY_size(ckey);
+    pad_len = prime_len - encoded_pub_len;
+    if (pad_len > 0) {
+        if (!WPACKET_sub_allocate_bytes_u16(pkt, pad_len, &keybytes)) {
+            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+        memset(keybytes, 0, pad_len);
+    }
+
+    if (!WPACKET_sub_memcpy_u16(pkt, encoded_pub, encoded_pub_len)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
         goto err;
     }
 
-    EVP_PKEY_free(ckey);
-
-    return 1;
+    ret = 1;
  err:
+    OPENSSL_free(encoded_pub);
     EVP_PKEY_free(ckey);
-    return 0;
-#else
-    SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-    return 0;
-#endif
+    return ret;
 }
 
 static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt)
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index 9d5e73f62c..c478c5a7e8 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -2418,9 +2418,7 @@ int tls_construct_server_done(SSL *s, WPACKET *pkt)
 
 int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
 {
-#ifndef OPENSSL_NO_DH
     EVP_PKEY *pkdh = NULL;
-#endif
 #ifndef OPENSSL_NO_EC
     unsigned char *encodedPoint = NULL;
     size_t encodedlen = 0;
@@ -2429,10 +2427,11 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
     const SIGALG_LOOKUP *lu = s->s3.tmp.sigalg;
     int i;
     unsigned long type;
-    const BIGNUM *r[4];
+    BIGNUM *r[4];
     EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
     EVP_PKEY_CTX *pctx = NULL;
     size_t paramlen, paramoffset;
+    int freer = 0, ret = 0;
 
     if (!WPACKET_get_total_written(pkt, &paramoffset)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
@@ -2452,35 +2451,30 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
     if (type & (SSL_kPSK | SSL_kRSAPSK)) {
     } else
 #endif                          /* !OPENSSL_NO_PSK */
-#ifndef OPENSSL_NO_DH
     if (type & (SSL_kDHE | SSL_kDHEPSK)) {
         CERT *cert = s->cert;
-
         EVP_PKEY *pkdhp = NULL;
-        DH *dh;
 
         if (s->cert->dh_tmp_auto) {
-            DH *dhp = ssl_get_auto_dh(s);
-            pkdh = EVP_PKEY_new();
-            if (pkdh == NULL || dhp == NULL) {
-                DH_free(dhp);
+            pkdh = ssl_get_auto_dh(s);
+            if (pkdh == NULL) {
                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
-            EVP_PKEY_assign_DH(pkdh, dhp);
             pkdhp = pkdh;
         } else {
             pkdhp = cert->dh_tmp;
         }
+#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
         if ((pkdhp == NULL) && (s->cert->dh_tmp_cb != NULL)) {
-            DH *dhp = s->cert->dh_tmp_cb(s, 0, 1024);
-            pkdh = ssl_dh_to_pkey(dhp);
+            pkdh = ssl_dh_to_pkey(s->cert->dh_tmp_cb(s, 0, 1024));
             if (pkdh == NULL) {
                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             pkdhp = pkdh;
         }
+#endif
         if (pkdhp == NULL) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_TMP_DH_KEY);
             goto err;
@@ -2501,19 +2495,21 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
             goto err;
         }
 
-        dh = EVP_PKEY_get0_DH(s->s3.tmp.pkey);
-        if (dh == NULL) {
-            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-            goto err;
-        }
-
         EVP_PKEY_free(pkdh);
         pkdh = NULL;
 
-        DH_get0_pqg(dh, &r[0], NULL, &r[1]);
-        DH_get0_key(dh, &r[2], NULL);
+        /* These BIGNUMs need to be freed when we're finished */
+        freer = 1;
+        if (!EVP_PKEY_get_bn_param(s->s3.tmp.pkey, OSSL_PKEY_PARAM_FFC_P,
+                                   &r[0])
+                || !EVP_PKEY_get_bn_param(s->s3.tmp.pkey, OSSL_PKEY_PARAM_FFC_G,
+                                          &r[1])
+                || !EVP_PKEY_get_bn_param(s->s3.tmp.pkey,
+                                          OSSL_PKEY_PARAM_PUB_KEY, &r[2])) {
+            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
     } else
-#endif
 #ifndef OPENSSL_NO_EC
     if (type & (SSL_kECDHE | SSL_kECDHEPSK)) {
 
@@ -2615,7 +2611,6 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
             goto err;
         }
 
-#ifndef OPENSSL_NO_DH
         /*-
          * for interoperability with some versions of the Microsoft TLS
          * stack, we need to zero pad the DHE pub key to the same length
@@ -2632,7 +2627,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
                 memset(binval, 0, len);
             }
         }
-#endif
+
         if (!WPACKET_allocate_bytes(pkt, BN_num_bytes(r[i]), &binval)
                 || !WPACKET_close(pkt)) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
@@ -2718,17 +2713,20 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
         OPENSSL_free(tbs);
     }
 
-    EVP_MD_CTX_free(md_ctx);
-    return 1;
+    ret = 1;
  err:
-#ifndef OPENSSL_NO_DH
     EVP_PKEY_free(pkdh);
-#endif
 #ifndef OPENSSL_NO_EC
     OPENSSL_free(encodedPoint);
 #endif
     EVP_MD_CTX_free(md_ctx);
-    return 0;
+    if (freer) {
+        BN_free(r[0]);
+        BN_free(r[1]);
+        BN_free(r[2]);
+        BN_free(r[3]);
+    }
+    return ret;
 }
 
 int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
@@ -2960,11 +2958,8 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt)
 
 static int tls_process_cke_dhe(SSL *s, PACKET *pkt)
 {
-#ifndef OPENSSL_NO_DH
     EVP_PKEY *skey = NULL;
-    DH *cdh;
     unsigned int i;
-    BIGNUM *pub_key;
     const unsigned char *data;
     EVP_PKEY *ckey = NULL;
     int ret = 0;
@@ -2994,11 +2989,8 @@ static int tls_process_cke_dhe(SSL *s, PACKET *pkt)
         goto err;
     }
 
-    cdh = EVP_PKEY_get0_DH(ckey);
-    pub_key = BN_bin2bn(data, i, NULL);
-    if (pub_key == NULL || cdh == NULL || !DH_set0_key(cdh, pub_key, NULL)) {
+    if (!EVP_PKEY_set1_encoded_public_key(ckey, data, i)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-        BN_free(pub_key);
         goto err;
     }
 
@@ -3013,11 +3005,6 @@ static int tls_process_cke_dhe(SSL *s, PACKET *pkt)
  err:
     EVP_PKEY_free(ckey);
     return ret;
-#else
-    /* Should never happen */
-    SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-    return 0;
-#endif
 }
 
 static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt)
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index ff80b81167..9089cb8086 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -19,6 +19,7 @@
 #include <openssl/dh.h>
 #include <openssl/bn.h>
 #include <openssl/provider.h>
+#include <openssl/param_build.h>
 #include "internal/nelem.h"
 #include "internal/evp.h"
 #include "internal/tlsgroups.h"
@@ -2873,12 +2874,15 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
     return tls1_check_chain(s, x, pk, chain, -1);
 }
 
-#ifndef OPENSSL_NO_DH
-DH *ssl_get_auto_dh(SSL *s)
+EVP_PKEY *ssl_get_auto_dh(SSL *s)
 {
-    DH *dhp;
-    BIGNUM *p, *g;
+    EVP_PKEY *dhp = NULL;
+    BIGNUM *p;
     int dh_secbits = 80;
+    EVP_PKEY_CTX *pctx = NULL;
+    OSSL_PARAM_BLD *tmpl = NULL;
+    OSSL_PARAM *params = NULL;
+
     if (s->cert->dh_tmp_auto != 2) {
         if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
             if (s->s3.tmp.new_cipher->strength_bits == 256)
@@ -2892,15 +2896,6 @@ DH *ssl_get_auto_dh(SSL *s)
         }
     }
 
-    dhp = DH_new();
-    if (dhp == NULL)
-        return NULL;
-    g = BN_new();
-    if (g == NULL || !BN_set_word(g, 2)) {
-        DH_free(dhp);
-        BN_free(g);
-        return NULL;
-    }
     if (dh_secbits >= 192)
         p = BN_get_rfc3526_prime_8192(NULL);
     else if (dh_secbits >= 152)
@@ -2911,15 +2906,31 @@ DH *ssl_get_auto_dh(SSL *s)
         p = BN_get_rfc3526_prime_2048(NULL);
     else
         p = BN_get_rfc2409_prime_1024(NULL);
-    if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) {
-        DH_free(dhp);
-        BN_free(p);
-        BN_free(g);
-        return NULL;
-    }
+    if (p == NULL)
+        goto err;
+
+    pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq);
+    if (pctx == NULL
+            || EVP_PKEY_key_fromdata_init(pctx) != 1)
+        goto err;
+
+    tmpl = OSSL_PARAM_BLD_new();
+    if (tmpl == NULL
+            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
+            || !OSSL_PARAM_BLD_push_uint(tmpl, OSSL_PKEY_PARAM_FFC_G, 2))
+        goto err;
+
+    params = OSSL_PARAM_BLD_to_param(tmpl);
+    if (params == NULL || EVP_PKEY_fromdata(pctx, &dhp, params) != 1)
+        goto err;
+
+err:
+    OSSL_PARAM_BLD_free_params(params);
+    OSSL_PARAM_BLD_free(tmpl);
+    EVP_PKEY_CTX_free(pctx);
+    BN_free(p);
     return dhp;
 }
-#endif
 
 static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op)
 {
diff --git a/ssl/tls_depr.c b/ssl/tls_depr.c
index 3fcc5b6740..6f2103ad91 100644
--- a/ssl/tls_depr.c
+++ b/ssl/tls_depr.c
@@ -142,5 +142,22 @@ HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx)
 {
     return ctx->old_ctx;
 }
+
+/* Some deprecated public APIs pass DH objects */
+# ifndef OPENSSL_NO_DH
+EVP_PKEY *ssl_dh_to_pkey(DH *dh)
+{
+    EVP_PKEY *ret;
+
+    if (dh == NULL)
+        return NULL;
+    ret = EVP_PKEY_new();
+    if (EVP_PKEY_set1_DH(ret, dh) <= 0) {
+        EVP_PKEY_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+# endif
 #endif
 
diff --git a/test/certs/ee-cert-1024.pem b/test/certs/ee-cert-1024.pem
new file mode 100644
index 0000000000..0d97ca461d
--- /dev/null
+++ b/test/certs/ee-cert-1024.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICnDCCAYSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg
+Fw0yMDEwMzAxMTMwMzdaGA8yMTIwMTAzMTExMzAzN1owGTEXMBUGA1UEAwwOc2Vy
+dmVyLmV4YW1wbGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMF7WhfgK/SV
+sZuatHn3zm/MBe70jdr6zoRozB5M/1NmbVdsltVk1F0A5QERefKT0ri6SxYaYq/D
+3dtIo/y0koeMh7pmdRj4wPmoD2rty2P3vnGLfla51VMrsXvVbYr+f2AQ7Y0DFwwU
+E1R/bnL3gRnJhAjg48ac0nKKYEAmM9vFAgMBAAGjfTB7MB0GA1UdDgQWBBR95tKu
+5TTscTOTJQSZ089kbmnKKjAfBgNVHSMEGDAWgBS0ETPx1+Je91OeICIQT4YGvx/J
+XjAJBgNVHRMEAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBkGA1UdEQQSMBCCDnNl
+cnZlci5leGFtcGxlMA0GCSqGSIb3DQEBCwUAA4IBAQB2cVVWl8qqyTakCb0xMeB+
+8kq1fKBGlNvnngfPsV9zgHn5eoqRNyvsUeOALTz3rJXnmcQnhzDoGVKzmHDXHKrI
+WfiDegb9cXEKWkOQhmuUspTh+Y2ata4pMRllU3ry9rKY97ZapSwezLvV/fRLpZeK
+9gFyFKXAa/oUtEis9lu13TZ/CZT1NKOz2hC3VAybArQkOWl+cy5VSaV473O1s8oR
+SZ66SsY5x5iWUzAA0ECA9cTk8eiVNvhQekNB4QlcAMJGbHAEHab6MjcghzljkmJ9
+1hFnLXkRArqXTPP33UWUvhkL4Le5YHdeS8aBRhflOKnc+bHLX2y1uS/AZhcaNPQE
+-----END CERTIFICATE-----
diff --git a/test/certs/ee-cert-3072.pem b/test/certs/ee-cert-3072.pem
new file mode 100644
index 0000000000..c018267e55
--- /dev/null
+++ b/test/certs/ee-cert-3072.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDoDCCAoigAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg
+Fw0yMDEwMzAxMTMwMzhaGA8yMTIwMTAzMTExMzAzOFowGTEXMBUGA1UEAwwOc2Vy
+dmVyLmV4YW1wbGUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCX3qH/
++MSc4mzbdaOIobBDJ4s4+NGOTpA7k6D6th54CgD6CbJFULLdmb1ZLZUd0PUxVpoV
+S8mUS70uJX+xSodgee4OliI3dJpaaLdtr8SUWmOIryPK6SElOuRFNtAiv5dwX3Gg
+bcK5R9G9MFnRmdSfMFmPpTKQXi3KzN8GCeV0CY2CqpHTPcMSLFckPLS0vXX532mK
+wQMj4Lt16qNRYUTllxyp8U4wHjy8dc0aLm7/fkexZYEyxceCqxfV7JXlQkbeSHMQ
+1Wby7bL78xrwmEQpQHYxG8kkvtEN1drBkNUPM7PXrT0pT+yZdDhn9hWEoYYgUQVe
+lWr8zaDpFDjDK64vpAl/hqEmxvvKKXcRM6AL8S40csQfMLQYzKVaDMFF+D/ZYbIW
+STQ++ipv8Czo7jIB0W/6CBxRvU/gJAQnfjDU3NPaSsC5d5LF5nPKPMRjP9O1jNBd
+pOpf2X2gWNBr+9fldpuFRvEYIx273FPyR/VgBDOONYx2gd1LqyFD6Z2/gWkCAwEA
+AaN9MHswHQYDVR0OBBYEFPbCRavcThg3gkDURzgxXBst3XYRMB8GA1UdIwQYMBaA
+FLQRM/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQCMAAwEwYDVR0lBAwwCgYIKwYB
+BQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1wbGUwDQYJKoZIhvcNAQELBQAD
+ggEBACdi4db3A97eMsFQBo4Mut5TXtJvYhnKNspUKwKIaRiue4Sk6B5TJvfonXji
+YIPCH+B0U2imwXcY9H5YwyjfGCzECCK8v+HgYJmp3NETVD3JcIt6a3qDjKl7ad7e
+m+08U/yWDOB9Hb9/tjmNyPMx4ttrhnsvTMwtEafYod0hTsDpyGpz0icjE6GrX/Y4
+7dBIzXiJBEMl+Uo22hdGwe5+6tHhHxz3R9XDxF58k6SDI04DCrh3w4SKBqGcZMTD
+lP0ra70NlDh+93thJIyxyAR2QyJDD9Bc429rbqBFbfNdDCvecWzzWLqg8JixhwNd
+60w1dz3OhCHbnBeY6gdoLAfsTqc=
+-----END CERTIFICATE-----
diff --git a/test/certs/ee-cert-4096.pem b/test/certs/ee-cert-4096.pem
new file mode 100644
index 0000000000..9ea1aba322
--- /dev/null
+++ b/test/certs/ee-cert-4096.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg
+Fw0yMDEwMjkxNjQ1MjFaGA8yMTIwMTAzMDE2NDUyMVowGTEXMBUGA1UEAwwOc2Vy
+dmVyLmV4YW1wbGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLvapx
+pa2O+SD5omABQRE9kRg34LRXcTi2Kqc2d1J8yEF+aPXcNj3gtKJ9dgMkrWEPbG7z
+RtpmbIgxr9O7e0Z4j7KziPjmhb9Rr39YtqKmH0zsqk9l1umI3Y+SYBN02qReUxcZ
+9OP2z6W5KNDhXp2H5n73Ol3iNGhlXz+OaxMricOyagwMKkvKXtoYa6U+04yrP1a+
+ud3itNEFNpGxW5blGGH15Bgylsqq3An+bJkCUE038/NIM1tYRDcFbxjJ1QZ4OeAM
+cc6AcjiPlMgYfs4JJFb7FahtgZlDnC7217eMFBbMde7SNaj0XcTt7P0I8tX91Bo7
+PqQtGWZzFQWE4nKY5Drvv0yvhhlixzXC+r1x5EKrWvc75EKr1RQkTNUyXhUMM5DA
+SI6pT1Tx0iWzG8konzRQ9EQXMDVVwlLmaNPgZTU0qgaGRMHdEgf8KYoh6fM9WRH4
+K8cKrthZenORwANg1SE3uXFFk86gE2Q6XyMIjK9xl/g8FA3hdM4NelVOw7IAdYEf
+0taAGygmHRcUS8UYX/8aBACp6RDyYeXS9/57SBm+aCdAaiy2TZgUl889zF7chXCA
+wUGk4rV0NtA6RYKwKJCR1nXccg0c2kDR+WZHFwqWLCKVtO18eMeCFdhyenuvYAtu
+ObWvluu/d6wu6+tS3nmRE1htNkgMNSTY4j+8+wIDAQABo30wezAdBgNVHQ4EFgQU
+h6+wtpPcwlG/dUr1BUrSi2b6dRYwHwYDVR0jBBgwFoAUtBEz8dfiXvdTniAiEE+G
+Br8fyV4wCQYDVR0TBAIwADATBgNVHSUEDDAKBggrBgEFBQcDATAZBgNVHREEEjAQ
+gg5zZXJ2ZXIuZXhhbXBsZTANBgkqhkiG9w0BAQsFAAOCAQEAaTmowdWbVDzRxQJJ
+0x0p6PjSkM/CHnBSZkgpAV1M5YwtVdH3xyaiP3r1sj/4BG3MGJXvbEeYoxy22V+R
+/pJNe/2mJ9rUNG6ZRTbEYXVKh61KoxCjmpDUU/z3hVYXN/MBNY0GEU0mpt9JoBwX
+su3Op3IOQid5itlvFQ1SVQnGLSks/eLKxioa+igMWLPuvDWHCGWTbQZ7jjOLBG9h
+kD1Xnm2QvIgDGHV9E5+bRjck0f1I1wq/DOpYP4Cg5caJlAWCn391p6r1YVB/Hs3X
+2uLQTtgeOKLtpDqhuvIriT0KTidm+NkAnbcxuLnJVlqa8XEx2P256juk9ce68CND
+n8e4xA==
+-----END CERTIFICATE-----
diff --git a/test/certs/ee-cert-8192.pem b/test/certs/ee-cert-8192.pem
new file mode 100644
index 0000000000..4c23a4bf8b
--- /dev/null
+++ b/test/certs/ee-cert-8192.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+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
+-----END CERTIFICATE-----
diff --git a/test/certs/ee-key-1024.pem b/test/certs/ee-key-1024.pem
new file mode 100644
index 0000000000..ae53c1dec4
--- /dev/null
+++ b/test/certs/ee-key-1024.pem
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMF7WhfgK/SVsZua
+tHn3zm/MBe70jdr6zoRozB5M/1NmbVdsltVk1F0A5QERefKT0ri6SxYaYq/D3dtI
+o/y0koeMh7pmdRj4wPmoD2rty2P3vnGLfla51VMrsXvVbYr+f2AQ7Y0DFwwUE1R/
+bnL3gRnJhAjg48ac0nKKYEAmM9vFAgMBAAECgYAQTifqiS7LHu5n0aLSAIs6KrR5
+TczCno5W5EoHZ6/AxIoEaxdPBn9LEy85ZtKjGcgRX0nCpBia/WOt/jIrssACXMAN
+896k5PQVeA0ngaru/1nUlQDmNRZIhg5igQ5NGu3GzSsAdRrylDHIfOOgfYGpF4po
+DUr3C41rNu3l2K14RQJBAO6pxDNnlg5s1sxStLGb1w641mcuBgWroigu1GE6khrj
+Fwt8AWeIozyaDvln5ZRf9d7T1o+/fFXsKVHMBRObswMCQQDPiWI/ofyPht8h4nZq
+y4oF9Aq3yENypTCyWlk9ANvQ49F7pjfYZa5cz4AUsMjB6Vn/8MiCmSB9evJLq7Hw
+GBeXAkEA45id9G+aWBNPG/bbPmzhP7bhL/Bh6dJth2hxPG+AmYdqmJcfN77D/Kzm
+Ds4Xz9FbRa469UakqcPW+5xWUwauRQJABfJz5ErqB9rfjgMFTa4jeGQz4mxUsnZV
+XOcF45+grO26VQbAVu0i//naO72NIzFiqNjnhgaJTc82HkD/SlgGZQJAY5hpFMnl
+dG32dM26PsroXaXzgdfAnH9sBjmVV6gapM+O5wHBA30kvOb3ADp7CgAWH/I0xucY
+HaAbZ6gFL8le+g==
+-----END PRIVATE KEY-----
diff --git a/test/certs/ee-key-3072.pem b/test/certs/ee-key-3072.pem
new file mode 100644
index 0000000000..b0cdacb4af
--- /dev/null
+++ b/test/certs/ee-key-3072.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+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
+uvykSnGTciZF/7JrWgG28GD+
+-----END PRIVATE KEY-----
diff --git a/test/certs/ee-key-4096.pem b/test/certs/ee-key-4096.pem
new file mode 100644
index 0000000000..be076e696d
--- /dev/null
+++ b/test/certs/ee-key-4096.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+Jo4wAiS72oydZ4JQ82eli3BipOQa6w==
+-----END PRIVATE KEY-----
diff --git a/test/certs/ee-key-8192.pem b/test/certs/ee-key-8192.pem
new file mode 100644
index 0000000000..febc0a15e3
--- /dev/null
+++ b/test/certs/ee-key-8192.pem
@@ -0,0 +1,100 @@
+-----BEGIN PRIVATE KEY-----
+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
+DGbpgiDY22rJfsfOSuuto687FIjKyo5T
+-----END PRIVATE KEY-----
diff --git a/test/certs/setup.sh b/test/certs/setup.sh
index eb7f77e231..dbc2fc71be 100755
--- a/test/certs/setup.sh
+++ b/test/certs/setup.sh
@@ -196,6 +196,18 @@ OPENSSL_KEYBITS=768 \
 # EC cert with named curve signed by named curve ca
 ./mkcert.sh genee server.example ee-key-ec-named-named \
     ee-cert-ec-named-named ca-key-ec-named ca-cert-ec-named
+# 1024-bit leaf key
+OPENSSL_KEYBITS=1024 \
+./mkcert.sh genee server.example ee-key-1024 ee-cert-1024 ca-key ca-cert
+# 3072-bit leaf key
+OPENSSL_KEYBITS=3072 \
+./mkcert.sh genee server.example ee-key-3072 ee-cert-3072 ca-key ca-cert
+# 4096-bit leaf key
+OPENSSL_KEYBITS=4096 \
+./mkcert.sh genee server.example ee-key-4096 ee-cert-4096 ca-key ca-cert
+# 8192-bit leaf key
+OPENSSL_KEYBITS=8192 \
+./mkcert.sh genee server.example ee-key-8192 ee-cert-8192 ca-key ca-cert
 
 # self-signed end-entity cert with explicit keyUsage not including KeyCertSign
 openssl req -new -x509 -key ee-key.pem -subj /CN=ee-self-signed -out ee-self-signed.pem -addext keyUsage=digitalSignature -days 36500
diff --git a/test/dtlstest.c b/test/dtlstest.c
index 1ac2850fd7..efdf842e2d 100644
--- a/test/dtlstest.c
+++ b/test/dtlstest.c
@@ -162,6 +162,9 @@ static int test_dtls_drop_records(int idx)
                                        &sctx, &cctx, cert, privkey)))
         return 0;
 
+    if (!TEST_true(SSL_CTX_set_dh_auto(sctx, 1)))
+        goto end;
+
     if (idx >= TOTAL_FULL_HAND_RECORDS) {
         /* We're going to do a resumption handshake. Get a session first. */
         if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
diff --git a/test/sslapitest.c b/test/sslapitest.c
index b87b07e270..19421947de 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -30,6 +30,7 @@
 #include <openssl/core_names.h>
 #include <openssl/core_dispatch.h>
 #include <openssl/provider.h>
+#include <openssl/param_build.h>
 
 #include "ssltestlib.h"
 #include "testutil.h"
@@ -74,6 +75,14 @@ static char *cert = NULL;
 static char *privkey = NULL;
 static char *cert2 = NULL;
 static char *privkey2 = NULL;
+static char *cert1024 = NULL;
+static char *privkey1024 = NULL;
+static char *cert3072 = NULL;
+static char *privkey3072 = NULL;
+static char *cert4096 = NULL;
+static char *privkey4096 = NULL;
+static char *cert8192 = NULL;
+static char *privkey8192 = NULL;
 static char *srpvfile = NULL;
 static char *tmpfilename = NULL;
 
@@ -6374,6 +6383,9 @@ static int test_info_callback(int tst)
                                        privkey)))
         goto end;
 
+    if (!TEST_true(SSL_CTX_set_dh_auto(sctx, 1)))
+        goto end;
+
     /*
      * For even numbered tests we check the server callbacks. For odd numbers we
      * check the client.
@@ -8045,7 +8057,305 @@ static int test_ssl_dup(void)
 
     return testresult;
 }
-#endif
+
+# ifndef OPENSSL_NO_DH
+
+static EVP_PKEY *tmp_dh_params = NULL;
+
+/* Helper function for the test_set_tmp_dh() tests */
+static EVP_PKEY *get_tmp_dh_params(void)
+{
+    if (tmp_dh_params == NULL) {
+        BIGNUM *p = NULL;
+        OSSL_PARAM_BLD *tmpl = NULL;
+        EVP_PKEY_CTX *pctx = NULL;
+        OSSL_PARAM *params = NULL;
+        EVP_PKEY *dhpkey = NULL;
+
+        p = BN_get_rfc3526_prime_2048(NULL);
+        if (!TEST_ptr(p))
+            goto end;
+
+        pctx = EVP_PKEY_CTX_new_from_name(libctx, "DH", NULL);
+        if (!TEST_ptr(pctx)
+                || !TEST_true(EVP_PKEY_key_fromdata_init(pctx)))
+            goto end;
+
+        tmpl = OSSL_PARAM_BLD_new();
+        if (!TEST_ptr(tmpl)
+                || !TEST_true(OSSL_PARAM_BLD_push_BN(tmpl,
+                                                        OSSL_PKEY_PARAM_FFC_P,
+                                                        p))
+                || !TEST_true(OSSL_PARAM_BLD_push_uint(tmpl,
+                                                        OSSL_PKEY_PARAM_FFC_G,
+                                                        2)))
+            goto end;
+
+        params = OSSL_PARAM_BLD_to_param(tmpl);
+        if (!TEST_ptr(params)
+                || !TEST_true(EVP_PKEY_fromdata(pctx, &dhpkey, params)))
+            goto end;
+
+        tmp_dh_params = dhpkey;
+    end:
+        BN_free(p);
+        EVP_PKEY_CTX_free(pctx);
+        OSSL_PARAM_BLD_free(tmpl);
+        OSSL_PARAM_BLD_free_params(params);
+    }
+
+    if (!EVP_PKEY_up_ref(tmp_dh_params))
+        return NULL;
+
+    return tmp_dh_params;
+}
+
+#  ifndef OPENSSL_NO_DEPRECATED
+/* Callback used by test_set_tmp_dh() */
+static DH *tmp_dh_callback(SSL *s, int is_export, int keylen)
+{
+    EVP_PKEY *dhpkey = get_tmp_dh_params();
+    DH *ret = NULL;
+
+    if (!TEST_ptr(dhpkey))
+        return NULL;
+
+    ret = EVP_PKEY_get0_DH(dhpkey);
+
+    EVP_PKEY_free(dhpkey);
+
+    return ret;
+}
+#  endif
+
+/*
+ * Test the various methods for setting temporary DH parameters
+ *
+ * Test  0: Default (no auto) setting
+ * Test  1: Explicit SSL_CTX auto off
+ * Test  2: Explicit SSL auto off
+ * Test  3: Explicit SSL_CTX auto on
+ * Test  4: Explicit SSL auto on
+ * Test  5: Explicit SSL_CTX auto off, custom DH params via EVP_PKEY
+ * Test  6: Explicit SSL auto off, custom DH params via EVP_PKEY
+ *
+ * The following are testing deprecated APIs, so we only run them if available
+ * Test  7: Explicit SSL_CTX auto off, custom DH params via DH
+ * Test  8: Explicit SSL auto off, custom DH params via DH
+ * Test  9: Explicit SSL_CTX auto off, custom DH params via callback
+ * Test 10: Explicit SSL auto off, custom DH params via callback
+ */
+static int test_set_tmp_dh(int idx)
+{
+    SSL_CTX *cctx = NULL, *sctx = NULL;
+    SSL *clientssl = NULL, *serverssl = NULL;
+    int testresult = 0;
+    int dhauto = (idx == 3 || idx == 4) ? 1 : 0;
+    int expected = (idx <= 2) ? 0 : 1;
+    EVP_PKEY *dhpkey = NULL;
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+    DH *dh = NULL;
+#  else
+
+    if (idx >= 7)
+        return 1;
+#  endif
+
+    if (idx >= 5 && idx <= 8) {
+        dhpkey = get_tmp_dh_params();
+        if (!TEST_ptr(dhpkey))
+            goto end;
+    }
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+    if (idx == 7 || idx == 8) {
+        dh = EVP_PKEY_get0_DH(dhpkey);
+        if (!TEST_ptr(dh))
+            goto end;
+    }
+#  endif
+
+    if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+                                       TLS_client_method(),
+                                       0,
+                                       0,
+                                       &sctx, &cctx, cert, privkey)))
+        goto end;
+
+    if ((idx & 1) == 1) {
+        if (!TEST_true(SSL_CTX_set_dh_auto(sctx, dhauto)))
+            goto end;
+    }
+
+    if (idx == 5) {
+        if (!TEST_true(SSL_CTX_set0_tmp_dh_pkey(sctx, dhpkey)))
+            goto end;
+        dhpkey = NULL;
+    }
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+    else if (idx == 7) {
+        if (!TEST_true(SSL_CTX_set_tmp_dh(sctx, dh)))
+            goto end;
+    } else if (idx == 9) {
+        SSL_CTX_set_tmp_dh_callback(sctx, tmp_dh_callback);
+    }
+#  endif
+
+    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+                                      NULL, NULL)))
+        goto end;
+
+    if ((idx & 1) == 0 && idx != 0) {
+        if (!TEST_true(SSL_set_dh_auto(serverssl, dhauto)))
+            goto end;
+    }
+    if (idx == 6) {
+        if (!TEST_true(SSL_set0_tmp_dh_pkey(serverssl, dhpkey)))
+            goto end;
+        dhpkey = NULL;
+    }
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+    else if (idx == 8) {
+        if (!TEST_true(SSL_set_tmp_dh(serverssl, dh)))
+            goto end;
+    } else if (idx == 10) {
+        SSL_set_tmp_dh_callback(serverssl, tmp_dh_callback);
+    }
+#  endif
+
+    if (!TEST_true(SSL_set_min_proto_version(serverssl, TLS1_2_VERSION))
+            || !TEST_true(SSL_set_max_proto_version(serverssl, TLS1_2_VERSION))
+            || !TEST_true(SSL_set_cipher_list(serverssl, "DHE-RSA-AES128-SHA")))
+        goto end;
+
+    /*
+     * If autoon then we should succeed. Otherwise we expect failure because
+     * there are no parameters
+     */
+    if (!TEST_int_eq(create_ssl_connection(serverssl, clientssl,
+                                           SSL_ERROR_NONE), expected))
+        goto end;
+
+    testresult = 1;
+
+ end:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+    EVP_PKEY_free(dhpkey);
+
+    return testresult;
+}
+
+/*
+ * Test the auto DH keys are appropriately sized
+ */
+static int test_dh_auto(int idx)
+{
+    SSL_CTX *cctx = NULL, *sctx = NULL;
+    SSL *clientssl = NULL, *serverssl = NULL;
+    int testresult = 0;
+    EVP_PKEY *tmpkey = NULL;
+    char *thiscert = NULL, *thiskey = NULL;
+    size_t expdhsize = 0;
+    const char *ciphersuite = "DHE-RSA-AES128-SHA";
+
+    switch (idx) {
+    case 0:
+        /* The FIPS provider doesn't support this DH size - so we ignore it */
+        if (is_fips)
+            return 1;
+        thiscert = cert1024;
+        thiskey = privkey1024;
+        expdhsize = 1024;
+        break;
+    case 1:
+        /* 2048 bit prime */
+        thiscert = cert;
+        thiskey = privkey;
+        expdhsize = 2048;
+        break;
+    case 2:
+        thiscert = cert3072;
+        thiskey = privkey3072;
+        expdhsize = 3072;
+        break;
+    case 3:
+        thiscert = cert4096;
+        thiskey = privkey4096;
+        expdhsize = 4096;
+        break;
+    case 4:
+        thiscert = cert8192;
+        thiskey = privkey8192;
+        expdhsize = 8192;
+        break;
+    /* No certificate cases */
+    case 5:
+        /* The FIPS provider doesn't support this DH size - so we ignore it */
+        if (is_fips)
+            return 1;
+        ciphersuite = "ADH-AES128-SHA256:@SECLEVEL=0";
+        expdhsize = 1024;
+        break;
+    case 6:
+        ciphersuite = "ADH-AES256-SHA256:@SECLEVEL=0";
+        expdhsize = 3072;
+        break;
+    default:
+        TEST_error("Invalid text index");
+        goto end;
+    }
+
+    if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+                                       TLS_client_method(),
+                                       0,
+                                       0,
+                                       &sctx, &cctx, thiscert, thiskey)))
+        goto end;
+
+    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+                                      NULL, NULL)))
+        goto end;
+
+    if (!TEST_true(SSL_set_dh_auto(serverssl, 1))
+            || !TEST_true(SSL_set_min_proto_version(serverssl, TLS1_2_VERSION))
+            || !TEST_true(SSL_set_max_proto_version(serverssl, TLS1_2_VERSION))
+            || !TEST_true(SSL_set_cipher_list(serverssl, ciphersuite))
+            || !TEST_true(SSL_set_cipher_list(clientssl, ciphersuite)))
+        goto end;
+
+    /*
+     * Send the server's first flight. At this point the server has created the
+     * temporary DH key but hasn't finished using it yet. Once used it is
+     * removed, so we cannot test it.
+     */
+    if (!TEST_int_le(SSL_connect(clientssl), 0)
+            || !TEST_int_le(SSL_accept(serverssl), 0))
+        goto end;
+
+    if (!TEST_int_gt(SSL_get_tmp_key(serverssl, &tmpkey), 0))
+        goto end;
+    if (!TEST_size_t_eq(EVP_PKEY_bits(tmpkey), expdhsize))
+        goto end;
+
+    if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+        goto end;
+
+    testresult = 1;
+
+ end:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+    EVP_PKEY_free(tmpkey);
+
+    return testresult;
+
+}
+# endif /* OPENSSL_NO_DH */
+#endif /* OPENSSL_NO_TLS1_2 */
 
 OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config\n")
 
@@ -8136,6 +8446,38 @@ int setup_tests(void)
     if (privkey2 == NULL)
         goto err;
 
+    cert1024 = test_mk_file_path(certsdir, "ee-cert-1024.pem");
+    if (cert1024 == NULL)
+        goto err;
+
+    privkey1024 = test_mk_file_path(certsdir, "ee-key-1024.pem");
+    if (privkey1024 == NULL)
+        goto err;
+
+    cert3072 = test_mk_file_path(certsdir, "ee-cert-3072.pem");
+    if (cert3072 == NULL)
+        goto err;
+
+    privkey3072 = test_mk_file_path(certsdir, "ee-key-3072.pem");
+    if (privkey3072 == NULL)
+        goto err;
+
+    cert4096 = test_mk_file_path(certsdir, "ee-cert-4096.pem");
+    if (cert4096 == NULL)
+        goto err;
+
+    privkey4096 = test_mk_file_path(certsdir, "ee-key-4096.pem");
+    if (privkey4096 == NULL)
+        goto err;
+
+    cert8192 = test_mk_file_path(certsdir, "ee-cert-8192.pem");
+    if (cert8192 == NULL)
+        goto err;
+
+    privkey8192 = test_mk_file_path(certsdir, "ee-key-8192.pem");
+    if (privkey8192 == NULL)
+        goto err;
+
 #if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK)
 # if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3)
     ADD_ALL_TESTS(test_ktls, 32);
@@ -8252,6 +8594,10 @@ int setup_tests(void)
 #endif
 #ifndef OPENSSL_NO_TLS1_2
     ADD_TEST(test_ssl_dup);
+# ifndef OPENSSL_NO_DH
+    ADD_ALL_TESTS(test_set_tmp_dh, 11);
+    ADD_ALL_TESTS(test_dh_auto, 7);
+# endif
 #endif
     return 1;
 
@@ -8265,10 +8611,21 @@ int setup_tests(void)
 
 void cleanup_tests(void)
 {
+# ifndef OPENSSL_NO_DH
+    EVP_PKEY_free(tmp_dh_params);
+#endif
     OPENSSL_free(cert);
     OPENSSL_free(privkey);
     OPENSSL_free(cert2);
     OPENSSL_free(privkey2);
+    OPENSSL_free(cert1024);
+    OPENSSL_free(privkey1024);
+    OPENSSL_free(cert3072);
+    OPENSSL_free(privkey3072);
+    OPENSSL_free(cert4096);
+    OPENSSL_free(privkey4096);
+    OPENSSL_free(cert8192);
+    OPENSSL_free(privkey8192);
     bio_s_mempacket_test_free();
     bio_s_always_retry_free();
     OSSL_PROVIDER_unload(defctxnull);
diff --git a/test/sslcorrupttest.c b/test/sslcorrupttest.c
index ca9e8bfd73..97d235c8ad 100644
--- a/test/sslcorrupttest.c
+++ b/test/sslcorrupttest.c
@@ -202,7 +202,8 @@ static int test_ssl_corrupt(int testidx)
                                        &sctx, &cctx, cert, privkey)))
         return 0;
 
-    if (!TEST_true(SSL_CTX_set_cipher_list(cctx, cipher_list[testidx]))
+    if (!TEST_true(SSL_CTX_set_dh_auto(sctx, 1))
+            || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher_list[testidx]))
             || !TEST_true(SSL_CTX_set_ciphersuites(cctx, ""))
             || !TEST_ptr(ciphers = SSL_CTX_get_ciphers(cctx))
             || !TEST_int_eq(sk_SSL_CIPHER_num(ciphers), 1)
diff --git a/test/ssltest_old.c b/test/ssltest_old.c
index 8368bd2409..df88385042 100644
--- a/test/ssltest_old.c
+++ b/test/ssltest_old.c
@@ -9,12 +9,6 @@
  * https://www.openssl.org/source/license.html
  */
 
-/*
- * DH low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
 #include "e_os.h"
 
 /* Or gethostname won't be declared properly on Linux and GNU platforms. */
@@ -58,14 +52,13 @@
 #ifndef OPENSSL_NO_DSA
 # include <openssl/dsa.h>
 #endif
-#ifndef OPENSSL_NO_DH
-# include <openssl/dh.h>
-#endif
 #include <openssl/bn.h>
 #ifndef OPENSSL_NO_CT
 # include <openssl/ct.h>
 #endif
 #include <openssl/provider.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
 
 /*
  * Or gethostname won't be declared properly
@@ -98,11 +91,9 @@ struct app_verify_arg {
     int app_verify;
 };
 
-#ifndef OPENSSL_NO_DH
-static DH *get_dh512(void);
-static DH *get_dh1024(void);
-static DH *get_dh1024dsa(void);
-#endif
+static EVP_PKEY *get_dh512(OSSL_LIB_CTX *libctx);
+static EVP_PKEY *get_dh1024(OSSL_LIB_CTX *libctx);
+static EVP_PKEY *get_dh1024dsa(OSSL_LIB_CTX *libctx);
 
 static char *psk_key = NULL;    /* by default PSK is not used */
 #ifndef OPENSSL_NO_PSK
@@ -641,7 +632,6 @@ static void sv_usage(void)
     fprintf(stderr, " -num <val>    - number of connections to perform\n");
     fprintf(stderr,
             " -bytes <val>  - number of bytes to swap between client/server\n");
-#ifndef OPENSSL_NO_DH
     fprintf(stderr,
             " -dhe512       - use 512 bit key for DHE (to test failure)\n");
     fprintf(stderr,
@@ -649,7 +639,6 @@ static void sv_usage(void)
     fprintf(stderr,
             " -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
     fprintf(stderr, " -no_dhe       - disable DHE\n");
-#endif
 #ifndef OPENSSL_NO_EC
     fprintf(stderr, " -no_ecdhe     - disable ECDHE\nTODO(openssl-team): no_ecdhe was broken by auto ecdh. Make this work again.\n");
 #endif
@@ -899,11 +888,13 @@ int main(int argc, char *argv[])
     int should_reuse = -1;
     int no_ticket = 0;
     long bytes = 256L;
-#ifndef OPENSSL_NO_DH
-    DH *dh;
+    EVP_PKEY *dhpkey;
     int dhe512 = 0, dhe1024dsa = 0;
-#endif
+#ifndef OPENSSL_NO_DH
     int no_dhe = 0;
+#else
+    int no_dhe = 1;
+#endif
     int no_psk = 0;
     int print_time = 0;
     clock_t s_time = 0, c_time = 0;
@@ -988,19 +979,9 @@ int main(int argc, char *argv[])
         else if (strcmp(*argv, "-reuse") == 0)
             reuse = 1;
         else if (strcmp(*argv, "-dhe512") == 0) {
-#ifndef OPENSSL_NO_DH
             dhe512 = 1;
-#else
-            fprintf(stderr,
-                    "ignoring -dhe512, since I'm compiled without DH\n");
-#endif
         } else if (strcmp(*argv, "-dhe1024dsa") == 0) {
-#ifndef OPENSSL_NO_DH
             dhe1024dsa = 1;
-#else
-            fprintf(stderr,
-                    "ignoring -dhe1024dsa, since I'm compiled without DH\n");
-#endif
         } else if (strcmp(*argv, "-no_dhe") == 0)
             no_dhe = 1;
         else if (strcmp(*argv, "-no_ecdhe") == 0)
@@ -1505,21 +1486,22 @@ int main(int argc, char *argv[])
         ERR_print_errors(bio_err);
         goto end;
     }
-#ifndef OPENSSL_NO_DH
     if (!no_dhe) {
         if (dhe1024dsa) {
-            dh = get_dh1024dsa();
+            dhpkey = get_dh1024dsa(libctx);
         } else if (dhe512)
-            dh = get_dh512();
+            dhpkey = get_dh512(libctx);
         else
-            dh = get_dh1024();
-        SSL_CTX_set_tmp_dh(s_ctx, dh);
-        SSL_CTX_set_tmp_dh(s_ctx2, dh);
-        DH_free(dh);
+            dhpkey = get_dh1024(libctx);
+        if (dhpkey == NULL || !EVP_PKEY_up_ref(dhpkey)) {
+            EVP_PKEY_free(dhpkey);
+            BIO_puts(bio_err, "Error getting DH parameters\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        SSL_CTX_set0_tmp_dh_pkey(s_ctx, dhpkey);
+        SSL_CTX_set0_tmp_dh_pkey(s_ctx2, dhpkey);
     }
-#else
-    (void)no_dhe;
-#endif
 
     if (!(SSL_CTX_load_verify_file(s_ctx, CAfile)
           || SSL_CTX_load_verify_dir(s_ctx, CApath))
@@ -2901,15 +2883,44 @@ static int app_verify_callback(X509_STORE_CTX *ctx, void *arg)
     return ok;
 }
 
-#ifndef OPENSSL_NO_DH
-/*-
- * These DH parameters have been generated as follows:
- *    $ openssl dhparam -C -noout 512
- *    $ openssl dhparam -C -noout 1024
- *    $ openssl dhparam -C -noout -dsaparam 1024
- * (The third function has been renamed to avoid name conflicts.)
- */
-static DH *get_dh512(void)
+static EVP_PKEY *get_dh_from_pg(OSSL_LIB_CTX *libctx, unsigned char *pdata,
+                                size_t plen, unsigned char *gdata, size_t glen)
+{
+    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(libctx, "DH", NULL);
+    OSSL_PARAM_BLD *tmpl = NULL;
+    OSSL_PARAM *params = NULL;
+    EVP_PKEY *dhpkey = NULL;
+    BIGNUM *p = NULL, *g = NULL;
+
+    if (pctx == NULL || !EVP_PKEY_key_fromdata_init(pctx))
+        goto err;
+
+    p = BN_bin2bn(pdata, plen, NULL);
+    g = BN_bin2bn(gdata, glen, NULL);
+    if (p == NULL || g == NULL)
+        goto err;
+
+    tmpl = OSSL_PARAM_BLD_new();
+    if (tmpl == NULL
+            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
+            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
+        goto err;
+
+    params = OSSL_PARAM_BLD_to_param(tmpl);
+    if (params == NULL || !EVP_PKEY_fromdata(pctx, &dhpkey, params))
+        goto err;
+
+ err:
+    BN_free(p);
+    BN_free(g);
+    EVP_PKEY_CTX_free(pctx);
+    OSSL_PARAM_BLD_free_params(params);
+    OSSL_PARAM_BLD_free(tmpl);
+    return dhpkey;
+}
+
+/* These DH parameters were generated using the dhparam command line app */
+static EVP_PKEY *get_dh512(OSSL_LIB_CTX *libctx)
 {
     static unsigned char dh512_p[] = {
         0xCB, 0xC8, 0xE1, 0x86, 0xD0, 0x1F, 0x94, 0x17, 0xA6, 0x99, 0xF0,
@@ -2927,23 +2938,12 @@ static DH *get_dh512(void)
     static unsigned char dh512_g[] = {
         0x02,
     };
-    DH *dh;
-    BIGNUM *p, *g;
 
-    if ((dh = DH_new()) == NULL)
-        return NULL;
-    p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
-    g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
-    if ((p == NULL) || (g == NULL) || !DH_set0_pqg(dh, p, NULL, g)) {
-        DH_free(dh);
-        BN_free(p);
-        BN_free(g);
-        return NULL;
-    }
-    return dh;
+    return get_dh_from_pg(libctx, dh512_p, sizeof(dh512_p), dh512_g,
+                          sizeof(dh512_g));
 }
 
-static DH *get_dh1024(void)
+static EVP_PKEY *get_dh1024(OSSL_LIB_CTX *libctx)
 {
     static unsigned char dh1024_p[] = {
         0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF,
@@ -2971,23 +2971,12 @@ static DH *get_dh1024(void)
     static unsigned char dh1024_g[] = {
         0x02,
     };
-    DH *dh;
-    BIGNUM *p, *g;
 
-    if ((dh = DH_new()) == NULL)
-        return NULL;
-    p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
-    g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
-    if ((p == NULL) || (g == NULL) || !DH_set0_pqg(dh, p, NULL, g)) {
-        DH_free(dh);
-        BN_free(p);
-        BN_free(g);
-        return NULL;
-    }
-    return dh;
+    return get_dh_from_pg(libctx, dh1024_p, sizeof(dh1024_p), dh1024_g,
+                          sizeof(dh1024_g));
 }
 
-static DH *get_dh1024dsa(void)
+static EVP_PKEY *get_dh1024dsa(OSSL_LIB_CTX *libctx)
 {
     static unsigned char dh1024_p[] = {
         0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5,
@@ -3035,23 +3024,10 @@ static DH *get_dh1024dsa(void)
         0x60,
         0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2,
     };
-    DH *dh;
-    BIGNUM *p, *g;
 
-    if ((dh = DH_new()) == NULL)
-        return NULL;
-    p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
-    g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
-    if ((p == NULL) || (g == NULL) || !DH_set0_pqg(dh, p, NULL, g)) {
-        DH_free(dh);
-        BN_free(p);
-        BN_free(g);
-        return NULL;
-    }
-    DH_set_length(dh, 160);
-    return dh;
+    return get_dh_from_pg(libctx, dh1024_p, sizeof(dh1024_p), dh1024_g,
+                          sizeof(dh1024_g));
 }
-#endif
 
 #ifndef OPENSSL_NO_PSK
 /* convert the PSK key (psk_key) in ascii to binary (psk) */
diff --git a/test/ssltestlib.c b/test/ssltestlib.c
index 734d1e936b..1fbe51763b 100644
--- a/test/ssltestlib.c
+++ b/test/ssltestlib.c
@@ -731,10 +731,6 @@ const SSL_METHOD *cm,
             goto err;
     }
 
-#ifndef OPENSSL_NO_DH
-    SSL_CTX_set_dh_auto(serverctx, 1);
-#endif
-
     *sctx = serverctx;
     if (cctx != NULL)
         *cctx = clientctx;
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 0f7dcb2b26..a5baf503e1 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -214,7 +214,7 @@ s2i_ASN1_OCTET_STRING                   217	3_0_0	EXIST::FUNCTION:
 POLICYINFO_it                           218	3_0_0	EXIST::FUNCTION:
 OBJ_create                              219	3_0_0	EXIST::FUNCTION:
 d2i_NOTICEREF                           220	3_0_0	EXIST::FUNCTION:
-BN_get_rfc2409_prime_768                221	3_0_0	EXIST::FUNCTION:DH
+BN_get_rfc2409_prime_768                221	3_0_0	EXIST::FUNCTION:
 PEM_read_bio_PKCS8                      222	3_0_0	EXIST::FUNCTION:
 X509_ATTRIBUTE_new                      223	3_0_0	EXIST::FUNCTION:
 ASN1_STRING_TABLE_cleanup               224	3_0_0	EXIST::FUNCTION:
@@ -483,7 +483,7 @@ BN_GF2m_mod_sqr_arr                     492	3_0_0	EXIST::FUNCTION:EC2M
 ASN1_PRINTABLESTRING_it                 493	3_0_0	EXIST::FUNCTION:
 BIO_f_cipher                            494	3_0_0	EXIST::FUNCTION:
 UI_destroy_method                       495	3_0_0	EXIST::FUNCTION:
-BN_get_rfc3526_prime_3072               496	3_0_0	EXIST::FUNCTION:DH
+BN_get_rfc3526_prime_3072               496	3_0_0	EXIST::FUNCTION:
 X509_INFO_new                           497	3_0_0	EXIST::FUNCTION:
 OCSP_RESPDATA_it                        498	3_0_0	EXIST::FUNCTION:OCSP
 X509_CRL_print                          499	3_0_0	EXIST::FUNCTION:
@@ -618,7 +618,7 @@ d2i_DSA_PUBKEY_fp                       633	3_0_0	EXIST::FUNCTION:DSA,STDIO
 OCSP_REQ_CTX_nbio_d2i                   634	3_0_0	EXIST::FUNCTION:
 d2i_X509_REQ_fp                         635	3_0_0	EXIST::FUNCTION:STDIO
 DH_OpenSSL                              636	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0,DH
-BN_get_rfc3526_prime_8192               637	3_0_0	EXIST::FUNCTION:DH
+BN_get_rfc3526_prime_8192               637	3_0_0	EXIST::FUNCTION:
 X509_REVOKED_it                         638	3_0_0	EXIST::FUNCTION:
 CRYPTO_THREAD_write_lock                639	3_0_0	EXIST::FUNCTION:
 X509V3_NAME_from_section                640	3_0_0	EXIST::FUNCTION:
@@ -888,7 +888,7 @@ EVP_read_pw_string                      909	3_0_0	EXIST::FUNCTION:
 i2d_ASN1_NULL                           910	3_0_0	EXIST::FUNCTION:
 DES_encrypt1                            911	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0,DES
 BN_mod_lshift1_quick                    912	3_0_0	EXIST::FUNCTION:
-BN_get_rfc3526_prime_6144               913	3_0_0	EXIST::FUNCTION:DH
+BN_get_rfc3526_prime_6144               913	3_0_0	EXIST::FUNCTION:
 OBJ_obj2txt                             914	3_0_0	EXIST::FUNCTION:
 UI_set_result                           915	3_0_0	EXIST::FUNCTION:
 EVP_EncodeUpdate                        916	3_0_0	EXIST::FUNCTION:
@@ -2129,7 +2129,7 @@ TS_RESP_CTX_set_accuracy                2174	3_0_0	EXIST::FUNCTION:TS
 NETSCAPE_SPKI_get_pubkey                2175	3_0_0	EXIST::FUNCTION:
 ECDSA_do_sign_ex                        2176	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0,EC
 OCSP_ONEREQ_get_ext                     2177	3_0_0	EXIST::FUNCTION:OCSP
-BN_get_rfc3526_prime_4096               2179	3_0_0	EXIST::FUNCTION:DH
+BN_get_rfc3526_prime_4096               2179	3_0_0	EXIST::FUNCTION:
 d2i_PKCS7_fp                            2180	3_0_0	EXIST::FUNCTION:STDIO
 PEM_write_bio_NETSCAPE_CERT_SEQUENCE    2181	3_0_0	EXIST::FUNCTION:
 PKCS12_AUTHSAFES_it                     2182	3_0_0	EXIST::FUNCTION:
@@ -2471,7 +2471,7 @@ BN_GF2m_mod_div                         2522	3_0_0	EXIST::FUNCTION:EC2M
 i2d_USERNOTICE                          2523	3_0_0	EXIST::FUNCTION:
 d2i_NETSCAPE_SPKI                       2524	3_0_0	EXIST::FUNCTION:
 CRYPTO_mem_leaks                        2525	3_0_0	EXIST::FUNCTION:CRYPTO_MDEBUG,DEPRECATEDIN_3_0
-BN_get_rfc3526_prime_1536               2526	3_0_0	EXIST::FUNCTION:DH
+BN_get_rfc3526_prime_1536               2526	3_0_0	EXIST::FUNCTION:
 DSA_sign                                2527	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0,DSA
 RAND_egd                                2528	3_0_0	EXIST::FUNCTION:EGD
 ASN1_d2i_bio                            2529	3_0_0	EXIST::FUNCTION:
@@ -2579,7 +2579,7 @@ ASIdentifierChoice_it                   2633	3_0_0	EXIST::FUNCTION:RFC3779
 CMS_RecipientEncryptedKey_cert_cmp      2634	3_0_0	EXIST::FUNCTION:CMS
 EVP_PKEY_CTX_get_app_data               2635	3_0_0	EXIST::FUNCTION:
 EC_GROUP_clear_free                     2636	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0,EC
-BN_get_rfc2409_prime_1024               2637	3_0_0	EXIST::FUNCTION:DH
+BN_get_rfc2409_prime_1024               2637	3_0_0	EXIST::FUNCTION:
 CRYPTO_set_mem_functions                2638	3_0_0	EXIST::FUNCTION:
 i2d_ASN1_VISIBLESTRING                  2639	3_0_0	EXIST::FUNCTION:
 d2i_PBKDF2PARAM                         2640	3_0_0	EXIST::FUNCTION:
@@ -3374,7 +3374,7 @@ EVP_EncodeFinal                         3444	3_0_0	EXIST::FUNCTION:
 X509_set_ex_data                        3445	3_0_0	EXIST::FUNCTION:
 ERR_get_next_error_library              3446	3_0_0	EXIST::FUNCTION:
 OCSP_RESPONSE_print                     3447	3_0_0	EXIST::FUNCTION:OCSP
-BN_get_rfc3526_prime_2048               3448	3_0_0	EXIST::FUNCTION:DH
+BN_get_rfc3526_prime_2048               3448	3_0_0	EXIST::FUNCTION:
 BIO_new_bio_pair                        3449	3_0_0	EXIST::FUNCTION:
 EC_GFp_nistp256_method                  3450	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0,EC,EC_NISTP_64_GCC_128
 BIO_method_type                         3451	3_0_0	EXIST::FUNCTION:
diff --git a/util/libssl.num b/util/libssl.num
index 193be1b7a1..75e45bb17f 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -16,7 +16,7 @@ SSL_get_verify_depth                    16	3_0_0	EXIST::FUNCTION:
 SSL_get0_dane                           17	3_0_0	EXIST::FUNCTION:
 SSL_CTX_sess_get_get_cb                 18	3_0_0	EXIST::FUNCTION:
 SSL_CTX_get_default_passwd_cb_userdata  19	3_0_0	EXIST::FUNCTION:
-SSL_set_tmp_dh_callback                 20	3_0_0	EXIST::FUNCTION:DH
+SSL_set_tmp_dh_callback                 20	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0,DH
 SSL_CTX_get_verify_depth                21	3_0_0	EXIST::FUNCTION:
 SSL_CTX_use_RSAPrivateKey_file          22	3_0_0	EXIST::FUNCTION:RSA
 SSL_use_PrivateKey_file                 23	3_0_0	EXIST::FUNCTION:
@@ -152,7 +152,7 @@ i2d_SSL_SESSION                         152	3_0_0	EXIST::FUNCTION:
 SSL_SESSION_get_master_key              153	3_0_0	EXIST::FUNCTION:
 SSL_COMP_get_compression_methods        154	3_0_0	EXIST::FUNCTION:
 SSL_CTX_set_alpn_select_cb              155	3_0_0	EXIST::FUNCTION:
-SSL_CTX_set_tmp_dh_callback             156	3_0_0	EXIST::FUNCTION:DH
+SSL_CTX_set_tmp_dh_callback             156	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0,DH
 SSL_CTX_get_default_passwd_cb           157	3_0_0	EXIST::FUNCTION:
 TLSv1_server_method                     158	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_1_1_0,TLS1_METHOD
 DTLS_server_method                      159	3_0_0	EXIST::FUNCTION:
@@ -517,3 +517,5 @@ SSL_new_session_ticket                  ?	3_0_0	EXIST::FUNCTION:
 SSL_get0_peer_certificate               ?	3_0_0	EXIST::FUNCTION:
 SSL_get1_peer_certificate               ?	3_0_0	EXIST::FUNCTION:
 SSL_load_client_CA_file_ex              ?	3_0_0	EXIST::FUNCTION:
+SSL_set0_tmp_dh_pkey                    ?	3_0_0	EXIST::FUNCTION:
+SSL_CTX_set0_tmp_dh_pkey                ?	3_0_0	EXIST::FUNCTION:
diff --git a/util/missingmacro.txt b/util/missingmacro.txt
index 2b02fef5f5..a24cb8a685 100644
--- a/util/missingmacro.txt
+++ b/util/missingmacro.txt
@@ -143,8 +143,6 @@ DTLSv1_handle_timeout(3)
 SSL_num_renegotiations(3)
 SSL_clear_num_renegotiations(3)
 SSL_total_renegotiations(3)
-SSL_CTX_set_dh_auto(3)
-SSL_set_dh_auto(3)
 SSL_get0_certificate_types(3)
 SSL_CTX_set1_client_certificate_types(3)
 SSL_set1_client_certificate_types(3)
diff --git a/util/missingmacro111.txt b/util/missingmacro111.txt
index 6adf5c6cef..0b6a86e7e3 100644
--- a/util/missingmacro111.txt
+++ b/util/missingmacro111.txt
@@ -179,8 +179,6 @@ SSL_num_renegotiations(3)
 SSL_clear_num_renegotiations(3)
 SSL_total_renegotiations(3)
 SSL_CTX_set_tmp_ecdh(3)
-SSL_CTX_set_dh_auto(3)
-SSL_set_dh_auto(3)
 SSL_set_tmp_ecdh(3)
 SSL_CTX_get_extra_chain_certs(3)
 SSL_CTX_get_extra_chain_certs_only(3)
diff --git a/util/other.syms b/util/other.syms
index aa85ffa26a..43072908ec 100644
--- a/util/other.syms
+++ b/util/other.syms
@@ -475,6 +475,7 @@ SSL_CTX_set1_sigalgs                    define
 SSL_CTX_set1_sigalgs_list               define
 SSL_CTX_set1_verify_cert_store          define
 SSL_CTX_set_current_cert                define
+SSL_CTX_set_dh_auto                     define
 SSL_CTX_set_ecdh_auto                   define
 SSL_CTX_set_max_cert_list               define
 SSL_CTX_set_max_pipelines               define
@@ -548,6 +549,7 @@ SSL_set1_sigalgs                        define
 SSL_set1_sigalgs_list                   define
 SSL_set1_verify_cert_store              define
 SSL_set_current_cert                    define
+SSL_set_dh_auto                         define
 SSL_set_ecdh_auto                       define
 SSL_set_max_cert_list                   define
 SSL_set_max_pipelines                   define


More information about the openssl-commits mailing list