X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdh%2Fdh_key.c;h=670727798e8c6b18dd4979f10f2769405366286a;hp=12f47c4574186392dc6c2a2b7a0092ee992ef7f4;hb=de3333bae446a185180287382b8abf25c4bac228;hpb=d02b48c63a58ea4367a0e905979f140b7d090f86;ds=sidebyside diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 12f47c4574..670727798e 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,32 +58,63 @@ #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; + int generate_new_key=0; + unsigned l; + BN_CTX *ctx; + BN_MONT_CTX *mont; BIGNUM *pub_key=NULL,*priv_key=NULL; - ctx=BN_CTX_new(); + ctx = BN_CTX_new(); if (ctx == NULL) goto err; if (dh->priv_key == NULL) { - i=dh->length; - if (i == 0) - { - /* Make the number p-1 bits long */ - i=BN_num_bits(dh->p)-1; - } priv_key=BN_new(); if (priv_key == NULL) goto err; - if (!BN_rand(priv_key,i,0,0)) goto err; + generate_new_key=1; } else priv_key=dh->priv_key; @@ -96,7 +127,21 @@ 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 (generate_new_key) + { + l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */ + if (!BN_rand(priv_key, l, 0, 0)) goto err; + } + 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,37 @@ 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_MONT_CTX *mont; BIGNUM *tmp; int ret= -1; - ctx=BN_CTX_new(); + ctx = BN_CTX_new(); if (ctx == NULL) goto err; - tmp=ctx->bn[ctx->tos++]; + 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 +190,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); + }