Put the first stage of my bignum debugging adventures into CVS. This code
authorGeoff Thorpe <geoff@openssl.org>
Tue, 4 Nov 2003 22:54:49 +0000 (22:54 +0000)
committerGeoff Thorpe <geoff@openssl.org>
Tue, 4 Nov 2003 22:54:49 +0000 (22:54 +0000)
is itself experimental, and in addition may cause execution to break on
existing openssl "bugs" that previously were harmless or at least
invisible.

25 files changed:
CHANGES
crypto/bn/bn.h
crypto/bn/bn_add.c
crypto/bn/bn_blind.c
crypto/bn/bn_ctx.c
crypto/bn/bn_div.c
crypto/bn/bn_exp.c
crypto/bn/bn_exp2.c
crypto/bn/bn_gcd.c
crypto/bn/bn_gf2m.c
crypto/bn/bn_lcl.h
crypto/bn/bn_lib.c
crypto/bn/bn_mod.c
crypto/bn/bn_mont.c
crypto/bn/bn_mpi.c
crypto/bn/bn_mul.c
crypto/bn/bn_nist.c
crypto/bn/bn_prime.c
crypto/bn/bn_print.c
crypto/bn/bn_rand.c
crypto/bn/bn_recp.c
crypto/bn/bn_shift.c
crypto/bn/bn_sqr.c
crypto/bn/bn_sqrt.c
crypto/bn/bn_word.c

diff --git a/CHANGES b/CHANGES
index d157408..e3b0623 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,22 @@
 
  Changes between 0.9.7c and 0.9.8  [xx XXX xxxx]
 
+  *) An audit of the BIGNUM code is underway, for which debugging code is
+     enabled when BN_DEBUG is defined. This makes stricter enforcements on what
+     is considered valid when processing BIGNUMs, and causes execution to
+     assert() when a problem is discovered. If BN_DEBUG_RAND is defined,
+     further steps are taken to deliberately pollute unused data in BIGNUM
+     structures to try and expose faulty code further on. For now, openssl will
+     (in its default mode of operation) continue to tolerate the inconsistent
+     forms that it has tolerated in the past, but authors and packagers should
+     consider trying openssl and their own applications when compiled with
+     these debugging symbols defined. It will help highlight potential bugs in
+     their own code, and will improve the test coverage for OpenSSL itself. At
+     some point, these tighter rules will become openssl's default to improve
+     maintainability, though the assert()s and other overheads will remain only
+     in debugging configurations. See bn.h for more details.
+     [Geoff Thorpe]
+
   *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure
      that can only be obtained through BN_CTX_new() (which implicitly
      initialises it). The presence of this function only made it possible
index 44ba175..d51c94f 100644 (file)
@@ -611,7 +611,34 @@ const BIGNUM *BN_get0_nist_prime_521(void);
 BIGNUM *bn_expand2(BIGNUM *a, int words);
 BIGNUM *bn_dup_expand(const BIGNUM *a, int words);
 
-#define bn_fix_top(a) \
+/* Bignum consistency macros
+ * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
+ * bignum data after direct manipulations on the data. There is also an
+ * "internal" macro, bn_check_top(), for verifying that there are no leading
+ * zeroes. Unfortunately, some auditing is required due to the fact that
+ * bn_fix_top() has become an overabused duct-tape because bignum data is
+ * occasionally passed around in an inconsistent state. So the following
+ * changes have been made to sort this out;
+ * - bn_fix_top()s implementation has been moved to bn_correct_top()
+ * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
+ *   bn_check_top() is as before.
+ * - if BN_DEBUG *is* defined;
+ *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
+ *     consistent. (ed: only if BN_DEBUG_RAND is defined)
+ *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
+ * The idea is to have debug builds flag up inconsistent bignums when they
+ * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
+ * the use of bn_fix_top() was appropriate (ie. it follows directly after code
+ * that manipulates the bignum) it is converted to bn_correct_top(), and if it
+ * was not appropriate, we convert it permanently to bn_check_top() and track
+ * down the cause of the bug. Eventually, no internal code should be using the
+ * bn_fix_top() macro. External applications and libraries should try this with
+ * their own code too, both in terms of building against the openssl headers
+ * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
+ * defined. This not only improves external code, it provides more test
+ * coverage for openssl's own code.
+ */
+#define bn_correct_top(a) \
         { \
         BN_ULONG *ftl; \
        if ((a)->top > 0) \
@@ -621,6 +648,55 @@ BIGNUM *bn_dup_expand(const BIGNUM *a, int words);
                } \
        }
 
