/* library internal functions */
#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
- (a):bn_expand2((a),(bits)/BN_BITS2+1))
+ (a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
BIGNUM *bn_expand2(BIGNUM *a, int words);
-BIGNUM *bn_dup_expand(const BIGNUM *a, int words);
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
+#endif
/* Bignum consistency macros
* There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
return(NULL);
}
- a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
+ a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
if (A == NULL)
{
BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
}
#else
- memset(A,0,sizeof(BN_ULONG)*(words+1));
+ memset(A,0,sizeof(BN_ULONG)*words);
memcpy(A,b->d,sizeof(b->d[0])*b->top);
#endif
* while bn_dup_expand() makes sure allocation is made only once.
*/
+#ifndef OPENSSL_NO_DEPRECATED
BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
{
BIGNUM *r = NULL;
bn_check_top(r);
return r;
}
+#endif
/* This is an internal function that should not be used in applications.
* It ensures that 'b' has enough room for a 'words' word number
BIGNUM *bn_expand2(BIGNUM *b, int words)
{
- BN_ULONG *A;
- int i;
-
bn_check_top(b);
if (words > b->dmax)
b->dmax=words;
}
+/* None of this should be necessary because of what b->top means! */
+#if 0
/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
if (b->top < b->dmax)
{
- A = &(b->d[b->top]);
+ int i;
+ BN_ULONG *A = &(b->d[b->top]);
for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
{
A[0]=0; A[1]=0; A[2]=0; A[3]=0;
A[0]=0;
assert(A == &(b->d[b->dmax]));
}
+#endif
bn_check_top(b);
return b;
}
return(ret);
}
+#if 0 /* a->d[0] is a BN_ULONG, w is a BN_ULONG, what's the big deal? */
int BN_set_word(BIGNUM *a, BN_ULONG w)
{
int i,n;
bn_check_top(a);
return(1);
}
+#else
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+ {
+ bn_check_top(a);
+ if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
+ a->neg = 0;
+ a->d[0] = w;
+ a->top = (w ? 1 : 0);
+ bn_check_top(a);
+ return(1);
+ }
+#endif
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
{
if (!rr || !tmp) goto err;
max = 2 * al; /* Non-zero (from above) */
- if (bn_wexpand(rr,max+1) == NULL) goto err;
+ if (bn_wexpand(rr,max) == NULL) goto err;
if (al == 4)
{
#endif
int i;
+ bn_check_top(a);
w&=BN_MASK2;
for (i=a->top-1; i>=0; i--)
{
BN_ULONG ret = 0;
int i;
+ bn_check_top(a);
w &= BN_MASK2;
if (!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;
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;
{
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)) return BN_set_word(a,w);
+ /* handle 'a' when negative */
+ if (a->neg)
{
a->neg=0;
i=BN_add_word(a,w);
{
BN_ULONG ll;
+ bn_check_top(a);
w&=BN_MASK2;
if (a->top)
{