Constify the BIGNUM routines a bit more. The only trouble were the
authorRichard Levitte <levitte@openssl.org>
Mon, 6 Nov 2000 21:15:54 +0000 (21:15 +0000)
committerRichard Levitte <levitte@openssl.org>
Mon, 6 Nov 2000 21:15:54 +0000 (21:15 +0000)
two functions that did expansion on in parameters (BN_mul() and
BN_sqr()).  The problem was solved by making bn_dup_expand() which is
a mix of bn_expand2() and BN_dup().

13 files changed:
CHANGES
crypto/bn/bn.h
crypto/bn/bn_exp.c
crypto/bn/bn_exp2.c
crypto/bn/bn_gcd.c
crypto/bn/bn_lib.c
crypto/bn/bn_mont.c
crypto/bn/bn_mul.c
crypto/bn/bn_prime.c
crypto/bn/bn_recp.c
crypto/bn/bn_shift.c
crypto/bn/bn_sqr.c
crypto/bn/bntest.c

diff --git a/CHANGES b/CHANGES
index 7c61898..7c30801 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,9 @@
 
  Changes between 0.9.6 and 0.9.7  [xx XXX 2000]
 
+  *) Constify the BIGNUM routines a little more.
+     [Richard Levitte]
+
   *) Make sure that shared libraries get the internal name engine with
      the full version number and not just 0.  This should mark the
      shared libraries as not backward compatible.  Of course, this should
index 1eb8395..dad488f 100644 (file)
@@ -345,33 +345,35 @@ int       BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
 int    BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
 int    BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
               BN_CTX *ctx);
-int    BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
-int    BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
+int    BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int    BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
 BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
 BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
 int    BN_mul_word(BIGNUM *a, BN_ULONG w);
 int    BN_add_word(BIGNUM *a, BN_ULONG w);
 int    BN_sub_word(BIGNUM *a, BN_ULONG w);
 int    BN_set_word(BIGNUM *a, BN_ULONG w);
-BN_ULONG BN_get_word(BIGNUM *a);
+BN_ULONG BN_get_word(const BIGNUM *a);
 int    BN_cmp(const BIGNUM *a, const BIGNUM *b);
 void   BN_free(BIGNUM *a);
 int    BN_is_bit_set(const BIGNUM *a, int n);
 int    BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
-int    BN_lshift1(BIGNUM *r, BIGNUM *a);
-int    BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx);
-int    BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
-                  const BIGNUM *m,BN_CTX *ctx);
-int    BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
-                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int    BN_lshift1(BIGNUM *r, const BIGNUM *a);
+int    BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx);
+int    BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m,BN_CTX *ctx);
+int    BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
 int    BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
-                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-int    BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2,
-               BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx);
-int    BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p,
-       BIGNUM *m,BN_CTX *ctx);
+       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int    BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+       const BIGNUM *a2, const BIGNUM *p2,const BIGNUM *m,
+       BN_CTX *ctx,BN_MONT_CTX *m_ctx);
+int    BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m,BN_CTX *ctx);
 int    BN_mask_bits(BIGNUM *a,int n);
-int    BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int    BN_mod_mul(BIGNUM *ret, const BIGNUM *a, const BIGNUM *b,
+       const BIGNUM *m, BN_CTX *ctx);
 #ifndef NO_FP_API
 int    BN_print_fp(FILE *fp, const BIGNUM *a);
 #endif
@@ -380,9 +382,9 @@ int BN_print(BIO *fp, const BIGNUM *a);
 #else
 int    BN_print(void *fp, const BIGNUM *a);
 #endif
-int    BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx);
-int    BN_rshift(BIGNUM *r, BIGNUM *a, int n);
-int    BN_rshift1(BIGNUM *r, BIGNUM *a);
+int    BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int    BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int    BN_rshift1(BIGNUM *r, const BIGNUM *a);
 void   BN_clear(BIGNUM *a);
 BIGNUM *BN_dup(const BIGNUM *a);
 int    BN_ucmp(const BIGNUM *a, const BIGNUM *b);