+/* #define BN_DEBUG_RAND */
+
+#ifdef BN_DEBUG
+
+/* We only need assert() when debugging */
+#include <assert.h>
+
+#ifdef BN_DEBUG_RAND
+/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
+#ifndef RAND_pseudo_bytes
+int RAND_pseudo_bytes(unsigned char *buf,int num);
+#define BN_DEBUG_TRIX
+#endif
+#define bn_check_top(a) \
+       do { \
+               const BIGNUM *_tbignum = (a); \
+               assert((_tbignum->top == 0) || \
+                               (_tbignum->d[_tbignum->top - 1] != 0)); \
+               if(_tbignum->top < _tbignum->dmax) { \
+                       /* We cast away const without the compiler knowing, any \
+                        * *genuinely* constant variables that aren't mutable \
+                        * wouldn't be constructed with top!=dmax. */ \
+                       BN_ULONG *_not_const; \
+                       memcpy(&_not_const, &_tbignum->d, sizeof(BN_ULONG*)); \
+                       RAND_pseudo_bytes((unsigned char *)(_not_const + _tbignum->top), \
+                               (_tbignum->dmax - _tbignum->top) * sizeof(BN_ULONG)); \
+               } \
+       } while(0)
+#ifdef BN_DEBUG_TRIX
+#undef RAND_pseudo_bytes
+#endif
+#else /* !BN_DEBUG_RAND */
+#define bn_check_top(a) \
+       do { \
+               const BIGNUM *_tbignum = (a); \
+               assert((_tbignum->top == 0) || \
+                               (_tbignum->d[_tbignum->top - 1] != 0)); \
+       } while(0)
+#endif
+
+#define bn_fix_top(a)          bn_check_top(a)
+
+#else /* !BN_DEBUG */
+
+#define bn_check_top(a)                do { ; } while(0)
+#define bn_fix_top(a)          bn_correct_top(a)
+
+#endif
+
 BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
 BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
 void     bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
index 6cba07e..a13b8a1 100644 (file)
@@ -100,6 +100,7 @@ int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
                r->neg=1;
        else
                r->neg=0;
+       bn_check_top(r);
        return(1);
        }
 
@@ -161,6 +162,7 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
                }
        /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
        r->neg = 0;
+       bn_check_top(r);
        return(1);
        }
 
@@ -253,7 +255,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
 
        r->top=max;
        r->neg=0;
-       bn_fix_top(r);
+       bn_correct_top(r);
        return(1);
        }
 
@@ -304,6 +306,7 @@ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
                if (!BN_usub(r,a,b)) return(0);
                r->neg=0;
                }
+       bn_check_top(r);
        return(1);
        }
 
index 2d287e6..011d37f 100644 (file)
@@ -139,6 +139,7 @@ int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
                if (!BN_BLINDING_update(b,ctx))
                        return(0);
                }
+       bn_check_top(n);
        return(ret);
        }
 
index a0e7915..7b5be7c 100644 (file)
@@ -121,8 +121,10 @@ void BN_CTX_free(BN_CTX *ctx)
        if (ctx == NULL) return;
        assert(ctx->depth == 0);
 
-       for (i=0; i < BN_CTX_NUM; i++)
+       for (i=0; i < BN_CTX_NUM; i++) {
+               bn_check_top(&(ctx->bn[i]));
                BN_clear_free(&(ctx->bn[i]));
+       }
        if (ctx->flags & BN_FLG_MALLOCED)
                OPENSSL_free(ctx);
        }
@@ -152,6 +154,7 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx)
                        }
                return NULL;
                }
