Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/crypto/dh
diff options
context:
space:
mode:
authorAdam Langley <agl@chromium.org>2014-06-20 23:00:00 +0400
committerAdam Langley <agl@chromium.org>2014-06-21 00:17:32 +0400
commit95c29f3cd1f6c08c6c0927868683392eea727ccb (patch)
tree012767320ced9abca61472a4daa4c4a56b7ebe2b /crypto/dh
Inital import.
Initial fork from f2d678e6e89b6508147086610e985d4e8416e867 (1.0.2 beta). (This change contains substantial changes from the original and effectively starts a new history.)
Diffstat (limited to 'crypto/dh')
-rw-r--r--crypto/dh/CMakeLists.txt22
-rw-r--r--crypto/dh/check.c177
-rw-r--r--crypto/dh/dh.c241
-rw-r--r--crypto/dh/dh.h259
-rw-r--r--crypto/dh/dh_asn1.c84
-rw-r--r--crypto/dh/dh_error.c29
-rw-r--r--crypto/dh/dh_impl.c323
-rw-r--r--crypto/dh/dh_test.c498
-rw-r--r--crypto/dh/internal.h76
-rw-r--r--crypto/dh/params.c271
10 files changed, 1980 insertions, 0 deletions
diff --git a/crypto/dh/CMakeLists.txt b/crypto/dh/CMakeLists.txt
new file mode 100644
index 00000000..719606cd
--- /dev/null
+++ b/crypto/dh/CMakeLists.txt
@@ -0,0 +1,22 @@
+include_directories(. .. ../../include)
+
+add_library(
+ dh
+
+ OBJECT
+
+ dh.c
+ dh_impl.c
+ params.c
+ check.c
+ dh_asn1.c
+ dh_error.c
+)
+
+add_executable(
+ dh_test
+
+ dh_test.c
+)
+
+target_link_libraries(dh_test crypto)
diff --git a/crypto/dh/check.c b/crypto/dh/check.c
new file mode 100644
index 00000000..f5099d5b
--- /dev/null
+++ b/crypto/dh/check.c
@@ -0,0 +1,177 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/dh.h>
+
+#include <openssl/bn.h>
+
+#include "internal.h"
+
+
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) {
+ int ok = 0;
+ BIGNUM q;
+
+ *ret = 0;
+ BN_init(&q);
+ if (!BN_set_word(&q, 1)) {
+ goto err;
+ }
+
+ if (BN_cmp(pub_key, &q) <= 0) {
+ *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
+ }
+ if (!BN_copy(&q, dh->p) ||
+ !BN_sub_word(&q, 1)) {
+ goto err;
+ }
+ if (BN_cmp(pub_key, &q) >= 0) {
+ *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
+ }
+
+ ok = 1;
+
+err:
+ BN_free(&q);
+ return ok;
+}
+
+
+int DH_check(const DH *dh, int *ret) {
+ /* 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 ok = 0;
+ 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);
+ t2 = BN_CTX_get(ctx);
+ if (t2 == NULL) {
+ goto err;
+ }
+
+ if (dh->q) {
+ if (BN_cmp(dh->g, BN_value_one()) <= 0) {
+ *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
+ } else if (BN_cmp(dh->g, dh->p) >= 0) {
+ *ret |= DH_CHECK_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_CHECK_NOT_SUITABLE_GENERATOR;
+ }
+ }
+ if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL)) {
+ *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 != 11) {
+ *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
+ }
+ } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
+ l = BN_mod_word(dh->p, 10);
+ if (l != 3 && l != 7) {
+ *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
+ }
+ } else {
+ *ret |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR;
+ }
+
+ if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL)) {
+ *ret |= DH_CHECK_P_NOT_PRIME;
+ } else if (!dh->q) {
+ if (!BN_rshift1(t1, dh->p)) {
+ goto err;
+ }
+ if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL)) {
+ *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
+ }
+ }
+ ok = 1;
+
+err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ok;
+}
diff --git a/crypto/dh/dh.c b/crypto/dh/dh.c
new file mode 100644
index 00000000..3e6ae6d4
--- /dev/null
+++ b/crypto/dh/dh.c
@@ -0,0 +1,241 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/dh.h>
+
+#include <openssl/bn.h>
+#include <openssl/buf.h>
+#include <openssl/err.h>
+#include <openssl/ex_data.h>
+#include <openssl/mem.h>
+#include <openssl/thread.h>
+
+#include "internal.h"
+
+
+extern const DH_METHOD DH_default_method;
+
+DH *DH_new(void) { return DH_new_method(NULL); }
+
+DH *DH_new_method(const ENGINE *engine) {
+ DH *dh = (DH *)OPENSSL_malloc(sizeof(DH));
+ if (dh == NULL) {
+ OPENSSL_PUT_ERROR(DH, DH_new_method, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ memset(dh, 0, sizeof(DH));
+
+ if (engine) {
+ dh->meth = ENGINE_get_DH_method(engine);
+ }
+
+ if (dh->meth == NULL) {
+ dh->meth = (DH_METHOD*) &DH_default_method;
+ }
+ METHOD_ref(dh->meth);
+
+ dh->references = 1;
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, dh, &dh->ex_data)) {
+ OPENSSL_free(dh);
+ return NULL;
+ }
+
+ if (dh->meth->init && !dh->meth->init(dh)) {
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, dh, &dh->ex_data);
+ METHOD_unref(dh->meth);
+ OPENSSL_free(dh);
+ return NULL;
+ }
+
+ return dh;
+}
+
+void DH_free(DH *dh) {
+ if (dh == NULL) {
+ return;
+ }
+
+ if (CRYPTO_add(&dh->references, -1, CRYPTO_LOCK_DH) > 0) {
+ return;
+ }
+
+ if (dh->meth->finish) {
+ dh->meth->finish(dh);
+ }
+ METHOD_unref(dh->meth);
+
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, dh, &dh->ex_data);
+
+ if (dh->method_mont_p) BN_MONT_CTX_free(dh->method_mont_p);
+ if (dh->p != NULL) BN_clear_free(dh->p);
+ if (dh->g != NULL) BN_clear_free(dh->g);
+ if (dh->q != NULL) BN_clear_free(dh->q);
+ if (dh->j != NULL) BN_clear_free(dh->j);
+ if (dh->seed) OPENSSL_free(dh->seed);
+ if (dh->counter != NULL) BN_clear_free(dh->counter);
+ if (dh->pub_key != NULL) BN_clear_free(dh->pub_key);
+ if (dh->priv_key != NULL) BN_clear_free(dh->priv_key);
+
+ OPENSSL_free(dh);
+}
+
+int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) {
+ if (dh->meth->generate_parameters) {
+ return dh->meth->generate_parameters(dh, prime_bits, generator, cb);
+ }
+ return DH_default_method.generate_parameters(dh, prime_bits, generator, cb);
+}
+
+int DH_generate_key(DH *dh) {
+ if (dh->meth->generate_key) {
+ return dh->meth->generate_key(dh);
+ }
+ return DH_default_method.generate_key(dh);
+}
+
+ssize_t DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
+ if (dh->meth->compute_key) {
+ return dh->meth->compute_key(dh, out, peers_key);
+ }
+ return DH_default_method.compute_key(dh, out, peers_key);
+}
+
+int DH_size(const DH *dh) { return BN_num_bytes(dh->p); }
+
+int DH_up_ref(DH *r) {
+ CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH);
+ return 1;
+}
+
+static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) {
+ BIGNUM *a = NULL;
+
+ if (src) {
+ a = BN_dup(src);
+ if (!a) {
+ return 0;
+ }
+ }
+
+ if (*dst) {
+ 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) ||
+ !int_dh_bn_cpy(&to->g, from->g)) {
+ return 0;
+ }
+
+ if (!is_x942) {
+ return 1;
+ }
+
+ if (!int_dh_bn_cpy(&to->q, from->q) ||
+ !int_dh_bn_cpy(&to->j, from->j)) {
+ return 0;
+ }
+
+ if (to->seed) {
+ OPENSSL_free(to->seed);
+ to->seed = NULL;
+ to->seedlen = 0;
+ }
+ if (from->seed) {
+ to->seed = BUF_memdup(from->seed, from->seedlen);
+ if (!to->seed) {
+ return 0;
+ }
+ to->seedlen = from->seedlen;
+ }
+
+ return 1;
+}
+
+DH *DHparams_dup(const DH *dh) {
+ DH *ret = DH_new();
+ if (!ret) {
+ return NULL;
+ }
+
+ if (!int_dh_param_copy(ret, dh, -1)) {
+ DH_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
+ return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp, new_func,
+ dup_func, free_func);
+}
+
+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));
+}
diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
new file mode 100644
index 00000000..d1b84f9f
--- /dev/null
+++ b/crypto/dh/dh.h
@@ -0,0 +1,259 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#ifndef OPENSSL_HEADER_DH_H
+#define OPENSSL_HEADER_DH_H
+
+#include <openssl/base.h>
+
+#include <openssl/engine.h>
+#include <openssl/ex_data.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* DH contains functions for performing Diffie-Hellman key agreement in
+ * multiplicative groups. */
+
+
+/* Allocation and destruction. */
+
+/* DH_new returns a new, empty DH object or NULL on error. */
+DH *DH_new(void);
+
+/* DH_new_method acts the same as |DH_new| but takes an explicit |ENGINE|. */
+DH *DH_new_method(const ENGINE *engine);
+
+/* DH_free decrements the reference count of |dh| and frees it if the reference
+ * count drops to zero. */
+void DH_free(DH *dh);
+
+/* DH_up_ref increments the reference count of |dh|. */
+int DH_up_ref(DH *dh);
+
+
+/* Standard parameters.
+ *
+ * These functions return new DH objects with standard parameters configured
+ * that use the given ENGINE, which may be NULL. They return NULL on allocation
+ * failure. */
+
+/* These parameters are taken from RFC 5114. */
+
+DH *DH_get_1024_160(const ENGINE *engine);
+DH *DH_get_2048_224(const ENGINE *engine);
+DH *DH_get_2048_256(const ENGINE *engine);
+
+
+/* Parameter generation. */
+
+#define DH_GENERATOR_2 2
+#define DH_GENERATOR_5 5
+
+/* DH_generate_parameters_ex generates a suitable Diffie-Hellman group with a
+ * prime that is |prime_bits| long and stores it in |dh|. The generator of the
+ * group will be |generator|, which should be |DH_GENERATOR_2| unless there's a
+ * good reason to use a different value. The |cb| argument contains a callback
+ * function that will be called during the generation. See the documentation in
+ * |bn.h| about this. In addition to the callback invocations from |BN|, |cb|
+ * will also be called with |event| equal to three when the generation is
+ * complete. */
+int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator,
+ BN_GENCB *cb);
+
+
+/* Diffie-Hellman operations. */
+
+/* DH_generate_key generates a new, random, private key and stores it in
+ * |dh|. It returns one on success and zero on error. */
+int DH_generate_key(DH *dh);
+
+/* DH_compute_key calculates the shared key between |dh| and |peers_key| and
+ * writes it as a big-endian integer into |out|, which must have |DH_size|
+ * bytes of space. It returns the number of bytes written, or a negative number
+ * on error. */
+ssize_t DH_compute_key(uint8_t *out, const BIGNUM *peers_key, DH *dh);
+
+
+/* Utility functions. */
+
+/* DH_size returns the number of bytes in the DH group's prime. */
+int DH_size(const DH *dh);
+
+#define DH_CHECK_P_NOT_PRIME 0x01
+#define DH_CHECK_P_NOT_SAFE_PRIME 0x02
+#define DH_CHECK_UNABLE_TO_CHECK_GENERATOR 0x04
+#define DH_CHECK_NOT_SUITABLE_GENERATOR 0x08
+#define DH_CHECK_Q_NOT_PRIME 0x10
+#define DH_CHECK_INVALID_Q_VALUE 0x20
+#define DH_CHECK_INVALID_J_VALUE 0x40
+
+/* DH_check checks the suitability of |dh| as a Diffie-Hellman group. and sets
+ * |DH_CHECK_*| flags in |*out_flags| if it finds any errors. It returns one if
+ * |*out_flags| was successfully set and zero on error.
+ *
+ * Note: these checks may be quite computationally expensive. */
+int DH_check(const DH *dh, int *out_flags);
+
+#define DH_CHECK_PUBKEY_TOO_SMALL 1
+#define DH_CHECK_PUBKEY_TOO_LARGE 2
+
+/* DH_check_pub_key checks the suitability of |pub_key| as a public key for the
+ * DH group in |dh| and sets |DH_CHECK_PUBKEY_*| flags in |*out_flags| if it
+ * finds any errors. It returns one if |*out_flags| was successfully set and
+ * zero on error. */
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags);
+
+/* DHparams_dup allocates a fresh |DH| and copies the parameters from |dh| into
+ * it. It returns the new |DH| or NULL on error. */
+DH *DHparams_dup(const DH *dh);
+
+
+/* ASN.1 functions. */
+
+/* d2i_DHparams parses an ASN.1, DER encoded Diffie-Hellman parameters
+ * structure from |len| bytes at |*inp|. If |ret| is not NULL then, on exit, a
+ * pointer to the result is in |*ret|. If |*ret| is already non-NULL on entry
+ * then the result is written directly into |*ret|, otherwise a fresh |DH| is
+ * allocated. On successful exit, |*inp| is advanced past the DER structure. It
+ * returns the result or NULL on error. */
+DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len);
+
+/* i2d_DHparams marshals |in| to an ASN.1, DER structure. If |outp| is not NULL
+ * then the result is written to |*outp| and |*outp| is advanced just past the
+ * output. It returns the number of bytes in the result, whether written or
+ * not, or a negative value on error. */
+int i2d_DHparams(const DH *in, unsigned char **outp);
+
+
+/* ex_data functions.
+ *
+ * These functions are wrappers. See |ex_data.h| for details. */
+
+int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DH_set_ex_data(DH *d, int idx, void *arg);
+void *DH_get_ex_data(DH *d, int idx);
+
+
+/* dh_method contains function pointers to override the implementation of DH.
+ * See |engine.h| for details. */
+struct dh_method {
+ struct openssl_method_common_st common;
+
+ /* app_data is an opaque pointer for the method to use. */
+ void *app_data;
+
+ /* init is called just before the return of |DH_new_method|. It returns one
+ * on success or zero on error. */
+ int (*init)(DH *dh);
+
+ /* finish is called before |dh| is destructed. */
+ void (*finish)(DH *dh);
+
+ /* generate_parameters is called by |DH_generate_parameters_ex|. */
+ int (*generate_parameters)(DH *dh, int prime_bits, int generator,
+ BN_GENCB *cb);
+
+ /* generate_parameters is called by |DH_generate_key|. */
+ int (*generate_key)(DH *dh);
+
+ /* generate_parameters is called by |DH_compute_key|. */
+ ssize_t (*compute_key)(DH *dh, uint8_t *out, const BIGNUM *pub_key);
+};
+
+struct dh_st {
+ DH_METHOD *meth;
+
+ BIGNUM *p;
+ BIGNUM *g;
+ BIGNUM *pub_key; /* g^x */
+ BIGNUM *priv_key; /* x */
+
+ /* priv_length contains the length, in bits, of the private value. If zero,
+ * the private value will be the same length as |p|. */
+ unsigned priv_length;
+ 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 flags;
+ int references;
+ CRYPTO_EX_DATA ex_data;
+};
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#define DH_F_generate_parameters 100
+#define DH_F_generate_key 101
+#define DH_F_compute_key 102
+#define DH_F_DH_new_method 103
+#define DH_R_INVALID_PUBKEY 100
+#define DH_R_BAD_GENERATOR 101
+#define DH_R_MODULUS_TOO_LARGE 102
+#define DH_R_NO_PRIVATE_VALUE 103
+
+#endif /* OPENSSL_HEADER_DH_H */
diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c
new file mode 100644
index 00000000..73cd4df7
--- /dev/null
+++ b/crypto/dh/dh_asn1.c
@@ -0,0 +1,84 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com). */
+
+#include <openssl/dh.h>
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+#include "internal.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) {
+ 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, priv_length, ZLONG)} ASN1_SEQUENCE_END_cb(DH, DHparams);
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
diff --git a/crypto/dh/dh_error.c b/crypto/dh/dh_error.c
new file mode 100644
index 00000000..8a7041cc
--- /dev/null
+++ b/crypto/dh/dh_error.c
@@ -0,0 +1,29 @@
+/* Copyright (c) 2014, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/err.h>
+
+#include "dh.h"
+
+const ERR_STRING_DATA DH_error_string_data[] = {
+ {ERR_PACK(ERR_LIB_DH, DH_F_DH_new_method, 0), "DH_new_method"},
+ {ERR_PACK(ERR_LIB_DH, DH_F_compute_key, 0), "compute_key"},
+ {ERR_PACK(ERR_LIB_DH, DH_F_generate_key, 0), "generate_key"},
+ {ERR_PACK(ERR_LIB_DH, DH_F_generate_parameters, 0), "generate_parameters"},
+ {ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR), "BAD_GENERATOR"},
+ {ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PUBKEY), "INVALID_PUBKEY"},
+ {ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "MODULUS_TOO_LARGE"},
+ {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PRIVATE_VALUE), "NO_PRIVATE_VALUE"},
+ {0, NULL},
+};
diff --git a/crypto/dh/dh_impl.c b/crypto/dh/dh_impl.c
new file mode 100644
index 00000000..edc3db7f
--- /dev/null
+++ b/crypto/dh/dh_impl.c
@@ -0,0 +1,323 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/dh.h>
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+
+#include "internal.h"
+
+#define OPENSSL_DH_MAX_MODULUS_BITS 10000
+
+static int generate_parameters(DH *ret, int prime_bits, int generator, BN_GENCB *cb) {
+ /* We generate DH parameters as follows
+ * find a prime q which is prime_bits/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.
+ */
+
+ BIGNUM *t1, *t2;
+ int g, ok = 0;
+ 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) {
+ OPENSSL_PUT_ERROR(DH, generate_parameters, 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_bits, 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) {
+ OPENSSL_PUT_ERROR(DH, generate_parameters, ERR_R_BN_LIB);
+ }
+
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ok;
+}
+
+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;
+ BIGNUM local_priv;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
+ }
+
+ if (dh->priv_key == NULL) {
+ priv_key = BN_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;
+ }
+
+ mont =
+ BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, 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->priv_length ? dh->priv_length : BN_num_bits(dh->p) - 1;
+ if (!BN_rand(priv_key, l, 0, 0)) {
+ goto err;
+ }
+ }
+ }
+
+ BN_with_flags(&local_priv, priv_key, BN_FLG_CONSTTIME);
+ if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx, mont)) {
+ goto err;
+ }
+
+ dh->pub_key = pub_key;
+ dh->priv_key = priv_key;
+ ok = 1;
+
+err:
+ if (ok != 1) {
+ OPENSSL_PUT_ERROR(DH, generate_key, ERR_R_BN_LIB);
+ }
+
+ if (pub_key != NULL && dh->pub_key == NULL) {
+ BN_free(pub_key);
+ }
+ if (priv_key != NULL && dh->priv_key == NULL) {
+ BN_free(priv_key);
+ }
+ BN_CTX_free(ctx);
+ return ok;
+}
+
+static ssize_t compute_key(DH *dh, unsigned char *out, const BIGNUM *pub_key) {
+ BN_CTX *ctx = NULL;
+ BN_MONT_CTX *mont = NULL;
+ BIGNUM *shared_key;
+ int ret = -1;
+ int check_result;
+ BIGNUM local_priv;
+
+ if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+ OPENSSL_PUT_ERROR(DH, compute_key, DH_R_MODULUS_TOO_LARGE);
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
+ }
+ BN_CTX_start(ctx);
+ shared_key = BN_CTX_get(ctx);
+ if (shared_key == NULL) {
+ goto err;
+ }
+
+ if (dh->priv_key == NULL) {
+ OPENSSL_PUT_ERROR(DH, compute_key, DH_R_NO_PRIVATE_VALUE);
+ goto err;
+ }
+
+ mont =
+ BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx);
+ if (!mont) {
+ goto err;
+ }
+
+ if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
+ OPENSSL_PUT_ERROR(DH, compute_key, DH_R_INVALID_PUBKEY);
+ goto err;
+ }
+
+ BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME);
+ if (!BN_mod_exp_mont(shared_key, pub_key, &local_priv, dh->p, ctx,
+ mont)) {
+ OPENSSL_PUT_ERROR(DH, compute_key, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ ret = BN_bn2bin(shared_key, out);
+
+err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ return ret;
+}
+
+const struct dh_method DH_default_method = {
+ {
+ 0 /* references */,
+ 1 /* is_static */,
+ },
+ NULL /* app_data */,
+ NULL /* init */,
+ NULL /* finish */,
+ generate_parameters,
+ generate_key,
+ compute_key,
+};
diff --git a/crypto/dh/dh_test.c b/crypto/dh/dh_test.c
new file mode 100644
index 00000000..73dbba92
--- /dev/null
+++ b/crypto/dh/dh_test.c
@@ -0,0 +1,498 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/dh.h>
+
+#include <stdio.h>
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/mem.h>
+
+#include "internal.h"
+
+
+static int cb(int p, int n, BN_GENCB *arg) {
+ char c = '*';
+
+ if (p == 0)
+ c = '.';
+ if (p == 1)
+ c = '+';
+ if (p == 2)
+ c = '*';
+ if (p == 3)
+ c = '\n';
+ BIO_write(arg->arg, &c, 1);
+ (void)BIO_flush(arg->arg);
+
+ return 1;
+}
+
+static int run_rfc5114_tests(void);
+
+int main(int argc, char *argv[]) {
+ BN_GENCB _cb;
+ DH *a;
+ DH *b = NULL;
+ char buf[12];
+ unsigned char *abuf = NULL, *bbuf = NULL;
+ int i, alen, blen, aout, bout, ret = 1;
+ BIO *out;
+
+ out = BIO_new(BIO_s_file());
+ if (out == NULL) {
+ return 1;
+ }
+ BIO_set_fp(out, stdout, BIO_NOCLOSE);
+
+ BN_GENCB_set(&_cb, &cb, out);
+ if (((a = DH_new()) == NULL) ||
+ !DH_generate_parameters_ex(a, 64, DH_GENERATOR_5, &_cb)) {
+ goto err;
+ }
+
+ if (!DH_check(a, &i))
+ goto err;
+ if (i & DH_CHECK_P_NOT_PRIME)
+ BIO_puts(out, "p value is not prime\n");
+ if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+ BIO_puts(out, "p value is not a safe prime\n");
+ if (i & DH_CHECK_UNABLE_TO_CHECK_GENERATOR)
+ BIO_puts(out, "unable to check the generator value\n");
+ if (i & DH_CHECK_NOT_SUITABLE_GENERATOR)
+ BIO_puts(out, "the g value is not a generator\n");
+
+ BIO_puts(out, "\np =");
+ BN_print(out, a->p);
+ BIO_puts(out, "\ng =");
+ BN_print(out, a->g);
+ BIO_puts(out, "\n");
+
+ b = DH_new();
+ if (b == NULL) {
+ goto err;
+ }
+
+ b->p = BN_dup(a->p);
+ b->g = BN_dup(a->g);
+ if (b->p == NULL || b->g == NULL) {
+ goto err;
+ }
+
+ if (!DH_generate_key(a))
+ goto err;
+ BIO_puts(out, "pri 1=");
+ BN_print(out, a->priv_key);
+ BIO_puts(out, "\npub 1=");
+ BN_print(out, a->pub_key);
+ BIO_puts(out, "\n");
+
+ if (!DH_generate_key(b))
+ goto err;
+ BIO_puts(out, "pri 2=");
+ BN_print(out, b->priv_key);
+ BIO_puts(out, "\npub 2=");
+ BN_print(out, b->pub_key);
+ BIO_puts(out, "\n");
+
+ alen = DH_size(a);
+ abuf = (unsigned char *)OPENSSL_malloc(alen);
+ aout = DH_compute_key(abuf, b->pub_key, a);
+
+ BIO_puts(out, "key1 =");
+ for (i = 0; i < aout; i++) {
+ sprintf(buf, "%02X", abuf[i]);
+ BIO_puts(out, buf);
+ }
+ BIO_puts(out, "\n");
+
+ blen = DH_size(b);
+ bbuf = (unsigned char *)OPENSSL_malloc(blen);
+ bout = DH_compute_key(bbuf, a->pub_key, b);
+
+ BIO_puts(out, "key2 =");
+ for (i = 0; i < bout; i++) {
+ sprintf(buf, "%02X", bbuf[i]);
+ BIO_puts(out, buf);
+ }
+ BIO_puts(out, "\n");
+ if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
+ fprintf(stderr, "Error in DH routines\n");
+ ret = 1;
+ } else
+ ret = 0;
+
+ if (!run_rfc5114_tests())
+ ret = 1;
+
+err:
+ BIO_print_errors_fp(stderr);
+
+ if (abuf != NULL)
+ OPENSSL_free(abuf);
+ if (bbuf != NULL)
+ OPENSSL_free(bbuf);
+ if (b != NULL)
+ DH_free(b);
+ if (a != NULL)
+ DH_free(a);
+ BIO_free(out);
+ return ret;
+}
+
+/* Test data from RFC 5114 */
+
+static const unsigned char dhtest_1024_160_xA[] = {
+ 0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04,
+ 0x96, 0x50, 0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E};
+static const unsigned char dhtest_1024_160_yA[] = {
+ 0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
+ 0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
+ 0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
+ 0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
+ 0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
+ 0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
+ 0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
+ 0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
+ 0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
+ 0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
+ 0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76};
+static const unsigned char dhtest_1024_160_xB[] = {
+ 0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22,
+ 0xF7, 0xD8, 0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA};
+static const unsigned char dhtest_1024_160_yB[] = {
+ 0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
+ 0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
+ 0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
+ 0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
+ 0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
+ 0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
+ 0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
+ 0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
+ 0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
+ 0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
+ 0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE};
+static const unsigned char dhtest_1024_160_Z[] = {
+ 0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
+ 0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
+ 0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
+ 0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
+ 0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
+ 0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
+ 0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
+ 0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
+ 0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
+ 0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
+ 0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D};
+static const unsigned char dhtest_2048_224_xA[] = {
+ 0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6,
+ 0x80, 0xF7, 0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72,
+ 0x1A, 0x05, 0x48, 0xE4, 0x83, 0x29, 0x4B, 0x0C};
+static const unsigned char dhtest_2048_224_yA[] = {
+ 0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
+ 0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
+ 0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
+ 0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
+ 0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
+ 0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
+ 0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
+ 0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
+ 0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
+ 0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
+ 0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
+ 0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
+ 0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
+ 0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
+ 0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
+ 0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
+ 0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
+ 0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
+ 0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
+ 0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
+ 0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
+ 0x71, 0x64, 0x8D, 0x6F};
+static const unsigned char dhtest_2048_224_xB[] = {
+ 0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3,
+ 0xB3, 0x63, 0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B,
+ 0x44, 0x17, 0xEA, 0x15, 0x35, 0x3B, 0x75, 0x90};
+static const unsigned char dhtest_2048_224_yB[] = {
+ 0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
+ 0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
+ 0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
+ 0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
+ 0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
+ 0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
+ 0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
+ 0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
+ 0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
+ 0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
+ 0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
+ 0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
+ 0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
+ 0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
+ 0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
+ 0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
+ 0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
+ 0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
+ 0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
+ 0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
+ 0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
+ 0x02, 0x14, 0x2B, 0x6C};
+static const unsigned char dhtest_2048_224_Z[] = {
+ 0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
+ 0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
+ 0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
+ 0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
+ 0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
+ 0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
+ 0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
+ 0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
+ 0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
+ 0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
+ 0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
+ 0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
+ 0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
+ 0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
+ 0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
+ 0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
+ 0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
+ 0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
+ 0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
+ 0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
+ 0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
+ 0xF9, 0xF6, 0x38, 0x69};
+static const unsigned char dhtest_2048_256_xA[] = {
+ 0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E,
+ 0x61, 0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C,
+ 0xC5, 0xE3, 0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E};
+static const unsigned char dhtest_2048_256_yA[] = {
+ 0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
+ 0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
+ 0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
+ 0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
+ 0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
+ 0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
+ 0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
+ 0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
+ 0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
+ 0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
+ 0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
+ 0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
+ 0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
+ 0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
+ 0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
+ 0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
+ 0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
+ 0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
+ 0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
+ 0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
+ 0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
+ 0x7C, 0xA6, 0x7E, 0x29};
+static const unsigned char dhtest_2048_256_xB[] = {
+ 0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1,
+ 0xAF, 0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67,
+ 0x05, 0x64, 0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D};
+static const unsigned char dhtest_2048_256_yB[] = {
+ 0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
+ 0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
+ 0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
+ 0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
+ 0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
+ 0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
+ 0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
+ 0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
+ 0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
+ 0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
+ 0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
+ 0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
+ 0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
+ 0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
+ 0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
+ 0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
+ 0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
+ 0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
+ 0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
+ 0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
+ 0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
+ 0x75, 0x7E, 0x19, 0x13};
+static const unsigned char dhtest_2048_256_Z[] = {
+ 0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
+ 0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
+ 0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
+ 0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
+ 0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
+ 0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
+ 0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
+ 0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
+ 0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
+ 0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
+ 0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
+ 0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
+ 0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
+ 0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
+ 0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
+ 0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
+ 0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
+ 0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
+ 0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
+ 0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
+ 0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
+ 0xC2, 0x6C, 0x5D, 0x7C};
+
+typedef struct {
+ DH *(*get_param)(const ENGINE *engine);
+ const unsigned char *xA;
+ size_t xA_len;
+ const unsigned char *yA;
+ size_t yA_len;
+ const unsigned char *xB;
+ size_t xB_len;
+ const unsigned char *yB;
+ size_t yB_len;
+ const unsigned char *Z;
+ size_t Z_len;
+} rfc5114_td;
+
+#define make_rfc5114_td(pre) \
+ { \
+ DH_get_##pre, dhtest_##pre##_xA, sizeof(dhtest_##pre##_xA), \
+ dhtest_##pre##_yA, sizeof(dhtest_##pre##_yA), dhtest_##pre##_xB, \
+ sizeof(dhtest_##pre##_xB), dhtest_##pre##_yB, \
+ sizeof(dhtest_##pre##_yB), dhtest_##pre##_Z, sizeof(dhtest_##pre##_Z) \
+ }
+
+static const rfc5114_td rfctd[] = {make_rfc5114_td(1024_160),
+ make_rfc5114_td(2048_224),
+ make_rfc5114_td(2048_256)};
+
+static int run_rfc5114_tests(void) {
+ int i;
+ DH *dhA = NULL, *dhB = NULL;
+ unsigned char *Z1 = NULL, *Z2 = NULL;
+
+ for (i = 0; i < (int)(sizeof(rfctd) / sizeof(rfc5114_td)); i++) {
+ const rfc5114_td *td = rfctd + i;
+ /* Set up DH structures setting key components */
+ dhA = td->get_param(NULL);
+ dhB = td->get_param(NULL);
+ if (!dhA || !dhB)
+ goto bad_err;
+
+ dhA->priv_key = BN_bin2bn(td->xA, td->xA_len, NULL);
+ dhA->pub_key = BN_bin2bn(td->yA, td->yA_len, NULL);
+
+ dhB->priv_key = BN_bin2bn(td->xB, td->xB_len, NULL);
+ dhB->pub_key = BN_bin2bn(td->yB, td->yB_len, NULL);
+
+ if (!dhA->priv_key || !dhA->pub_key || !dhB->priv_key || !dhB->pub_key)
+ goto bad_err;
+
+ if ((td->Z_len != (size_t)DH_size(dhA)) ||
+ (td->Z_len != (size_t)DH_size(dhB)))
+ goto err;
+
+ Z1 = OPENSSL_malloc(DH_size(dhA));
+ Z2 = OPENSSL_malloc(DH_size(dhB));
+ /* Work out shared secrets using both sides and compare
+ * with expected values.
+ */
+ if (!DH_compute_key(Z1, dhB->pub_key, dhA))
+ goto bad_err;
+ if (!DH_compute_key(Z2, dhA->pub_key, dhB))
+ goto bad_err;
+
+ if (memcmp(Z1, td->Z, td->Z_len))
+ goto err;
+ if (memcmp(Z2, td->Z, td->Z_len))
+ goto err;
+
+ printf("RFC5114 parameter test %d OK\n", i + 1);
+
+ DH_free(dhA);
+ dhA = NULL;
+ DH_free(dhB);
+ dhB = NULL;
+ OPENSSL_free(Z1);
+ Z1 = NULL;
+ OPENSSL_free(Z2);
+ Z2 = NULL;
+ }
+
+ printf("PASS\n");
+ return 1;
+
+bad_err:
+ fprintf(stderr, "Initalisation error RFC5114 set %d\n", i + 1);
+ BIO_print_errors_fp(stderr);
+
+err:
+ if (Z1 != NULL) {
+ OPENSSL_free(Z1);
+ }
+ if (Z2 != NULL) {
+ OPENSSL_free(Z2);
+ }
+ if (dhA != NULL) {
+ DH_free(dhA);
+ }
+ if (dhB != NULL) {
+ DH_free(dhB);
+ }
+
+ fprintf(stderr, "Test failed RFC5114 set %d\n", i + 1);
+ return 0;
+}
diff --git a/crypto/dh/internal.h b/crypto/dh/internal.h
new file mode 100644
index 00000000..e4c725cc
--- /dev/null
+++ b/crypto/dh/internal.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#ifndef OPENSSL_HEADER_DH_INTERNAL_H
+#define OPENSSL_HEADER_DH_INTERNAL_H
+
+#include <openssl/base.h>
+
+#include <openssl/bn.h>
+#include <openssl/ex_data.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_DH_INTERNAL_H */
diff --git a/crypto/dh/params.c b/crypto/dh/params.c
new file mode 100644
index 00000000..4b30c043
--- /dev/null
+++ b/crypto/dh/params.c
@@ -0,0 +1,271 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com). */
+
+#include <openssl/dh.h>
+
+#include <openssl/bn.h>
+
+#include "internal.h"
+
+
+#if BN_BITS2 == 64
+static const BN_ULONG dh1024_160_p[] = {
+ 0xDF1FB2BC2E4A4371ULL, 0xE68CFDA76D4DA708ULL, 0x45BF37DF365C1A65ULL,
+ 0xA151AF5F0DC8B4BDULL, 0xFAA31A4FF55BCCC0ULL, 0x4EFFD6FAE5644738ULL,
+ 0x98488E9C219A7372ULL, 0xACCBDD7D90C4BD70ULL, 0x24975C3CD49B83BFULL,
+ 0x13ECB4AEA9061123ULL, 0x9838EF1E2EE652C0ULL, 0x6073E28675A23D18ULL,
+ 0x9A6A9DCA52D23B61ULL, 0x52C99FBCFB06A3C6ULL, 0xDE92DE5EAE5D54ECULL,
+ 0xB10B8F96A080E01DULL};
+static const BN_ULONG dh1024_160_g[] = {
+ 0x855E6EEB22B3B2E5ULL, 0x858F4DCEF97C2A24ULL, 0x2D779D5918D08BC8ULL,
+ 0xD662A4D18E73AFA3ULL, 0x1DBF0A0169B6A28AULL, 0xA6A24C087A091F53ULL,
+ 0x909D0D2263F80A76ULL, 0xD7FBD7D3B9A92EE1ULL, 0x5E91547F9E2749F4ULL,
+ 0x160217B4B01B886AULL, 0x777E690F5504F213ULL, 0x266FEA1E5C41564BULL,
+ 0xD6406CFF14266D31ULL, 0xF8104DD258AC507FULL, 0x6765A442EFB99905ULL,
+ 0xA4D1CBD5C3FD3412ULL};
+static const BN_ULONG dh1024_160_q[] = {
+ 0x64B7CB9D49462353ULL, 0x81A8DF278ABA4E7DULL, 0x00000000F518AA87ULL};
+
+static const BN_ULONG dh2048_224_p[] = {
+ 0x0AC4DFFE0C10E64FULL, 0xCF9DE5384E71B81CULL, 0x7EF363E2FFA31F71ULL,
+ 0xE3FB73C16B8E75B9ULL, 0xC9B53DCF4BA80A29ULL, 0x23F10B0E16E79763ULL,
+ 0xC52172E413042E9BULL, 0xBE60E69CC928B2B9ULL, 0x80CD86A1B9E587E8ULL,
+ 0x315D75E198C641A4ULL, 0xCDF93ACC44328387ULL, 0x15987D9ADC0A486DULL,
+ 0x7310F7121FD5A074ULL, 0x278273C7DE31EFDCULL, 0x1602E714415D9330ULL,
+ 0x81286130BC8985DBULL, 0xB3BF8A3170918836ULL, 0x6A00E0A0B9C49708ULL,
+ 0xC6BA0B2C8BBC27BEULL, 0xC9F98D11ED34DBF6ULL, 0x7AD5B7D0B6C12207ULL,
+ 0xD91E8FEF55B7394BULL, 0x9037C9EDEFDA4DF8ULL, 0x6D3F8152AD6AC212ULL,
+ 0x1DE6B85A1274A0A6ULL, 0xEB3D688A309C180EULL, 0xAF9A3C407BA1DF15ULL,
+ 0xE6FA141DF95A56DBULL, 0xB54B1597B61D0A75ULL, 0xA20D64E5683B9FD1ULL,
+ 0xD660FAA79559C51FULL, 0xAD107E1E9123A9D0ULL};
+static const BN_ULONG dh2048_224_g[] = {
+ 0x84B890D3191F2BFAULL, 0x81BC087F2A7065B3ULL, 0x19C418E1F6EC0179ULL,
+ 0x7B5A0F1C71CFFF4CULL, 0xEDFE72FE9B6AA4BDULL, 0x81E1BCFE94B30269ULL,
+ 0x566AFBB48D6C0191ULL, 0xB539CCE3409D13CDULL, 0x6AA21E7F5F2FF381ULL,
+ 0xD9E263E4770589EFULL, 0x10E183EDD19963DDULL, 0xB70A8137150B8EEBULL,
+ 0x051AE3D428C8F8ACULL, 0xBB77A86F0C1AB15BULL, 0x6E3025E316A330EFULL,
+ 0x19529A45D6F83456ULL, 0xF180EB34118E98D1ULL, 0xB5F6C6B250717CBEULL,
+ 0x09939D54DA7460CDULL, 0xE247150422EA1ED4ULL, 0xB8A762D0521BC98AULL,
+ 0xF4D027275AC1348BULL, 0xC17669101999024AULL, 0xBE5E9001A8D66AD7ULL,
+ 0xC57DB17C620A8652ULL, 0xAB739D7700C29F52ULL, 0xDD921F01A70C4AFAULL,
+ 0xA6824A4E10B9A6F0ULL, 0x74866A08CFE4FFE3ULL, 0x6CDEBE7B89998CAFULL,
+ 0x9DF30B5C8FFDAC50ULL, 0xAC4032EF4F2D9AE3ULL};
+static const BN_ULONG dh2048_224_q[] = {
+ 0xBF389A99B36371EBULL, 0x1F80535A4738CEBCULL, 0xC58D93FE99717710ULL,
+ 0x00000000801C0D34ULL};
+
+static const BN_ULONG dh2048_256_p[] = {
+ 0xDB094AE91E1A1597ULL, 0x693877FAD7EF09CAULL, 0x6116D2276E11715FULL,
+ 0xA4B54330C198AF12ULL, 0x75F26375D7014103ULL, 0xC3A3960A54E710C3ULL,
+ 0xDED4010ABD0BE621ULL, 0xC0B857F689962856ULL, 0xB3CA3F7971506026ULL,
+ 0x1CCACB83E6B486F6ULL, 0x67E144E514056425ULL, 0xF6A167B5A41825D9ULL,
+ 0x3AD8347796524D8EULL, 0xF13C6D9A51BFA4ABULL, 0x2D52526735488A0EULL,
+ 0xB63ACAE1CAA6B790ULL, 0x4FDB70C581B23F76ULL, 0xBC39A0BF12307F5CULL,
+ 0xB941F54EB1E59BB8ULL, 0x6C5BFC11D45F9088ULL, 0x22E0B1EF4275BF7BULL,
+ 0x91F9E6725B4758C0ULL, 0x5A8A9D306BCF67EDULL, 0x209E0C6497517ABDULL,
+ 0x3BF4296D830E9A7CULL, 0x16C3D91134096FAAULL, 0xFAF7DF4561B2AA30ULL,
+ 0xE00DF8F1D61957D4ULL, 0x5D2CEED4435E3B00ULL, 0x8CEEF608660DD0F2ULL,
+ 0xFFBBD19C65195999ULL, 0x87A8E61DB4B6663CULL};
+static const BN_ULONG dh2048_256_g[] = {
+ 0x664B4C0F6CC41659ULL, 0x5E2327CFEF98C582ULL, 0xD647D148D4795451ULL,
+ 0x2F63078490F00EF8ULL, 0x184B523D1DB246C3ULL, 0xC7891428CDC67EB6ULL,
+ 0x7FD028370DF92B52ULL, 0xB3353BBB64E0EC37ULL, 0xECD06E1557CD0915ULL,
+ 0xB7D2BBD2DF016199ULL, 0xC8484B1E052588B9ULL, 0xDB2A3B7313D3FE14ULL,
+ 0xD052B985D182EA0AULL, 0xA4BD1BFFE83B9C80ULL, 0xDFC967C1FB3F2E55ULL,
+ 0xB5045AF2767164E1ULL, 0x1D14348F6F2F9193ULL, 0x64E67982428EBC83ULL,
+ 0x8AC376D282D6ED38ULL, 0x777DE62AAAB8A862ULL, 0xDDF463E5E9EC144BULL,
+ 0x0196F931C77A57F2ULL, 0xA55AE31341000A65ULL, 0x901228F8C28CBB18ULL,
+ 0xBC3773BF7E8C6F62ULL, 0xBE3A6C1B0C6B47B1ULL, 0xFF4FED4AAC0BB555ULL,
+ 0x10DBC15077BE463FULL, 0x07F4793A1A0BA125ULL, 0x4CA7B18F21EF2054ULL,
+ 0x2E77506660EDBD48ULL, 0x3FB32C9B73134D0BULL};
+static const BN_ULONG dh2048_256_q[] = {
+ 0xA308B0FE64F5FBD3ULL, 0x99B1A47D1EB3750BULL, 0xB447997640129DA2ULL,
+ 0x8CF83642A709A097ULL};
+
+#elif BN_BITS2 == 32
+
+static const BN_ULONG dh1024_160_p[] = {
+ 0x2E4A4371, 0xDF1FB2BC, 0x6D4DA708, 0xE68CFDA7, 0x365C1A65, 0x45BF37DF,
+ 0x0DC8B4BD, 0xA151AF5F, 0xF55BCCC0, 0xFAA31A4F, 0xE5644738, 0x4EFFD6FA,
+ 0x219A7372, 0x98488E9C, 0x90C4BD70, 0xACCBDD7D, 0xD49B83BF, 0x24975C3C,
+ 0xA9061123, 0x13ECB4AE, 0x2EE652C0, 0x9838EF1E, 0x75A23D18, 0x6073E286,
+ 0x52D23B61, 0x9A6A9DCA, 0xFB06A3C6, 0x52C99FBC, 0xAE5D54EC, 0xDE92DE5E,
+ 0xA080E01D, 0xB10B8F96};
+static const BN_ULONG dh1024_160_g[] = {
+ 0x22B3B2E5, 0x855E6EEB, 0xF97C2A24, 0x858F4DCE, 0x18D08BC8, 0x2D779D59,
+ 0x8E73AFA3, 0xD662A4D1, 0x69B6A28A, 0x1DBF0A01, 0x7A091F53, 0xA6A24C08,
+ 0x63F80A76, 0x909D0D22, 0xB9A92EE1, 0xD7FBD7D3, 0x9E2749F4, 0x5E91547F,
+ 0xB01B886A, 0x160217B4, 0x5504F213, 0x777E690F, 0x5C41564B, 0x266FEA1E,
+ 0x14266D31, 0xD6406CFF, 0x58AC507F, 0xF8104DD2, 0xEFB99905, 0x6765A442,
+ 0xC3FD3412, 0xA4D1CBD5};
+static const BN_ULONG dh1024_160_q[] = {0x49462353, 0x64B7CB9D, 0x8ABA4E7D,
+ 0x81A8DF27, 0xF518AA87};
+
+static const BN_ULONG dh2048_224_p[] = {
+ 0x0C10E64F, 0x0AC4DFFE, 0x4E71B81C, 0xCF9DE538, 0xFFA31F71, 0x7EF363E2,
+ 0x6B8E75B9, 0xE3FB73C1, 0x4BA80A29, 0xC9B53DCF, 0x16E79763, 0x23F10B0E,
+ 0x13042E9B, 0xC52172E4, 0xC928B2B9, 0xBE60E69C, 0xB9E587E8, 0x80CD86A1,
+ 0x98C641A4, 0x315D75E1, 0x44328387, 0xCDF93ACC, 0xDC0A486D, 0x15987D9A,
+ 0x1FD5A074, 0x7310F712, 0xDE31EFDC, 0x278273C7, 0x415D9330, 0x1602E714,
+ 0xBC8985DB, 0x81286130, 0x70918836, 0xB3BF8A31, 0xB9C49708, 0x6A00E0A0,
+ 0x8BBC27BE, 0xC6BA0B2C, 0xED34DBF6, 0xC9F98D11, 0xB6C12207, 0x7AD5B7D0,
+ 0x55B7394B, 0xD91E8FEF, 0xEFDA4DF8, 0x9037C9ED, 0xAD6AC212, 0x6D3F8152,
+ 0x1274A0A6, 0x1DE6B85A, 0x309C180E, 0xEB3D688A, 0x7BA1DF15, 0xAF9A3C40,
+ 0xF95A56DB, 0xE6FA141D, 0xB61D0A75, 0xB54B1597, 0x683B9FD1, 0xA20D64E5,
+ 0x9559C51F, 0xD660FAA7, 0x9123A9D0, 0xAD107E1E};
+static const BN_ULONG dh2048_224_g[] = {
+ 0x191F2BFA, 0x84B890D3, 0x2A7065B3, 0x81BC087F, 0xF6EC0179, 0x19C418E1,
+ 0x71CFFF4C, 0x7B5A0F1C, 0x9B6AA4BD, 0xEDFE72FE, 0x94B30269, 0x81E1BCFE,
+ 0x8D6C0191, 0x566AFBB4, 0x409D13CD, 0xB539CCE3, 0x5F2FF381, 0x6AA21E7F,
+ 0x770589EF, 0xD9E263E4, 0xD19963DD, 0x10E183ED, 0x150B8EEB, 0xB70A8137,
+ 0x28C8F8AC, 0x051AE3D4, 0x0C1AB15B, 0xBB77A86F, 0x16A330EF, 0x6E3025E3,
+ 0xD6F83456, 0x19529A45, 0x118E98D1, 0xF180EB34, 0x50717CBE, 0xB5F6C6B2,
+ 0xDA7460CD, 0x09939D54, 0x22EA1ED4, 0xE2471504, 0x521BC98A, 0xB8A762D0,
+ 0x5AC1348B, 0xF4D02727, 0x1999024A, 0xC1766910, 0xA8D66AD7, 0xBE5E9001,
+ 0x620A8652, 0xC57DB17C, 0x00C29F52, 0xAB739D77, 0xA70C4AFA, 0xDD921F01,
+ 0x10B9A6F0, 0xA6824A4E, 0xCFE4FFE3, 0x74866A08, 0x89998CAF, 0x6CDEBE7B,
+ 0x8FFDAC50, 0x9DF30B5C, 0x4F2D9AE3, 0xAC4032EF};
+static const BN_ULONG dh2048_224_q[] = {0xB36371EB, 0xBF389A99, 0x4738CEBC,
+ 0x1F80535A, 0x99717710, 0xC58D93FE,
+ 0x801C0D34};
+
+static const BN_ULONG dh2048_256_p[] = {
+ 0x1E1A1597, 0xDB094AE9, 0xD7EF09CA, 0x693877FA, 0x6E11715F, 0x6116D227,
+ 0xC198AF12, 0xA4B54330, 0xD7014103, 0x75F26375, 0x54E710C3, 0xC3A3960A,
+ 0xBD0BE621, 0xDED4010A, 0x89962856, 0xC0B857F6, 0x71506026, 0xB3CA3F79,
+ 0xE6B486F6, 0x1CCACB83, 0x14056425, 0x67E144E5, 0xA41825D9, 0xF6A167B5,
+ 0x96524D8E, 0x3AD83477, 0x51BFA4AB, 0xF13C6D9A, 0x35488A0E, 0x2D525267,
+ 0xCAA6B790, 0xB63ACAE1, 0x81B23F76, 0x4FDB70C5, 0x12307F5C, 0xBC39A0BF,
+ 0xB1E59BB8, 0xB941F54E, 0xD45F9088, 0x6C5BFC11, 0x4275BF7B, 0x22E0B1EF,
+ 0x5B4758C0, 0x91F9E672, 0x6BCF67ED, 0x5A8A9D30, 0x97517ABD, 0x209E0C64,
+ 0x830E9A7C, 0x3BF4296D, 0x34096FAA, 0x16C3D911, 0x61B2AA30, 0xFAF7DF45,
+ 0xD61957D4, 0xE00DF8F1, 0x435E3B00, 0x5D2CEED4, 0x660DD0F2, 0x8CEEF608,
+ 0x65195999, 0xFFBBD19C, 0xB4B6663C, 0x87A8E61D};
+static const BN_ULONG dh2048_256_g[] = {
+ 0x6CC41659, 0x664B4C0F, 0xEF98C582, 0x5E2327CF, 0xD4795451, 0xD647D148,
+ 0x90F00EF8, 0x2F630784, 0x1DB246C3, 0x184B523D, 0xCDC67EB6, 0xC7891428,
+ 0x0DF92B52, 0x7FD02837, 0x64E0EC37, 0xB3353BBB, 0x57CD0915, 0xECD06E15,
+ 0xDF016199, 0xB7D2BBD2, 0x052588B9, 0xC8484B1E, 0x13D3FE14, 0xDB2A3B73,
+ 0xD182EA0A, 0xD052B985, 0xE83B9C80, 0xA4BD1BFF, 0xFB3F2E55, 0xDFC967C1,
+ 0x767164E1, 0xB5045AF2, 0x6F2F9193, 0x1D14348F, 0x428EBC83, 0x64E67982,
+ 0x82D6ED38, 0x8AC376D2, 0xAAB8A862, 0x777DE62A, 0xE9EC144B, 0xDDF463E5,
+ 0xC77A57F2, 0x0196F931, 0x41000A65, 0xA55AE313, 0xC28CBB18, 0x901228F8,
+ 0x7E8C6F62, 0xBC3773BF, 0x0C6B47B1, 0xBE3A6C1B, 0xAC0BB555, 0xFF4FED4A,
+ 0x77BE463F, 0x10DBC150, 0x1A0BA125, 0x07F4793A, 0x21EF2054, 0x4CA7B18F,
+ 0x60EDBD48, 0x2E775066, 0x73134D0B, 0x3FB32C9B};
+static const BN_ULONG dh2048_256_q[] = {0x64F5FBD3, 0xA308B0FE, 0x1EB3750B,
+ 0x99B1A47D, 0x40129DA2, 0xB4479976,
+ 0xA709A097, 0x8CF83642};
+
+#else
+#error "unsupported BN_BITS2"
+#endif
+
+#define STATIC_BIGNUM(x) \
+ { \
+ (BN_ULONG *) x, sizeof(x) / sizeof(BN_ULONG), \
+ sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
+ }
+
+struct standard_parameters {
+ BIGNUM p, q, g;
+};
+
+static const struct standard_parameters dh1024_160 = {
+ STATIC_BIGNUM(dh1024_160_p),
+ STATIC_BIGNUM(dh1024_160_q),
+ STATIC_BIGNUM(dh1024_160_g),
+};
+
+static const struct standard_parameters dh2048_224 = {
+ STATIC_BIGNUM(dh2048_224_p),
+ STATIC_BIGNUM(dh2048_224_q),
+ STATIC_BIGNUM(dh2048_224_g),
+};
+
+static const struct standard_parameters dh2048_256 = {
+ STATIC_BIGNUM(dh2048_256_p),
+ STATIC_BIGNUM(dh2048_256_q),
+ STATIC_BIGNUM(dh2048_256_g),
+};
+
+static DH *get_standard_parameters(const struct standard_parameters *params,
+ const ENGINE *engine) {
+ DH *dh;
+
+ dh = DH_new_method(engine);
+ if (!dh) {
+ return NULL;
+ }
+
+ dh->p = BN_dup(&params->p);
+ dh->q = BN_dup(&params->q);
+ dh->g = BN_dup(&params->g);
+ if (!dh->p || !dh->q || !dh->g) {
+ DH_free(dh);
+ return NULL;
+ }
+
+ return dh;
+}
+
+DH *DH_get_1024_160(const ENGINE *engine) {
+ return get_standard_parameters(&dh1024_160, engine);
+}
+
+DH *DH_get_2048_224(const ENGINE *engine) {
+ return get_standard_parameters(&dh2048_224, engine);
+}
+
+DH *DH_get_2048_256(const ENGINE *engine) {
+ return get_standard_parameters(&dh2048_256, engine);
+}