diff options
Diffstat (limited to 'src/crypto/dh')
-rw-r--r-- | src/crypto/dh/CMakeLists.txt | 22 | ||||
-rw-r--r-- | src/crypto/dh/check.c | 180 | ||||
-rw-r--r-- | src/crypto/dh/dh.c | 243 | ||||
-rw-r--r-- | src/crypto/dh/dh_asn1.c | 84 | ||||
-rw-r--r-- | src/crypto/dh/dh_error.c | 29 | ||||
-rw-r--r-- | src/crypto/dh/dh_impl.c | 324 | ||||
-rw-r--r-- | src/crypto/dh/dh_test.c | 502 | ||||
-rw-r--r-- | src/crypto/dh/internal.h | 80 | ||||
-rw-r--r-- | src/crypto/dh/params.c | 316 |
9 files changed, 1780 insertions, 0 deletions
diff --git a/src/crypto/dh/CMakeLists.txt b/src/crypto/dh/CMakeLists.txt new file mode 100644 index 0000000..4e31206 --- /dev/null +++ b/src/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/src/crypto/dh/check.c b/src/crypto/dh/check.c new file mode 100644 index 0000000..06af6f2 --- /dev/null +++ b/src/crypto/dh/check.c @@ -0,0 +1,180 @@ +/* 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); + 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_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/src/crypto/dh/dh.c b/src/crypto/dh/dh.c new file mode 100644 index 0000000..7a50da7 --- /dev/null +++ b/src/crypto/dh/dh.c @@ -0,0 +1,243 @@ +/* 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 <string.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); +} + +int 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/src/crypto/dh/dh_asn1.c b/src/crypto/dh/dh_asn1.c new file mode 100644 index 0000000..73cd4df --- /dev/null +++ b/src/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/src/crypto/dh/dh_error.c b/src/crypto/dh/dh_error.c new file mode 100644 index 0000000..5ecc5d1 --- /dev/null +++ b/src/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 <openssl/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/src/crypto/dh/dh_impl.c b/src/crypto/dh/dh_impl.c new file mode 100644 index 0000000..9f416b7 --- /dev/null +++ b/src/crypto/dh/dh_impl.c @@ -0,0 +1,324 @@ +/* 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 */ + DH_check_standard_parameters(dh); + 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 int 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/src/crypto/dh/dh_test.c b/src/crypto/dh/dh_test.c new file mode 100644 index 0000000..3575f34 --- /dev/null +++ b/src/crypto/dh/dh_test.c @@ -0,0 +1,502 @@ +/* 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 <string.h> + +#include <openssl/bio.h> +#include <openssl/bn.h> +#include <openssl/crypto.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; + + CRYPTO_library_init(); + + 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/src/crypto/dh/internal.h b/src/crypto/dh/internal.h new file mode 100644 index 0000000..81b9c90 --- /dev/null +++ b/src/crypto/dh/internal.h @@ -0,0 +1,80 @@ +/* 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 + + +/* DH_check_standard_parameters checks if the parameters in |dh| are well + * known and safe. If so, it sets |dh->priv_length| to an appropriately smaller + * value than the default. */ +void DH_check_standard_parameters(DH *dh); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_DH_INTERNAL_H */ diff --git a/src/crypto/dh/params.c b/src/crypto/dh/params.c new file mode 100644 index 0000000..82d1d92 --- /dev/null +++ b/src/crypto/dh/params.c @@ -0,0 +1,316 @@ +/* ==================================================================== + * 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 == 32 +#define TOBN(lo, hi) lo, hi +#elif BN_BITS2 == 64 +#define TOBN(lo, hi) ((BN_ULONG)hi << 32 | lo) +#else +#error "unsupported BN_BITS2" +#endif + +static const BN_ULONG dh1024_160_p[] = { + TOBN(0x2E4A4371, 0xDF1FB2BC), TOBN(0x6D4DA708, 0xE68CFDA7), + TOBN(0x365C1A65, 0x45BF37DF), TOBN(0x0DC8B4BD, 0xA151AF5F), + TOBN(0xF55BCCC0, 0xFAA31A4F), TOBN(0xE5644738, 0x4EFFD6FA), + TOBN(0x219A7372, 0x98488E9C), TOBN(0x90C4BD70, 0xACCBDD7D), + TOBN(0xD49B83BF, 0x24975C3C), TOBN(0xA9061123, 0x13ECB4AE), + TOBN(0x2EE652C0, 0x9838EF1E), TOBN(0x75A23D18, 0x6073E286), + TOBN(0x52D23B61, 0x9A6A9DCA), TOBN(0xFB06A3C6, 0x52C99FBC), + TOBN(0xAE5D54EC, 0xDE92DE5E), TOBN(0xA080E01D, 0xB10B8F96), +}; +static const BN_ULONG dh1024_160_g[] = { + TOBN(0x22B3B2E5, 0x855E6EEB), TOBN(0xF97C2A24, 0x858F4DCE), + TOBN(0x18D08BC8, 0x2D779D59), TOBN(0x8E73AFA3, 0xD662A4D1), + TOBN(0x69B6A28A, 0x1DBF0A01), TOBN(0x7A091F53, 0xA6A24C08), + TOBN(0x63F80A76, 0x909D0D22), TOBN(0xB9A92EE1, 0xD7FBD7D3), + TOBN(0x9E2749F4, 0x5E91547F), TOBN(0xB01B886A, 0x160217B4), + TOBN(0x5504F213, 0x777E690F), TOBN(0x5C41564B, 0x266FEA1E), + TOBN(0x14266D31, 0xD6406CFF), TOBN(0x58AC507F, 0xF8104DD2), + TOBN(0xEFB99905, 0x6765A442), TOBN(0xC3FD3412, 0xA4D1CBD5), +}; +static const BN_ULONG dh1024_160_q[] = { + TOBN(0x49462353, 0x64B7CB9D), TOBN(0x8ABA4E7D, 0x81A8DF27), 0xF518AA87, +}; + +static const BN_ULONG dh2048_224_p[] = { + TOBN(0x0C10E64F, 0x0AC4DFFE), TOBN(0x4E71B81C, 0xCF9DE538), + TOBN(0xFFA31F71, 0x7EF363E2), TOBN(0x6B8E75B9, 0xE3FB73C1), + TOBN(0x4BA80A29, 0xC9B53DCF), TOBN(0x16E79763, 0x23F10B0E), + TOBN(0x13042E9B, 0xC52172E4), TOBN(0xC928B2B9, 0xBE60E69C), + TOBN(0xB9E587E8, 0x80CD86A1), TOBN(0x98C641A4, 0x315D75E1), + TOBN(0x44328387, 0xCDF93ACC), TOBN(0xDC0A486D, 0x15987D9A), + TOBN(0x1FD5A074, 0x7310F712), TOBN(0xDE31EFDC, 0x278273C7), + TOBN(0x415D9330, 0x1602E714), TOBN(0xBC8985DB, 0x81286130), + TOBN(0x70918836, 0xB3BF8A31), TOBN(0xB9C49708, 0x6A00E0A0), + TOBN(0x8BBC27BE, 0xC6BA0B2C), TOBN(0xED34DBF6, 0xC9F98D11), + TOBN(0xB6C12207, 0x7AD5B7D0), TOBN(0x55B7394B, 0xD91E8FEF), + TOBN(0xEFDA4DF8, 0x9037C9ED), TOBN(0xAD6AC212, 0x6D3F8152), + TOBN(0x1274A0A6, 0x1DE6B85A), TOBN(0x309C180E, 0xEB3D688A), + TOBN(0x7BA1DF15, 0xAF9A3C40), TOBN(0xF95A56DB, 0xE6FA141D), + TOBN(0xB61D0A75, 0xB54B1597), TOBN(0x683B9FD1, 0xA20D64E5), + TOBN(0x9559C51F, 0xD660FAA7), TOBN(0x9123A9D0, 0xAD107E1E), +}; + +static const BN_ULONG dh2048_224_g[] = { + TOBN(0x191F2BFA, 0x84B890D3), TOBN(0x2A7065B3, 0x81BC087F), + TOBN(0xF6EC0179, 0x19C418E1), TOBN(0x71CFFF4C, 0x7B5A0F1C), + TOBN(0x9B6AA4BD, 0xEDFE72FE), TOBN(0x94B30269, 0x81E1BCFE), + TOBN(0x8D6C0191, 0x566AFBB4), TOBN(0x409D13CD, 0xB539CCE3), + TOBN(0x5F2FF381, 0x6AA21E7F), TOBN(0x770589EF, 0xD9E263E4), + TOBN(0xD19963DD, 0x10E183ED), TOBN(0x150B8EEB, 0xB70A8137), + TOBN(0x28C8F8AC, 0x051AE3D4), TOBN(0x0C1AB15B, 0xBB77A86F), + TOBN(0x16A330EF, 0x6E3025E3), TOBN(0xD6F83456, 0x19529A45), + TOBN(0x118E98D1, 0xF180EB34), TOBN(0x50717CBE, 0xB5F6C6B2), + TOBN(0xDA7460CD, 0x09939D54), TOBN(0x22EA1ED4, 0xE2471504), + TOBN(0x521BC98A, 0xB8A762D0), TOBN(0x5AC1348B, 0xF4D02727), + TOBN(0x1999024A, 0xC1766910), TOBN(0xA8D66AD7, 0xBE5E9001), + TOBN(0x620A8652, 0xC57DB17C), TOBN(0x00C29F52, 0xAB739D77), + TOBN(0xA70C4AFA, 0xDD921F01), TOBN(0x10B9A6F0, 0xA6824A4E), + TOBN(0xCFE4FFE3, 0x74866A08), TOBN(0x89998CAF, 0x6CDEBE7B), + TOBN(0x8FFDAC50, 0x9DF30B5C), TOBN(0x4F2D9AE3, 0xAC4032EF), +}; + +static const BN_ULONG dh2048_224_q[] = { + TOBN(0xB36371EB, 0xBF389A99), TOBN(0x4738CEBC, 0x1F80535A), + TOBN(0x99717710, 0xC58D93FE), 0x801C0D34, +}; + +static const BN_ULONG dh2048_256_p[] = { + TOBN(0x1E1A1597, 0xDB094AE9), TOBN(0xD7EF09CA, 0x693877FA), + TOBN(0x6E11715F, 0x6116D227), TOBN(0xC198AF12, 0xA4B54330), + TOBN(0xD7014103, 0x75F26375), TOBN(0x54E710C3, 0xC3A3960A), + TOBN(0xBD0BE621, 0xDED4010A), TOBN(0x89962856, 0xC0B857F6), + TOBN(0x71506026, 0xB3CA3F79), TOBN(0xE6B486F6, 0x1CCACB83), + TOBN(0x14056425, 0x67E144E5), TOBN(0xA41825D9, 0xF6A167B5), + TOBN(0x96524D8E, 0x3AD83477), TOBN(0x51BFA4AB, 0xF13C6D9A), + TOBN(0x35488A0E, 0x2D525267), TOBN(0xCAA6B790, 0xB63ACAE1), + TOBN(0x81B23F76, 0x4FDB70C5), TOBN(0x12307F5C, 0xBC39A0BF), + TOBN(0xB1E59BB8, 0xB941F54E), TOBN(0xD45F9088, 0x6C5BFC11), + TOBN(0x4275BF7B, 0x22E0B1EF), TOBN(0x5B4758C0, 0x91F9E672), + TOBN(0x6BCF67ED, 0x5A8A9D30), TOBN(0x97517ABD, 0x209E0C64), + TOBN(0x830E9A7C, 0x3BF4296D), TOBN(0x34096FAA, 0x16C3D911), + TOBN(0x61B2AA30, 0xFAF7DF45), TOBN(0xD61957D4, 0xE00DF8F1), + TOBN(0x435E3B00, 0x5D2CEED4), TOBN(0x660DD0F2, 0x8CEEF608), + TOBN(0x65195999, 0xFFBBD19C), TOBN(0xB4B6663C, 0x87A8E61D), +}; +static const BN_ULONG dh2048_256_g[] = { + TOBN(0x6CC41659, 0x664B4C0F), TOBN(0xEF98C582, 0x5E2327CF), + TOBN(0xD4795451, 0xD647D148), TOBN(0x90F00EF8, 0x2F630784), + TOBN(0x1DB246C3, 0x184B523D), TOBN(0xCDC67EB6, 0xC7891428), + TOBN(0x0DF92B52, 0x7FD02837), TOBN(0x64E0EC37, 0xB3353BBB), + TOBN(0x57CD0915, 0xECD06E15), TOBN(0xDF016199, 0xB7D2BBD2), + TOBN(0x052588B9, 0xC8484B1E), TOBN(0x13D3FE14, 0xDB2A3B73), + TOBN(0xD182EA0A, 0xD052B985), TOBN(0xE83B9C80, 0xA4BD1BFF), + TOBN(0xFB3F2E55, 0xDFC967C1), TOBN(0x767164E1, 0xB5045AF2), + TOBN(0x6F2F9193, 0x1D14348F), TOBN(0x428EBC83, 0x64E67982), + TOBN(0x82D6ED38, 0x8AC376D2), TOBN(0xAAB8A862, 0x777DE62A), + TOBN(0xE9EC144B, 0xDDF463E5), TOBN(0xC77A57F2, 0x0196F931), + TOBN(0x41000A65, 0xA55AE313), TOBN(0xC28CBB18, 0x901228F8), + TOBN(0x7E8C6F62, 0xBC3773BF), TOBN(0x0C6B47B1, 0xBE3A6C1B), + TOBN(0xAC0BB555, 0xFF4FED4A), TOBN(0x77BE463F, 0x10DBC150), + TOBN(0x1A0BA125, 0x07F4793A), TOBN(0x21EF2054, 0x4CA7B18F), + TOBN(0x60EDBD48, 0x2E775066), TOBN(0x73134D0B, 0x3FB32C9B), +}; +static const BN_ULONG dh2048_256_q[] = { + TOBN(0x64F5FBD3, 0xA308B0FE), TOBN(0x1EB3750B, 0x99B1A47D), + TOBN(0x40129DA2, 0xB4479976), TOBN(0xA709A097, 0x8CF83642), +}; + +/* dh1024_safe_prime_1 is hard-coded in Apache httpd 2.2, + * modules/ssl/ssl_engine_dh.c. */ +static const BN_ULONG dh1024_safe_prime_1[] = { + TOBN(0x24218EB3, 0xE7393E0F), TOBN(0xE2BD68B0, 0x7DE0F4D6), + TOBN(0x88AEAA74, 0x07DD62DB), TOBN(0x9DDD3305, 0x10EA9FCC), + TOBN(0x74087D15, 0xA7DBCA78), TOBN(0x78045B07, 0xDAE88600), + TOBN(0x1AAD3B72, 0x33168A46), TOBN(0x7BEDDCFD, 0xFF590137), + TOBN(0x7A635E81, 0xFE324A46), TOBN(0x420B2A29, 0x5AC179BA), + TOBN(0x177E16D5, 0x13B4B4D7), TOBN(0x639C72FB, 0x849F912E), + TOBN(0x98BCE951, 0xB88174CB), TOBN(0xA45F520B, 0x0C84D239), + TOBN(0x4AFD0AD5, 0x36D693D3), TOBN(0xCBBBDC19, 0xD67DE440), +}; + +/* dh1024_safe_prime_2 is hard-coded in nginx, + * src/event/ngx_event_openssl.c. */ +static const BN_ULONG dh1024_safe_prime_2[] = { + TOBN(0xCFE16B9B, 0x071DF045), TOBN(0x146757DA, 0x88D0F65D), + TOBN(0x58FAFD49, 0x4A63AB1E), TOBN(0xEF9EA027, 0x35D8CECE), + TOBN(0x70CC9A50, 0x25ECE662), TOBN(0x81DC2CA7, 0xF29BA5DF), + TOBN(0xF7D36CC8, 0x8F68B076), TOBN(0xA757E304, 0x60E91A92), + TOBN(0x9BE67780, 0x87A2BC04), TOBN(0xA5FDF1D2, 0xBEECA565), + TOBN(0x922614C5, 0x5CCBBAA8), TOBN(0xE710800C, 0x6C030276), + TOBN(0x0FB3504C, 0x08EED4EB), TOBN(0x68B42D4B, 0xD958A3F5), + TOBN(0x80E9CFDB, 0x7C43FCF5), TOBN(0xD8467490, 0xBBBC2DCA), +}; + +/* dh1024_safe_prime_3 is offered as a parameter by several high-traffic sites, + * including mozilla.org, as of Jan 2015. */ +static const BN_ULONG dh1024_safe_prime_3[] = { + TOBN(0x349E721B, 0x671746AE), TOBN(0xD75E93B2, 0x258A0655), + TOBN(0x25592EB6, 0xD425E6FB), TOBN(0xBF7CDD9A, 0x0C46AB04), + TOBN(0x28968680, 0x0AD0BC99), TOBN(0xD0B7EB49, 0xF53907FB), + TOBN(0xEBC85C1D, 0x202EABB3), TOBN(0x364D8C71, 0x3129C693), + TOBN(0x2D46F195, 0x53728351), TOBN(0x8C76CC85, 0xDF326DD6), + TOBN(0x9188E24E, 0xF898B3F9), TOBN(0x2855DFD2, 0x95EFB13C), + TOBN(0x7B2241FE, 0x1F5DAC48), TOBN(0x99A13D9F, 0x117B6BF7), + TOBN(0x3A3468C7, 0x0F97CDDA), TOBN(0x74A8297B, 0xC9BBF5F7)}; + +/* dh1024_safe_prime_4 is hard-coded in Apache httpd 2.0, + * modules/ssl/ssl_engine_dh.c. */ +static const BN_ULONG dh1024_safe_prime_4[] = { + TOBN(0x0DD5C86B, 0x5085E21F), TOBN(0xD823C650, 0x871538DF), + TOBN(0x262E56A8, 0x125136F7), TOBN(0x839EB5DB, 0x974E9EF1), + TOBN(0x1B13A63C, 0xEA9BAD99), TOBN(0x3D76E05E, 0x6044CF02), + TOBN(0x1BAC9B5C, 0x611EBBBE), TOBN(0x4E5327DF, 0x3E371D79), + TOBN(0x061CBC05, 0x000E6EDD), TOBN(0x20129B48, 0x2F971F3C), + TOBN(0x3048D5A2, 0xA6EF09C4), TOBN(0xCBD523A6, 0xFA15A259), + TOBN(0x4A79A770, 0x2A206490), TOBN(0x51BB055E, 0x91B78182), + TOBN(0xBDD4798E, 0x7CF180C3), TOBN(0x495BE32C, 0xE6969D3D)}; + +static const BN_ULONG bn_two_data[] = {2}; + +#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 const BIGNUM dh1024_safe_prime[] = { + STATIC_BIGNUM(dh1024_safe_prime_1), + STATIC_BIGNUM(dh1024_safe_prime_2), + STATIC_BIGNUM(dh1024_safe_prime_3), + STATIC_BIGNUM(dh1024_safe_prime_4) +}; + +BIGNUM bn_two = STATIC_BIGNUM(bn_two_data); + +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(¶ms->p); + dh->q = BN_dup(¶ms->q); + dh->g = BN_dup(¶ms->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); +} + +void DH_check_standard_parameters(DH *dh) { + int i; + + if (dh->p == NULL || + dh->g == NULL || + BN_num_bytes(dh->p) != (1024 / 8) || + BN_cmp(dh->g, &bn_two) != 0) { + return; + } + + for (i = 0; i < sizeof(dh1024_safe_prime) / sizeof(dh1024_safe_prime[0]); + i++) { + if (BN_cmp(dh->p, &dh1024_safe_prime[i]) == 0) { + /* The well-known DH groups are known to have safe primes. In this case + * we can safely reduce the size of the private key. */ + dh->priv_length = 161; + break; + } + } +} |