+       bn_check_top(&(ctx->bn[ctx->tos]));
        return (&(ctx->bn[ctx->tos++]));
        }
 
index 0fe58db..ff21895 100644 (file)
@@ -249,7 +249,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
        /* space for temp */
        if (!bn_wexpand(tmp,(div_n+1))) goto err;
 
-       bn_fix_top(&wnum);
+       bn_correct_top(&wnum);
        if (BN_ucmp(&wnum,sdiv) >= 0)
                {
                if (!BN_usub(&wnum,&wnum,sdiv)) goto err;
@@ -359,7 +359,7 @@ X) -> 0x%08X\n",
                tmp->top=j;
 
                j=wnum.top;
-               bn_fix_top(&wnum);
+               bn_correct_top(&wnum);
                if (!BN_sub(&wnum,&wnum,tmp)) goto err;
 
                snum->top=snum->top+wnum.top-j;
@@ -380,14 +380,16 @@ X) -> 0x%08X\n",
                 * BN_rshift() will overwrite it.
                 */
                int neg = num->neg;
-               bn_fix_top(snum);
+               bn_correct_top(snum);
                BN_rshift(rm,snum,norm_shift);
                if (!BN_is_zero(rm))
                        rm->neg = neg;
+               bn_check_top(rm);
                }
        BN_CTX_end(ctx);
        return(1);
 err:
+       bn_check_top(rm);
        BN_CTX_end(ctx);
        return(0);
        }
index afdfd58..462d4db 100644 (file)
@@ -147,6 +147,7 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
 err:
        if (r != rr) BN_copy(r,rr);
        BN_CTX_end(ctx);
+       bn_check_top(r);
        return(ret);
        }
 
@@ -221,6 +222,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
                { ret=BN_mod_exp_simple(r,a,p,m,ctx); }
 #endif
 
+       bn_check_top(r);
        return(ret);
        }
 
@@ -347,6 +349,7 @@ err:
        for (i=0; i<ts; i++)
                BN_clear_free(&(val[i]));
        BN_RECP_CTX_free(&recp);
+       bn_check_top(r);
        return(ret);
        }
 
@@ -490,6 +493,7 @@ err:
        BN_CTX_end(ctx);
        for (i=0; i<ts; i++)
                BN_clear_free(&(val[i]));
+       bn_check_top(rr);
        return(ret);
        }
 
@@ -630,6 +634,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
 err:
        if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
        BN_CTX_end(ctx);
+       bn_check_top(rr);
        return(ret);
        }
 
@@ -742,6 +747,7 @@ err:
        BN_CTX_end(ctx);
        for (i=0; i<ts; i++)
                BN_clear_free(&(val[i]));
+       bn_check_top(r);
        return(ret);
        }
 
index 73ccd58..3bf7daf 100644 (file)
@@ -309,5 +309,6 @@ err:
                BN_clear_free(&(val1[i]));
        for (i=0; i<ts2; i++)
                BN_clear_free(&(val2[i]));
+       bn_check_top(rr);
        return(ret);
        }
index 7649f63..f02e6fc 100644 (file)
@@ -140,6 +140,7 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
        ret=1;
 err:
        BN_CTX_end(ctx);
+       bn_check_top(r);
        return(ret);
        }
 
@@ -194,6 +195,7 @@ static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
                {
                if (!BN_lshift(a,a,shifts)) goto err;
                }
+       bn_check_top(a);
        return(a);
 err:
        return(NULL);
@@ -486,5 +488,6 @@ BIGNUM *BN_mod_inverse(BIGNUM *in,
 err:
        if ((ret == NULL) && (in == NULL)) BN_free(R);
        BN_CTX_end(ctx);
+       bn_check_top(ret);
        return(ret);
        }
index 6edd8ab..0bb4f9b 100644 (file)
@@ -303,7 +303,7 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
                }
        
        r->top = at->top;
-       bn_fix_top(r);
+       bn_correct_top(r);
        
        return 1;
        }
@@ -392,7 +392,7 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[])
                
                }
 
