X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fbn%2Fbn_mont.c;h=6bcc9ad2e762f11f51cb0b135f00263c4c3da12f;hp=b8eb2b7998e2384230fbfe57e2444e74ef8c6031;hb=c1a8a5de13776c1a7b1bdbef574dd47948f77372;hpb=26a3a48d65c7464b400ec1de439994d7f0d25fed diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c index b8eb2b7998..6bcc9ad2e7 100644 --- a/crypto/bn/bn_mont.c +++ b/crypto/bn/bn_mont.c @@ -69,32 +69,20 @@ #define MONT_WORD /* use the faster word-based algorithm */ -int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx) { - BIGNUM *tmp,*tmp2; + BIGNUM *tmp; int ret=0; BN_CTX_start(ctx); tmp = BN_CTX_get(ctx); - tmp2 = BN_CTX_get(ctx); - if (tmp == NULL || tmp2 == NULL) goto err; + if (tmp == NULL) goto err; bn_check_top(tmp); - bn_check_top(tmp2); - if (a == b) { -#if 0 - bn_wexpand(tmp,a->top*2); - bn_wexpand(tmp2,a->top*4); - bn_sqr_recursive(tmp->d,a->d,a->top,tmp2->d); - tmp->top=a->top*2; - if (tmp->d[tmp->top-1] == 0) - tmp->top--; -#else if (!BN_sqr(tmp,a,ctx)) goto err; -#endif } else { @@ -102,13 +90,14 @@ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, } /* reduce from aRR to aR */ if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; + bn_check_top(r); ret=1; err: BN_CTX_end(ctx); return(ret); } -int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, +int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) { int retn=0; @@ -153,11 +142,26 @@ int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, n0=mont->n0; #ifdef BN_COUNT - printf("word BN_from_montgomery %d * %d\n",nl,nl); + fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl); #endif for (i=0; i= v) @@ -169,12 +173,13 @@ int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ; } } - bn_fix_top(r); + bn_correct_top(r); /* mont->ri will be a multiple of the word size */ #if 0 BN_rshift(ret,r,mont->ri); #else + ret->neg = r->neg; x=ri; rp=ret->d; ap= &(r->d[x]); @@ -217,14 +222,15 @@ int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, if (!BN_mul(t1,t2,&mont->N,ctx)) goto err; if (!BN_add(t2,a,t1)) goto err; - BN_rshift(ret,t2,mont->ri); + if (!BN_rshift(ret,t2,mont->ri)) goto err; #endif /* MONT_WORD */ if (BN_ucmp(ret, &(mont->N)) >= 0) { - BN_usub(ret,ret,&(mont->N)); + if (!BN_usub(ret,ret,&(mont->N))) goto err; } retn=1; + bn_check_top(ret); err: BN_CTX_end(ctx); return(retn); @@ -265,11 +271,14 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { - BIGNUM Ri,*R; + int ret = 0; + BIGNUM *Ri,*R; - BN_init(&Ri); + BN_CTX_start(ctx); + if((Ri = BN_CTX_get(ctx)) == NULL) goto err; R= &(mont->RR); /* grab RR as a temp */ - BN_copy(&(mont->N),mod); /* Set N */ + if (!BN_copy(&(mont->N),mod)) goto err; /* Set N */ + mont->N.neg = 0; #ifdef MONT_WORD { @@ -278,62 +287,84 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; BN_zero(R); - BN_set_bit(R,BN_BITS2); /* R */ + if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */ buf[0]=mod->d[0]; /* tmod = N mod word size */ buf[1]=0; tmod.d=buf; tmod.top=1; - tmod.max=2; - tmod.neg=mod->neg; + tmod.dmax=2; + tmod.neg=0; /* Ri = R^-1 mod N*/ - if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL) + if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL) goto err; - BN_lshift(&Ri,&Ri,BN_BITS2); /* R*Ri */ - if (!BN_is_zero(&Ri)) - BN_sub_word(&Ri,1); + if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */ + if (!BN_is_zero(Ri)) + { + if (!BN_sub_word(Ri,1)) goto err; + } else /* if N mod word size == 1 */ - BN_set_word(&Ri,BN_MASK2); /* Ri-- (mod word size) */ - BN_div(&Ri,NULL,&Ri,&tmod,ctx); /* Ni = (R*Ri-1)/N, - * keep only least significant word: */ - mont->n0=Ri.d[0]; - BN_free(&Ri); + { + if (!BN_set_word(Ri,BN_MASK2)) goto err; /* Ri-- (mod word size) */ + } + if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err; + /* Ni = (R*Ri-1)/N, + * keep only least significant word: */ + mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0; } #else /* !MONT_WORD */ { /* bignum version */ - mont->ri=BN_num_bits(mod); + mont->ri=BN_num_bits(&mont->N); BN_zero(R); - BN_set_bit(R,mont->ri); /* R = 2^ri */ - /* Ri = R^-1 mod N*/ - if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL) + if (!BN_set_bit(R,mont->ri)) goto err; /* R = 2^ri */ + /* Ri = R^-1 mod N*/ + if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL) goto err; - BN_lshift(&Ri,&Ri,mont->ri); /* R*Ri */ - BN_sub_word(&Ri,1); + if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */ + if (!BN_sub_word(Ri,1)) goto err; /* Ni = (R*Ri-1) / N */ - BN_div(&(mont->Ni),NULL,&Ri,mod,ctx); - BN_free(&Ri); + if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err; } #endif /* setup RR for conversions */ BN_zero(&(mont->RR)); - BN_set_bit(&(mont->RR),mont->ri*2); - BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx); + if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err; + if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err; - return(1); + ret = 1; err: - return(0); + BN_CTX_end(ctx); + return ret; } BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) { if (to == from) return(to); - BN_copy(&(to->RR),&(from->RR)); - BN_copy(&(to->N),&(from->N)); - BN_copy(&(to->Ni),&(from->Ni)); + if (!BN_copy(&(to->RR),&(from->RR))) return NULL; + if (!BN_copy(&(to->N),&(from->N))) return NULL; + if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL; to->ri=from->ri; to->n0=from->n0; return(to); } +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx) + { + if (*pmont) + return *pmont; + CRYPTO_w_lock(lock); + if (!*pmont) + { + *pmont = BN_MONT_CTX_new(); + if (*pmont && !BN_MONT_CTX_set(*pmont, mod, ctx)) + { + BN_MONT_CTX_free(*pmont); + *pmont = NULL; + } + } + CRYPTO_w_unlock(lock); + return *pmont; + }