X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=crypto%2Fdh%2Fdh_key.c;h=37a2c1bca23f4d7a4810a786146132ef48add7e8;hb=82877ea449c322fce79d1b46c9ad354c15513f63;hp=6915d79dcc2ec24bf3c6d1b826420713ce695350;hpb=5270e7025e11b2fd1a5bdf8d81feded1167b1c87;p=oweals%2Fopenssl.git diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 6915d79dcc..37a2c1bca2 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -61,11 +61,11 @@ #include #include #include -#include static int generate_key(DH *dh); -static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh); -static int dh_bn_mod_exp(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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); @@ -73,12 +73,12 @@ static int dh_finish(DH *dh); int DH_generate_key(DH *dh) { - return ENGINE_get_DH(dh->engine)->generate_key(dh); + return dh->meth->generate_key(dh); } -int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *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); + return dh->meth->compute_key(key, pub_key, dh); } static DH_METHOD dh_ossl = { @@ -89,10 +89,11 @@ dh_bn_mod_exp, dh_init, dh_finish, 0, +NULL, NULL }; -DH_METHOD *DH_OpenSSL(void) +const DH_METHOD *DH_OpenSSL(void) { return &dh_ossl; } @@ -100,24 +101,20 @@ DH_METHOD *DH_OpenSSL(void) static int generate_key(DH *dh) { int ok=0; - unsigned int i; - BN_CTX ctx; - BN_MONT_CTX *mont; + int generate_new_key=0; + unsigned l; + BN_CTX *ctx; + BN_MONT_CTX *mont=NULL; BIGNUM *pub_key=NULL,*priv_key=NULL; - BN_CTX_init(&ctx); + 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; @@ -130,74 +127,119 @@ static int generate_key(DH *dh) else pub_key=dh->pub_key; - if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P)) + + if (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_set_locked(&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if (!mont) + 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; + 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; + } + + { + BIGNUM local_prk; + BIGNUM *prk; + + if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) + { + BN_init(&local_prk); + prk = &local_prk; + BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME); + } + else + prk = priv_key; + + if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err; + } dh->pub_key=pub_key; dh->priv_key=priv_key; ok=1; err: if (ok != 1) - DHerr(DH_F_DH_GENERATE_KEY,ERR_R_BN_LIB); + DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB); if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); - BN_CTX_free(&ctx); + BN_CTX_free(ctx); return(ok); } -static int compute_key(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; + BN_CTX *ctx=NULL; + BN_MONT_CTX *mont=NULL; BIGNUM *tmp; int ret= -1; + int check_result; - BN_CTX_init(&ctx); - BN_CTX_start(&ctx); - tmp = BN_CTX_get(&ctx); + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) + { + DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) goto err; + 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); + DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); goto err; } - if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P)) + + if (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_set_locked(&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) + { + /* XXX */ + BN_set_flags(dh->priv_key, BN_FLG_EXP_CONSTTIME); + } + if (!mont) + 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)) + if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) { - DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB); + DHerr(DH_F_COMPUTE_KEY,DH_R_INVALID_PUBKEY); + goto err; + } + + if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont)) + { + DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB); goto err; } ret=BN_bn2bin(tmp,key); err: - BN_CTX_end(&ctx); - BN_CTX_free(&ctx); + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } return(ret); } -static int dh_bn_mod_exp(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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) + /* If a is only one word long and constant time is false, use the faster + * exponenentiation function. + */ + if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0)) { BN_ULONG A = a->d[0]; return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx); @@ -216,6 +258,6 @@ static int dh_init(DH *dh) static int dh_finish(DH *dh) { if(dh->method_mont_p) - BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p); + BN_MONT_CTX_free(dh->method_mont_p); return(1); }