-       bn_fix_top(r);
+       bn_correct_top(r);
        
        return 1;
        }
@@ -414,6 +414,7 @@ int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
                goto err;
                }
        ret = BN_GF2m_mod_arr(r, a, arr);
+       bn_check_top(r);
   err:
        if (arr) OPENSSL_free(arr);
        return ret;
@@ -457,8 +458,9 @@ int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsig
                        }
                }
 
-       bn_fix_top(s);
+       bn_correct_top(s);
        BN_GF2m_mod_arr(r, s, p);
+       bn_check_top(r);
        ret = 1;
 
   err:
@@ -485,6 +487,7 @@ int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p
                goto err;
                }
        ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
+       bn_check_top(r);
   err:
        if (arr) OPENSSL_free(arr);
        return ret;
@@ -508,8 +511,9 @@ int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_C
                }
 
        s->top = 2 * a->top;
-       bn_fix_top(s);
+       bn_correct_top(s);
        if (!BN_GF2m_mod_arr(r, s, p)) goto err;
+       bn_check_top(r);
        ret = 1;
   err:
        BN_CTX_end(ctx);
@@ -533,6 +537,7 @@ int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                goto err;
                }
        ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
+       bn_check_top(r);
   err:
        if (arr) OPENSSL_free(arr);
        return ret;
@@ -594,6 +599,7 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
 
 
        if (!BN_copy(r, b)) goto err;
+       bn_check_top(r);
        ret = 1;
 
   err:
@@ -617,6 +623,7 @@ int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const unsigned int p[], BN_
        if (!BN_GF2m_arr2poly(p, field)) goto err;
        
        ret = BN_GF2m_mod_inv(r, xx, field, ctx);
+       bn_check_top(r);
 
   err:
        BN_CTX_end(ctx);
@@ -639,6 +646,7 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
        
        if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) goto err;
        if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) goto err;
+       bn_check_top(r);
        ret = 1;
 
   err:
@@ -711,6 +719,7 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
                } while (1);
 
        if (!BN_copy(r, u)) goto err;
+       bn_check_top(r);
        ret = 1;
 
   err:
@@ -736,6 +745,7 @@ int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const uns
        if (!BN_GF2m_arr2poly(p, field)) goto err;
        
        ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
+       bn_check_top(r);
 
   err:
        BN_CTX_end(ctx);
@@ -773,6 +783,7 @@ int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsig
                        }
                }
        if (!BN_copy(r, u)) goto err;
+       bn_check_top(r);
 
        ret = 1;
 
@@ -799,6 +810,7 @@ int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p
                goto err;
                }
        ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
+       bn_check_top(r);
   err:
        if (arr) OPENSSL_free(arr);
        return ret;
@@ -819,6 +831,7 @@ int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_
        if (!BN_zero(u)) goto err;
        if (!BN_set_bit(u, p[0] - 1)) goto err;
        ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
+       bn_check_top(r);
 
   err:
        BN_CTX_end(ctx);
@@ -843,6 +856,7 @@ int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                goto err;
                }
        ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
+       bn_check_top(r);
   err:
        if (arr) OPENSSL_free(arr);
        return ret;
@@ -917,6 +931,7 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p
        if (BN_GF2m_cmp(w, a)) goto err;
 
        if (!BN_copy(r, z)) goto err;
+       bn_check_top(r);
 
        ret = 1;
 
@@ -942,6 +957,7 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *
                goto err;
                }
        ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
+       bn_check_top(r);
   err:
        if (arr) OPENSSL_free(arr);
        return ret;
@@ -990,6 +1006,7 @@ int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a)
                BN_set_bit(a, p[i]);
                }
        BN_set_bit(a, 0);
+       bn_check_top(a);
        
        return 1;
        }
index 0c44872..4603b4f 100644 (file)
@@ -250,14 +250,6 @@ extern "C" {
        }
 
 
-/* This is used for internal error checking and is not normally used */
-#ifdef BN_DEBUG
-# include <assert.h>
-# define bn_check_top(a) assert ((a)->top >= 0 && (a)->top <= (a)->dmax);
-#else
-# define bn_check_top(a)
-#endif
-
 /* This macro is to add extra stuff for development checking */
 #ifdef BN_DEBUG
 #define        bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
