aboutsummaryrefslogtreecommitdiff
path: root/openssl-1.1.0h/crypto/dh
diff options
context:
space:
mode:
Diffstat (limited to 'openssl-1.1.0h/crypto/dh')
-rw-r--r--openssl-1.1.0h/crypto/dh/build.info4
-rw-r--r--openssl-1.1.0h/crypto/dh/dh1024.pem5
-rw-r--r--openssl-1.1.0h/crypto/dh/dh192.pem3
-rw-r--r--openssl-1.1.0h/crypto/dh/dh2048.pem16
-rw-r--r--openssl-1.1.0h/crypto/dh/dh4096.pem14
-rw-r--r--openssl-1.1.0h/crypto/dh/dh512.pem4
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_ameth.c870
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_asn1.c138
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_check.c183
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_depr.c46
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_err.c73
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_gen.c130
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_kdf.c150
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_key.c227
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_lib.c263
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_locl.h56
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_meth.c173
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_pmeth.c501
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_prn.c30
-rw-r--r--openssl-1.1.0h/crypto/dh/dh_rfc5114.c41
20 files changed, 2927 insertions, 0 deletions
diff --git a/openssl-1.1.0h/crypto/dh/build.info b/openssl-1.1.0h/crypto/dh/build.info
new file mode 100644
index 0000000..dba9306
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/build.info
@@ -0,0 +1,4 @@
+LIBS=../../libcrypto
+SOURCE[../../libcrypto]=\
+ dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \
+ dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c
diff --git a/openssl-1.1.0h/crypto/dh/dh1024.pem b/openssl-1.1.0h/crypto/dh/dh1024.pem
new file mode 100644
index 0000000..81d43f6
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh1024.pem
@@ -0,0 +1,5 @@
+-----BEGIN DH PARAMETERS-----
+MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
+/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
+/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
+-----END DH PARAMETERS-----
diff --git a/openssl-1.1.0h/crypto/dh/dh192.pem b/openssl-1.1.0h/crypto/dh/dh192.pem
new file mode 100644
index 0000000..521c072
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh192.pem
@@ -0,0 +1,3 @@
+-----BEGIN DH PARAMETERS-----
+MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM=
+-----END DH PARAMETERS-----
diff --git a/openssl-1.1.0h/crypto/dh/dh2048.pem b/openssl-1.1.0h/crypto/dh/dh2048.pem
new file mode 100644
index 0000000..295460f
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh2048.pem
@@ -0,0 +1,16 @@
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o
+AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh
+z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo
+pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW
+aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA
+Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==
+-----END DH PARAMETERS-----
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEArtA3w73zP6Lu3EOQtwogiXt3AXXpuS6yD4BhzNS1pZFyPHk0/an5
+8ydEkPhQZHKDW+BZJxxPLANaTudWo2YT8TgtvUdN6KSgMiEi6McwqDw+SADuvW+F
+SKUYFxG6VFIxyEP6xBdf+vhJxEDbRG2EYsHDRRtJ76gp9cSKTHusf2R+4AAVGqnt
+gRAbNqtcOar/7FSj+Pl8G3v0Bty0LcCSpbqgYlnv6z+rErQmmC6PPvSz97TDMCok
+yKpCE9hFA1zkqK3TH4FmFvGeIaXJUIBZf4mArWuBTjWFW3nmhESRUn1VK3K3x42N
+a5k6c2+EhrMFiLjxuH6JZoqL0/E93FF9SwIBAg==
+-----END DH PARAMETERS-----
diff --git a/openssl-1.1.0h/crypto/dh/dh4096.pem b/openssl-1.1.0h/crypto/dh/dh4096.pem
new file mode 100644
index 0000000..390943a
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh4096.pem
@@ -0,0 +1,14 @@
+-----BEGIN DH PARAMETERS-----
+MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7
+vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H
+TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF
+bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1
+rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE
+EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9
+bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3
+W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH
+ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb
+NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR
+jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=
+-----END DH PARAMETERS-----
+
diff --git a/openssl-1.1.0h/crypto/dh/dh512.pem b/openssl-1.1.0h/crypto/dh/dh512.pem
new file mode 100644
index 0000000..0a4d863
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh512.pem
@@ -0,0 +1,4 @@
+-----BEGIN DH PARAMETERS-----
+MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
+a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
+-----END DH PARAMETERS-----
diff --git a/openssl-1.1.0h/crypto/dh/dh_ameth.c b/openssl-1.1.0h/crypto/dh/dh_ameth.c
new file mode 100644
index 0000000..cd77867
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_ameth.c
@@ -0,0 +1,870 @@
+/*
+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include "dh_locl.h"
+#include <openssl/bn.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include <openssl/cms.h>
+
+/*
+ * i2d/d2i like DH parameter functions which use the appropriate routine for
+ * PKCS#3 DH or X9.42 DH.
+ */
+
+static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp,
+ long length)
+{
+ if (pkey->ameth == &dhx_asn1_meth)
+ return d2i_DHxparams(NULL, pp, length);
+ return d2i_DHparams(NULL, pp, length);
+}
+
+static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp)
+{
+ if (pkey->ameth == &dhx_asn1_meth)
+ return i2d_DHxparams(a, pp);
+ return i2d_DHparams(a, pp);
+}
+
+static void int_dh_free(EVP_PKEY *pkey)
+{
+ DH_free(pkey->pkey.dh);
+}
+
+static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+ const unsigned char *p, *pm;
+ int pklen, pmlen;
+ int ptype;
+ const void *pval;
+ const ASN1_STRING *pstr;
+ X509_ALGOR *palg;
+ ASN1_INTEGER *public_key = NULL;
+
+ DH *dh = NULL;
+
+ if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+ return 0;
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+ if (ptype != V_ASN1_SEQUENCE) {
+ DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
+ goto err;
+ }
+
+ pstr = pval;
+ pm = pstr->data;
+ pmlen = pstr->length;
+
+ if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL) {
+ DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+ goto err;
+ }
+
+ if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
+ DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* We have parameters now set public key */
+ if ((dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
+ DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
+ goto err;
+ }
+
+ ASN1_INTEGER_free(public_key);
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
+ return 1;
+
+ err:
+ ASN1_INTEGER_free(public_key);
+ DH_free(dh);
+ return 0;
+
+}
+
+static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+ DH *dh;
+ int ptype;
+ unsigned char *penc = NULL;
+ int penclen;
+ ASN1_STRING *str;
+ ASN1_INTEGER *pub_key = NULL;
+
+ dh = pkey->pkey.dh;
+
+ str = ASN1_STRING_new();
+ if (str == NULL) {
+ DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ str->length = i2d_dhp(pkey, dh, &str->data);
+ if (str->length <= 0) {
+ DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ptype = V_ASN1_SEQUENCE;
+
+ pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
+ if (!pub_key)
+ goto err;
+
+ penclen = i2d_ASN1_INTEGER(pub_key, &penc);
+
+ ASN1_INTEGER_free(pub_key);
+
+ if (penclen <= 0) {
+ DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
+ ptype, str, penc, penclen))
+ return 1;
+
+ err:
+ OPENSSL_free(penc);
+ ASN1_STRING_free(str);
+
+ return 0;
+}
+
+/*
+ * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in that
+ * the AlgorithmIdentifier contains the parameters, the private key is
+ * explicitly included and the pubkey must be recalculated.
+ */
+
+static int dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+{
+ const unsigned char *p, *pm;
+ int pklen, pmlen;
+ int ptype;
+ const void *pval;
+ const ASN1_STRING *pstr;
+ const X509_ALGOR *palg;
+ ASN1_INTEGER *privkey = NULL;
+
+ DH *dh = NULL;
+
+ if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+ return 0;
+
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+ if (ptype != V_ASN1_SEQUENCE)
+ goto decerr;
+ if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
+ goto decerr;
+
+ pstr = pval;
+ pm = pstr->data;
+ pmlen = pstr->length;
+ if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL)
+ goto decerr;
+
+ /* We have parameters now set private key */
+ if ((dh->priv_key = BN_secure_new()) == NULL
+ || !ASN1_INTEGER_to_BN(privkey, dh->priv_key)) {
+ DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR);
+ goto dherr;
+ }
+ /* Calculate public key */
+ if (!DH_generate_key(dh))
+ goto dherr;
+
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
+
+ ASN1_STRING_clear_free(privkey);
+
+ return 1;
+
+ decerr:
+ DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
+ dherr:
+ DH_free(dh);
+ ASN1_STRING_clear_free(privkey);
+ return 0;
+}
+
+static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+ ASN1_STRING *params = NULL;
+ ASN1_INTEGER *prkey = NULL;
+ unsigned char *dp = NULL;
+ int dplen;
+
+ params = ASN1_STRING_new();
+
+ if (params == NULL) {
+ DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ params->length = i2d_dhp(pkey, pkey->pkey.dh, &params->data);
+ if (params->length <= 0) {
+ DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ params->type = V_ASN1_SEQUENCE;
+
+ /* Get private key into integer */
+ prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
+
+ if (!prkey) {
+ DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR);
+ goto err;
+ }
+
+ dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+ ASN1_STRING_clear_free(prkey);
+ prkey = NULL;
+
+ if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
+ V_ASN1_SEQUENCE, params, dp, dplen))
+ goto err;
+
+ return 1;
+
+ err:
+ OPENSSL_free(dp);
+ ASN1_STRING_free(params);
+ ASN1_STRING_clear_free(prkey);
+ return 0;
+}
+
+static int dh_param_decode(EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen)
+{
+ DH *dh;
+
+ if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL) {
+ DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
+ return 0;
+ }
+ EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
+ return 1;
+}
+
+static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+ return i2d_dhp(pkey, pkey->pkey.dh, pder);
+}
+
+static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype)
+{
+ int reason = ERR_R_BUF_LIB;
+ const char *ktype = NULL;
+ BIGNUM *priv_key, *pub_key;
+
+ if (ptype == 2)
+ priv_key = x->priv_key;
+ else
+ priv_key = NULL;
+
+ if (ptype > 0)
+ pub_key = x->pub_key;
+ else
+ pub_key = NULL;
+
+ if (x->p == NULL || (ptype == 2 && priv_key == NULL)
+ || (ptype > 0 && pub_key == NULL)) {
+ reason = ERR_R_PASSED_NULL_PARAMETER;
+ goto err;
+ }
+
+ if (ptype == 2)
+ ktype = "DH Private-Key";
+ else if (ptype == 1)
+ ktype = "DH Public-Key";
+ else
+ ktype = "DH Parameters";
+
+ BIO_indent(bp, indent, 128);
+ if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
+ goto err;
+ indent += 4;
+
+ if (!ASN1_bn_print(bp, "private-key:", priv_key, NULL, indent))
+ goto err;
+ if (!ASN1_bn_print(bp, "public-key:", pub_key, NULL, indent))
+ goto err;
+
+ if (!ASN1_bn_print(bp, "prime:", x->p, NULL, indent))
+ goto err;
+ if (!ASN1_bn_print(bp, "generator:", x->g, NULL, indent))
+ goto err;
+ if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, NULL, indent))
+ goto err;
+ if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, NULL, indent))
+ goto err;
+ if (x->seed) {
+ int i;
+ BIO_indent(bp, indent, 128);
+ BIO_puts(bp, "seed:");
+ for (i = 0; i < x->seedlen; i++) {
+ if ((i % 15) == 0) {
+ if (BIO_puts(bp, "\n") <= 0
+ || !BIO_indent(bp, indent + 4, 128))
+ goto err;
+ }
+ if (BIO_printf(bp, "%02x%s", x->seed[i],
+ ((i + 1) == x->seedlen) ? "" : ":") <= 0)
+ goto err;
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ return (0);
+ }
+ if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, NULL, indent))
+ goto err;
+ if (x->length != 0) {
+ BIO_indent(bp, indent, 128);
+ if (BIO_printf(bp, "recommended-private-length: %d bits\n",
+ (int)x->length) <= 0)
+ goto err;
+ }
+
+ return 1;
+
+ err:
+ DHerr(DH_F_DO_DH_PRINT, reason);
+ return 0;
+}
+
+static int int_dh_size(const EVP_PKEY *pkey)
+{
+ return (DH_size(pkey->pkey.dh));
+}
+
+static int dh_bits(const EVP_PKEY *pkey)
+{
+ return BN_num_bits(pkey->pkey.dh->p);
+}
+
+static int dh_security_bits(const EVP_PKEY *pkey)
+{
+ return DH_security_bits(pkey->pkey.dh);
+}
+
+static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+ if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) ||
+ BN_cmp(a->pkey.dh->g, b->pkey.dh->g))
+ return 0;
+ else if (a->ameth == &dhx_asn1_meth) {
+ if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q))
+ return 0;
+ }
+ return 1;
+}
+
+static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
+{
+ BIGNUM *a;
+ if (src) {
+ a = BN_dup(src);
+ if (!a)
+ return 0;
+ } else
+ a = NULL;
+ BN_free(*dst);
+ *dst = a;
+ return 1;
+}
+
+static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
+{
+ if (is_x942 == -1)
+ is_x942 = ! !from->q;
+ if (!int_dh_bn_cpy(&to->p, from->p))
+ return 0;
+ if (!int_dh_bn_cpy(&to->g, from->g))
+ return 0;
+ if (is_x942) {
+ if (!int_dh_bn_cpy(&to->q, from->q))
+ return 0;
+ if (!int_dh_bn_cpy(&to->j, from->j))
+ return 0;
+ OPENSSL_free(to->seed);
+ to->seed = NULL;
+ to->seedlen = 0;
+ if (from->seed) {
+ to->seed = OPENSSL_memdup(from->seed, from->seedlen);
+ if (!to->seed)
+ return 0;
+ to->seedlen = from->seedlen;
+ }
+ } else
+ to->length = from->length;
+ return 1;
+}
+
+DH *DHparams_dup(DH *dh)
+{
+ DH *ret;
+ ret = DH_new();
+ if (ret == NULL)
+ return NULL;
+ if (!int_dh_param_copy(ret, dh, -1)) {
+ DH_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+ if (to->pkey.dh == NULL) {
+ to->pkey.dh = DH_new();
+ if (to->pkey.dh == NULL)
+ return 0;
+ }
+ return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
+ from->ameth == &dhx_asn1_meth);
+}
+
+static int dh_missing_parameters(const EVP_PKEY *a)
+{
+ if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL)
+ return 1;
+ return 0;
+}
+
+static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+ if (dh_cmp_parameters(a, b) == 0)
+ return 0;
+ if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0)
+ return 0;
+ else
+ return 1;
+}
+
+static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+{
+ return do_dh_print(bp, pkey->pkey.dh, indent, 0);
+}
+
+static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+{
+ return do_dh_print(bp, pkey->pkey.dh, indent, 1);
+}
+
+static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+{
+ return do_dh_print(bp, pkey->pkey.dh, indent, 2);
+}
+
+int DHparams_print(BIO *bp, const DH *x)
+{
+ return do_dh_print(bp, x, 4, 0);
+}
+
+#ifndef OPENSSL_NO_CMS
+static int dh_cms_decrypt(CMS_RecipientInfo *ri);
+static int dh_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
+
+static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+ switch (op) {
+#ifndef OPENSSL_NO_CMS
+
+ case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+ if (arg1 == 1)
+ return dh_cms_decrypt(arg2);
+ else if (arg1 == 0)
+ return dh_cms_encrypt(arg2);
+ return -2;
+
+ case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+ *(int *)arg2 = CMS_RECIPINFO_AGREE;
+ return 1;
+#endif
+ default:
+ return -2;
+ }
+
+}
+
+const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
+ EVP_PKEY_DH,
+ EVP_PKEY_DH,
+ 0,
+
+ "DH",
+ "OpenSSL PKCS#3 DH method",
+
+ dh_pub_decode,
+ dh_pub_encode,
+ dh_pub_cmp,
+ dh_public_print,
+
+ dh_priv_decode,
+ dh_priv_encode,
+ dh_private_print,
+
+ int_dh_size,
+ dh_bits,
+ dh_security_bits,
+
+ dh_param_decode,
+ dh_param_encode,
+ dh_missing_parameters,
+ dh_copy_parameters,
+ dh_cmp_parameters,
+ dh_param_print,
+ 0,
+
+ int_dh_free,
+ 0
+};
+
+const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
+ EVP_PKEY_DHX,
+ EVP_PKEY_DHX,
+ 0,
+
+ "X9.42 DH",
+ "OpenSSL X9.42 DH method",
+
+ dh_pub_decode,
+ dh_pub_encode,
+ dh_pub_cmp,
+ dh_public_print,
+
+ dh_priv_decode,
+ dh_priv_encode,
+ dh_private_print,
+
+ int_dh_size,
+ dh_bits,
+ dh_security_bits,
+
+ dh_param_decode,
+ dh_param_encode,
+ dh_missing_parameters,
+ dh_copy_parameters,
+ dh_cmp_parameters,
+ dh_param_print,
+ 0,
+
+ int_dh_free,
+ dh_pkey_ctrl
+};
+
+#ifndef OPENSSL_NO_CMS
+
+static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
+ X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
+{
+ const ASN1_OBJECT *aoid;
+ int atype;
+ const void *aval;
+ ASN1_INTEGER *public_key = NULL;
+ int rv = 0;
+ EVP_PKEY *pkpeer = NULL, *pk = NULL;
+ DH *dhpeer = NULL;
+ const unsigned char *p;
+ int plen;
+
+ X509_ALGOR_get0(&aoid, &atype, &aval, alg);
+ if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
+ goto err;
+ /* Only absent parameters allowed in RFC XXXX */
+ if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
+ goto err;
+
+ pk = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (!pk)
+ goto err;
+ if (pk->type != EVP_PKEY_DHX)
+ goto err;
+ /* Get parameters from parent key */
+ dhpeer = DHparams_dup(pk->pkey.dh);
+ /* We have parameters now set public key */
+ plen = ASN1_STRING_length(pubkey);
+ p = ASN1_STRING_get0_data(pubkey);
+ if (!p || !plen)
+ goto err;
+
+ if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) {
+ DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* We have parameters now set public key */
+ if ((dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
+ DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
+ goto err;
+ }
+
+ pkpeer = EVP_PKEY_new();
+ if (pkpeer == NULL)
+ goto err;
+ EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
+ dhpeer = NULL;
+ if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
+ rv = 1;
+ err:
+ ASN1_INTEGER_free(public_key);
+ EVP_PKEY_free(pkpeer);
+ DH_free(dhpeer);
+ return rv;
+}
+
+static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
+{
+ int rv = 0;
+
+ X509_ALGOR *alg, *kekalg = NULL;
+ ASN1_OCTET_STRING *ukm;
+ const unsigned char *p;
+ unsigned char *dukm = NULL;
+ size_t dukmlen = 0;
+ int keylen, plen;
+ const EVP_CIPHER *kekcipher;
+ EVP_CIPHER_CTX *kekctx;
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
+ goto err;
+
+ /*
+ * For DH we only have one OID permissible. If ever any more get defined
+ * we will need something cleverer.
+ */
+ if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
+ DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
+ goto err;
+
+ if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
+ goto err;
+
+ if (alg->parameter->type != V_ASN1_SEQUENCE)
+ goto err;
+
+ p = alg->parameter->value.sequence->data;
+ plen = alg->parameter->value.sequence->length;
+ kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+ if (!kekalg)
+ goto err;
+ kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ if (!kekctx)
+ goto err;
+ kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+ if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
+ goto err;
+ if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
+ goto err;
+ if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
+ goto err;
+
+ keylen = EVP_CIPHER_CTX_key_length(kekctx);
+ if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+ goto err;
+ /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
+ if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
+ OBJ_nid2obj(EVP_CIPHER_type(kekcipher)))
+ <= 0)
+ goto err;
+
+ if (ukm) {
+ dukmlen = ASN1_STRING_length(ukm);
+ dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
+ if (!dukm)
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+ goto err;
+ dukm = NULL;
+
+ rv = 1;
+ err:
+ X509_ALGOR_free(kekalg);
+ OPENSSL_free(dukm);
+ return rv;
+}
+
+static int dh_cms_decrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx;
+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (!pctx)
+ return 0;
+ /* See if we need to set peer key */
+ if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
+ X509_ALGOR *alg;
+ ASN1_BIT_STRING *pubkey;
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
+ NULL, NULL, NULL))
+ return 0;
+ if (!alg || !pubkey)
+ return 0;
+ if (!dh_cms_set_peerkey(pctx, alg, pubkey)) {
+ DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
+ return 0;
+ }
+ }
+ /* Set DH derivation parameters and initialise unwrap context */
+ if (!dh_cms_set_shared_info(pctx, ri)) {
+ DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+static int dh_cms_encrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx;
+ EVP_PKEY *pkey;
+ EVP_CIPHER_CTX *ctx;
+ int keylen;
+ X509_ALGOR *talg, *wrap_alg = NULL;
+ const ASN1_OBJECT *aoid;
+ ASN1_BIT_STRING *pubkey;
+ ASN1_STRING *wrap_str;
+ ASN1_OCTET_STRING *ukm;
+ unsigned char *penc = NULL, *dukm = NULL;
+ int penclen;
+ size_t dukmlen = 0;
+ int rv = 0;
+ int kdf_type, wrap_nid;
+ const EVP_MD *kdf_md;
+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (!pctx)
+ return 0;
+ /* Get ephemeral key */
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
+ NULL, NULL, NULL))
+ goto err;
+ X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+ /* Is everything uninitialised? */
+ if (aoid == OBJ_nid2obj(NID_undef)) {
+ ASN1_INTEGER *pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
+ if (!pubk)
+ goto err;
+ /* Set the key */
+
+ penclen = i2d_ASN1_INTEGER(pubk, &penc);
+ ASN1_INTEGER_free(pubk);
+ if (penclen <= 0)
+ goto err;
+ ASN1_STRING_set0(pubkey, penc, penclen);
+ pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+ penc = NULL;
+ X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
+ V_ASN1_UNDEF, NULL);
+ }
+
+ /* See if custom parameters set */
+ kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
+ if (kdf_type <= 0)
+ goto err;
+ if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
+ goto err;
+
+ if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
+ kdf_type = EVP_PKEY_DH_KDF_X9_42;
+ if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
+ goto err;
+ } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
+ /* Unknown KDF */
+ goto err;
+ if (kdf_md == NULL) {
+ /* Only SHA1 supported */
+ kdf_md = EVP_sha1();
+ if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
+ goto err;
+ } else if (EVP_MD_type(kdf_md) != NID_sha1)
+ /* Unsupported digest */
+ goto err;
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
+ goto err;
+
+ /* Get wrap NID */
+ ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ wrap_nid = EVP_CIPHER_CTX_type(ctx);
+ if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
+ goto err;
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+ /* Package wrap algorithm in an AlgorithmIdentifier */
+
+ wrap_alg = X509_ALGOR_new();
+ if (wrap_alg == NULL)
+ goto err;
+ wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
+ wrap_alg->parameter = ASN1_TYPE_new();
+ if (wrap_alg->parameter == NULL)
+ goto err;
+ if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
+ goto err;
+ if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
+ ASN1_TYPE_free(wrap_alg->parameter);
+ wrap_alg->parameter = NULL;
+ }
+
+ if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+ goto err;
+
+ if (ukm) {
+ dukmlen = ASN1_STRING_length(ukm);
+ dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
+ if (!dukm)
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+ goto err;
+ dukm = NULL;
+
+ /*
+ * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
+ * of another AlgorithmIdentifier.
+ */
+ penc = NULL;
+ penclen = i2d_X509_ALGOR(wrap_alg, &penc);
+ if (!penc || !penclen)
+ goto err;
+ wrap_str = ASN1_STRING_new();
+ if (wrap_str == NULL)
+ goto err;
+ ASN1_STRING_set0(wrap_str, penc, penclen);
+ penc = NULL;
+ X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
+ V_ASN1_SEQUENCE, wrap_str);
+
+ rv = 1;
+
+ err:
+ OPENSSL_free(penc);
+ X509_ALGOR_free(wrap_alg);
+ return rv;
+}
+
+#endif
diff --git a/openssl-1.1.0h/crypto/dh/dh_asn1.c b/openssl-1.1.0h/crypto/dh/dh_asn1.c
new file mode 100644
index 0000000..7c72fd6
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_asn1.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dh_locl.h"
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+
+/* Override the default free and new methods */
+static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ if (operation == ASN1_OP_NEW_PRE) {
+ *pval = (ASN1_VALUE *)DH_new();
+ if (*pval != NULL)
+ return 2;
+ return 0;
+ } else if (operation == ASN1_OP_FREE_PRE) {
+ DH_free((DH *)*pval);
+ *pval = NULL;
+ return 2;
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
+ ASN1_SIMPLE(DH, p, BIGNUM),
+ ASN1_SIMPLE(DH, g, BIGNUM),
+ ASN1_OPT(DH, length, ZLONG),
+} ASN1_SEQUENCE_END_cb(DH, DHparams)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
+
+/*
+ * Internal only structures for handling X9.42 DH: this gets translated to or
+ * from a DH structure straight away.
+ */
+
+typedef struct {
+ ASN1_BIT_STRING *seed;
+ BIGNUM *counter;
+} int_dhvparams;
+
+typedef struct {
+ BIGNUM *p;
+ BIGNUM *q;
+ BIGNUM *g;
+ BIGNUM *j;
+ int_dhvparams *vparams;
+} int_dhx942_dh;
+
+ASN1_SEQUENCE(DHvparams) = {
+ ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
+ ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
+} static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
+
+ASN1_SEQUENCE(DHxparams) = {
+ ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
+ ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
+ ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM),
+ ASN1_OPT(int_dhx942_dh, j, BIGNUM),
+ ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
+} static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
+
+int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a,
+ const unsigned char **pp, long length);
+int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp);
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx)
+
+/* Application public function: read in X9.42 DH parameters into DH structure */
+
+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length)
+{
+ int_dhx942_dh *dhx = NULL;
+ DH *dh = NULL;
+ dh = DH_new();
+ if (dh == NULL)
+ return NULL;
+ dhx = d2i_int_dhx(NULL, pp, length);
+ if (dhx == NULL) {
+ DH_free(dh);
+ return NULL;
+ }
+
+ if (a) {
+ DH_free(*a);
+ *a = dh;
+ }
+
+ dh->p = dhx->p;
+ dh->q = dhx->q;
+ dh->g = dhx->g;
+ dh->j = dhx->j;
+
+ if (dhx->vparams) {
+ dh->seed = dhx->vparams->seed->data;
+ dh->seedlen = dhx->vparams->seed->length;
+ dh->counter = dhx->vparams->counter;
+ dhx->vparams->seed->data = NULL;
+ ASN1_BIT_STRING_free(dhx->vparams->seed);
+ OPENSSL_free(dhx->vparams);
+ dhx->vparams = NULL;
+ }
+
+ OPENSSL_free(dhx);
+ return dh;
+}
+
+int i2d_DHxparams(const DH *dh, unsigned char **pp)
+{
+ int_dhx942_dh dhx;
+ int_dhvparams dhv;
+ ASN1_BIT_STRING bs;
+ dhx.p = dh->p;
+ dhx.g = dh->g;
+ dhx.q = dh->q;
+ dhx.j = dh->j;
+ if (dh->counter && dh->seed && dh->seedlen > 0) {
+ bs.flags = ASN1_STRING_FLAG_BITS_LEFT;
+ bs.data = dh->seed;
+ bs.length = dh->seedlen;
+ dhv.seed = &bs;
+ dhv.counter = dh->counter;
+ dhx.vparams = &dhv;
+ } else
+ dhx.vparams = NULL;
+
+ return i2d_int_dhx(&dhx, pp);
+}
diff --git a/openssl-1.1.0h/crypto/dh/dh_check.c b/openssl-1.1.0h/crypto/dh/dh_check.c
new file mode 100644
index 0000000..3b0fa59
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_check.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dh_locl.h"
+
+/*-
+ * Check that p and g are suitable enough
+ *
+ * p is odd
+ * 1 < g < p - 1
+ */
+
+int DH_check_params(const DH *dh, int *ret)
+{
+ int ok = 0;
+ BIGNUM *tmp = NULL;
+ BN_CTX *ctx = NULL;
+
+ *ret = 0;
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (tmp == NULL)
+ goto err;
+
+ if (!BN_is_odd(dh->p))
+ *ret |= DH_CHECK_P_NOT_PRIME;
+ if (BN_is_negative(dh->g) || BN_is_zero(dh->g) || BN_is_one(dh->g))
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
+ goto err;
+ if (BN_cmp(dh->g, tmp) >= 0)
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+
+ ok = 1;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return (ok);
+}
+
+/*-
+ * Check that p is a safe prime and
+ * if g is 2, 3 or 5, check that it is a suitable generator
+ * where
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5
+ * for 5, p mod 10 == 3 or 7
+ * should hold.
+ */
+
+int DH_check(const DH *dh, int *ret)
+{
+ int ok = 0, r;
+ BN_CTX *ctx = NULL;
+ BN_ULONG l;
+ BIGNUM *t1 = NULL, *t2 = NULL;
+
+ *ret = 0;
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ if (t1 == NULL)
+ goto err;
+ t2 = BN_CTX_get(ctx);
+ if (t2 == NULL)
+ goto err;
+
+ if (dh->q) {
+ if (BN_cmp(dh->g, BN_value_one()) <= 0)
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ else if (BN_cmp(dh->g, dh->p) >= 0)
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ else {
+ /* Check g^q == 1 mod p */
+ if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
+ goto err;
+ if (!BN_is_one(t1))
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ }
+ r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL);
+ if (r < 0)
+ goto err;
+ if (!r)
+ *ret |= DH_CHECK_Q_NOT_PRIME;
+ /* Check p == 1 mod q i.e. q divides p - 1 */
+ if (!BN_div(t1, t2, dh->p, dh->q, ctx))
+ goto err;
+ if (!BN_is_one(t2))
+ *ret |= DH_CHECK_INVALID_Q_VALUE;
+ if (dh->j && BN_cmp(dh->j, t1))
+ *ret |= DH_CHECK_INVALID_J_VALUE;
+
+ } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
+ l = BN_mod_word(dh->p, 24);
+ if (l == (BN_ULONG)-1)
+ goto err;
+ if (l != 11)
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
+ l = BN_mod_word(dh->p, 10);
+ if (l == (BN_ULONG)-1)
+ goto err;
+ if ((l != 3) && (l != 7))
+ *ret |= DH_NOT_SUITABLE_GENERATOR;
+ } else
+ *ret |= DH_UNABLE_TO_CHECK_GENERATOR;
+
+ r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL);
+ if (r < 0)
+ goto err;
+ if (!r)
+ *ret |= DH_CHECK_P_NOT_PRIME;
+ else if (!dh->q) {
+ if (!BN_rshift1(t1, dh->p))
+ goto err;
+ r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL);
+ if (r < 0)
+ goto err;
+ if (!r)
+ *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
+ }
+ ok = 1;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return (ok);
+}
+
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
+{
+ int ok = 0;
+ BIGNUM *tmp = NULL;
+ BN_CTX *ctx = NULL;
+
+ *ret = 0;
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (tmp == NULL || !BN_set_word(tmp, 1))
+ goto err;
+ if (BN_cmp(pub_key, tmp) <= 0)
+ *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
+ if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
+ goto err;
+ if (BN_cmp(pub_key, tmp) >= 0)
+ *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
+
+ if (dh->q != NULL) {
+ /* Check pub_key^q == 1 mod p */
+ if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx))
+ goto err;
+ if (!BN_is_one(tmp))
+ *ret |= DH_CHECK_PUBKEY_INVALID;
+ }
+
+ ok = 1;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return (ok);
+}
diff --git a/openssl-1.1.0h/crypto/dh/dh_depr.c b/openssl-1.1.0h/crypto/dh/dh_depr.c
new file mode 100644
index 0000000..f8ed1b7
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_depr.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* This file contains deprecated functions as wrappers to the new ones */
+
+#include <openssl/opensslconf.h>
+#if OPENSSL_API_COMPAT >= 0x00908000L
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include "internal/cryptlib.h"
+# include <openssl/bn.h>
+# include <openssl/dh.h>
+
+DH *DH_generate_parameters(int prime_len, int generator,
+ void (*callback) (int, int, void *), void *cb_arg)
+{
+ BN_GENCB *cb;
+ DH *ret = NULL;
+
+ if ((ret = DH_new()) == NULL)
+ return NULL;
+ cb = BN_GENCB_new();
+ if (cb == NULL) {
+ DH_free(ret);
+ return NULL;
+ }
+
+ BN_GENCB_set_old(cb, callback, cb_arg);
+
+ if (DH_generate_parameters_ex(ret, prime_len, generator, cb)) {
+ BN_GENCB_free(cb);
+ return ret;
+ }
+ BN_GENCB_free(cb);
+ DH_free(ret);
+ return NULL;
+}
+#endif
diff --git a/openssl-1.1.0h/crypto/dh/dh_err.c b/openssl-1.1.0h/crypto/dh/dh_err.c
new file mode 100644
index 0000000..4e21f28
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_err.c
@@ -0,0 +1,73 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dh.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason)
+
+static ERR_STRING_DATA DH_str_functs[] = {
+ {ERR_FUNC(DH_F_COMPUTE_KEY), "compute_key"},
+ {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"},
+ {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "dh_builtin_genparams"},
+ {ERR_FUNC(DH_F_DH_CMS_DECRYPT), "dh_cms_decrypt"},
+ {ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "dh_cms_set_peerkey"},
+ {ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "dh_cms_set_shared_info"},
+ {ERR_FUNC(DH_F_DH_METH_DUP), "DH_meth_dup"},
+ {ERR_FUNC(DH_F_DH_METH_NEW), "DH_meth_new"},
+ {ERR_FUNC(DH_F_DH_METH_SET1_NAME), "DH_meth_set1_name"},
+ {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"},
+ {ERR_FUNC(DH_F_DH_PARAM_DECODE), "dh_param_decode"},
+ {ERR_FUNC(DH_F_DH_PRIV_DECODE), "dh_priv_decode"},
+ {ERR_FUNC(DH_F_DH_PRIV_ENCODE), "dh_priv_encode"},
+ {ERR_FUNC(DH_F_DH_PUB_DECODE), "dh_pub_decode"},
+ {ERR_FUNC(DH_F_DH_PUB_ENCODE), "dh_pub_encode"},
+ {ERR_FUNC(DH_F_DO_DH_PRINT), "do_dh_print"},
+ {ERR_FUNC(DH_F_GENERATE_KEY), "generate_key"},
+ {ERR_FUNC(DH_F_PKEY_DH_DERIVE), "pkey_dh_derive"},
+ {ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "pkey_dh_keygen"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA DH_str_reasons[] = {
+ {ERR_REASON(DH_R_BAD_GENERATOR), "bad generator"},
+ {ERR_REASON(DH_R_BN_DECODE_ERROR), "bn decode error"},
+ {ERR_REASON(DH_R_BN_ERROR), "bn error"},
+ {ERR_REASON(DH_R_DECODE_ERROR), "decode error"},
+ {ERR_REASON(DH_R_INVALID_PUBKEY), "invalid public key"},
+ {ERR_REASON(DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
+ {ERR_REASON(DH_R_KEYS_NOT_SET), "keys not set"},
+ {ERR_REASON(DH_R_MODULUS_TOO_LARGE), "modulus too large"},
+ {ERR_REASON(DH_R_NO_PARAMETERS_SET), "no parameters set"},
+ {ERR_REASON(DH_R_NO_PRIVATE_VALUE), "no private value"},
+ {ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"},
+ {ERR_REASON(DH_R_PEER_KEY_ERROR), "peer key error"},
+ {ERR_REASON(DH_R_SHARED_INFO_ERROR), "shared info error"},
+ {0, NULL}
+};
+
+#endif
+
+int ERR_load_DH_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(DH_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, DH_str_functs);
+ ERR_load_strings(0, DH_str_reasons);
+ }
+#endif
+ return 1;
+}
diff --git a/openssl-1.1.0h/crypto/dh/dh_gen.c b/openssl-1.1.0h/crypto/dh/dh_gen.c
new file mode 100644
index 0000000..27ecb98
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_gen.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * NB: These functions have been upgraded - the previous prototypes are in
+ * dh_depr.c as wrappers to these ones. - Geoff
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dh_locl.h"
+
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
+ BN_GENCB *cb);
+
+int DH_generate_parameters_ex(DH *ret, int prime_len, int generator,
+ BN_GENCB *cb)
+{
+ if (ret->meth->generate_params)
+ return ret->meth->generate_params(ret, prime_len, generator, cb);
+ return dh_builtin_genparams(ret, prime_len, generator, cb);
+}
+
+/*-
+ * We generate DH parameters as follows
+ * find a prime q which is prime_len/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a safe prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+/*
+ * Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
+ BN_GENCB *cb)
+{
+ BIGNUM *t1, *t2;
+ int g, ok = -1;
+ BN_CTX *ctx = NULL;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ t2 = BN_CTX_get(ctx);
+ if (t1 == NULL || t2 == NULL)
+ goto err;
+
+ /* Make sure 'ret' has the necessary elements */
+ if (!ret->p && ((ret->p = BN_new()) == NULL))
+ goto err;
+ if (!ret->g && ((ret->g = BN_new()) == NULL))
+ goto err;
+
+ if (generator <= 1) {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
+ goto err;
+ }
+ if (generator == DH_GENERATOR_2) {
+ if (!BN_set_word(t1, 24))
+ goto err;
+ if (!BN_set_word(t2, 11))
+ goto err;
+ g = 2;
+ } else if (generator == DH_GENERATOR_5) {
+ if (!BN_set_word(t1, 10))
+ goto err;
+ if (!BN_set_word(t2, 3))
+ goto err;
+ /*
+ * BN_set_word(t3,7); just have to miss out on these ones :-(
+ */
+ g = 5;
+ } else {
+ /*
+ * in the general case, don't worry if 'generator' is a generator or
+ * not: since we are using safe primes, it will generate either an
+ * order-q or an order-2q group, which both is OK
+ */
+ if (!BN_set_word(t1, 2))
+ goto err;
+ if (!BN_set_word(t2, 1))
+ goto err;
+ g = generator;
+ }
+
+ if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb))
+ goto err;
+ if (!BN_GENCB_call(cb, 3, 0))
+ goto err;
+ if (!BN_set_word(ret->g, g))
+ goto err;
+ ok = 1;
+ err:
+ if (ok == -1) {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB);
+ ok = 0;
+ }
+
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ok;
+}
diff --git a/openssl-1.1.0h/crypto/dh/dh_kdf.c b/openssl-1.1.0h/crypto/dh/dh_kdf.c
new file mode 100644
index 0000000..2782eee
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_kdf.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <e_os.h>
+
+#ifndef OPENSSL_NO_CMS
+#include <string.h>
+#include <openssl/dh.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/cms.h>
+
+
+/* Key derivation from X9.42/RFC2631 */
+/* Uses CMS functions, hence the #ifdef wrapper. */
+
+#define DH_KDF_MAX (1L << 30)
+
+/* Skip past an ASN1 structure: for OBJECT skip content octets too */
+
+static int skip_asn1(unsigned char **pp, long *plen, int exptag)
+{
+ const unsigned char *q = *pp;
+ int i, tag, xclass;
+ long tmplen;
+ i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen);
+ if (i & 0x80)
+ return 0;
+ if (tag != exptag || xclass != V_ASN1_UNIVERSAL)
+ return 0;
+ if (tag == V_ASN1_OBJECT)
+ q += tmplen;
+ *plen -= q - *pp;
+ *pp = (unsigned char *)q;
+ return 1;
+}
+
+/*
+ * Encode the DH shared info structure, return an offset to the counter value
+ * so we can update the structure without reencoding it.
+ */
+
+static int dh_sharedinfo_encode(unsigned char **pder, unsigned char **pctr,
+ ASN1_OBJECT *key_oid, size_t outlen,
+ const unsigned char *ukm, size_t ukmlen)
+{
+ unsigned char *p;
+ int derlen;
+ long tlen;
+ /* "magic" value to check offset is sane */
+ static unsigned char ctr[4] = { 0xF3, 0x17, 0x22, 0x53 };
+ X509_ALGOR atmp;
+ ASN1_OCTET_STRING ctr_oct, ukm_oct, *pukm_oct;
+ ASN1_TYPE ctr_atype;
+ if (ukmlen > DH_KDF_MAX || outlen > DH_KDF_MAX)
+ return 0;
+ ctr_oct.data = ctr;
+ ctr_oct.length = 4;
+ ctr_oct.flags = 0;
+ ctr_oct.type = V_ASN1_OCTET_STRING;
+ ctr_atype.type = V_ASN1_OCTET_STRING;
+ ctr_atype.value.octet_string = &ctr_oct;
+ atmp.algorithm = key_oid;
+ atmp.parameter = &ctr_atype;
+ if (ukm) {
+ ukm_oct.type = V_ASN1_OCTET_STRING;
+ ukm_oct.flags = 0;
+ ukm_oct.data = (unsigned char *)ukm;
+ ukm_oct.length = ukmlen;
+ pukm_oct = &ukm_oct;
+ } else
+ pukm_oct = NULL;
+ derlen = CMS_SharedInfo_encode(pder, &atmp, pukm_oct, outlen);
+ if (derlen <= 0)
+ return 0;
+ p = *pder;
+ tlen = derlen;
+ if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE))
+ return 0;
+ if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE))
+ return 0;
+ if (!skip_asn1(&p, &tlen, V_ASN1_OBJECT))
+ return 0;
+ if (!skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING))
+ return 0;
+ if (CRYPTO_memcmp(p, ctr, 4))
+ return 0;
+ *pctr = p;
+ return derlen;
+}
+
+int DH_KDF_X9_42(unsigned char *out, size_t outlen,
+ const unsigned char *Z, size_t Zlen,
+ ASN1_OBJECT *key_oid,
+ const unsigned char *ukm, size_t ukmlen, const EVP_MD *md)
+{
+ EVP_MD_CTX *mctx = NULL;
+ int rv = 0;
+ unsigned int i;
+ size_t mdlen;
+ unsigned char *der = NULL, *ctr;
+ int derlen;
+ if (Zlen > DH_KDF_MAX)
+ return 0;
+ mctx = EVP_MD_CTX_new();
+ if (mctx == NULL)
+ return 0;
+ mdlen = EVP_MD_size(md);
+ derlen = dh_sharedinfo_encode(&der, &ctr, key_oid, outlen, ukm, ukmlen);
+ if (derlen == 0)
+ goto err;
+ for (i = 1;; i++) {
+ unsigned char mtmp[EVP_MAX_MD_SIZE];
+ if (!EVP_DigestInit_ex(mctx, md, NULL)
+ || !EVP_DigestUpdate(mctx, Z, Zlen))
+ goto err;
+ ctr[3] = i & 0xFF;
+ ctr[2] = (i >> 8) & 0xFF;
+ ctr[1] = (i >> 16) & 0xFF;
+ ctr[0] = (i >> 24) & 0xFF;
+ if (!EVP_DigestUpdate(mctx, der, derlen))
+ goto err;
+ if (outlen >= mdlen) {
+ if (!EVP_DigestFinal(mctx, out, NULL))
+ goto err;
+ outlen -= mdlen;
+ if (outlen == 0)
+ break;
+ out += mdlen;
+ } else {
+ if (!EVP_DigestFinal(mctx, mtmp, NULL))
+ goto err;
+ memcpy(out, mtmp, outlen);
+ OPENSSL_cleanse(mtmp, mdlen);
+ break;
+ }
+ }
+ rv = 1;
+ err:
+ OPENSSL_free(der);
+ EVP_MD_CTX_free(mctx);
+ return rv;
+}
+#endif
diff --git a/openssl-1.1.0h/crypto/dh/dh_key.c b/openssl-1.1.0h/crypto/dh/dh_key.c
new file mode 100644
index 0000000..fce9ff4
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_key.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include "dh_locl.h"
+#include "internal/bn_int.h"
+
+static int generate_key(DH *dh);
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int dh_init(DH *dh);
+static int dh_finish(DH *dh);
+
+int DH_generate_key(DH *dh)
+{
+ return dh->meth->generate_key(dh);
+}
+
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+ return dh->meth->compute_key(key, pub_key, dh);
+}
+
+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+ int rv, pad;
+ rv = dh->meth->compute_key(key, pub_key, dh);
+ if (rv <= 0)
+ return rv;
+ pad = BN_num_bytes(dh->p) - rv;
+ if (pad > 0) {
+ memmove(key + pad, key, rv);
+ memset(key, 0, pad);
+ }
+ return rv + pad;
+}
+
+static DH_METHOD dh_ossl = {
+ "OpenSSL DH Method",
+ generate_key,
+ compute_key,
+ dh_bn_mod_exp,
+ dh_init,
+ dh_finish,
+ DH_FLAG_FIPS_METHOD,
+ NULL,
+ NULL
+};
+
+static const DH_METHOD *default_DH_method = &dh_ossl;
+
+const DH_METHOD *DH_OpenSSL(void)
+{
+ return &dh_ossl;
+}
+
+void DH_set_default_method(const DH_METHOD *meth)
+{
+ default_DH_method = meth;
+}
+
+const DH_METHOD *DH_get_default_method(void)
+{
+ return default_DH_method;
+}
+
+static int generate_key(DH *dh)
+{
+ int ok = 0;
+ int generate_new_key = 0;
+ unsigned l;
+ BN_CTX *ctx;
+ BN_MONT_CTX *mont = NULL;
+ BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+
+ if (dh->priv_key == NULL) {
+ priv_key = BN_secure_new();
+ if (priv_key == NULL)
+ goto err;
+ generate_new_key = 1;
+ } else
+ priv_key = dh->priv_key;
+
+ if (dh->pub_key == NULL) {
+ pub_key = BN_new();
+ if (pub_key == NULL)
+ goto err;
+ } else
+ pub_key = dh->pub_key;
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P) {
+ mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+ dh->lock, dh->p, ctx);
+ if (!mont)
+ goto err;
+ }
+
+ if (generate_new_key) {
+ if (dh->q) {
+ do {
+ if (!BN_rand_range(priv_key, dh->q))
+ goto err;
+ }
+ while (BN_is_zero(priv_key) || BN_is_one(priv_key));
+ } else {
+ /* secret exponent length */
+ l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
+ if (!BN_rand(priv_key, l, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
+ goto err;
+ }
+ }
+
+ {
+ BIGNUM *prk = BN_new();
+
+ if (prk == NULL)
+ goto err;
+ BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+
+ if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) {
+ BN_free(prk);
+ goto err;
+ }
+ /* We MUST free prk before any further use of priv_key */
+ BN_free(prk);
+ }
+
+ dh->pub_key = pub_key;
+ dh->priv_key = priv_key;
+ ok = 1;
+ err:
+ if (ok != 1)
+ DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);
+
+ if (pub_key != dh->pub_key)
+ BN_free(pub_key);
+ if (priv_key != dh->priv_key)
+ BN_free(priv_key);
+ BN_CTX_free(ctx);
+ return (ok);
+}
+
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+ BN_CTX *ctx = NULL;
+ BN_MONT_CTX *mont = NULL;
+ BIGNUM *tmp;
+ int ret = -1;
+ int check_result;
+
+ if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+ DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (tmp == NULL)
+ goto err;
+
+ if (dh->priv_key == NULL) {
+ DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);
+ goto err;
+ }
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P) {
+ mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+ dh->lock, dh->p, ctx);
+ BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
+ if (!mont)
+ goto err;
+ }
+
+ if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
+ DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY);
+ goto err;
+ }
+
+ if (!dh->
+ meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) {
+ DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ ret = BN_bn2bin(tmp, key);
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return (ret);
+}
+
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+ return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
+}
+
+static int dh_init(DH *dh)
+{
+ dh->flags |= DH_FLAG_CACHE_MONT_P;
+ return (1);
+}
+
+static int dh_finish(DH *dh)
+{
+ BN_MONT_CTX_free(dh->method_mont_p);
+ return (1);
+}
diff --git a/openssl-1.1.0h/crypto/dh/dh_lib.c b/openssl-1.1.0h/crypto/dh/dh_lib.c
new file mode 100644
index 0000000..716f4a4
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_lib.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dh_locl.h"
+#include <openssl/engine.h>
+
+int DH_set_method(DH *dh, const DH_METHOD *meth)
+{
+ /*
+ * NB: The caller is specifically setting a method, so it's not up to us
+ * to deal with which ENGINE it comes from.
+ */
+ const DH_METHOD *mtmp;
+ mtmp = dh->meth;
+ if (mtmp->finish)
+ mtmp->finish(dh);
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_finish(dh->engine);
+ dh->engine = NULL;
+#endif
+ dh->meth = meth;
+ if (meth->init)
+ meth->init(dh);
+ return 1;
+}
+
+DH *DH_new(void)
+{
+ return DH_new_method(NULL);
+}
+
+DH *DH_new_method(ENGINE *engine)
+{
+ DH *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL) {
+ DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ret->references = 1;
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL) {
+ DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ ret->meth = DH_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+ ret->flags = ret->meth->flags; /* early default init */
+ if (engine) {
+ if (!ENGINE_init(engine)) {
+ DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+ goto err;
+ }
+ ret->engine = engine;
+ } else
+ ret->engine = ENGINE_get_default_DH();
+ if (ret->engine) {
+ ret->meth = ENGINE_get_DH(ret->engine);
+ if (ret->meth == NULL) {
+ DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+ goto err;
+ }
+ }
+#endif
+
+ ret->flags = ret->meth->flags;
+
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data))
+ goto err;
+
+ if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+ DHerr(DH_F_DH_NEW_METHOD, ERR_R_INIT_FAIL);
+err:
+ DH_free(ret);
+ ret = NULL;
+ }
+
+ return ret;
+}
+
+void DH_free(DH *r)
+{
+ int i;
+
+ if (r == NULL)
+ return;
+
+ CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
+ REF_PRINT_COUNT("DH", r);
+ if (i > 0)
+ return;
+ REF_ASSERT_ISNT(i < 0);
+
+ if (r->meth->finish)
+ r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_finish(r->engine);
+#endif
+
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data);
+
+ CRYPTO_THREAD_lock_free(r->lock);
+
+ BN_clear_free(r->p);
+ BN_clear_free(r->g);
+ BN_clear_free(r->q);
+ BN_clear_free(r->j);
+ OPENSSL_free(r->seed);
+ BN_clear_free(r->counter);
+ BN_clear_free(r->pub_key);
+ BN_clear_free(r->priv_key);
+ OPENSSL_free(r);
+}
+
+int DH_up_ref(DH *r)
+{
+ int i;
+
+ if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("DH", r);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
+int DH_set_ex_data(DH *d, int idx, void *arg)
+{
+ return (CRYPTO_set_ex_data(&d->ex_data, idx, arg));
+}
+
+void *DH_get_ex_data(DH *d, int idx)
+{
+ return (CRYPTO_get_ex_data(&d->ex_data, idx));
+}
+
+int DH_bits(const DH *dh)
+{
+ return BN_num_bits(dh->p);
+}
+
+int DH_size(const DH *dh)
+{
+ return (BN_num_bytes(dh->p));
+}
+
+int DH_security_bits(const DH *dh)
+{
+ int N;
+ if (dh->q)
+ N = BN_num_bits(dh->q);
+ else if (dh->length)
+ N = dh->length;
+ else
+ N = -1;
+ return BN_security_bits(BN_num_bits(dh->p), N);
+}
+
+
+void DH_get0_pqg(const DH *dh,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = dh->p;
+ if (q != NULL)
+ *q = dh->q;
+ if (g != NULL)
+ *g = dh->g;
+}
+
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL. q may remain NULL.
+ */
+ if ((dh->p == NULL && p == NULL)
+ || (dh->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(dh->p);
+ dh->p = p;
+ }
+ if (q != NULL) {
+ BN_free(dh->q);
+ dh->q = q;
+ }
+ if (g != NULL) {
+ BN_free(dh->g);
+ dh->g = g;
+ }
+
+ if (q != NULL) {
+ dh->length = BN_num_bits(q);
+ }
+
+ return 1;
+}
+
+long DH_get_length(const DH *dh)
+{
+ return dh->length;
+}
+
+int DH_set_length(DH *dh, long length)
+{
+ dh->length = length;
+ return 1;
+}
+
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = dh->pub_key;
+ if (priv_key != NULL)
+ *priv_key = dh->priv_key;
+}
+
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ if (pub_key != NULL) {
+ BN_free(dh->pub_key);
+ dh->pub_key = pub_key;
+ }
+ if (priv_key != NULL) {
+ BN_free(dh->priv_key);
+ dh->priv_key = priv_key;
+ }
+
+ return 1;
+}
+
+void DH_clear_flags(DH *dh, int flags)
+{
+ dh->flags &= ~flags;
+}
+
+int DH_test_flags(const DH *dh, int flags)
+{
+ return dh->flags & flags;
+}
+
+void DH_set_flags(DH *dh, int flags)
+{
+ dh->flags |= flags;
+}
+
+ENGINE *DH_get0_engine(DH *dh)
+{
+ return dh->engine;
+}
diff --git a/openssl-1.1.0h/crypto/dh/dh_locl.h b/openssl-1.1.0h/crypto/dh/dh_locl.h
new file mode 100644
index 0000000..19301c3
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_locl.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/dh.h>
+
+struct dh_st {
+ /*
+ * This first argument is used to pick up errors when a DH is passed
+ * instead of a EVP_PKEY
+ */
+ int pad;
+ int version;
+ BIGNUM *p;
+ BIGNUM *g;
+ long length; /* optional */
+ BIGNUM *pub_key; /* g^x % p */
+ BIGNUM *priv_key; /* x */
+ int flags;
+ BN_MONT_CTX *method_mont_p;
+ /* Place holders if we want to do X9.42 DH */
+ BIGNUM *q;
+ BIGNUM *j;
+ unsigned char *seed;
+ int seedlen;
+ BIGNUM *counter;
+ int references;
+ CRYPTO_EX_DATA ex_data;
+ const DH_METHOD *meth;
+ ENGINE *engine;
+ CRYPTO_RWLOCK *lock;
+};
+
+struct dh_method {
+ char *name;
+ /* Methods here */
+ int (*generate_key) (DH *dh);
+ int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh);
+
+ /* Can be null */
+ int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+ int (*init) (DH *dh);
+ int (*finish) (DH *dh);
+ int flags;
+ char *app_data;
+ /* If this is non-NULL, it will be used to generate parameters */
+ int (*generate_params) (DH *dh, int prime_len, int generator,
+ BN_GENCB *cb);
+};
diff --git a/openssl-1.1.0h/crypto/dh/dh_meth.c b/openssl-1.1.0h/crypto/dh/dh_meth.c
new file mode 100644
index 0000000..ce6114c
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_meth.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "dh_locl.h"
+#include <string.h>
+#include <openssl/err.h>
+
+DH_METHOD *DH_meth_new(const char *name, int flags)
+{
+ DH_METHOD *dhm = OPENSSL_zalloc(sizeof(*dhm));
+
+ if (dhm != NULL) {
+ dhm->flags = flags;
+
+ dhm->name = OPENSSL_strdup(name);
+ if (dhm->name != NULL)
+ return dhm;
+
+ OPENSSL_free(dhm);
+ }
+
+ DHerr(DH_F_DH_METH_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+}
+
+void DH_meth_free(DH_METHOD *dhm)
+{
+ if (dhm != NULL) {
+ OPENSSL_free(dhm->name);
+ OPENSSL_free(dhm);
+ }
+}
+
+DH_METHOD *DH_meth_dup(const DH_METHOD *dhm)
+{
+ DH_METHOD *ret = OPENSSL_malloc(sizeof(*ret));
+
+ if (ret != NULL) {
+ memcpy(ret, dhm, sizeof(*dhm));
+
+ ret->name = OPENSSL_strdup(dhm->name);
+ if (ret->name != NULL)
+ return ret;
+
+ OPENSSL_free(ret);
+ }
+
+ DHerr(DH_F_DH_METH_DUP, ERR_R_MALLOC_FAILURE);
+ return NULL;
+}
+
+const char *DH_meth_get0_name(const DH_METHOD *dhm)
+{
+ return dhm->name;
+}
+
+int DH_meth_set1_name(DH_METHOD *dhm, const char *name)
+{
+ char *tmpname = OPENSSL_strdup(name);
+
+ if (tmpname == NULL) {
+ DHerr(DH_F_DH_METH_SET1_NAME, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ OPENSSL_free(dhm->name);
+ dhm->name = tmpname;
+
+ return 1;
+}
+
+int DH_meth_get_flags(DH_METHOD *dhm)
+{
+ return dhm->flags;
+}
+
+int DH_meth_set_flags(DH_METHOD *dhm, int flags)
+{
+ dhm->flags = flags;
+ return 1;
+}
+
+void *DH_meth_get0_app_data(const DH_METHOD *dhm)
+{
+ return dhm->app_data;
+}
+
+int DH_meth_set0_app_data(DH_METHOD *dhm, void *app_data)
+{
+ dhm->app_data = app_data;
+ return 1;
+}
+
+int (*DH_meth_get_generate_key(const DH_METHOD *dhm)) (DH *)
+{
+ return dhm->generate_key;
+}
+
+int DH_meth_set_generate_key(DH_METHOD *dhm, int (*generate_key) (DH *))
+{
+ dhm->generate_key = generate_key;
+ return 1;
+}
+
+int (*DH_meth_get_compute_key(const DH_METHOD *dhm))
+ (unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+ return dhm->compute_key;
+}
+
+int DH_meth_set_compute_key(DH_METHOD *dhm,
+ int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh))
+{
+ dhm->compute_key = compute_key;
+ return 1;
+}
+
+
+int (*DH_meth_get_bn_mod_exp(const DH_METHOD *dhm))
+ (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
+ BN_CTX *, BN_MONT_CTX *)
+{
+ return dhm->bn_mod_exp;
+}
+
+int DH_meth_set_bn_mod_exp(DH_METHOD *dhm,
+ int (*bn_mod_exp) (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+ const BIGNUM *, BN_CTX *, BN_MONT_CTX *))
+{
+ dhm->bn_mod_exp = bn_mod_exp;
+ return 1;
+}
+
+int (*DH_meth_get_init(const DH_METHOD *dhm))(DH *)
+{
+ return dhm->init;
+}
+
+int DH_meth_set_init(DH_METHOD *dhm, int (*init)(DH *))
+{
+ dhm->init = init;
+ return 1;
+}
+
+int (*DH_meth_get_finish(const DH_METHOD *dhm)) (DH *)
+{
+ return dhm->finish;
+}
+
+int DH_meth_set_finish(DH_METHOD *dhm, int (*finish) (DH *))
+{
+ dhm->finish = finish;
+ return 1;
+}
+
+int (*DH_meth_get_generate_params(const DH_METHOD *dhm))
+ (DH *, int, int, BN_GENCB *)
+{
+ return dhm->generate_params;
+}
+
+int DH_meth_set_generate_params(DH_METHOD *dhm,
+ int (*generate_params) (DH *, int, int, BN_GENCB *))
+{
+ dhm->generate_params = generate_params;
+ return 1;
+}
diff --git a/openssl-1.1.0h/crypto/dh/dh_pmeth.c b/openssl-1.1.0h/crypto/dh/dh_pmeth.c
new file mode 100644
index 0000000..c3e03c7
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_pmeth.c
@@ -0,0 +1,501 @@
+/*
+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include "dh_locl.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/objects.h>
+#include "internal/evp_int.h"
+
+/* DH pkey context structure */
+
+typedef struct {
+ /* Parameter gen parameters */
+ int prime_len;
+ int generator;
+ int use_dsa;
+ int subprime_len;
+ /* message digest used for parameter generation */
+ const EVP_MD *md;
+ int rfc5114_param;
+ /* Keygen callback info */
+ int gentmp[2];
+ /* KDF (if any) to use for DH */
+ char kdf_type;
+ /* OID to use for KDF */
+ ASN1_OBJECT *kdf_oid;
+ /* Message digest to use for key derivation */
+ const EVP_MD *kdf_md;
+ /* User key material */
+ unsigned char *kdf_ukm;
+ size_t kdf_ukmlen;
+ /* KDF output length */
+ size_t kdf_outlen;
+} DH_PKEY_CTX;
+
+static int pkey_dh_init(EVP_PKEY_CTX *ctx)
+{
+ DH_PKEY_CTX *dctx;
+
+ dctx = OPENSSL_zalloc(sizeof(*dctx));
+ if (dctx == NULL)
+ return 0;
+ dctx->prime_len = 1024;
+ dctx->subprime_len = -1;
+ dctx->generator = 2;
+ dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
+
+ ctx->data = dctx;
+ ctx->keygen_info = dctx->gentmp;
+ ctx->keygen_info_count = 2;
+
+ return 1;
+}
+
+static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
+{
+ DH_PKEY_CTX *dctx = ctx->data;
+ if (dctx != NULL) {
+ OPENSSL_free(dctx->kdf_ukm);
+ ASN1_OBJECT_free(dctx->kdf_oid);
+ OPENSSL_free(dctx);
+ }
+}
+
+
+static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+ DH_PKEY_CTX *dctx, *sctx;
+ if (!pkey_dh_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ dctx->prime_len = sctx->prime_len;
+ dctx->subprime_len = sctx->subprime_len;
+ dctx->generator = sctx->generator;
+ dctx->use_dsa = sctx->use_dsa;
+ dctx->md = sctx->md;
+ dctx->rfc5114_param = sctx->rfc5114_param;
+
+ dctx->kdf_type = sctx->kdf_type;
+ dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
+ if (dctx->kdf_oid == NULL)
+ return 0;
+ dctx->kdf_md = sctx->kdf_md;
+ if (sctx->kdf_ukm != NULL) {
+ dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
+ if (dctx->kdf_ukm == NULL)
+ return 0;
+ dctx->kdf_ukmlen = sctx->kdf_ukmlen;
+ }
+ dctx->kdf_outlen = sctx->kdf_outlen;
+ return 1;
+}
+
+static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+ DH_PKEY_CTX *dctx = ctx->data;
+ switch (type) {
+ case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
+ if (p1 < 256)
+ return -2;
+ dctx->prime_len = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
+ if (dctx->use_dsa == 0)
+ return -2;
+ dctx->subprime_len = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
+ if (dctx->use_dsa)
+ return -2;
+ dctx->generator = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
+#ifdef OPENSSL_NO_DSA
+ if (p1 != 0)
+ return -2;
+#else
+ if (p1 < 0 || p1 > 2)
+ return -2;
+#endif
+ dctx->use_dsa = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_RFC5114:
+ if (p1 < 1 || p1 > 3)
+ return -2;
+ dctx->rfc5114_param = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_PEER_KEY:
+ /* Default behaviour is OK */
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_KDF_TYPE:
+ if (p1 == -2)
+ return dctx->kdf_type;
+#ifdef OPENSSL_NO_CMS
+ if (p1 != EVP_PKEY_DH_KDF_NONE)
+#else
+ if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
+#endif
+ return -2;
+ dctx->kdf_type = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_KDF_MD:
+ dctx->kdf_md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_DH_KDF_MD:
+ *(const EVP_MD **)p2 = dctx->kdf_md;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
+ if (p1 <= 0)
+ return -2;
+ dctx->kdf_outlen = (size_t)p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
+ *(int *)p2 = dctx->kdf_outlen;
+ return 1;
+
+ case EVP_PKEY_CTRL_DH_KDF_UKM:
+ OPENSSL_free(dctx->kdf_ukm);
+ dctx->kdf_ukm = p2;
+ if (p2)
+ dctx->kdf_ukmlen = p1;
+ else
+ dctx->kdf_ukmlen = 0;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
+ *(unsigned char **)p2 = dctx->kdf_ukm;
+ return dctx->kdf_ukmlen;
+
+ case EVP_PKEY_CTRL_DH_KDF_OID:
+ ASN1_OBJECT_free(dctx->kdf_oid);
+ dctx->kdf_oid = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_DH_KDF_OID:
+ *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
+ return 1;
+
+ default:
+ return -2;
+
+ }
+}
+
+static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
+ const char *type, const char *value)
+{
+ if (strcmp(type, "dh_paramgen_prime_len") == 0) {
+ int len;
+ len = atoi(value);
+ return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
+ }
+ if (strcmp(type, "dh_rfc5114") == 0) {
+ DH_PKEY_CTX *dctx = ctx->data;
+ int len;
+ len = atoi(value);
+ if (len < 0 || len > 3)
+ return -2;
+ dctx->rfc5114_param = len;
+ return 1;
+ }
+ if (strcmp(type, "dh_paramgen_generator") == 0) {
+ int len;
+ len = atoi(value);
+ return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
+ }
+ if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
+ int len;
+ len = atoi(value);
+ return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
+ }
+ if (strcmp(type, "dh_paramgen_type") == 0) {
+ int typ;
+ typ = atoi(value);
+ return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
+ }
+ return -2;
+}
+
+#ifndef OPENSSL_NO_DSA
+
+extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+ const EVP_MD *evpmd,
+ const unsigned char *seed_in, size_t seed_len,
+ unsigned char *seed_out, int *counter_ret,
+ unsigned long *h_ret, BN_GENCB *cb);
+
+extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
+ const EVP_MD *evpmd,
+ const unsigned char *seed_in,
+ size_t seed_len, int idx,
+ unsigned char *seed_out, int *counter_ret,
+ unsigned long *h_ret, BN_GENCB *cb);
+
+static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
+{
+ DSA *ret;
+ int rv = 0;
+ int prime_len = dctx->prime_len;
+ int subprime_len = dctx->subprime_len;
+ const EVP_MD *md = dctx->md;
+ if (dctx->use_dsa > 2)
+ return NULL;
+ ret = DSA_new();
+ if (ret == NULL)
+ return NULL;
+ if (subprime_len == -1) {
+ if (prime_len >= 2048)
+ subprime_len = 256;
+ else
+ subprime_len = 160;
+ }
+ if (md == NULL) {
+ if (prime_len >= 2048)
+ md = EVP_sha256();
+ else
+ md = EVP_sha1();
+ }
+ if (dctx->use_dsa == 1)
+ rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
+ NULL, 0, NULL, NULL, NULL, pcb);
+ else if (dctx->use_dsa == 2)
+ rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
+ NULL, 0, -1, NULL, NULL, NULL, pcb);
+ if (rv <= 0) {
+ DSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+#endif
+
+static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ DH *dh = NULL;
+ DH_PKEY_CTX *dctx = ctx->data;
+ BN_GENCB *pcb;
+ int ret;
+ if (dctx->rfc5114_param) {
+ switch (dctx->rfc5114_param) {
+ case 1:
+ dh = DH_get_1024_160();
+ break;
+
+ case 2:
+ dh = DH_get_2048_224();
+ break;
+
+ case 3:
+ dh = DH_get_2048_256();
+ break;
+
+ default:
+ return -2;
+ }
+ EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+ return 1;
+ }
+
+ if (ctx->pkey_gencb) {
+ pcb = BN_GENCB_new();
+ if (pcb == NULL)
+ return 0;
+ evp_pkey_set_cb_translate(pcb, ctx);
+ } else
+ pcb = NULL;
+#ifndef OPENSSL_NO_DSA
+ if (dctx->use_dsa) {
+ DSA *dsa_dh;
+ dsa_dh = dsa_dh_generate(dctx, pcb);
+ BN_GENCB_free(pcb);
+ if (dsa_dh == NULL)
+ return 0;
+ dh = DSA_dup_DH(dsa_dh);
+ DSA_free(dsa_dh);
+ if (!dh)
+ return 0;
+ EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+ return 1;
+ }
+#endif
+ dh = DH_new();
+ if (dh == NULL) {
+ BN_GENCB_free(pcb);
+ return 0;
+ }
+ ret = DH_generate_parameters_ex(dh,
+ dctx->prime_len, dctx->generator, pcb);
+ BN_GENCB_free(pcb);
+ if (ret)
+ EVP_PKEY_assign_DH(pkey, dh);
+ else
+ DH_free(dh);
+ return ret;
+}
+
+static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ DH *dh = NULL;
+ if (ctx->pkey == NULL) {
+ DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
+ return 0;
+ }
+ dh = DH_new();
+ if (dh == NULL)
+ return 0;
+ EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
+ /* Note: if error return, pkey is freed by parent routine */
+ if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+ return 0;
+ return DH_generate_key(pkey->pkey.dh);
+}
+
+static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
+ size_t *keylen)
+{
+ int ret;
+ DH *dh;
+ DH_PKEY_CTX *dctx = ctx->data;
+ BIGNUM *dhpub;
+ if (!ctx->pkey || !ctx->peerkey) {
+ DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
+ return 0;
+ }
+ dh = ctx->pkey->pkey.dh;
+ dhpub = ctx->peerkey->pkey.dh->pub_key;
+ if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
+ if (key == NULL) {
+ *keylen = DH_size(dh);
+ return 1;
+ }
+ ret = DH_compute_key(key, dhpub, dh);
+ if (ret < 0)
+ return ret;
+ *keylen = ret;
+ return 1;
+ }
+#ifndef OPENSSL_NO_CMS
+ else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
+
+ unsigned char *Z = NULL;
+ size_t Zlen = 0;
+ if (!dctx->kdf_outlen || !dctx->kdf_oid)
+ return 0;
+ if (key == NULL) {
+ *keylen = dctx->kdf_outlen;
+ return 1;
+ }
+ if (*keylen != dctx->kdf_outlen)
+ return 0;
+ ret = 0;
+ Zlen = DH_size(dh);
+ Z = OPENSSL_malloc(Zlen);
+ if (Z == NULL) {
+ goto err;
+ }
+ if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
+ goto err;
+ if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
+ dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
+ goto err;
+ *keylen = dctx->kdf_outlen;
+ ret = 1;
+ err:
+ OPENSSL_clear_free(Z, Zlen);
+ return ret;
+ }
+#endif
+ return 0;
+}
+
+const EVP_PKEY_METHOD dh_pkey_meth = {
+ EVP_PKEY_DH,
+ 0,
+ pkey_dh_init,
+ pkey_dh_copy,
+ pkey_dh_cleanup,
+
+ 0,
+ pkey_dh_paramgen,
+
+ 0,
+ pkey_dh_keygen,
+
+ 0,
+ 0,
+
+ 0,
+ 0,
+
+ 0, 0,
+
+ 0, 0, 0, 0,
+
+ 0, 0,
+
+ 0, 0,
+
+ 0,
+ pkey_dh_derive,
+
+ pkey_dh_ctrl,
+ pkey_dh_ctrl_str
+};
+
+const EVP_PKEY_METHOD dhx_pkey_meth = {
+ EVP_PKEY_DHX,
+ 0,
+ pkey_dh_init,
+ pkey_dh_copy,
+ pkey_dh_cleanup,
+
+ 0,
+ pkey_dh_paramgen,
+
+ 0,
+ pkey_dh_keygen,
+
+ 0,
+ 0,
+
+ 0,
+ 0,
+
+ 0, 0,
+
+ 0, 0, 0, 0,
+
+ 0, 0,
+
+ 0, 0,
+
+ 0,
+ pkey_dh_derive,
+
+ pkey_dh_ctrl,
+ pkey_dh_ctrl_str
+};
diff --git a/openssl-1.1.0h/crypto/dh/dh_prn.c b/openssl-1.1.0h/crypto/dh/dh_prn.c
new file mode 100644
index 0000000..283fb0f
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_prn.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/dh.h>
+
+#ifndef OPENSSL_NO_STDIO
+int DHparams_print_fp(FILE *fp, const DH *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = DHparams_print(b, x);
+ BIO_free(b);
+ return (ret);
+}
+#endif
diff --git a/openssl-1.1.0h/crypto/dh/dh_rfc5114.c b/openssl-1.1.0h/crypto/dh/dh_rfc5114.c
new file mode 100644
index 0000000..c4a2195
--- /dev/null
+++ b/openssl-1.1.0h/crypto/dh/dh_rfc5114.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include "dh_locl.h"
+#include <openssl/bn.h>
+#include "internal/bn_dh.h"
+
+/*
+ * Macro to make a DH structure from BIGNUM data. NB: although just copying
+ * the BIGNUM static pointers would be more efficient, we can't do that
+ * because they get wiped using BN_clear_free() when DH_free() is called.
+ */
+
+#define make_dh(x) \
+DH *DH_get_##x(void) \
+{ \
+ DH *dh = DH_new(); \
+\
+ if (dh == NULL) \
+ return NULL; \
+ dh->p = BN_dup(&_bignum_dh##x##_p); \
+ dh->g = BN_dup(&_bignum_dh##x##_g); \
+ dh->q = BN_dup(&_bignum_dh##x##_q); \
+ if (dh->p == NULL || dh->q == NULL || dh->g == NULL) {\
+ DH_free(dh); \
+ return NULL; \
+ } \
+ return dh; \
+}
+
+make_dh(1024_160)
+make_dh(2048_224)
+make_dh(2048_256)