Really remove DHE ciphersuites from TLS.

This follows up on cedc6f18 by removing support for the
-DBORINGSSL_ENABLE_DHE_TLS compile flag, and the code needed to
support it.

Change-Id: I53b6aa7a0eddd23ace8b770edb2a31b18ba2ce26
Reviewed-on: https://boringssl-review.googlesource.com/14886
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/fuzz/server.cc b/fuzz/server.cc
index c7b3fe3..af1696c 100644
--- a/fuzz/server.cc
+++ b/fuzz/server.cc
@@ -16,7 +16,6 @@
 #include <stdlib.h>
 
 #include <openssl/bio.h>
-#include <openssl/dh.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
@@ -278,10 +277,6 @@
   // Enable ciphers that are off by default.
   SSL_set_strict_cipher_list(server, "ALL:NULL-SHA");
 
-  DH *dh = DH_get_1024_160(nullptr);
-  SSL_set_tmp_dh(server, dh);
-  DH_free(dh);
-
   BIO_write(in, buf, len);
   if (SSL_do_handshake(server) == 1) {
     // Keep reading application data until error or EOF.
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 13ebae5..c4b7387 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1222,9 +1222,6 @@
 /* SSL_CIPHER_is_ECDSA returns one if |cipher| uses ECDSA. */
 OPENSSL_EXPORT int SSL_CIPHER_is_ECDSA(const SSL_CIPHER *cipher);
 
-/* SSL_CIPHER_is_DHE returns one if |cipher| uses DHE. */
-OPENSSL_EXPORT int SSL_CIPHER_is_DHE(const SSL_CIPHER *cipher);
-
 /* SSL_CIPHER_is_ECDHE returns one if |cipher| uses ECDHE. */
 OPENSSL_EXPORT int SSL_CIPHER_is_ECDHE(const SSL_CIPHER *cipher);
 
@@ -2125,44 +2122,6 @@
 OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id);
 
 
-/* Multiplicative Diffie-Hellman.
- *
- * Cipher suites using a DHE key exchange perform Diffie-Hellman over a
- * multiplicative group selected by the server. These ciphers are disabled for a
- * server unless a group is chosen with one of these functions. */
-
-/* SSL_CTX_set_tmp_dh configures |ctx| to use the group from |dh| as the group
- * for DHE. Only the group is used, so |dh| needn't have a keypair. It returns
- * one on success and zero on error. */
-OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
-
-/* SSL_set_tmp_dh configures |ssl| to use the group from |dh| as the group for
- * DHE. Only the group is used, so |dh| needn't have a keypair. It returns one
- * on success and zero on error. */
-OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh);
-
-/* SSL_CTX_set_tmp_dh_callback configures |ctx| to use |callback| to determine
- * the group for DHE ciphers. |callback| should ignore |is_export| and
- * |keylength| and return a |DH| of the selected group or NULL on error. Only
- * the parameters are used, so the |DH| needn't have a generated keypair.
- *
- * WARNING: The caller does not take ownership of the resulting |DH|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback(
-    SSL_CTX *ctx, DH *(*callback)(SSL *ssl, int is_export, int keylength));
-
-/* SSL_set_tmp_dh_callback configures |ssl| to use |callback| to determine the
- * group for DHE ciphers. |callback| should ignore |is_export| and |keylength|
- * and return a |DH| of the selected group or NULL on error. Only the
- * parameters are used, so the |DH| needn't have a generated keypair.
- *
- * WARNING: The caller does not take ownership of the resulting |DH|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
-                                            DH *(*dh)(SSL *ssl, int is_export,
-                                                      int keylength));
-
-
 /* Certificate verification.
  *
  * SSL may authenticate either endpoint with an X.509 certificate. Typically
@@ -3582,6 +3541,22 @@
 /* SSL_get_server_tmp_key returns zero. */
 OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key);
 