index f63232b..85b72e0 100644 (file)
@@ -286,6 +286,7 @@ void BN_free(BIGNUM *a)
 void BN_init(BIGNUM *a)
        {
        memset(a,0,sizeof(BIGNUM));
+       bn_check_top(a);
        }
 
 BIGNUM *BN_new(void)
@@ -302,6 +303,7 @@ BIGNUM *BN_new(void)
        ret->neg=0;
        ret->dmax=0;
        ret->d=NULL;
+       bn_check_top(ret);
        return(ret);
        }
 
@@ -420,6 +422,7 @@ BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
                r = BN_dup(b);
                }
 
+       bn_check_top(r);
        return r;
        }
 
@@ -462,6 +465,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 +483,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 +523,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 +567,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);
        }
 
@@ -592,6 +599,8 @@ 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);
        }
 
 
@@ -601,6 +610,7 @@ void BN_clear(BIGNUM *a)
                memset(a->d,0,a->dmax*sizeof(a->d[0]));
        a->top=0;
        a->neg=0;
+       bn_check_top(a);
        }
 
 BN_ULONG BN_get_word(const BIGNUM *a)
@@ -648,6 +658,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);
        }
 
@@ -684,7 +695,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);
        }
 
@@ -700,6 +711,7 @@ int BN_bn2bin(const BIGNUM *a, unsigned char *to)
                l=a->d[i/BN_BYTES];
                *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
                }
+       bn_check_top(a);
        return(n);
        }
 
@@ -781,6 +793,7 @@ int BN_set_bit(BIGNUM *a, int n)
                }
 
        a->d[i]|=(((BN_ULONG)1)<<j);
+       bn_check_top(a);
        return(1);
        }
 
@@ -793,7 +806,7 @@ int BN_clear_bit(BIGNUM *a, int n)
        if (a->top <= i) return(0);
 
        a->d[i]&=(~(((BN_ULONG)1)<<j));
-       bn_fix_top(a);
+       bn_correct_top(a);
        return(1);
        }
 
@@ -822,7 +835,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);
        }
 
index 5cf8248..61b7255 100644 (file)
@@ -192,6 +192,7 @@ int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
        else
                { if (!BN_mul(t,a,b,ctx)) goto err; }
        if (!BN_nnmod(r,t,m,ctx)) goto err;
+       bn_check_top(r);
        ret=1;
 err:
        BN_CTX_end(ctx);
@@ -210,6 +211,7 @@ int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
 int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
        {
        if (!BN_lshift1(r, a)) return 0;
+       bn_check_top(r);
        return BN_nnmod(r, r, m, ctx);
        }
 
@@ -219,6 +221,7 @@ int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
 int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
        {
        if (!BN_lshift1(r, a)) return 0;
+       bn_check_top(r);
        if (BN_cmp(r, m) >= 0)
                return BN_sub(r, r, m);
        return 1;
@@ -240,6 +243,7 @@ int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ct
                }
        
        ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
+       bn_check_top(r);
 
        if (abs_m)
                BN_free(abs_m);
@@ -291,6 +295,7 @@ int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
                        if (!BN_sub(r, r, m)) return 0;
                        }
                }
+       bn_check_top(r);
        
        return 1;
        }
index c9ebdba..22d23cc 100644 (file)
@@ -90,6 +90,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                }
        /* reduce from aRR to aR */
        if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
+       bn_check_top(r);
        ret=1;
 err:
        BN_CTX_end(ctx);
@@ -172,7 +173,7 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
                        for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
                        }
                }
-       bn_fix_top(r);
+       bn_correct_top(r);
        
        /* mont->ri will be a multiple of the word size */
 #if 0
@@ -229,6 +230,7 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
                if (!BN_usub(ret,ret,&(mont->N))) goto err;
                }
        retn=1;
+       bn_check_top(ret);
  err:
        BN_CTX_end(ctx);
        return(retn);
