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 7c618989f09df4f829aea446f9c5f72e1c8e6624..7c308011c5f1cfcc8b9f3df860d1d75e0bc1cb97 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 1eb8395b25c3c6c2a0f521dbb54d52d1cedceff3..dad488fafb6a876957d3dffd30b11cbe5063c112 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 d2c91628acba0ecce6f4898e67417a340e73ad80..74b1f0e89e0f015b939a452e1a5fc269fb3d379f 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 29029f4c724a6c8cfcbef584347ca068ee73d535..70c4d83a794048bb22380d87cc764b025afc7402 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 398207196be841403cc5c2b3caf36e9c7cb8e9a4..61c431fc7b4d1864d3df2cae482cf8ec018a8adb 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 b6b0ce4b3c9fe134396a5187b1dae3e4785e1034..3e4965d695e5c7655d0aea5bca5f06252ae3deb7 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 8cf1febaccad8579bcc13d91caf55d520d1c25e1..202eec4462f3e52bc2613e54ecd8cd25729c400a 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 3e8d8b9567a89af94383b8e6120a78cb060a55a5..aed752818295424b3cbeae33af02cb54475737f0 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 a5f01b92eb2f21ef1be2b6c91d0263cd84b13027..b75e58c6ae244749f8bac1312cc616269f1eba39 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 d019941d6be4140c5109d010915de148e9a65e78..a175e1c5f2fcdef12cd8f74d9cd49a5fa414481f 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 0883247384e97a4d8ac9c37f83c4c4a21cb49b96..e4da833ea67f33aa68b22a7dde588ca182034358 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 75f4f38392dcb686f005800652c23de64ea76efd..4789f131a160e118e95f274c2d114fd49db4e7fc 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 0a97af69c5867f6423a8b29ded9d61db5514e758..11e58f994a3b85b7d8b808ef8fe4ca7b2c999589 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;
                    }
                }