+/* SSL_CTX_set_tmp_dh returns 1. */
+OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
+
+/* SSL_set_tmp_dh returns 1. */
+OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh);
+
+/* SSL_CTX_set_tmp_dh_callback does nothing. */
+OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback(
+    SSL_CTX *ctx, DH *(*callback)(SSL *ssl, int is_export, int keylength));
+
+/* SSL_set_tmp_dh_callback does nothing. */
+OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
+                                            DH *(*dh)(SSL *ssl, int is_export,
+                                                      int keylength));
+
+
 #define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)(arg)))
 #define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
 #define SSL_SESSION_set_app_data(s, a) \
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c
index e649680..0629078 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -156,7 +156,6 @@
 #include <openssl/bn.h>
 #include <openssl/buf.h>
 #include <openssl/bytestring.h>
-#include <openssl/dh.h>
 #include <openssl/ec_key.h>
 #include <openssl/ecdsa.h>
 #include <openssl/err.h>
@@ -1133,7 +1132,6 @@
 static int ssl3_get_server_key_exchange(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
   int al;
-  DH *dh = NULL;
   EC_KEY *ecdh = NULL;
   EC_POINT *srvr_ecpoint = NULL;
 
@@ -1204,50 +1202,7 @@
     }
   }
 
-  if (alg_k & SSL_kDHE) {
-    CBS dh_p, dh_g, dh_Ys;
-    if (!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_p) ||
-        CBS_len(&dh_p) == 0 ||
-        !CBS_get_u16_length_prefixed(&server_key_exchange, &dh_g) ||
-        CBS_len(&dh_g) == 0 ||
-        !CBS_get_u16_length_prefixed(&server_key_exchange, &dh_Ys) ||
-        CBS_len(&dh_Ys) == 0) {
-      al = SSL_AD_DECODE_ERROR;
-      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
-      goto f_err;
-    }
-
-    dh = DH_new();
-    if (dh == NULL) {
-      goto err;
-    }
-
-    dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL);
-    dh->g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL);
-    if (dh->p == NULL || dh->g == NULL) {
-      goto err;
-    }
-
-    unsigned bits = DH_num_bits(dh);
-    if (bits < 1024) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DH_P_LENGTH);
-      goto err;
-    } else if (bits > 4096) {
-      /* Overly large DHE groups are prohibitively expensive, so enforce a limit
-       * to prevent a server from causing us to perform too expensive of a
-       * computation. */
-      OPENSSL_PUT_ERROR(SSL, SSL_R_DH_P_TOO_LONG);
-      goto err;
-    }
-
-    SSL_ECDH_CTX_init_for_dhe(&hs->ecdh_ctx, dh);
-    dh = NULL;
-
-    /* Save the peer public key for later. */
-    if (!CBS_stow(&dh_Ys, &hs->peer_key, &hs->peer_key_len)) {
-      goto err;
-    }
-  } else if (alg_k & SSL_kECDHE) {
+  if (alg_k & SSL_kECDHE) {
     /* Parse the server parameters. */
     uint8_t group_type;
     uint16_t group_id;
@@ -1363,7 +1318,6 @@
 f_err:
   ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
 err:
-  DH_free(dh);
   EC_POINT_free(srvr_ecpoint);
   EC_KEY_free(ecdh);
   return -1;
@@ -1590,10 +1544,10 @@
         !CBB_flush(&body)) {
       goto err;
     }
-  } else if (alg_k & (SSL_kECDHE|SSL_kDHE)) {
+  } else if (alg_k & SSL_kECDHE) {
     /* Generate a keypair and serialize the public half. */
     CBB child;
-    if (!SSL_ECDH_CTX_add_key(&hs->ecdh_ctx, &body, &child)) {
+    if (!CBB_add_u8_length_prefixed(&body, &child)) {
       goto err;
     }
 
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index 02f2e84..63027d6 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -155,7 +155,6 @@
 #include <openssl/buf.h>
 #include <openssl/bytestring.h>
 #include <openssl/cipher.h>
-#include <openssl/dh.h>
 #include <openssl/ec.h>
 #include <openssl/ecdsa.h>
 #include <openssl/err.h>
@@ -701,10 +700,6 @@
     }
   }
 