index 05fa9d1..a054d21 100644 (file)
@@ -124,6 +124,7 @@ BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a)
                {
                BN_clear_bit(a,BN_num_bits(a)-1);
                }
+       bn_check_top(a);
        return(a);
        }
 
index 6b633b9..5a92f9a 100644 (file)
@@ -1090,11 +1090,12 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
 #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
 end:
 #endif
-       bn_fix_top(rr);
+       bn_correct_top(rr);
        if (r != rr) BN_copy(r,rr);
        ret=1;
 err:
        BN_CTX_end(ctx);
+       bn_check_top(r);
        return(ret);
        }
 
index ed148d8..2e03d07 100644 (file)
@@ -358,14 +358,15 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 #if 1
        bn_clear_top2max(r);
 #endif
-       bn_fix_top(r);
+       bn_correct_top(r);
 
        if (BN_ucmp(r, field) >= 0)
                {
                bn_sub_words(r_d, r_d, _nist_p_192, BN_NIST_192_TOP);
-               bn_fix_top(r);
+               bn_correct_top(r);
                }
 
+       bn_check_top(r);
        return 1;
        }
 
@@ -450,13 +451,14 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 #if 1
        bn_clear_top2max(r);
 #endif
-       bn_fix_top(r);
+       bn_correct_top(r);
 
        if (BN_ucmp(r, field) >= 0)
                {
                bn_sub_words(r_d, r_d, _nist_p_224, BN_NIST_224_TOP);
-               bn_fix_top(r);
+               bn_correct_top(r);
                }
+       bn_check_top(r);
        return 1;
 #else
        return 0;
@@ -608,13 +610,14 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 #if 1
        bn_clear_top2max(r);
 #endif
-       bn_fix_top(r);
+       bn_correct_top(r);
 
        if (BN_ucmp(r, field) >= 0)
                {
                bn_sub_words(r_d, r_d, _nist_p_256, BN_NIST_256_TOP);
-               bn_fix_top(r);
+               bn_correct_top(r);
                }
+       bn_check_top(r);
        return 1;
 #else
        return 0;
@@ -776,13 +779,14 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 #if 1
        bn_clear_top2max(r);
 #endif
-       bn_fix_top(r);
+       bn_correct_top(r);
 
        if (BN_ucmp(r, field) >= 0)
                {
                bn_sub_words(r_d, r_d, _nist_p_384, BN_NIST_384_TOP);
-               bn_fix_top(r);
+               bn_correct_top(r);
                }
+       bn_check_top(r);
        return 1;
 #else
        return 0;
@@ -824,7 +828,7 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        if (tmp->top == BN_NIST_521_TOP)
                tmp->d[BN_NIST_521_TOP-1]  &= BN_NIST_521_TOP_MASK;
 
-       bn_fix_top(tmp);
+       bn_correct_top(tmp);
        if (!BN_uadd(r, tmp, r))
                return 0;
        top = r->top;
@@ -835,11 +839,12 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
                BN_NIST_ADD_ONE(r_d)
                r_d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK; 
                }
-       bn_fix_top(r);
+       bn_correct_top(r);
 
        ret = 1;
 err:
        BN_CTX_end(ctx);
 
+       bn_check_top(r);
        return ret;
        }
index fd86393..4430e90 100644 (file)
@@ -226,6 +226,7 @@ loop:
 err:
        BN_free(&t);
        if (ctx != NULL) BN_CTX_free(ctx);
+       bn_check_top(ret);
        return found;
        }
 
@@ -363,6 +364,7 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
                }
        /* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
         * and it is neither -1 nor +1 -- so 'a' cannot be prime */
+       bn_check_top(w);
        return 1;
        }
 
@@ -394,6 +396,7 @@ again:
                        }
                }
        if (!BN_add_word(rnd,delta)) return(0);
+       bn_check_top(rnd);
        return(1);
        }
 
@@ -431,6 +434,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits,
        ret=1;
 err:
        BN_CTX_end(ctx);
+       bn_check_top(rnd);
        return(ret);
        }
 
