1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * All rights reserved. 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This package is an SSL implementation written 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * by Eric Young (eay@cryptsoft.com). 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The implementation was written so as to conform with Netscapes SSL. 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This library is free for commercial and non-commercial use as long as 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the following conditions are aheared to. The following conditions 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * apply to all code found in this distribution, be it the RC4, RSA, 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * included with this distribution is covered by the same copyright terms 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the code are not to be removed. 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If this package is used in a product, Eric Young should be given attribution 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * as the author of the parts of the library used. 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This can be in the form of a textual message at program startup or 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * in documentation (online or textual) provided with the package. 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the copyright 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in the 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * documentation and/or other materials provided with the distribution. 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this software 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * must display the following acknowledgement: 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes cryptographic software written by 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Eric Young (eay@cryptsoft.com)" 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The word 'cryptographic' can be left out if the rouines from the library 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * being used are not cryptographic related :-). 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the apps directory (application code) you must include an acknowledgement: 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUCH DAMAGE. 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The licence and distribution terms for any publically available version or 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copied and put under another distribution licence 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * [including the GNU Public Licence.] */ 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/dh.h> 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h> 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/bn.h> 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/buf.h> 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ex_data.h> 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h> 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/thread.h> 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 68e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "../internal.h" 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 71fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley#define OPENSSL_DH_MAX_MODULUS_BITS 10000 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 73e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; 74e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 75fad6327e4112082b1e77e89a995723f26bd5a9aaAdam LangleyDH *DH_new(void) { 764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin DH *dh = OPENSSL_malloc(sizeof(DH)); 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dh == NULL) { 78b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE); 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 8269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memset(dh, 0, sizeof(DH)); 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 84e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_MUTEX_init(&dh->method_mont_p_lock); 85e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dh->references = 1; 874139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley CRYPTO_new_ex_data(&dh->ex_data); 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return dh; 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid DH_free(DH *dh) { 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dh == NULL) { 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 97f4e427204234da139fd0585def4b4e22502e33f0Adam Langley if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) { 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 101e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_free_ex_data(&g_ex_data_class, dh, &dh->ex_data); 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 103e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_MONT_CTX_free(dh->method_mont_p); 104e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->p); 105e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->g); 106e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->q); 107e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->j); 108e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root OPENSSL_free(dh->seed); 109e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->counter); 110e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->pub_key); 111e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->priv_key); 112e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock); 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_free(dh); 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 117c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjaminvoid DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, 118c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin const BIGNUM **out_priv_key) { 119c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (out_pub_key != NULL) { 120c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin *out_pub_key = dh->pub_key; 121c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 122c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (out_priv_key != NULL) { 123c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin *out_priv_key = dh->priv_key; 124c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 125c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin} 126c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 127c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjaminvoid DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q, 128c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin const BIGNUM **out_g) { 129c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (out_p != NULL) { 130c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin *out_p = dh->p; 131c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 132c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (out_q != NULL) { 133c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin *out_q = dh->q; 134c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 135c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (out_g != NULL) { 136c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin *out_g = dh->g; 137c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 138c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin} 139c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) { 141fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* We generate DH parameters as follows 142fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * find a prime q which is prime_bits/2 bits long. 143fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * p=(2*q)+1 or (p-1)/2 = q 144fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * For this case, g is a generator if 145fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. 146fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * Since the factors of p-1 are q and 2, we just need to check 147fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * g^2 mod p != 1 and g^q mod p != 1. 148fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * 149fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * Having said all that, 150fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * there is another special case method for the generators 2, 3 and 5. 151fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * for 2, p mod 24 == 11 152fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * for 3, p mod 12 == 5 <<<<< does not work for safe primes. 153fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * for 5, p mod 10 == 3 or 7 154fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * 155fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the 156fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * special generators and for answering some of my questions. 157fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * 158fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * I've implemented the second simple method :-). 159fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * Since DH should be using a safe prime (both p and q are prime), 160fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * this generator function can take a very very long time to run. 161fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley */ 162fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 163fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* Actually there is no reason to insist that 'generator' be a generator. 164fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * It's just as OK (and in some sense better) to use a generator of the 165fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * order-q subgroup. 166fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley */ 167fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 168fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BIGNUM *t1, *t2; 169fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int g, ok = 0; 170fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX *ctx = NULL; 171fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 172fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ctx = BN_CTX_new(); 173fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx == NULL) { 174fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 175fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 176fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_start(ctx); 177fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley t1 = BN_CTX_get(ctx); 178fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley t2 = BN_CTX_get(ctx); 179fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (t1 == NULL || t2 == NULL) { 180fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 181fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 182fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 183fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* Make sure |dh| has the necessary elements */ 184fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->p == NULL) { 185fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->p = BN_new(); 186fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->p == NULL) { 187fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 188fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 189fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 190fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->g == NULL) { 191fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->g = BN_new(); 192fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->g == NULL) { 193fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 194fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 195fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 196fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 197fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (generator <= 1) { 198fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR); 199fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 200fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 201fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (generator == DH_GENERATOR_2) { 202fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t1, 24)) { 203fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 204fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 205fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t2, 11)) { 206fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 207fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 208fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley g = 2; 209fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else if (generator == DH_GENERATOR_5) { 210fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t1, 10)) { 211fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 212fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 213fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t2, 3)) { 214fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 215fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 216fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* BN_set_word(t3,7); just have to miss 217fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * out on these ones :-( */ 218fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley g = 5; 219fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else { 220fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* in the general case, don't worry if 'generator' is a 221fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * generator or not: since we are using safe primes, 222fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * it will generate either an order-q or an order-2q group, 223fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * which both is OK */ 224fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t1, 2)) { 225fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 226fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 227fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t2, 1)) { 228fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 229fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 230fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley g = generator; 231fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 232fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 233fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_generate_prime_ex(dh->p, prime_bits, 1, t1, t2, cb)) { 234fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 235fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 236fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_GENCB_call(cb, 3, 0)) { 237fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 238fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 239fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(dh->g, g)) { 240fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 241fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 242fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ok = 1; 243fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 244fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyerr: 245fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!ok) { 246fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); 247fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 248fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 249fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx != NULL) { 250fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_end(ctx); 251fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_free(ctx); 252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 253fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return ok; 254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 256d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_generate_key(DH *dh) { 257fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int ok = 0; 258fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int generate_new_key = 0; 2594139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley BN_CTX *ctx = NULL; 260fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BIGNUM *pub_key = NULL, *priv_key = NULL; 261fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 2624139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { 2634139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); 2644139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley goto err; 2654139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley } 2664139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley 267fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ctx = BN_CTX_new(); 268fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx == NULL) { 269fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 271fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 272fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->priv_key == NULL) { 273fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley priv_key = BN_new(); 274fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (priv_key == NULL) { 275fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 276fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 277fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley generate_new_key = 1; 278fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else { 279fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley priv_key = dh->priv_key; 280fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 281fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 282fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->pub_key == NULL) { 283fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley pub_key = BN_new(); 284fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (pub_key == NULL) { 285fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 286fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 287fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else { 288fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley pub_key = dh->pub_key; 289fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 290fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 2914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, 2924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin dh->p, ctx)) { 293fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 294fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 295fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 296fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (generate_new_key) { 297fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->q) { 298c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (!BN_rand_range_ex(priv_key, 2, dh->q)) { 299c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin goto err; 300c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 301fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else { 302fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* secret exponent length */ 303c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin unsigned priv_bits = dh->priv_length; 304c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (priv_bits == 0) { 305c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin const unsigned p_bits = BN_num_bits(dh->p); 306c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin if (p_bits == 0) { 307c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin goto err; 308c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 309c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 310c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin priv_bits = p_bits - 1; 311c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin } 312c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin 313f0c4a6c4bbde5229ceb86740703243fe5c436aadDavid Benjamin if (!BN_rand(priv_key, priv_bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) { 314fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 315fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 316fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 317fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 318fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 319b0b45c63bbbf16b7f5ff3cbe3f1d0905108038aaSteven Valdez if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx, 320d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin dh->method_mont_p)) { 321fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 322fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 323fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 324fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->pub_key = pub_key; 325fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->priv_key = priv_key; 326fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ok = 1; 327fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 328fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyerr: 329fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ok != 1) { 330fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); 331fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 332fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 333fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->pub_key == NULL) { 334fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_free(pub_key); 335fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 336fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->priv_key == NULL) { 337fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_free(priv_key); 338fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 339fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_free(ctx); 340fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return ok; 341d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 343d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { 344fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX *ctx = NULL; 345fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BIGNUM *shared_key; 346fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int ret = -1; 347fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int check_result; 348fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 349fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { 350fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); 351fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 352fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 353fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 354fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ctx = BN_CTX_new(); 355fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx == NULL) { 356fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 358fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_start(ctx); 359fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley shared_key = BN_CTX_get(ctx); 360fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (shared_key == NULL) { 361fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 362fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 363fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 364fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->priv_key == NULL) { 365fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE); 366fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 367fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 368fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 3694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, 3704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin dh->p, ctx)) { 371fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 372fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 373fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 374fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!DH_check_pub_key(dh, peers_key, &check_result) || check_result) { 375fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY); 376fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 377fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 378fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 379b0b45c63bbbf16b7f5ff3cbe3f1d0905108038aaSteven Valdez if (!BN_mod_exp_mont_consttime(shared_key, peers_key, dh->priv_key, dh->p, 380b0b45c63bbbf16b7f5ff3cbe3f1d0905108038aaSteven Valdez ctx, dh->method_mont_p)) { 381fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); 382fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 383fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 384fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 385fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ret = BN_bn2bin(shared_key, out); 386fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 387fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyerr: 388fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx != NULL) { 389fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_end(ctx); 390fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_free(ctx); 391fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 392fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 393fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return ret; 394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 396d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_size(const DH *dh) { return BN_num_bytes(dh->p); } 397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 398f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyunsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); } 399f4e427204234da139fd0585def4b4e22502e33f0Adam Langley 400f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyint DH_up_ref(DH *dh) { 401f4e427204234da139fd0585def4b4e22502e33f0Adam Langley CRYPTO_refcount_inc(&dh->references); 402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 405d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) { 406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *a = NULL; 407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (src) { 409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley a = BN_dup(src); 410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!a) { 411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 415e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_free(*dst); 416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *dst = a; 417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 419d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 420d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int int_dh_param_copy(DH *to, const DH *from, int is_x942) { 421d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (is_x942 == -1) { 422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley is_x942 = !!from->q; 423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!int_dh_bn_cpy(&to->p, from->p) || 425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !int_dh_bn_cpy(&to->g, from->g)) { 426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 429d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!is_x942) { 430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!int_dh_bn_cpy(&to->q, from->q) || 434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !int_dh_bn_cpy(&to->j, from->j)) { 435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 438e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley OPENSSL_free(to->seed); 439e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley to->seed = NULL; 440e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley to->seedlen = 0; 441e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (from->seed) { 443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley to->seed = BUF_memdup(from->seed, from->seedlen); 444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!to->seed) { 445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 447d9e397b599b13d642138480a28c14db7a136bf0Adam Langley to->seedlen = from->seedlen; 448d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 449d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 450d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 451d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 452d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 453d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyDH *DHparams_dup(const DH *dh) { 454d9e397b599b13d642138480a28c14db7a136bf0Adam Langley DH *ret = DH_new(); 455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!ret) { 456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 457d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!int_dh_param_copy(ret, dh, -1)) { 460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley DH_free(ret); 461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4674139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, 4688ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { 469e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley int index; 4708ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, 4714139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley free_func)) { 472e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return -1; 473e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 474e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return index; 475d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 476d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 477d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_set_ex_data(DH *d, int idx, void *arg) { 478fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return CRYPTO_set_ex_data(&d->ex_data, idx, arg); 479d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 480d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 481d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *DH_get_ex_data(DH *d, int idx) { 482fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return CRYPTO_get_ex_data(&d->ex_data, idx); 483d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 484