-  if (ssl->cert->dh_tmp != NULL || ssl->cert->dh_tmp_cb != NULL) {
-    mask_k |= SSL_kDHE;
-  }
-
   /* Check for a shared group to consider ECDHE ciphers. */
   uint16_t unused;
   if (tls1_get_shared_group(hs, &unused)) {
@@ -1155,34 +1150,7 @@
       }
     }
 
-    if (alg_k & SSL_kDHE) {
-      /* Determine the group to use. */
-      DH *params = ssl->cert->dh_tmp;
-      if (params == NULL && ssl->cert->dh_tmp_cb != NULL) {
-        params = ssl->cert->dh_tmp_cb(ssl, 0, 1024);
-      }
-      if (params == NULL) {
-        OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY);
-        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-        goto err;
-      }
-
-      /* Set up DH, generate a key, and emit the public half. */
-      DH *dh = DHparams_dup(params);
-      if (dh == NULL) {
-        goto err;
-      }
-
-      SSL_ECDH_CTX_init_for_dhe(&hs->ecdh_ctx, dh);
-      if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
-          !BN_bn2cbb_padded(&child, BN_num_bytes(params->p), params->p) ||
-          !CBB_add_u16_length_prefixed(&cbb, &child) ||
-          !BN_bn2cbb_padded(&child, BN_num_bytes(params->g), params->g) ||
-          !CBB_add_u16_length_prefixed(&cbb, &child) ||
-          !SSL_ECDH_CTX_offer(&hs->ecdh_ctx, &child)) {
-        goto err;
-      }
-    } else if (alg_k & SSL_kECDHE) {
+    if (alg_k & SSL_kECDHE) {
       /* Determine the group to use. */
       uint16_t group_id;
       if (!tls1_get_shared_group(hs, &group_id)) {
@@ -1632,10 +1600,10 @@
 
     OPENSSL_free(decrypt_buf);
     decrypt_buf = NULL;
-  } else if (alg_k & (SSL_kECDHE|SSL_kDHE)) {
+  } else if (alg_k & SSL_kECDHE) {
     /* Parse the ClientKeyExchange. */
     CBS peer_key;
-    if (!SSL_ECDH_CTX_get_key(&hs->ecdh_ctx, &client_key_exchange, &peer_key) ||
+    if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) ||
         CBS_len(&client_key_exchange) != 0) {
       al = SSL_AD_DECODE_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
diff --git a/ssl/internal.h b/ssl/internal.h
index 8d38cda..4d148c6 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -167,11 +167,10 @@
 
 /* Bits for |algorithm_mkey| (key exchange algorithm). */
 #define SSL_kRSA 0x00000001L
-#define SSL_kDHE 0x00000002L
-#define SSL_kECDHE 0x00000004L
+#define SSL_kECDHE 0x00000002L
 /* SSL_kPSK is only set for plain PSK, not ECDHE_PSK. */
-#define SSL_kPSK 0x00000008L
-#define SSL_kGENERIC 0x00000010L
+#define SSL_kPSK 0x00000004L
+#define SSL_kGENERIC 0x00000008L
 
 /* Bits for |algorithm_auth| (server authentication). */
 #define SSL_aRSA 0x00000001L
@@ -637,15 +636,6 @@
   int (*finish)(SSL_ECDH_CTX *ctx, uint8_t **out_secret, size_t *out_secret_len,
                 uint8_t *out_alert, const uint8_t *peer_key,
                 size_t peer_key_len);
-
-  /* get_key initializes |out| with a length-prefixed key from |cbs|. It returns
-   * one on success and zero on error. */
-  int (*get_key)(CBS *cbs, CBS *out);
-
-  /* add_key initializes |out_contents| to receive a key. Typically it will then
-   * be passed to |offer| or |accept|. It returns one on success and zero on
-   * error. */
-  int (*add_key)(CBB *cbb, CBB *out_contents);
 } SSL_ECDH_METHOD;
 
 struct ssl_ecdh_ctx_st {
@@ -667,10 +657,6 @@
  * on success and zero on error. */
 int SSL_ECDH_CTX_init(SSL_ECDH_CTX *ctx, uint16_t group_id);
 
-/* SSL_ECDH_CTX_init_for_dhe sets up |ctx| for use with legacy DHE-based ciphers
- * where the server specifies a group. It takes ownership of |params|. */
-void SSL_ECDH_CTX_init_for_dhe(SSL_ECDH_CTX *ctx, DH *params);
-
 /* SSL_ECDH_CTX_cleanup releases memory associated with |ctx|. It is legal to
  * call it in the zero state. */
 void SSL_ECDH_CTX_cleanup(SSL_ECDH_CTX *ctx);
@@ -1340,9 +1326,6 @@
    * compatibility, or might be a no-op, depending on the application. */
   const SSL_X509_METHOD *x509_method;
 
-  DH *dh_tmp;
-  DH *(*dh_tmp_cb)(SSL *ssl, int is_export, int keysize);
-
   /* sigalgs, if non-NULL, is the set of signature algorithms supported by
    * |privatekey| in decreasing order of preference. */
   uint16_t *sigalgs;
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 57a27c7..ac8bb67 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -152,7 +152,6 @@
 #include <string.h>
 
 #include <openssl/buf.h>
-#include <openssl/dh.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/md5.h>
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index cfcc12a..114eb8d 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -121,9 +121,9 @@
  *                                  -- stapled OCSP response from the server
  *     extendedMasterSecret    [17] BOOLEAN OPTIONAL,
  *     groupID                 [18] INTEGER OPTIONAL,
- *                                  -- For historical reasons, for legacy DHE or
- *                                  -- static RSA ciphers, this field contains
- *                                  -- another value to be discarded.
+ *                                  -- For historical reasons, for static RSA
+                                    -- ciphers, this field contains another
+                                    -- value to be discarded.
  *     certChain               [19] SEQUENCE OF Certificate OPTIONAL,
  *     ticketAgeAdd            [21] OCTET STRING OPTIONAL,
  *     isServer                [22] BOOLEAN DEFAULT TRUE,
@@ -700,7 +700,7 @@
 
   /* Historically, the group_id field was used for key-exchange-specific
    * information. Discard all but the group ID. */
-  if (ret->cipher->algorithm_mkey & (SSL_kRSA | SSL_kDHE)) {
+  if (ret->cipher->algorithm_mkey & SSL_kRSA) {
     value = 0;
   }
 
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 4680e5f..674db10 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -121,7 +121,6 @@
 #include <openssl/bn.h>
 #include <openssl/buf.h>
 #include <openssl/bytestring.h>
-#include <openssl/dh.h>
 #include <openssl/ec_key.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
@@ -168,15 +167,6 @@
   ret->key_method = cert->key_method;
   ret->x509_method = cert->x509_method;
 
-  if (cert->dh_tmp != NULL) {
-    ret->dh_tmp = DHparams_dup(cert->dh_tmp);
-    if (ret->dh_tmp == NULL) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
-      goto err;
-    }
-  }
-  ret->dh_tmp_cb = cert->dh_tmp_cb;
-
   if (cert->sigalgs != NULL) {
     ret->sigalgs =
         BUF_memdup(cert->sigalgs, cert->num_sigalgs * sizeof(cert->sigalgs[0]));
@@ -233,8 +223,6 @@
     return;
   }
 
-  DH_free(c->dh_tmp);
-
   ssl_cert_clear_certs(c);
   c->x509_method->cert_free(c);
   OPENSSL_free(c->sigalgs);
diff --git a/ssl/ssl_cipher.c b/ssl/ssl_cipher.c
index 4ade583..cb62edd 100644
--- a/ssl/ssl_cipher.c
+++ b/ssl/ssl_cipher.c
@@ -193,19 +193,6 @@
      SSL_HANDSHAKE_MAC_DEFAULT,
     },
 
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-    /* Cipher 33 */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_128_SHA,
-     TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
-     SSL_kDHE,
-     SSL_aRSA,
-     SSL_AES128,
-     SSL_SHA1,
-     SSL_HANDSHAKE_MAC_DEFAULT,
-    },
-#endif
-
     /* Cipher 35 */
     {
      TLS1_TXT_RSA_WITH_AES_256_SHA,
@@ -217,19 +204,6 @@
      SSL_HANDSHAKE_MAC_DEFAULT,
     },
 
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-    /* Cipher 39 */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_256_SHA,
-     TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
-     SSL_kDHE,
-     SSL_aRSA,
-     SSL_AES256,
-     SSL_SHA1,
-     SSL_HANDSHAKE_MAC_DEFAULT,
-    },
-#endif
-
 
     /* TLS v1.2 ciphersuites */
 