@@ -393,9 +395,11 @@ char *     BN_bn2dec(const BIGNUM *a);
 int    BN_hex2bn(BIGNUM **a, const char *str);
 int    BN_dec2bn(BIGNUM **a, const char *str);
 int    BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
-BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
-BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add,
-               BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+       const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
+       const BIGNUM *add, const BIGNUM *rem,
+       void (*callback)(int,int,void *),void *cb_arg);
 int    BN_is_prime(const BIGNUM *p,int nchecks,
                void (*callback)(int,int,void *),
                BN_CTX *ctx,void *cb_arg);
@@ -406,8 +410,8 @@ void        ERR_load_BN_strings(void );
 
 BN_MONT_CTX *BN_MONT_CTX_new(void );
 void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
-int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont,
-                         BN_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
+       BN_MONT_CTX *mont, BN_CTX *ctx);
 int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx);
 void BN_MONT_CTX_free(BN_MONT_CTX *mont);
 int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx);
@@ -426,11 +430,11 @@ void      BN_RECP_CTX_init(BN_RECP_CTX *recp);
 BN_RECP_CTX *BN_RECP_CTX_new(void);
 void   BN_RECP_CTX_free(BN_RECP_CTX *recp);
 int    BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
-int    BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y,
+int    BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
                BN_RECP_CTX *recp,BN_CTX *ctx);
 int    BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                        const BIGNUM *m, BN_CTX *ctx);
-int    BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
+int    BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
                BN_RECP_CTX *recp, BN_CTX *ctx);
 
 /* library internal functions */
