X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=crypto%2Fbn%2Fbn_word.c;h=ee7b87c45ccd38839db6261ed81c2d87b9e881b5;hb=1e8569398cd406b967501ed6e38cd2392d25ec2c;hp=a241150157ca385d65306105c645067023103023;hpb=6defae04f3c44087d9129994fa88b4f9271b153f;p=openssl.git diff --git a/crypto/bn/bn_word.c b/crypto/bn/bn_word.c index a241150157..ee7b87c45c 100644 --- a/crypto/bn/bn_word.c +++ b/crypto/bn/bn_word.c @@ -69,6 +69,10 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) #endif int i; + if (w == 0) + return (BN_ULONG)-1; + + bn_check_top(a); w&=BN_MASK2; for (i=a->top-1; i>=0; i--) { @@ -86,16 +90,23 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) { BN_ULONG ret = 0; - int i; + int i, j; + bn_check_top(a); w &= BN_MASK2; if (!w) /* actually this an error (division by zero) */ - return 0; + return (BN_ULONG)-1; if (a->top == 0) return 0; + /* normalize input (so bn_div_words doesn't complain) */ + j = BN_BITS2 - BN_num_bits_word(w); + w <<= j; + if (!BN_lshift(a, a, j)) + return (BN_ULONG)-1; + for (i=a->top-1; i>=0; i--) { BN_ULONG l,d; @@ -107,6 +118,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) } if ((a->top > 0) && (a->d[a->top-1] == 0)) a->top--; + ret >>= j; bn_check_top(a); return(ret); } @@ -116,11 +128,14 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) BN_ULONG l; int i; + bn_check_top(a); w &= BN_MASK2; - if (!w) - return 1; - + /* degenerate case: w is zero */ + if (!w) return 1; + /* degenerate case: a is zero */ + if(BN_is_zero(a)) return BN_set_word(a, w); + /* handle 'a' when negative */ if (a->neg) { a->neg=0; @@ -129,14 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) a->neg=!(a->neg); return(i); } - if (bn_wexpand(a,a->top+1) == NULL) return(0); + /* Only expand (and risk failing) if it's possibly necessary */ + if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) && + (bn_wexpand(a,a->top+1) == NULL)) + return(0); i=0; for (;;) { if (i >= a->top) l=w; else - l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; + l=(a->d[i]+w)&BN_MASK2; a->d[i]=l; if (w > l) w=1; @@ -154,12 +172,21 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w) { int i; + bn_check_top(a); w &= BN_MASK2; - if (!w) - return 1; - - if (BN_is_zero(a) || a->neg) + /* degenerate case: w is zero */ + if (!w) return 1; + /* degenerate case: a is zero */ + if(BN_is_zero(a)) + { + i = BN_set_word(a,w); + if (i != 0) + BN_set_negative(a, 1); + return i; + } + /* handle 'a' when negative */ + if (a->neg) { a->neg=0; i=BN_add_word(a,w); @@ -198,6 +225,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w) { BN_ULONG ll; + bn_check_top(a); w&=BN_MASK2; if (a->top) {