@@ -255,30 +229,6 @@
      SSL_HANDSHAKE_MAC_SHA256,
     },
 
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-    /* Cipher 67 */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
-     TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
-     SSL_kDHE,
-     SSL_aRSA,
-     SSL_AES128,
-     SSL_SHA256,
-     SSL_HANDSHAKE_MAC_SHA256,
-    },
-
-    /* Cipher 6B */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
-     TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
-     SSL_kDHE,
-     SSL_aRSA,
-     SSL_AES256,
-     SSL_SHA256,
-     SSL_HANDSHAKE_MAC_SHA256,
-    },
-#endif
-
     /* PSK cipher suites. */
 
     /* Cipher 8C */
@@ -327,30 +277,6 @@
      SSL_HANDSHAKE_MAC_SHA384,
     },
 
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-    /* Cipher 9E */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
-     TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
-     SSL_kDHE,
-     SSL_aRSA,
-     SSL_AES128GCM,
-     SSL_AEAD,
-     SSL_HANDSHAKE_MAC_SHA256,
-    },
-
-    /* Cipher 9F */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
-     TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
-     SSL_kDHE,
-     SSL_aRSA,
-     SSL_AES256GCM,
-     SSL_AEAD,
-     SSL_HANDSHAKE_MAC_SHA384,
-    },
-#endif
-
     /* TLS 1.3 suites. */
 
     /* Cipher 1301 */