@@ -439,6 +443,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
        (a):bn_expand2((a),(bits)/BN_BITS2+1))
 #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);
 
 #define bn_fix_top(a) \
         { \
index d2c9162..74b1f0e 100644 (file)
 #define TABLE_SIZE     32
 
 /* slow but works */
-int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+int BN_mod_mul(BIGNUM *ret, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+       BN_CTX *ctx)
        {
        BIGNUM *t;
        int r=0;
@@ -141,7 +142,7 @@ err:
 
 
 /* this one works - simple but works */
-int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        {
        int i,bits,ret=0;
        BIGNUM *v,*rr;
@@ -176,7 +177,7 @@ err:
        }
 
 
-int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
               BN_CTX *ctx)
        {
        int ret;
@@ -325,13 +326,13 @@ err:
        }
 
 
-int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
+int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
        {
        int i,j,bits,ret=0,wstart,wend,window,wvalue;
        int start=1,ts=0;
        BIGNUM *d,*r;
-       BIGNUM *aa;
+       const BIGNUM *aa;
        BIGNUM val[TABLE_SIZE];
        BN_MONT_CTX *mont=NULL;
 
@@ -590,8 +591,9 @@ err:
 
 
 /* The old fallback, simple version :-) */
-int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
-            BN_CTX *ctx)
+int BN_mod_exp_simple(BIGNUM *r,
+       const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+       BN_CTX *ctx)
        {
        int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0;
        int start=1;
index 29029f4..70c4d83 100644 (file)
 
 #define TABLE_SIZE     32
 
-int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2,
-            BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
+       const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+       BN_CTX *ctx, BN_MONT_CTX *in_mont)
        {
        int i,j,bits,b,bits1,bits2,ret=0,wpos1,wpos2,window1,window2,wvalue1,wvalue2;
        int r_is_one=1,ts1=0,ts2=0;
        BIGNUM *d,*r;
-       BIGNUM *a_mod_m;
+       const BIGNUM *a_mod_m;
        BIGNUM val1[TABLE_SIZE], val2[TABLE_SIZE];
        BN_MONT_CTX *mont=NULL;
 
index 3982071..61c431f 100644 (file)
@@ -144,7 +144,8 @@ err:
        }
 
 /* solves ax == 1 (mod n) */
-BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+BIGNUM *BN_mod_inverse(BIGNUM *in,
+       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
        {
        BIGNUM *A,*B,*X,*Y,*M,*D,*R=NULL;
        BIGNUM *T,*ret=NULL;
index b6b0ce4..3e4965d 100644 (file)
@@ -304,42 +304,35 @@ BIGNUM *BN_new(void)
        return(ret);
        }
 
-/* This is an internal function that should not be used in applications.
- * It ensures that 'b' has enough room for a 'words' word number number.
- * It is mostly used by the various BIGNUM routines. If there is an error,
- * NULL is returned. If not, 'b' is returned. */
-
-BIGNUM *bn_expand2(BIGNUM *b, int words)
+/* This is used both by bn_expand2() and bn_dup_expand() */
+/* The caller MUST check that words > b->dmax before calling this */
+static BN_ULONG *internal_bn_expand(const BIGNUM *b, int words)
        {
-       BN_ULONG *A,*a;
+       BN_ULONG *A,*a = NULL;
        const BN_ULONG *B;
        int i;
 
-       bn_check_top(b);
-
-       if (words > b->dmax)
+       bn_check_top(b);        
+       if (BN_get_flags(b,BN_FLG_STATIC_DATA))
                {
-               bn_check_top(b);        
-               if (BN_get_flags(b,BN_FLG_STATIC_DATA))
-                       {
-                       BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
-                       return(NULL);
-                       }
-               a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
-               if (A == NULL)
-                       {
-                       BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
-                       return(NULL);
-                       }
+               BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+               return(NULL);
+               }
+       a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
+       if (A == NULL)
+               {
+               BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
+               return(NULL);
+               }
 #if 1
-               B=b->d;
-               /* Check if the previous number needs to be copied */
-               if (B != NULL)
-                       {
+       B=b->d;
+       /* Check if the previous number needs to be copied */
+       if (B != NULL)
+               {
 #if 0
-                       /* This lot is an unrolled loop to copy b->top 
-                        * BN_ULONGs from B to A
-                        */
+               /* This lot is an unrolled loop to copy b->top 
+                * BN_ULONGs from B to A
+                */
 /*
  * I have nothing against unrolling but it's usually done for
  * several reasons, namely:
@@ -363,94 +356,145 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
  *
  *                                     <appro@fy.chalmers.se>
  */
-                       for (i=b->top&(~7); i>0; i-=8)
-                               {
-                               A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
-                               A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
-                               A+=8;
-                               B+=8;
-                               }
-                       switch (b->top&7)
-                               {
-                       case 7:
-                               A[6]=B[6];
-                       case 6:
-                               A[5]=B[5];
-                       case 5:
-                               A[4]=B[4];
-                       case 4:
-                               A[3]=B[3];
-                       case 3:
-                               A[2]=B[2];
-                       case 2:
-                               A[1]=B[1];
-                       case 1:
-                               A[0]=B[0];
-                       case 0:
-                               /* I need the 'case 0' entry for utrix cc.
-                                * If the optimizer is turned on, it does the
-                                * switch table by doing
-                                * a=top&7
-                                * a--;
-                                * goto jump_table[a];
-                                * If top is 0, this makes us jump to 0xffffffc 
-                                * which is rather bad :-(.
-                                * eric 23-Apr-1998
-                                */
-                               ;
-                               }
+               for (i=b->top&(~7); i>0; i-=8)
+                       {
+                       A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
+                       A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
+                       A+=8;
+                       B+=8;
+                       }
+               switch (b->top&7)
+                       {
+               case 7:
+                       A[6]=B[6];
+               case 6:
+                       A[5]=B[5];
+               case 5:
+                       A[4]=B[4];
+               case 4:
+                       A[3]=B[3];
+               case 3:
+                       A[2]=B[2];
+               case 2:
+                       A[1]=B[1];
+               case 1:
+                       A[0]=B[0];
+               case 0:
+                       /* I need the 'case 0' entry for utrix cc.
+                        * If the optimizer is turned on, it does the
+                        * switch table by doing
+                        * a=top&7
+                        * a--;
+                        * goto jump_table[a];
+                        * If top is 0, this makes us jump to 0xffffffc 
+                        * which is rather bad :-(.
+                        * eric 23-Apr-1998
+                        */
+                       ;
+                       }
 #else
-                       for (i=b->top>>2; i>0; i--,A+=4,B+=4)
-                               {
-                               /*
-                                * The fact that the loop is unrolled
-                                * 4-wise is a tribute to Intel. It's
-                                * the one that doesn't have enough
-                                * registers to accomodate more data.
-                                * I'd unroll it 8-wise otherwise:-)
-                                *
-                                *              <appro@fy.chalmers.se>
-                                */
-                               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 (b->top&3)
-                               {
-                               case 3: A[2]=B[2];
-                               case 2: A[1]=B[1];
-                               case 1: A[0]=B[0];
-                               case 0: ; /* ultrix cc workaround, see above */
-                               }
-#endif
-                       OPENSSL_free(b->d);
+               for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+                       {
+                       /*
+                        * The fact that the loop is unrolled
+                        * 4-wise is a tribute to Intel. It's
+                        * the one that doesn't have enough
+                        * registers to accomodate more data.
+                        * I'd unroll it 8-wise otherwise:-)
+                        *
+                        *              <appro@fy.chalmers.se>
+                        */
+                       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;
                        }
-
-               b->d=a;
-               b->dmax=words;
-
-               /* Now need to zero any data between b->top and b->max */
-
-               A= &(b->d[b->top]);
-               for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
+               switch (b->top&3)
                        {
-                       A[0]=0; A[1]=0; A[2]=0; A[3]=0;
-                       A[4]=0; A[5]=0; A[6]=0; A[7]=0;
+               case 3: A[2]=B[2];
+               case 2: A[1]=B[1];
+               case 1: A[0]=B[0];
+               case 0: ; /* ultrix cc workaround, see above */
                        }
-               for (i=(b->dmax - b->top)&7; i>0; i--,A++)
-                       A[0]=0;
+#endif
+               }
+
+       /* Now need to zero any data between b->top and b->max */
+
+       A= &(a[b->top]);
+       for (i=(words - 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++)
+               A[0]=0;
 #else
-                       memset(A,0,sizeof(BN_ULONG)*(words+1));
-                       memcpy(A,b->d,sizeof(b->d[0])*b->top);
-                       b->d=a;
-                       b->max=words;
+       memset(A,0,sizeof(BN_ULONG)*(words+1));
+       memcpy(A,b->d,sizeof(b->d[0])*b->top);
 #endif
                
-/*             memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
-/*     { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
+       return(a);
+       }
 
+/* This is an internal function that can be used instead of bn_expand2()
+ * when there is a need to copy BIGNUMs instead of only expanding the
+ * data part, while still expanding them.
+ * Especially useful when needing to expand BIGNUMs that are declared
+ * 'const' and should therefore not be changed.
+ * The reason to use this instead of a BN_dup() followed by a bn_expand2()
+ * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
+ * will allocate new memory for the BIGNUM data twice, and free it once,
+ * while bn_dup_expand() makes sure allocation is made only once.
+ */
+
+BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
+       {
+       BIGNUM *r = NULL;
+
+       if (words > b->dmax)
+               {
+               BN_ULONG *a = internal_bn_expand(b, words);
+
+               if (a)
+                       {
+                       r = BN_new();
+                       r->top = b->top;
+                       r->dmax = words;
+                       r->neg = b->neg;
+                       r->d = a;
+                       }
+               /* Otherwise, there was an error in allocation in
+                  internal_bn_expand(), and NULL should be returned */
+               }
+       else
+               {
+               r = BN_dup(b);
+               }
+
+       return r;
+       }
+
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'words' word number number.
+ * It is mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. If not, 'b' is returned. */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+       {
+       if (words > b->dmax)
+               {
+               BN_ULONG *a = internal_bn_expand(b, words);
+
+               if (a)
+                       {
+                       OPENSSL_free(b->d);
+                       b->d=a;
+                       b->dmax=words;
+                       }
+               else
+                       b = NULL;
                }
-       return(b);
+       return b;
        }
 
 BIGNUM *BN_dup(const BIGNUM *a)
@@ -513,7 +557,7 @@ void BN_clear(BIGNUM *a)
        a->neg=0;
        }
 
-BN_ULONG BN_get_word(BIGNUM *a)
+BN_ULONG BN_get_word(const BIGNUM *a)
        {
        int i,n;
        BN_ULONG ret=0;
index 8cf1feb..202eec4 100644 (file)
@@ -69,7 +69,7 @@
 
 #define MONT_WORD /* use the faster word-based algorithm */
 
-int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                          BN_MONT_CTX *mont, BN_CTX *ctx)
        {
        BIGNUM *tmp,*tmp2;
index 3e8d8b9..aed7528 100644 (file)
@@ -608,7 +608,7 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
        }
 #endif /* BN_RECURSION */
 
-int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        {
        int top,al,bl;
        BIGNUM *rr;
@@ -620,6 +620,7 @@ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
        BIGNUM *t;
        int j,k;
 #endif
+       BIGNUM *free_a = NULL, *free_b = NULL;
 
 #ifdef BN_COUNT
        printf("BN_mul %d * %d\n",a->top,b->top);
@@ -677,17 +678,21 @@ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
                {
                if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
                        {
-                       bn_wexpand(b,al);
-                       b->d[bl]=0;
+                       BIGNUM *tmp_bn = free_b;
+                       b = free_b = bn_dup_expand(b,al);
+                       free_b->d[bl]=0;
                        bl++;
                        i--;
+                       if (tmp_bn) BN_free(tmp_bn);
                        }
                else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
                        {
-                       bn_wexpand(a,bl);
-                       a->d[al]=0;
+                       BIGNUM *tmp_bn = free_a;
+                       a = free_a = bn_dup_expand(a,bl);
+                       free_a->d[al]=0;
                        al++;
                        i++;
+                       if (tmp_bn) BN_free(tmp_bn);
                        }
                if (i == 0)
                        {
@@ -705,14 +710,17 @@ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
                                }
                        else
                                {
-                               bn_wexpand(a,k);
-                               bn_wexpand(b,k);
+                               BIGNUM *tmp_a = free_a,*tmp_b = free_b;
+                               a = free_a = bn_dup_expand(a,k);
+                               b = free_b = bn_dup_expand(b,k);
+                               if (tmp_a) BN_free(tmp_a);
+                               if (tmp_b) BN_free(tmp_b);
                                bn_wexpand(t,k*4);
                                bn_wexpand(rr,k*4);
-                               for (i=a->top; i<k; i++)
-                                       a->d[i]=0;
-                               for (i=b->top; i<k; i++)
-                                       b->d[i]=0;
+                               for (i=free_a->top; i<k; i++)
+                                       free_a->d[i]=0;
+                               for (i=free_b->top; i<k; i++)
+                                       free_b->d[i]=0;
                                bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
                                }
                        rr->top=top;
@@ -731,6 +739,8 @@ end:
        if (r != rr) BN_copy(r,rr);
        ret=1;
 err:
+       if (free_a) BN_free(free_a);
+       if (free_b) BN_free(free_b);
        BN_CTX_end(ctx);
        return(ret);
        }
index a5f01b9..b75e58c 100644 (file)
@@ -125,12 +125,13 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
        const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
 static int probable_prime(BIGNUM *rnd, int bits);
 static int probable_prime_dh(BIGNUM *rnd, int bits,
-       BIGNUM *add, BIGNUM *rem, BN_CTX *ctx);
+       const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
 static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
-       BIGNUM *add, BIGNUM *rem, BN_CTX *ctx);
+       const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
 
-BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BIGNUM *add,
-            BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg)
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+       const BIGNUM *add, const BIGNUM *rem,
+       void (*callback)(int,int,void *), void *cb_arg)
        {
        BIGNUM *rnd=NULL;
        BIGNUM t;
@@ -376,8 +377,8 @@ again:
        return(1);
        }
 
-static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
-            BN_CTX *ctx)
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+       const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx)
        {
        int i,ret=0;
        BIGNUM *t1;
@@ -413,8 +414,8 @@ err:
        return(ret);
        }
 
-static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd,
-            BIGNUM *rem, BN_CTX *ctx)
+static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
+       const BIGNUM *rem, BN_CTX *ctx)
        {
        int i,ret=0;
        BIGNUM *t1,*qadd,*q;
index d019941..a175e1c 100644 (file)
@@ -100,11 +100,12 @@ int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
        return(1);
        }
 
