X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdh%2Fdh_key.c;h=0e4fee101fc541a434788c76a28d76f493f39b4e;hp=12f47c4574186392dc6c2a2b7a0092ee992ef7f4;hb=f971ccb2646828aee104c5be5deab9991f0a4d2b;hpb=b7896b3cb86d80206af14a14d69b0717786f2729 diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 12f47c4574..0e4fee101f 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -1,5 +1,5 @@ /* crypto/dh/dh_key.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -58,20 +58,55 @@ #include #include "cryptlib.h" -#include "bn.h" -#include "rand.h" -#include "dh.h" +#include +#include +#include +#include -int DH_generate_key(dh) -DH *dh; +static int generate_key(DH *dh); +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int dh_init(DH *dh); +static int dh_finish(DH *dh); + +int DH_generate_key(DH *dh) + { + return ENGINE_get_DH(dh->engine)->generate_key(dh); + } + +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) + { + return ENGINE_get_DH(dh->engine)->compute_key(key, pub_key, dh); + } + +static DH_METHOD dh_ossl = { +"OpenSSL DH Method", +generate_key, +compute_key, +dh_bn_mod_exp, +dh_init, +dh_finish, +0, +NULL +}; + +const DH_METHOD *DH_OpenSSL(void) +{ + return &dh_ossl; +} + +static int generate_key(DH *dh) { int ok=0; unsigned int i; - BN_CTX *ctx=NULL; + BN_CTX ctx; + BN_MONT_CTX *mont; BIGNUM *pub_key=NULL,*priv_key=NULL; - ctx=BN_CTX_new(); - if (ctx == NULL) goto err; + BN_CTX_init(&ctx); if (dh->priv_key == NULL) { @@ -96,7 +131,17 @@ DH *dh; else pub_key=dh->pub_key; - if (!BN_mod_exp(pub_key,dh->g,priv_key,dh->p,ctx)) goto err; + if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P)) + { + if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p, + dh->p,&ctx)) goto err; + } + mont=(BN_MONT_CTX *)dh->method_mont_p; + + if (!ENGINE_get_DH(dh->engine)->bn_mod_exp(dh, pub_key, dh->g, + priv_key,dh->p,&ctx,mont)) + goto err; dh->pub_key=pub_key; dh->priv_key=priv_key; @@ -107,29 +152,36 @@ err: if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); - if (ctx != NULL) BN_CTX_free(ctx); + BN_CTX_free(&ctx); return(ok); } -int DH_compute_key(key,pub_key,dh) -unsigned char *key; -BIGNUM *pub_key; -DH *dh; +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) { - BN_CTX *ctx; + BN_CTX ctx; + BN_MONT_CTX *mont; BIGNUM *tmp; int ret= -1; - ctx=BN_CTX_new(); - if (ctx == NULL) goto err; - tmp=ctx->bn[ctx->tos++]; + BN_CTX_init(&ctx); + BN_CTX_start(&ctx); + tmp = BN_CTX_get(&ctx); if (dh->priv_key == NULL) { DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); goto err; } - if (!BN_mod_exp(tmp,pub_key,dh->priv_key,dh->p,ctx)) + if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P)) + { + if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p, + dh->p,&ctx)) goto err; + } + + mont=(BN_MONT_CTX *)dh->method_mont_p; + if (!ENGINE_get_DH(dh->engine)->bn_mod_exp(dh, tmp, pub_key, + dh->priv_key,dh->p,&ctx,mont)) { DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB); goto err; @@ -137,6 +189,35 @@ DH *dh; ret=BN_bn2bin(tmp,key); err: - if (ctx != NULL) BN_CTX_free(ctx); + BN_CTX_end(&ctx); + BN_CTX_free(&ctx); return(ret); } + +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) + { + if (a->top == 1) + { + BN_ULONG A = a->d[0]; + return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx); + } + else + return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx); + } + + +static int dh_init(DH *dh) + { + dh->flags |= DH_FLAG_CACHE_MONT_P; + return(1); + } + +static int dh_finish(DH *dh) + { + if(dh->method_mont_p) + BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p); + return(1); + }