X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fbn%2Fbn_exp.c;h=afdfd580fb43947dc380aa44dccd232d1cc5c5c8;hb=710e5d5639c8f943d73f49733382c1b787d1abb6;hp=eab394b96231051d0dc5070dd679142f3ceca8f9;hpb=c94b6de0171d2f71a643e6eac778b417d938080e;p=oweals%2Fopenssl.git diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index eab394b962..afdfd580fb 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -191,6 +191,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, */ #define MONT_MUL_MOD +#define MONT_EXP_WORD #define RECP_MUL_MOD #ifdef MONT_MUL_MOD @@ -202,12 +203,14 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, if (BN_is_odd(m)) { +# ifdef MONT_EXP_WORD if (a->top == 1 && !a->neg) { BN_ULONG A = a->d[0]; ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL); } else +# endif ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); } else @@ -235,20 +238,35 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, if (bits == 0) { - BN_one(r); - return(1); + ret = BN_one(r); + return ret; } BN_CTX_start(ctx); if ((aa = BN_CTX_get(ctx)) == NULL) goto err; BN_RECP_CTX_init(&recp); - if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; + if (m->neg) + { + /* ignore sign of 'm' */ + if (!BN_copy(aa, m)) goto err; + aa->neg = 0; + if (BN_RECP_CTX_set(&recp,aa,ctx) <= 0) goto err; + } + else + { + if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; + } BN_init(&(val[0])); ts=1; if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err; /* 1 */ + if (BN_is_zero(&(val[0]))) + { + ret = BN_zero(r); + goto err; + } window = BN_window_bits_for_exponent_size(bits); if (window > 1) @@ -355,9 +373,10 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, bits=BN_num_bits(p); if (bits == 0) { - BN_one(rr); - return(1); + ret = BN_one(rr); + return ret; } + BN_CTX_start(ctx); d = BN_CTX_get(ctx); r = BN_CTX_get(ctx); @@ -376,7 +395,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, BN_init(&val[0]); ts=1; - if (!a->neg && BN_ucmp(a,m) >= 0) + if (a->neg || BN_ucmp(a,m) >= 0) { if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err; @@ -384,6 +403,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, } else aa=a; + if (BN_is_zero(aa)) + { + ret = BN_zero(rr); + goto err; + } if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */ window = BN_window_bits_for_exponent_size(bits); @@ -483,26 +507,39 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \ (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1)))) /* BN_MOD_MUL_WORD is only used with 'w' large, - * so the BN_ucmp test is probably more overhead - * than always using BN_mod (which uses BN_copy if - * a similar test returns true). */ + * so the BN_ucmp test is probably more overhead + * than always using BN_mod (which uses BN_copy if + * a similar test returns true). */ + /* We can use BN_mod and do not need BN_nnmod because our + * accumulator is never negative (the result of BN_mod does + * not depend on the sign of the modulus). + */ #define BN_TO_MONTGOMERY_WORD(r, w, mont) \ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) bn_check_top(p); bn_check_top(m); - if (!(m->d[0] & 1)) + if (m->top == 0 || !(m->d[0] & 1)) { BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS); return(0); } + if (m->top == 1) + a %= m->d[0]; /* make sure that 'a' is reduced */ + bits = BN_num_bits(p); if (bits == 0) { - BN_one(rr); - return(1); + ret = BN_one(rr); + return ret; + } + if (a == 0) + { + ret = BN_zero(rr); + return ret; } + BN_CTX_start(ctx); d = BN_CTX_get(ctx); r = BN_CTX_get(ctx); @@ -611,8 +648,8 @@ int BN_mod_exp_simple(BIGNUM *r, if (bits == 0) { - BN_one(r); - return(1); + ret = BN_one(r); + return ret; } BN_CTX_start(ctx); @@ -621,6 +658,11 @@ int BN_mod_exp_simple(BIGNUM *r, BN_init(&(val[0])); ts=1; if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err; /* 1 */ + if (BN_is_zero(&(val[0]))) + { + ret = BN_zero(r); + goto err; + } window = BN_window_bits_for_exponent_size(bits); if (window > 1)