dh_lib.c revision 296341
1139749Simp/* crypto/dh/dh_lib.c */ 265942Sgibbs/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 365942Sgibbs * All rights reserved. 465942Sgibbs * 565942Sgibbs * This package is an SSL implementation written 695378Sgibbs * by Eric Young (eay@cryptsoft.com). 795378Sgibbs * The implementation was written so as to conform with Netscapes SSL. 865942Sgibbs * 965942Sgibbs * This library is free for commercial and non-commercial use as long as 1065942Sgibbs * the following conditions are aheared to. The following conditions 1165942Sgibbs * apply to all code found in this distribution, be it the RC4, RSA, 1265942Sgibbs * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1365942Sgibbs * included with this distribution is covered by the same copyright terms 1465942Sgibbs * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1595378Sgibbs * 1695378Sgibbs * Copyright remains Eric Young's, and as such any Copyright notices in 1795378Sgibbs * the code are not to be removed. 1895378Sgibbs * If this package is used in a product, Eric Young should be given attribution 1995378Sgibbs * as the author of the parts of the library used. 2095378Sgibbs * This can be in the form of a textual message at program startup or 2195378Sgibbs * in documentation (online or textual) provided with the package. 2295378Sgibbs * 2395378Sgibbs * Redistribution and use in source and binary forms, with or without 2465942Sgibbs * modification, are permitted provided that the following conditions 2565942Sgibbs * are met: 2695378Sgibbs * 1. Redistributions of source code must retain the copyright 2795378Sgibbs * notice, this list of conditions and the following disclaimer. 2865942Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 2995378Sgibbs * notice, this list of conditions and the following disclaimer in the 3095378Sgibbs * documentation and/or other materials provided with the distribution. 3195378Sgibbs * 3. All advertising materials mentioning features or use of this software 3295378Sgibbs * must display the following acknowledgement: 3395378Sgibbs * "This product includes cryptographic software written by 3495378Sgibbs * Eric Young (eay@cryptsoft.com)" 3565942Sgibbs * The word 'cryptographic' can be left out if the rouines from the library 3665942Sgibbs * being used are not cryptographic related :-). 3795378Sgibbs * 4. If you include any Windows specific code (or a derivative thereof) from 3895378Sgibbs * the apps directory (application code) you must include an acknowledgement: 3995378Sgibbs * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4095378Sgibbs * 4165942Sgibbs * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42123579Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4365942Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4465942Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4595378Sgibbs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4695378Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4795378Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4895378Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4995378Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50123579Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51123579Sgibbs * SUCH DAMAGE. 5295378Sgibbs * 5365942Sgibbs * The licence and distribution terms for any publically available version or 5465942Sgibbs * derivative of this code cannot be changed. i.e. this code cannot simply be 5595378Sgibbs * copied and put under another distribution licence 5665942Sgibbs * [including the GNU Public Licence.] 5765942Sgibbs */ 5865942Sgibbs 5965942Sgibbs#include <stdio.h> 6065942Sgibbs#include "cryptlib.h" 6165942Sgibbs#include <openssl/bn.h> 6265942Sgibbs#include <openssl/dh.h> 6365942Sgibbs#ifndef OPENSSL_NO_ENGINE 6465942Sgibbs# include <openssl/engine.h> 6565942Sgibbs#endif 6665942Sgibbs 6765942Sgibbs#ifdef OPENSSL_FIPS 6865942Sgibbs# include <openssl/fips.h> 6965942Sgibbs#endif 7074094Sgibbs 7174094Sgibbsconst char DH_version[] = "Diffie-Hellman" OPENSSL_VERSION_PTEXT; 7274094Sgibbs 7374094Sgibbsstatic const DH_METHOD *default_DH_method = NULL; 7474094Sgibbs 7574094Sgibbsvoid DH_set_default_method(const DH_METHOD *meth) 76115338Sgibbs{ 7774094Sgibbs default_DH_method = meth; 7874094Sgibbs} 7974094Sgibbs 8074094Sgibbsconst DH_METHOD *DH_get_default_method(void) 8174094Sgibbs{ 8274094Sgibbs if (!default_DH_method) { 8374094Sgibbs#ifdef OPENSSL_FIPS 8474094Sgibbs if (FIPS_mode()) 8574094Sgibbs return FIPS_dh_openssl(); 8674094Sgibbs else 8765942Sgibbs return DH_OpenSSL(); 8874094Sgibbs#else 8974094Sgibbs default_DH_method = DH_OpenSSL(); 9074094Sgibbs#endif 9174094Sgibbs } 9274094Sgibbs return default_DH_method; 9374094Sgibbs} 9474094Sgibbs 9565942Sgibbsint DH_set_method(DH *dh, const DH_METHOD *meth) 9674094Sgibbs{ 9774094Sgibbs /* 9874094Sgibbs * NB: The caller is specifically setting a method, so it's not up to us 9974094Sgibbs * to deal with which ENGINE it comes from. 10074094Sgibbs */ 10174094Sgibbs const DH_METHOD *mtmp; 10274094Sgibbs mtmp = dh->meth; 10374094Sgibbs if (mtmp->finish) 10474094Sgibbs mtmp->finish(dh); 10574094Sgibbs#ifndef OPENSSL_NO_ENGINE 10674094Sgibbs if (dh->engine) { 10774094Sgibbs ENGINE_finish(dh->engine); 10865942Sgibbs dh->engine = NULL; 10974094Sgibbs } 11074094Sgibbs#endif 11174094Sgibbs dh->meth = meth; 11274094Sgibbs if (meth->init) 11374094Sgibbs meth->init(dh); 11474094Sgibbs return 1; 11565942Sgibbs} 11674094Sgibbs 11774094SgibbsDH *DH_new(void) 11874094Sgibbs{ 11974094Sgibbs return DH_new_method(NULL); 12074094Sgibbs} 12174094Sgibbs 12274094SgibbsDH *DH_new_method(ENGINE *engine) 12374094Sgibbs{ 12465942Sgibbs DH *ret; 12574094Sgibbs 12674094Sgibbs ret = (DH *)OPENSSL_malloc(sizeof(DH)); 12774094Sgibbs if (ret == NULL) { 12874094Sgibbs DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE); 12974094Sgibbs return (NULL); 13074094Sgibbs } 13174094Sgibbs 13274094Sgibbs ret->meth = DH_get_default_method(); 133123579Sgibbs#ifndef OPENSSL_NO_ENGINE 13465942Sgibbs if (engine) { 13574094Sgibbs if (!ENGINE_init(engine)) { 13674094Sgibbs DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); 13774094Sgibbs OPENSSL_free(ret); 13874094Sgibbs return NULL; 13974094Sgibbs } 14074094Sgibbs ret->engine = engine; 14165942Sgibbs } else 14274094Sgibbs ret->engine = ENGINE_get_default_DH(); 14374094Sgibbs if (ret->engine) { 14474094Sgibbs ret->meth = ENGINE_get_DH(ret->engine); 14574094Sgibbs if (!ret->meth) { 14665942Sgibbs DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); 14774094Sgibbs ENGINE_finish(ret->engine); 14874094Sgibbs OPENSSL_free(ret); 14965942Sgibbs return NULL; 15072325Sgibbs } 15172325Sgibbs } 15272325Sgibbs#endif 15395378Sgibbs 15472325Sgibbs ret->pad = 0; 15572325Sgibbs ret->version = 0; 15672325Sgibbs ret->p = NULL; 15772325Sgibbs ret->g = NULL; 15872325Sgibbs ret->length = 0; 15972325Sgibbs ret->pub_key = NULL; 16072325Sgibbs ret->priv_key = NULL; 16172325Sgibbs ret->q = NULL; 16272325Sgibbs ret->j = NULL; 16372325Sgibbs ret->seed = NULL; 16472325Sgibbs ret->seedlen = 0; 16572325Sgibbs ret->counter = NULL; 16672325Sgibbs ret->method_mont_p = NULL; 16770693Sgibbs ret->references = 1; 16870693Sgibbs ret->flags = ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW; 16970693Sgibbs CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); 17070693Sgibbs if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { 17170693Sgibbs#ifndef OPENSSL_NO_ENGINE 17270204Sgibbs if (ret->engine) 17372811Sgibbs ENGINE_finish(ret->engine); 17472811Sgibbs#endif 17572811Sgibbs CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); 17672811Sgibbs OPENSSL_free(ret); 17772811Sgibbs ret = NULL; 17872811Sgibbs } 17970693Sgibbs return (ret); 18070693Sgibbs} 18170693Sgibbs 18270693Sgibbsvoid DH_free(DH *r) 18370693Sgibbs{ 18470693Sgibbs int i; 18570693Sgibbs if (r == NULL) 18670693Sgibbs return; 18770693Sgibbs i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH); 18870693Sgibbs#ifdef REF_PRINT 18970693Sgibbs REF_PRINT("DH", r); 19070693Sgibbs#endif 19170693Sgibbs if (i > 0) 19270693Sgibbs return; 19370693Sgibbs#ifdef REF_CHECK 19470693Sgibbs if (i < 0) { 19570693Sgibbs fprintf(stderr, "DH_free, bad reference count\n"); 19670693Sgibbs abort(); 19770693Sgibbs } 19870693Sgibbs#endif 19970693Sgibbs 20070693Sgibbs if (r->meth->finish) 20170693Sgibbs r->meth->finish(r); 20270693Sgibbs#ifndef OPENSSL_NO_ENGINE 20370693Sgibbs if (r->engine) 20470693Sgibbs ENGINE_finish(r->engine); 20570693Sgibbs#endif 20670693Sgibbs 20770693Sgibbs CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); 20870693Sgibbs 20970693Sgibbs if (r->p != NULL) 21070693Sgibbs BN_clear_free(r->p); 21170693Sgibbs if (r->g != NULL) 21270693Sgibbs BN_clear_free(r->g); 21370693Sgibbs if (r->q != NULL) 21495378Sgibbs BN_clear_free(r->q); 21570693Sgibbs if (r->j != NULL) 21670693Sgibbs BN_clear_free(r->j); 21770693Sgibbs if (r->seed) 21870693Sgibbs OPENSSL_free(r->seed); 21970693Sgibbs if (r->counter != NULL) 22074094Sgibbs BN_clear_free(r->counter); 22165942Sgibbs if (r->pub_key != NULL) 22271390Sgibbs BN_clear_free(r->pub_key); 22365942Sgibbs if (r->priv_key != NULL) 22465942Sgibbs BN_clear_free(r->priv_key); 22565942Sgibbs OPENSSL_free(r); 22665942Sgibbs} 22765942Sgibbs 22871390Sgibbsint DH_up_ref(DH *r) 22965942Sgibbs{ 23065942Sgibbs int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH); 23165942Sgibbs#ifdef REF_PRINT 23265942Sgibbs REF_PRINT("DH", r); 23365942Sgibbs#endif 23465942Sgibbs#ifdef REF_CHECK 23565942Sgibbs if (i < 2) { 23671390Sgibbs fprintf(stderr, "DH_up, bad reference count\n"); 23765942Sgibbs abort(); 23865942Sgibbs } 23965942Sgibbs#endif 24065942Sgibbs return ((i > 1) ? 1 : 0); 24165942Sgibbs} 24265942Sgibbs 24365942Sgibbsint DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 24465942Sgibbs CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 24565942Sgibbs{ 246115338Sgibbs return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp, 24765942Sgibbs new_func, dup_func, free_func); 248115338Sgibbs} 24974094Sgibbs 25065942Sgibbsint DH_set_ex_data(DH *d, int idx, void *arg) 25165942Sgibbs{ 25265942Sgibbs return (CRYPTO_set_ex_data(&d->ex_data, idx, arg)); 25365942Sgibbs} 25465942Sgibbs 25565942Sgibbsvoid *DH_get_ex_data(DH *d, int idx) 25665942Sgibbs{ 25765942Sgibbs return (CRYPTO_get_ex_data(&d->ex_data, idx)); 25865942Sgibbs} 25965942Sgibbs 26065942Sgibbsint DH_size(const DH *dh) 26165942Sgibbs{ 26271390Sgibbs return (BN_num_bytes(dh->p)); 26365942Sgibbs} 26465942Sgibbs