@@ -626,16 +552,9 @@
 
     /* key exchange aliases
      * (some of those using only a single bit here combine
-     * multiple key exchange algs according to the RFCs,
-     * e.g. kEDH combines DHE_DSS and DHE_RSA) */
+     * multiple key exchange algs according to the RFCs. */
     {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0},
 
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-    {"kDHE", SSL_kDHE, ~0u, ~0u, ~0u, 0},
-    {"kEDH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
-    {"DH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
-#endif
-
     {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
     {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
     {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
@@ -649,10 +568,6 @@
     {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, 0},
 
     /* aliases combining key exchange and server authentication */
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-    {"DHE", SSL_kDHE, ~0u, ~0u, ~0u, 0},
-    {"EDH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
-#endif
     {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
     {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
     {"RSA", SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, 0},
@@ -1485,10 +1400,6 @@
   return (cipher->algorithm_auth & SSL_aECDSA) != 0;
 }
 
-int SSL_CIPHER_is_DHE(const SSL_CIPHER *cipher) {
-  return (cipher->algorithm_mkey & SSL_kDHE) != 0;
-}
-
 int SSL_CIPHER_is_ECDHE(const SSL_CIPHER *cipher) {
   return (cipher->algorithm_mkey & SSL_kECDHE) != 0;
 }
@@ -1537,15 +1448,6 @@
     case SSL_kRSA:
       return "RSA";
 
-    case SSL_kDHE:
-      switch (cipher->algorithm_auth) {
-        case SSL_aRSA:
-          return "DHE_RSA";
-        default:
-          assert(0);
-          return "UNKNOWN";
-      }
-
     case SSL_kECDHE:
       switch (cipher->algorithm_auth) {
         case SSL_aECDSA:
@@ -1705,10 +1607,6 @@
       kx = "RSA";
       break;
 
-    case SSL_kDHE:
-      kx = "DH";
-      break;
-
     case SSL_kECDHE:
       kx = "ECDH";
       break;
@@ -1849,8 +1747,7 @@
 
 int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
   /* Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. */
-  if (cipher->algorithm_mkey & SSL_kDHE ||
-      cipher->algorithm_mkey & SSL_kECDHE) {
+  if (cipher->algorithm_mkey & SSL_kECDHE) {
     return 1;
   }
 
diff --git a/ssl/ssl_ecdh.c b/ssl/ssl_ecdh.c
index 25e3df9..30fe7e4 100644
--- a/ssl/ssl_ecdh.c
+++ b/ssl/ssl_ecdh.c
@@ -219,85 +219,6 @@
 }
 
 
-/* Legacy DHE-based implementation. */
-
-static void ssl_dhe_cleanup(SSL_ECDH_CTX *ctx) {
-  DH_free((DH *)ctx->data);
-}
-
-static int ssl_dhe_offer(SSL_ECDH_CTX *ctx, CBB *out) {
-  DH *dh = (DH *)ctx->data;
-  /* The group must have been initialized already, but not the key. */
-  assert(dh != NULL);
-  assert(dh->priv_key == NULL);
-
-  /* Due to a bug in yaSSL, the public key must be zero padded to the size of
-   * the prime. */
-  return DH_generate_key(dh) &&
-         BN_bn2cbb_padded(out, BN_num_bytes(dh->p), dh->pub_key);
-}
-
-static int ssl_dhe_finish(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
-                          size_t *out_secret_len, uint8_t *out_alert,
-                          const uint8_t *peer_key, size_t peer_key_len) {
-  DH *dh = (DH *)ctx->data;
-  assert(dh != NULL);
-  assert(dh->priv_key != NULL);
-  *out_alert = SSL_AD_INTERNAL_ERROR;
-
-  int secret_len = 0;
-  uint8_t *secret = NULL;
-  BIGNUM *peer_point = BN_bin2bn(peer_key, peer_key_len, NULL);
-  if (peer_point == NULL) {
-    goto err;
-  }
-
-  secret = OPENSSL_malloc(DH_size(dh));
-  if (secret == NULL) {
-    goto err;
-  }
-  secret_len = DH_compute_key(secret, peer_point, dh);
-  if (secret_len <= 0) {
-    goto err;
-  }
-
-  *out_secret = secret;
-  *out_secret_len = (size_t)secret_len;
-  BN_free(peer_point);
-  return 1;
-
-err:
-  if (secret_len > 0) {
-    OPENSSL_cleanse(secret, (size_t)secret_len);
-  }
-  OPENSSL_free(secret);
-  BN_free(peer_point);
-  return 0;
-}
-
-static int ssl_dhe_accept(SSL_ECDH_CTX *ctx, CBB *out_public_key,
-                          uint8_t **out_secret, size_t *out_secret_len,
-                          uint8_t *out_alert, const uint8_t *peer_key,
-                          size_t peer_key_len) {
-  *out_alert = SSL_AD_INTERNAL_ERROR;
-  if (!ssl_dhe_offer(ctx, out_public_key) ||
-      !ssl_dhe_finish(ctx, out_secret, out_secret_len, out_alert, peer_key,
-                      peer_key_len)) {
-    return 0;
-  }
-  return 1;
-}
-
-static const SSL_ECDH_METHOD kDHEMethod = {
-    NID_undef, 0, "",
-    ssl_dhe_cleanup,
-    ssl_dhe_offer,
-    ssl_dhe_accept,
-    ssl_dhe_finish,
-    CBS_get_u16_length_prefixed,
-    CBB_add_u16_length_prefixed,
-};
-
 static const SSL_ECDH_METHOD kMethods[] = {
     {
         NID_secp224r1,
@@ -307,8 +228,6 @@
         ssl_ec_point_offer,
         ssl_ec_point_accept,
         ssl_ec_point_finish,
-        CBS_get_u8_length_prefixed,
-        CBB_add_u8_length_prefixed,
     },
     {
         NID_X9_62_prime256v1,
@@ -318,8 +237,6 @@
         ssl_ec_point_offer,
         ssl_ec_point_accept,
         ssl_ec_point_finish,
-        CBS_get_u8_length_prefixed,
-        CBB_add_u8_length_prefixed,
     },
     {
         NID_secp384r1,
@@ -329,8 +246,6 @@
         ssl_ec_point_offer,
         ssl_ec_point_accept,
         ssl_ec_point_finish,
-        CBS_get_u8_length_prefixed,
-        CBB_add_u8_length_prefixed,
     },
     {
         NID_secp521r1,
@@ -340,8 +255,6 @@
         ssl_ec_point_offer,
         ssl_ec_point_accept,
         ssl_ec_point_finish,
-        CBS_get_u8_length_prefixed,
-        CBB_add_u8_length_prefixed,
     },
     {
         NID_X25519,
@@ -351,8 +264,6 @@
         ssl_x25519_offer,
         ssl_x25519_accept,
         ssl_x25519_finish,
-        CBS_get_u8_length_prefixed,
-        CBB_add_u8_length_prefixed,
     },
 };
 
@@ -422,13 +333,6 @@
   return 1;
 }
 
-void SSL_ECDH_CTX_init_for_dhe(SSL_ECDH_CTX *ctx, DH *params) {
-  SSL_ECDH_CTX_cleanup(ctx);
-
-  ctx->method = &kDHEMethod;
-  ctx->data = params;
-}
-
 void SSL_ECDH_CTX_cleanup(SSL_ECDH_CTX *ctx) {
   if (ctx->method == NULL) {
     return;
@@ -442,20 +346,6 @@
   return ctx->method->group_id;
 }
 
-int SSL_ECDH_CTX_get_key(SSL_ECDH_CTX *ctx, CBS *cbs, CBS *out) {
-  if (ctx->method == NULL) {
-    return 0;
-  }
-  return ctx->method->get_key(cbs, out);
-}
-
-int SSL_ECDH_CTX_add_key(SSL_ECDH_CTX *ctx, CBB *cbb, CBB *out_contents) {
-  if (ctx->method == NULL) {
-    return 0;
-  }
-  return ctx->method->add_key(cbb, out_contents);
-}
-
 int SSL_ECDH_CTX_offer(SSL_ECDH_CTX *ctx, CBB *out_public_key) {
   return ctx->method->offer(ctx, out_public_key);
 }
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 9f77c5a..7db06d5 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -146,7 +146,6 @@
 
 #include <openssl/bytestring.h>
 #include <openssl/crypto.h>
-#include <openssl/dh.h>
 #include <openssl/err.h>
 #include <openssl/lhash.h>
 #include <openssl/mem.h>
@@ -1466,22 +1465,10 @@
 }
 
 int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) {
-  DH_free(ctx->cert->dh_tmp);
-  ctx->cert->dh_tmp = DHparams_dup(dh);
-  if (ctx->cert->dh_tmp == NULL) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
-    return 0;
-  }
   return 1;
 }
 
 int SSL_set_tmp_dh(SSL *ssl, const DH *dh) {
-  DH_free(ssl->cert->dh_tmp);
-  ssl->cert->dh_tmp = DHparams_dup(dh);
-  if (ssl->cert->dh_tmp == NULL) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
-    return 0;
-  }
   return 1;
 }
 
@@ -2110,12 +2097,10 @@
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
                                  DH *(*callback)(SSL *ssl, int is_export,
                                                  int keylength)) {
-  ctx->cert->dh_tmp_cb = callback;
 }
 
 void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*callback)(SSL *ssl, int is_export,
                                                        int keylength)) {
-  ssl->cert->dh_tmp_cb = callback;
 }
 
 int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index 17ad4e4..3296c17 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -126,16 +126,10 @@
     // ECDHE_RSA.
     {
         "ALL:-kECDHE:"
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-        "-kDHE:"
-#endif
         "-kRSA:-ALL:"
         "AESGCM+AES128+aRSA",
         {
             {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-            {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
-#endif
             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
         },
         false,
@@ -188,9 +182,6 @@
     {
         // To simplify things, banish all but {ECDHE_RSA,RSA} x
         // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-        "!kEDH:"
-#endif
         "!AESGCM:!3DES:!SHA256:!SHA384:"
         // Order some ciphers backwards by strength.
         "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
@@ -800,11 +791,6 @@
 static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
     {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
     {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-    {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
-    {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
-     "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
-#endif
     {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
     {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
@@ -1850,12 +1836,7 @@
   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
   // Our default cipher list varies by CPU capabilities, so manually place the
   // ChaCha20 ciphers in front.
-  const char* cipher_list =
-#ifdef BORINGSSL_ENABLE_DHE_TLS
-      "!DHE:CHACHA20:ALL";
-#else
-      "CHACHA20:ALL";
-#endif
+  const char* cipher_list = "CHACHA20:ALL";
   if (!ctx ||
       // SSLv3 is off by default.
       !SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION) ||
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 6421af5..bbdd344 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -46,7 +46,6 @@
 #include <openssl/bytestring.h>
 #include <openssl/cipher.h>
 #include <openssl/crypto.h>
-#include <openssl/dh.h>
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
@@ -1054,34 +1053,6 @@
     return nullptr;
   }
 
-  bssl::UniquePtr<DH> dh(DH_get_2048_256(NULL));
-  if (!dh) {
-    return nullptr;
-  }
-
-  if (config->use_sparse_dh_prime) {
-    // This prime number is 2^1024 + 643 – a value just above a power of two.
-    // Because of its form, values modulo it are essentially certain to be one
-    // byte shorter. This is used to test padding of these values.
-    if (BN_hex2bn(
-            &dh->p,
-            "1000000000000000000000000000000000000000000000000000000000000000"
-            "0000000000000000000000000000000000000000000000000000000000000000"
-            "0000000000000000000000000000000000000000000000000000000000000000"
-            "0000000000000000000000000000000000000000000000000000000000000028"
-            "3") == 0 ||
-        !BN_set_word(dh->g, 2)) {
-      return nullptr;
-    }
-    BN_free(dh->q);
-    dh->q = NULL;
-    dh->priv_length = 0;
-  }
-
-  if (!SSL_CTX_set_tmp_dh(ssl_ctx.get(), dh.get())) {
-    return nullptr;
-  }
-
   if (config->async && config->is_server) {
     // Disable the internal session cache. To test asynchronous session lookup,
     // we use an external session cache.
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 5f3d65b..77fc89f 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -102,7 +102,6 @@
   { "-renegotiate-ignore", &TestConfig::renegotiate_ignore },
   { "-p384-only", &TestConfig::p384_only },
   { "-enable-all-curves", &TestConfig::enable_all_curves },
-  { "-use-sparse-dh-prime", &TestConfig::use_sparse_dh_prime },
   { "-use-old-client-cert-callback",
     &TestConfig::use_old_client_cert_callback },
   { "-send-alert", &TestConfig::send_alert },
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 0714585..24e6f69 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -112,7 +112,6 @@
   int expect_peer_signature_algorithm = 0;
   bool p384_only = false;
   bool enable_all_curves = false;
-  bool use_sparse_dh_prime = false;
   int expect_curve_id = 0;
   int expect_resume_curve_id = 0;
   bool use_old_client_cert_callback = false;