X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fbn%2Fbn_mul.c;h=12e5be80eb2b442db28f6b1955c0d583bb91bb83;hp=eb5d5256137ea5861f3cf71d2f07ae83b75afbe9;hb=46bf83f07ae1ba7fda435c90af93960e77159f4b;hpb=90e7ce363ae8278bb4ac647739c89a43ed341e34 diff --git a/crypto/bn/bn_mul.c b/crypto/bn/bn_mul.c index eb5d525613..12e5be80eb 100644 --- a/crypto/bn/bn_mul.c +++ b/crypto/bn/bn_mul.c @@ -66,6 +66,7 @@ #include "cryptlib.h" #include "bn_lcl.h" +#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS) /* Here follows specialised variants of bn_add_words() and bn_sub_words(). They have the property performing operations on arrays of different sizes. The sizes of those arrays is expressed through @@ -201,6 +202,7 @@ BN_ULONG bn_sub_part_words(BN_ULONG *r, } return c; } +#endif BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, @@ -387,6 +389,7 @@ BN_ULONG bn_add_part_words(BN_ULONG *r, * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) * a[1]*b[1] */ +/* dnX may not be positive, but n2/2+dnX has to be */ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, int dna, int dnb, BN_ULONG *t) { @@ -396,7 +399,7 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, BN_ULONG ln,lo,*p; # ifdef BN_COUNT - fprintf(stderr," bn_mul_recursive %d * %d\n",n2,n2); + fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb); # endif # ifdef BN_MUL_COMBA # if 0 @@ -406,16 +409,22 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, return; } # endif - if (n2 == 8) + /* Only call bn_mul_comba 8 if n2 == 8 and the + * two arrays are complete [steve] + */ + if (n2 == 8 && dna == 0 && dnb == 0) { bn_mul_comba8(r,a,b); return; } # endif /* BN_MUL_COMBA */ + /* Else do normal multiply */ if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) { - /* This should not happen */ - bn_mul_normal(r,a,n2,b,n2); + bn_mul_normal(r,a,n2+dna,b,n2+dnb); + if ((dna + dnb) < 0) + memset(&r[2*n2 + dna + dnb], 0, + sizeof(BN_ULONG) * -(dna + dnb)); return; } /* r=(a[0]-a[1])*(b[1]-b[0]) */ @@ -456,7 +465,8 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, } # ifdef BN_MUL_COMBA - if (n == 4) + if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take + extra args to do this well */ { if (!zero) bn_mul_comba4(&(t[n2]),t,&(t[n])); @@ -466,7 +476,9 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, bn_mul_comba4(r,a,b); bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n])); } - else if (n == 8) + else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could + take extra args to do this + well */ { if (!zero) bn_mul_comba8(&(t[n2]),t,&(t[n])); @@ -534,16 +546,17 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, /* n+tn is the word length * t needs to be n*4 is size, as does r */ +/* tnX may not be negative but less than n */ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, int tna, int tnb, BN_ULONG *t) { int i,j,n2=n*2; - unsigned int c1,c2,neg,zero; + int c1,c2,neg; BN_ULONG ln,lo,*p; # ifdef BN_COUNT - fprintf(stderr," bn_mul_part_recursive (%d+%d) * (%d+%d)\n", - tna, n, tnb, n); + fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n", + n, tna, n, tnb); # endif if (n < 8) { @@ -554,7 +567,7 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, /* r=(a[0]-a[1])*(b[1]-b[0]) */ c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna); c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n); - zero=neg=0; + neg=0; switch (c1*3+c2) { case -4: @@ -562,7 +575,6 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */ break; case -3: - zero=1; /* break; */ case -2: bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */ @@ -572,7 +584,6 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, case -1: case 0: case 1: - zero=1; /* break; */ case 2: bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */ @@ -580,7 +591,6 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, neg=1; break; case 3: - zero=1; /* break; */ case 4: bn_sub_part_words(t, a, &(a[n]),tna,n-tna); @@ -644,14 +654,17 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, for (;;) { i/=2; - if (i < tna && i < tnb) + /* these simplified conditions work + * exclusively because difference + * between tna and tnb is 1 or 0 */ + if (i < tna || i < tnb) { bn_mul_part_recursive(&(r[n2]), &(a[n]),&(b[n]), i,tna-i,tnb-i,p); break; } - else if (i <= tna && i <= tnb) + else if (i == tna || i == tnb) { bn_mul_recursive(&(r[n2]), &(a[n]),&(b[n]), @@ -695,7 +708,7 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, /* The overflow will stop before we over write * words we should not overwrite */ - if (ln < c1) + if (ln < (BN_ULONG)c1) { do { p++; @@ -936,8 +949,8 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) int i; #endif #ifdef BN_RECURSION - BIGNUM *t; - int j,k; + BIGNUM *t=NULL; + int j=0,k; #endif #ifdef BN_COUNT @@ -996,7 +1009,6 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { if (i >= -1 && i <= 1) { - int sav_j =0; /* Find out the power of two lower or equal to the longest of the two numbers */ if (i >= 0) @@ -1007,22 +1019,23 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { j = BN_num_bits_word((BN_ULONG)bl); } - sav_j = j; j = 1<<(j-1); assert(j <= al || j <= bl); k = j+j; t = BN_CTX_get(ctx); + if (t == NULL) + goto err; if (al > j || bl > j) { - bn_wexpand(t,k*4); - bn_wexpand(rr,k*4); + if (bn_wexpand(t,k*4) == NULL) goto err; + if (bn_wexpand(rr,k*4) == NULL) goto err; bn_mul_part_recursive(rr->d,a->d,b->d, j,al-j,bl-j,t->d); } else /* al <= j || bl <= j */ { - bn_wexpand(t,k*2); - bn_wexpand(rr,k*2); + if (bn_wexpand(t,k*2) == NULL) goto err; + if (bn_wexpand(rr,k*2) == NULL) goto err; bn_mul_recursive(rr->d,a->d,b->d, j,al-j,bl-j,t->d); } @@ -1033,7 +1046,7 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA)) { BIGNUM *tmp_bn = (BIGNUM *)b; - bn_wexpand(tmp_bn,al); + if (bn_wexpand(tmp_bn,al) == NULL) goto err; tmp_bn->d[bl]=0; bl++; i--; @@ -1041,7 +1054,7 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA)) { BIGNUM *tmp_bn = (BIGNUM *)a; - bn_wexpand(tmp_bn,bl); + if (bn_wexpand(tmp_bn,bl) == NULL) goto err; tmp_bn->d[al]=0; al++; i++; @@ -1056,14 +1069,14 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) t = BN_CTX_get(ctx); if (al == j) /* exact multiple */ { - bn_wexpand(t,k*2); - bn_wexpand(rr,k*2); + if (bn_wexpand(t,k*2) == NULL) goto err; + if (bn_wexpand(rr,k*2) == NULL) goto err; bn_mul_recursive(rr->d,a->d,b->d,al,t->d); } else { - bn_wexpand(t,k*4); - bn_wexpand(rr,k*4); + if (bn_wexpand(t,k*4) == NULL) goto err; + if (bn_wexpand(rr,k*4) == NULL) goto err; bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d); } rr->top=top; @@ -1079,10 +1092,11 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) end: #endif - bn_fix_top(rr); + bn_correct_top(rr); if (r != rr) BN_copy(r,rr); ret=1; err: + bn_check_top(r); BN_CTX_end(ctx); return(ret); } @@ -1105,7 +1119,13 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) } rr= &(r[na]); - rr[0]=bn_mul_words(r,a,na,b[0]); + if (nb <= 0) + { + (void)bn_mul_words(r,a,na,0); + return; + } + else + rr[0]=bn_mul_words(r,a,na,b[0]); for (;;) {