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 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "internal.h" 69e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "../internal.h" 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 72fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley#define OPENSSL_DH_MAX_MODULUS_BITS 10000 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 74e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; 75e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 76fad6327e4112082b1e77e89a995723f26bd5a9aaAdam LangleyDH *DH_new(void) { 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley DH *dh = (DH *)OPENSSL_malloc(sizeof(DH)); 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dh == NULL) { 79b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE); 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley memset(dh, 0, sizeof(DH)); 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 85e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_MUTEX_init(&dh->method_mont_p_lock); 86e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dh->references = 1; 884139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley CRYPTO_new_ex_data(&dh->ex_data); 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return dh; 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid DH_free(DH *dh) { 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dh == NULL) { 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 98f4e427204234da139fd0585def4b4e22502e33f0Adam Langley if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) { 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 102e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_free_ex_data(&g_ex_data_class, dh, &dh->ex_data); 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 104e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_MONT_CTX_free(dh->method_mont_p); 105e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->p); 106e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->g); 107e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->q); 108e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->j); 109e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root OPENSSL_free(dh->seed); 110e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->counter); 111e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->pub_key); 112e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root BN_clear_free(dh->priv_key); 113e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock); 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_free(dh); 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) { 119fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* We generate DH parameters as follows 120fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * find a prime q which is prime_bits/2 bits long. 121fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * p=(2*q)+1 or (p-1)/2 = q 122fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * For this case, g is a generator if 123fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. 124fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * Since the factors of p-1 are q and 2, we just need to check 125fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * g^2 mod p != 1 and g^q mod p != 1. 126fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * 127fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * Having said all that, 128fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * there is another special case method for the generators 2, 3 and 5. 129fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * for 2, p mod 24 == 11 130fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * for 3, p mod 12 == 5 <<<<< does not work for safe primes. 131fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * for 5, p mod 10 == 3 or 7 132fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * 133fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the 134fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * special generators and for answering some of my questions. 135fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * 136fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * I've implemented the second simple method :-). 137fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * Since DH should be using a safe prime (both p and q are prime), 138fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * this generator function can take a very very long time to run. 139fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley */ 140fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 141fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* Actually there is no reason to insist that 'generator' be a generator. 142fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * It's just as OK (and in some sense better) to use a generator of the 143fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * order-q subgroup. 144fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley */ 145fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 146fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BIGNUM *t1, *t2; 147fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int g, ok = 0; 148fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX *ctx = NULL; 149fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 150fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ctx = BN_CTX_new(); 151fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx == NULL) { 152fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 153fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 154fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_start(ctx); 155fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley t1 = BN_CTX_get(ctx); 156fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley t2 = BN_CTX_get(ctx); 157fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (t1 == NULL || t2 == NULL) { 158fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 159fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 160fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 161fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* Make sure |dh| has the necessary elements */ 162fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->p == NULL) { 163fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->p = BN_new(); 164fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->p == NULL) { 165fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 166fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 167fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 168fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->g == NULL) { 169fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->g = BN_new(); 170fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->g == NULL) { 171fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 172fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 173fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 174fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 175fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (generator <= 1) { 176fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR); 177fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 178fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 179fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (generator == DH_GENERATOR_2) { 180fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t1, 24)) { 181fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 182fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 183fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t2, 11)) { 184fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 185fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 186fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley g = 2; 187fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else if (generator == DH_GENERATOR_5) { 188fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t1, 10)) { 189fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 190fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 191fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t2, 3)) { 192fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 193fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 194fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* BN_set_word(t3,7); just have to miss 195fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * out on these ones :-( */ 196fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley g = 5; 197fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else { 198fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* in the general case, don't worry if 'generator' is a 199fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * generator or not: since we are using safe primes, 200fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * it will generate either an order-q or an order-2q group, 201fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley * which both is OK */ 202fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t1, 2)) { 203fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 204fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 205fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(t2, 1)) { 206fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 207fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 208fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley g = generator; 209fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 210fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 211fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_generate_prime_ex(dh->p, prime_bits, 1, t1, t2, cb)) { 212fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 213fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 214fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_GENCB_call(cb, 3, 0)) { 215fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 216fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 217fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_set_word(dh->g, g)) { 218fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 219fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 220fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ok = 1; 221fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 222fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyerr: 223fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!ok) { 224fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); 225fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 226fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 227fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx != NULL) { 228fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_end(ctx); 229fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_free(ctx); 230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 231fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return ok; 232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 234d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_generate_key(DH *dh) { 235fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int ok = 0; 236fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int generate_new_key = 0; 237fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley unsigned l; 2384139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley BN_CTX *ctx = NULL; 239fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_MONT_CTX *mont = NULL; 240fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BIGNUM *pub_key = NULL, *priv_key = NULL; 241fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BIGNUM local_priv; 242fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 2434139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { 2444139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); 2454139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley goto err; 2464139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley } 2474139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley 248fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ctx = BN_CTX_new(); 249fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx == NULL) { 250fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 252fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 253fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->priv_key == NULL) { 254fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley priv_key = BN_new(); 255fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (priv_key == NULL) { 256fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 257fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 258fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley generate_new_key = 1; 259fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else { 260fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley priv_key = dh->priv_key; 261fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 262fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 263fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->pub_key == NULL) { 264fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley pub_key = BN_new(); 265fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (pub_key == NULL) { 266fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 267fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 268fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else { 269fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley pub_key = dh->pub_key; 270fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 271fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 272fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, 273fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->p, ctx); 274fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!mont) { 275fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 276fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 277fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 278fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (generate_new_key) { 279fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->q) { 280fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley do { 281fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_rand_range(priv_key, dh->q)) { 282fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 283fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 284fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } while (BN_is_zero(priv_key) || BN_is_one(priv_key)); 285fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } else { 286fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley /* secret exponent length */ 287fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley DH_check_standard_parameters(dh); 288fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley l = dh->priv_length ? dh->priv_length : BN_num_bits(dh->p) - 1; 289fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_rand(priv_key, l, 0, 0)) { 290fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 291fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 292fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 293fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 294fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 295fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_with_flags(&local_priv, priv_key, BN_FLG_CONSTTIME); 296fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx, mont)) { 297fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 298fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 299fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 300fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->pub_key = pub_key; 301fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->priv_key = priv_key; 302fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ok = 1; 303fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 304fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyerr: 305fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ok != 1) { 306fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); 307fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 308fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 309fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->pub_key == NULL) { 310fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_free(pub_key); 311fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 312fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->priv_key == NULL) { 313fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_free(priv_key); 314fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 315fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_free(ctx); 316fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return ok; 317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 319d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { 320fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX *ctx = NULL; 321fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_MONT_CTX *mont = NULL; 322fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BIGNUM *shared_key; 323fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int ret = -1; 324fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley int check_result; 325fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BIGNUM local_priv; 326fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 327fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { 328fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); 329fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 330fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 331fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 332fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ctx = BN_CTX_new(); 333fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx == NULL) { 334fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 336fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_start(ctx); 337fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley shared_key = BN_CTX_get(ctx); 338fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (shared_key == NULL) { 339fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 340fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 341fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 342fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (dh->priv_key == NULL) { 343fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE); 344fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 345fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 346fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 347fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, 348fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley dh->p, ctx); 349fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!mont) { 350fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 351fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 352fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 353fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!DH_check_pub_key(dh, peers_key, &check_result) || check_result) { 354fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY); 355fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 356fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 357fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 358fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME); 359fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (!BN_mod_exp_mont(shared_key, peers_key, &local_priv, dh->p, ctx, 360fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley mont)) { 361fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); 362fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley goto err; 363fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 364fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 365fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley ret = BN_bn2bin(shared_key, out); 366fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 367fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyerr: 368fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley if (ctx != NULL) { 369fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_end(ctx); 370fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley BN_CTX_free(ctx); 371fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley } 372fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley 373fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return ret; 374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 376d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_size(const DH *dh) { return BN_num_bytes(dh->p); } 377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 378f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyunsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); } 379f4e427204234da139fd0585def4b4e22502e33f0Adam Langley 380f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyint DH_up_ref(DH *dh) { 381f4e427204234da139fd0585def4b4e22502e33f0Adam Langley CRYPTO_refcount_inc(&dh->references); 382d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 383d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 385d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) { 386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *a = NULL; 387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (src) { 389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley a = BN_dup(src); 390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!a) { 391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 395e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_free(*dst); 396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *dst = a; 397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 400d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int int_dh_param_copy(DH *to, const DH *from, int is_x942) { 401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (is_x942 == -1) { 402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley is_x942 = !!from->q; 403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!int_dh_bn_cpy(&to->p, from->p) || 405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !int_dh_bn_cpy(&to->g, from->g)) { 406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!is_x942) { 410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!int_dh_bn_cpy(&to->q, from->q) || 414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !int_dh_bn_cpy(&to->j, from->j)) { 415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 418e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley OPENSSL_free(to->seed); 419e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley to->seed = NULL; 420e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley to->seedlen = 0; 421e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (from->seed) { 423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley to->seed = BUF_memdup(from->seed, from->seedlen); 424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!to->seed) { 425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley to->seedlen = from->seedlen; 428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 429d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 433d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyDH *DHparams_dup(const DH *dh) { 434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley DH *ret = DH_new(); 435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!ret) { 436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!int_dh_param_copy(ret, dh, -1)) { 440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley DH_free(ret); 441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4474139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, 448d9e397b599b13d642138480a28c14db7a136bf0Adam Langley CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { 449e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley int index; 4504139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func, 4514139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley free_func)) { 452e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return -1; 453e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 454e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return index; 455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 457d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint DH_set_ex_data(DH *d, int idx, void *arg) { 458fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return CRYPTO_set_ex_data(&d->ex_data, idx, arg); 459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 461d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *DH_get_ex_data(DH *d, int idx) { 462fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley return CRYPTO_get_ex_data(&d->ex_data, idx); 463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 464