@@ -482,5 +486,6 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
        ret=1;
 err:
        BN_CTX_end(ctx);
+       bn_check_top(p);
        return(ret);
        }
index 5f46b18..5b5eb8f 100644 (file)
@@ -210,10 +210,11 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
                j-=(BN_BYTES*2);
                }
        ret->top=h;
-       bn_fix_top(ret);
+       bn_correct_top(ret);
        ret->neg=neg;
 
        *bn=ret;
+       bn_check_top(ret);
        return(num);
 err:
        if (*bn == NULL) BN_free(ret);
@@ -269,8 +270,9 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
                }
        ret->neg=neg;
 
-       bn_fix_top(ret);
+       bn_correct_top(ret);
        *bn=ret;
+       bn_check_top(ret);
        return(num);
 err:
        if (*bn == NULL) BN_free(ret);
index 480817a..de5a1f0 100644 (file)
@@ -204,6 +204,7 @@ err:
                OPENSSL_cleanse(buf,bytes);
                OPENSSL_free(buf);
                }
+       bn_check_top(rnd);
        return(ret);
        }
 
@@ -290,6 +291,7 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
                while (BN_cmp(r, range) >= 0);
                }
 
+       bn_check_top(r);
        return 1;
        }
 
index 22cbcfc..ea39677 100644 (file)
@@ -123,6 +123,7 @@ int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
        ret = BN_div_recp(NULL,r,ca,recp,ctx);
 err:
        BN_CTX_end(ctx);
+       bn_check_top(r);
        return(ret);
        }
 
@@ -228,5 +229,6 @@ int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
        ret=len;
 err:
        BN_free(&t);
+       bn_check_top(r);
        return(ret);
        }
index 70f785e..513e686 100644 (file)
@@ -89,6 +89,7 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a)
                *rp=1;
                r->top++;
                }
+       bn_check_top(r);
        return(1);
        }
 
@@ -117,7 +118,8 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a)
                rp[i]=((t>>1)&BN_MASK2)|c;
                c=(t&1)?BN_TBIT:0;
                }
-       bn_fix_top(r);
+       bn_correct_top(r);
+       bn_check_top(r);
        return(1);
        }
 
@@ -149,7 +151,8 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
 /*     for (i=0; i<nw; i++)
                t[i]=0;*/
        r->top=a->top+nw+1;
-       bn_fix_top(r);
+       bn_correct_top(r);
+       bn_check_top(r);
        return(1);
        }
 
@@ -200,6 +203,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
                *(t++) =(l>>rb)&BN_MASK2;
                }
        *t=0;
-       bn_fix_top(r);
+       bn_correct_top(r);
+       bn_check_top(r);
        return(1);
        }
index c1d0cca..ab678d1 100644 (file)
@@ -145,6 +145,7 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        ret = 1;
  err:
        BN_CTX_end(ctx);
+       bn_check_top(r);
        return(ret);
        }
 
index 463d4a8..5190270 100644 (file)
@@ -86,6 +86,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                                BN_free(ret);
                                return NULL;
                                }
+                       bn_check_top(ret);
                        return ret;
                        }
 
@@ -104,6 +105,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                        BN_free(ret);
                        return NULL;
                        }
+               bn_check_top(ret);
                return ret;
                }
 
@@ -384,5 +386,6 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                ret = NULL;
                }
        BN_CTX_end(ctx);
+       bn_check_top(ret);
        return ret;
        }
index 988e0ca..560a499 100644 (file)
@@ -102,6 +102,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
                }
        if ((a->top > 0) && (a->d[a->top-1] == 0))
                a->top--;
+       bn_check_top(a);
        return(ret);
        }
 
@@ -136,6 +137,7 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
                }
        if (i >= a->top)
                a->top++;
+       bn_check_top(a);
        return(1);
        }
 
@@ -175,6 +177,7 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
                }
        if ((a->d[i] == 0) && (i == (a->top-1)))
                a->top--;
+       bn_check_top(a);
        return(1);
        }
 
@@ -197,6 +200,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w)
                                }
                        }
                }
+       bn_check_top(a);
        return(1);
        }