When OPENSSL_NO_DEPRECATED is defined, deprecated functions are (or should
[oweals/openssl.git] / crypto / bn / bn_lib.c
index 60e3c680bc1813353614696b51cea4434c4dd56f..bbcc62d831a47108e5a9f0ebd565d4177067f1cb 100644 (file)
@@ -263,12 +263,12 @@ void BN_clear_free(BIGNUM *a)
        if (a == NULL) return;
        if (a->d != NULL)
                {
-               memset(a->d,0,a->dmax*sizeof(a->d[0]));
+               OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
                if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
                        OPENSSL_free(a->d);
                }
        i=BN_get_flags(a,BN_FLG_MALLOCED);
-       memset(a,0,sizeof(BIGNUM));
+       OPENSSL_cleanse(a,sizeof(BIGNUM));
        if (i)
                OPENSSL_free(a);
        }
@@ -453,13 +453,14 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
        if ((b != NULL) && (b->top < b->dmax))
                {
                A = &(b->d[b->top]);
-               for (i=(words - b->top)>>3; i>0; i--,A+=8)
+               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[4]=0; A[5]=0; A[6]=0; A[7]=0;
                        }
-               for (i=(words - b->top)&7; i>0; i--,A++)
+               for (i=(b->dmax - b->top)&7; i>0; i--,A++)
                        A[0]=0;
+               assert(A == &(b->d[b->dmax]));
                }
                
        return b;
@@ -521,6 +522,51 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
        return(a);
        }
 
+BIGNUM *BN_ncopy(BIGNUM *a, const BIGNUM *b, size_t n)
+       {
+       int i, min;
+       BN_ULONG *A;
+       const BN_ULONG *B;
+
+       bn_check_top(b);
+
+       if (a == b)
+               return a;
+
+       min = (b->top < (int)n)? b->top: (int)n;
+
+       if (!min)
+               {
+               BN_zero(a);
+               return a;
+               }
+
+       if (bn_wexpand(a, min) == NULL)
+               return NULL;
+
+       A=a->d;
+       B=b->d;
+       for (i=min>>2; i>0; i--, A+=4, B+=4)
+               {
+               BN_ULONG a0,a1,a2,a3;
+               a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+               A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+               }
+       switch (min&3)
+               {
+               case 3: A[2]=B[2];
+               case 2: A[1]=B[1];
+               case 1: A[0]=B[0];
+               case 0: ;
+               }
+       a->top = min;
+
+       a->neg = b->neg;
+       bn_fix_top(a);
+
+       return(a);
+       }
+
 void BN_swap(BIGNUM *a, BIGNUM *b)
        {
        int flags_old_a, flags_old_b;