BN_FLG_FREE is of extremely dubious usefulness, and is only referred to
[openssl.git] / crypto / bn / bn_lib.c
index 783881d3a6977964c8993a25a8673d4128c462d1..3bc67f9de2c267a5a9a4f5f23a38b284cae1bc80 100644 (file)
@@ -131,7 +131,7 @@ int BN_get_params(int which)
 const BIGNUM *BN_value_one(void)
        {
        static BN_ULONG data_one=1L;
-       static BIGNUM const_one={&data_one,1,1,0};
+       static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA};
 
        return(&const_one);
        }
@@ -278,14 +278,21 @@ void BN_free(BIGNUM *a)
        if (a == NULL) return;
        if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
                OPENSSL_free(a->d);
-       a->flags|=BN_FLG_FREE; /* REMOVE? */
        if (a->flags & BN_FLG_MALLOCED)
                OPENSSL_free(a);
+       else
+               {
+#ifndef OPENSSL_NO_DEPRECATED
+               a->flags|=BN_FLG_FREE;
+#endif
+               a->d = NULL;
+               }
        }
 
 void BN_init(BIGNUM *a)
        {
        memset(a,0,sizeof(BIGNUM));
+       bn_check_top(a);
        }
 
 BIGNUM *BN_new(void)
@@ -302,6 +309,7 @@ BIGNUM *BN_new(void)
        ret->neg=0;
        ret->dmax=0;
        ret->d=NULL;
+       bn_check_top(ret);
        return(ret);
        }
 
@@ -420,6 +428,7 @@ BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
                r = BN_dup(b);
                }
 
+       bn_check_top(r);
        return r;
        }
 
@@ -462,6 +471,7 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
                        A[0]=0;
                assert(A == &(b->d[b->dmax]));
                }
+       else if(b) bn_check_top(b);
        return b;
        }
 
@@ -479,6 +489,7 @@ BIGNUM *BN_dup(const BIGNUM *a)
        /* now  r == t || r == NULL */
        if (r == NULL)
                BN_free(t);
+       bn_check_top(r);
        return r;
        }
 
@@ -518,6 +529,7 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
        if ((a->top == 0) && (a->d != NULL))
                a->d[0]=0;
        a->neg=b->neg;
+       bn_check_top(a);
        return(a);
        }
 
@@ -561,8 +573,9 @@ BIGNUM *BN_ncopy(BIGNUM *a, const BIGNUM *b, size_t n)
        a->top = min;
 
        a->neg = b->neg;
-       bn_fix_top(a);
+       bn_correct_top(a);
 
+       bn_check_top(a);
        return(a);
        }
 
@@ -572,6 +585,9 @@ void BN_swap(BIGNUM *a, BIGNUM *b)
        BN_ULONG *tmp_d;
        int tmp_top, tmp_dmax, tmp_neg;
        
+       bn_check_top(a);
+       bn_check_top(b);
+
        flags_old_a = a->flags;
        flags_old_b = b->flags;
 
@@ -592,11 +608,14 @@ void BN_swap(BIGNUM *a, BIGNUM *b)
        
        a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
        b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
+       bn_check_top(a);
+       bn_check_top(b);
        }
 
 
 void BN_clear(BIGNUM *a)
        {
+       bn_check_top(a);
        if (a->d != NULL)
                memset(a->d,0,a->dmax*sizeof(a->d[0]));
        a->top=0;
@@ -627,6 +646,7 @@ BN_ULONG BN_get_word(const BIGNUM *a)
 int BN_set_word(BIGNUM *a, BN_ULONG w)
        {
        int i,n;
+       bn_check_top(a);
        if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
 
        n=sizeof(BN_ULONG)/BN_BYTES;
@@ -648,6 +668,7 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
                a->d[i]=(BN_ULONG)w&BN_MASK2;
                if (a->d[i] != 0) a->top=i+1;
                }
+       bn_check_top(a);
        return(1);
        }
 
@@ -659,6 +680,7 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
 
        if (ret == NULL) ret=BN_new();
        if (ret == NULL) return(NULL);
+       bn_check_top(ret);
        l=0;
        n=len;
        if (n == 0)
@@ -684,7 +706,7 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
                }
        /* need to call this due to clear byte at top if avoiding
         * having the top bit set (-ve number) */
-       bn_fix_top(ret);
+       bn_correct_top(ret);
        return(ret);
        }
 
@@ -694,6 +716,7 @@ int BN_bn2bin(const BIGNUM *a, unsigned char *to)
        int n,i;
        BN_ULONG l;
 
+       bn_check_top(a);
        n=i=BN_num_bytes(a);
        while (i-- > 0)
                {
@@ -770,6 +793,9 @@ int BN_set_bit(BIGNUM *a, int n)
        {
        int i,j,k;
 
+       if (n < 0)
+               return 0;
+
        i=n/BN_BITS2;
        j=n%BN_BITS2;
        if (a->top <= i)
@@ -781,6 +807,7 @@ int BN_set_bit(BIGNUM *a, int n)
                }
 
        a->d[i]|=(((BN_ULONG)1)<<j);
+       bn_check_top(a);
        return(1);
        }
 
@@ -788,12 +815,15 @@ int BN_clear_bit(BIGNUM *a, int n)
        {
        int i,j;
 
+       if (n < 0)
+               return 0;
+
        i=n/BN_BITS2;
        j=n%BN_BITS2;
        if (a->top <= i) return(0);
 
        a->d[i]&=(~(((BN_ULONG)1)<<j));
-       bn_fix_top(a);
+       bn_correct_top(a);
        return(1);
        }
 
@@ -812,6 +842,9 @@ int BN_mask_bits(BIGNUM *a, int n)
        {
        int b,w;
 
+       if (n < 0)
+               return 0;
+
        w=n/BN_BITS2;
        b=n%BN_BITS2;
        if (w >= a->top) return(0);
@@ -822,7 +855,7 @@ int BN_mask_bits(BIGNUM *a, int n)
                a->top=w+1;
                a->d[w]&= ~(BN_MASK2<<b);
                }
-       bn_fix_top(a);
+       bn_correct_top(a);
        return(1);
        }