-int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,
-            BN_CTX *ctx)
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+       BN_RECP_CTX *recp, BN_CTX *ctx)
        {
        int ret=0;
        BIGNUM *a;
+       const BIGNUM *ca;
 
        BN_CTX_start(ctx);
        if ((a = BN_CTX_get(ctx)) == NULL) goto err;
@@ -114,19 +115,20 @@ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,
                        { if (!BN_sqr(a,x,ctx)) goto err; }
                else
                        { if (!BN_mul(a,x,y,ctx)) goto err; }
+               ca = a;
                }
        else
-               a=x; /* Just do the mod */
+               ca=x; /* Just do the mod */
 
-       BN_div_recp(NULL,r,a,recp,ctx);
+       BN_div_recp(NULL,r,ca,recp,ctx);
        ret=1;
 err:
        BN_CTX_end(ctx);
        return(ret);
        }
 
-int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp,
-            BN_CTX *ctx)
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+       BN_RECP_CTX *recp, BN_CTX *ctx)
        {
        int i,j,ret=0;
        BIGNUM *a,*b,*d,*r;
@@ -201,7 +203,7 @@ err:
  * We actually calculate with an extra word of precision, so
  * we can do faster division if the remainder is not required.
  */
-int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx)
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
        {
        int ret= -1;
        BIGNUM t;
index 0883247..e4da833 100644 (file)
@@ -60,7 +60,7 @@
 #include "cryptlib.h"
 #include "bn_lcl.h"
 
-int BN_lshift1(BIGNUM *r, BIGNUM *a)
+int BN_lshift1(BIGNUM *r, const BIGNUM *a)
        {
        register BN_ULONG *ap,*rp,t,c;
        int i;
@@ -92,7 +92,7 @@ int BN_lshift1(BIGNUM *r, BIGNUM *a)
        return(1);
        }
 
-int BN_rshift1(BIGNUM *r, BIGNUM *a)
+int BN_rshift1(BIGNUM *r, const BIGNUM *a)
        {
        BN_ULONG *ap,*rp,t,c;
        int i;
@@ -153,7 +153,7 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
        return(1);
        }
 
-int BN_rshift(BIGNUM *r, BIGNUM *a, int n)
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
        {
        int i,j,nw,lb,rb;
        BN_ULONG *t,*f;
index 75f4f38..4789f13 100644 (file)
 
 /* r must not be a */
 /* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
-int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx)
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        {
        int max,al;
        int ret = 0;
-       BIGNUM *tmp,*rr;
+       BIGNUM *tmp,*rr,*free_a = NULL;
 
 #ifdef BN_COUNT
 printf("BN_sqr %d * %d\n",a->top,a->top);
@@ -124,8 +124,10 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
                        k=j+j;
                        if (al == j)
                                {
-                               if (bn_wexpand(a,k*2) == NULL) goto err;
+                               BIGNUM *tmp_bn = free_a;
+                               if ((a = free_a = bn_dup_expand(a,k*2)) == NULL) goto err;
                                if (bn_wexpand(tmp,k*2) == NULL) goto err;
+                               if (tmp_bn) BN_free(tmp_bn);
                                bn_sqr_recursive(rr->d,a->d,al,tmp->d);
                                }
                        else
@@ -145,6 +147,7 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
        if (rr != r) BN_copy(r,rr);
        ret = 1;
  err:
+       if (free_a) BN_free(free_a);
        BN_CTX_end(ctx);
        return(ret);
        }
index 0a97af6..11e58f9 100644 (file)
@@ -772,6 +772,7 @@ int test_mod_mul(BIO *bp, BN_CTX *ctx)
                if(!BN_is_zero(b))
                    {
                    fprintf(stderr,"Modulo multiply test failed!\n");
+                   ERR_print_errors_fp(stderr);
                    return 0;
                    }
                }