Don't allow BIGNUMs to become so large that computations with dmax
[openssl.git] / crypto / bn / bn_lib.c
index f0dc7d52dc257ef84abebb5619402a76d9bd7adf..096bcf183583d6c3d189abb65395bd3b6b266437 100644 (file)
@@ -312,6 +312,12 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
        const BN_ULONG *B;
        int i;
 
+       if (words > (INT_MAX/(4*BN_BITS2)))
+               {
+               BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_TOO_LARGE);
+               return NULL;
+               }
+
        bn_check_top(b);        
        if (BN_get_flags(b,BN_FLG_STATIC_DATA))
                {
@@ -357,6 +363,7 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
                }
 
        /* Now need to zero any data between b->top and b->max */
+       /* XXX Why? */
 
        A= &(a[b->top]);
        for (i=(words - b->top)>>3; i>0; i--,A+=8)
@@ -585,7 +592,6 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
        return(1);
        }
 
-/* ignore negative */
 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
        {
        unsigned int i,m;
@@ -605,7 +611,8 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
                return(NULL);
        i=((n-1)/BN_BYTES)+1;
        m=((n-1)%(BN_BYTES));
-       ret->top=i-1;
+       ret->top=i;
+       ret->neg=0;
        while (n-- > 0)
                {
                l=(l<<8L)| *(s++);
@@ -777,3 +784,34 @@ int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
        return(0);
        }
 
+/* Here follows a specialised variants of bn_cmp_words().  It has the
+   property of performing the operation on arrays of different sizes.
+   The sizes of those arrays is expressed through cl, which is the
+   common length ( basicall, min(len(a),len(b)) ), and dl, which is the
+   delta between the two lengths, calculated as len(a)-len(b).
+   All lengths are the number of BN_ULONGs...  */
+
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
+       int cl, int dl)
+       {
+       int n,i;
+       n = cl-1;
+
+       if (dl < 0)
+               {
+               for (i=dl; i<0; i++)
+                       {
+                       if (b[n-i] != 0)
+                               return -1; /* a < b */
+                       }
+               }
+       if (dl > 0)
+               {
+               for (i=dl; i>0; i--)
+                       {
+                       if (a[n+i] != 0)
+                               return 1; /* a > b */
+                       }
+               }
+       return bn_cmp_words(a,b,cl);
+       }