Put the first stage of my bignum debugging adventures into CVS. This code
is itself experimental, and in addition may cause execution to break on
existing openssl "bugs" that previously were harmless or at least
invisible.
diff --git a/CHANGES b/CHANGES
index d157408..e3b0623 100644
--- 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
diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h
index 44ba175..d51c94f 100644
--- a/crypto/bn/bn.h
+++ b/crypto/bn/bn.h
@@ -611,7 +611,34 @@
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 @@
} \
}
+/* #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);
diff --git a/crypto/bn/bn_add.c b/crypto/bn/bn_add.c
index 6cba07e..a13b8a1 100644
--- a/crypto/bn/bn_add.c
+++ b/crypto/bn/bn_add.c
@@ -100,6 +100,7 @@
r->neg=1;
else
r->neg=0;
+ bn_check_top(r);
return(1);
}
@@ -161,6 +162,7 @@
}
/* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
r->neg = 0;
+ bn_check_top(r);
return(1);
}
@@ -253,7 +255,7 @@
r->top=max;
r->neg=0;
- bn_fix_top(r);
+ bn_correct_top(r);
return(1);
}
@@ -304,6 +306,7 @@
if (!BN_usub(r,a,b)) return(0);
r->neg=0;
}
+ bn_check_top(r);
return(1);
}
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c
index 2d287e6..011d37f 100644
--- a/crypto/bn/bn_blind.c
+++ b/crypto/bn/bn_blind.c
@@ -139,6 +139,7 @@
if (!BN_BLINDING_update(b,ctx))
return(0);
}
+ bn_check_top(n);
return(ret);
}
diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c
index a0e7915..7b5be7c 100644
--- a/crypto/bn/bn_ctx.c
+++ b/crypto/bn/bn_ctx.c
@@ -121,8 +121,10 @@
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 @@
}
return NULL;
}
+ bn_check_top(&(ctx->bn[ctx->tos]));
return (&(ctx->bn[ctx->tos++]));
}
diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c
index 0fe58db..ff21895 100644
--- a/crypto/bn/bn_div.c
+++ b/crypto/bn/bn_div.c
@@ -249,7 +249,7 @@
/* 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 @@
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 @@
* 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);
}
diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c
index afdfd58..462d4db 100644
--- a/crypto/bn/bn_exp.c
+++ b/crypto/bn/bn_exp.c
@@ -147,6 +147,7 @@
err:
if (r != rr) BN_copy(r,rr);
BN_CTX_end(ctx);
+ bn_check_top(r);
return(ret);
}
@@ -221,6 +222,7 @@
{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }
#endif
+ bn_check_top(r);
return(ret);
}
@@ -347,6 +349,7 @@
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 @@
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 @@
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 @@
BN_CTX_end(ctx);
for (i=0; i<ts; i++)
BN_clear_free(&(val[i]));
+ bn_check_top(r);
return(ret);
}
diff --git a/crypto/bn/bn_exp2.c b/crypto/bn/bn_exp2.c
index 73ccd58..3bf7daf 100644
--- a/crypto/bn/bn_exp2.c
+++ b/crypto/bn/bn_exp2.c
@@ -309,5 +309,6 @@
BN_clear_free(&(val1[i]));
for (i=0; i<ts2; i++)
BN_clear_free(&(val2[i]));
+ bn_check_top(rr);
return(ret);
}
diff --git a/crypto/bn/bn_gcd.c b/crypto/bn/bn_gcd.c
index 7649f63..f02e6fc 100644
--- a/crypto/bn/bn_gcd.c
+++ b/crypto/bn/bn_gcd.c
@@ -140,6 +140,7 @@
ret=1;
err:
BN_CTX_end(ctx);
+ bn_check_top(r);
return(ret);
}
@@ -194,6 +195,7 @@
{
if (!BN_lshift(a,a,shifts)) goto err;
}
+ bn_check_top(a);
return(a);
err:
return(NULL);
@@ -486,5 +488,6 @@
err:
if ((ret == NULL) && (in == NULL)) BN_free(R);
BN_CTX_end(ctx);
+ bn_check_top(ret);
return(ret);
}
diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c
index 6edd8ab..0bb4f9b 100644
--- a/crypto/bn/bn_gf2m.c
+++ b/crypto/bn/bn_gf2m.c
@@ -303,7 +303,7 @@
}
r->top = at->top;
- bn_fix_top(r);
+ bn_correct_top(r);
return 1;
}
@@ -392,7 +392,7 @@
}
- bn_fix_top(r);
+ bn_correct_top(r);
return 1;
}
@@ -414,6 +414,7 @@
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 @@
}
}
- 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 @@
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 @@
}
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 @@
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 @@
if (!BN_copy(r, b)) goto err;
+ bn_check_top(r);
ret = 1;
err:
@@ -617,6 +623,7 @@
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 @@
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 @@
} while (1);
if (!BN_copy(r, u)) goto err;
+ bn_check_top(r);
ret = 1;
err:
@@ -736,6 +745,7 @@
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 @@
}
}
if (!BN_copy(r, u)) goto err;
+ bn_check_top(r);
ret = 1;
@@ -799,6 +810,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
BN_set_bit(a, p[i]);
}
BN_set_bit(a, 0);
+ bn_check_top(a);
return 1;
}
diff --git a/crypto/bn/bn_lcl.h b/crypto/bn/bn_lcl.h
index 0c44872..4603b4f 100644
--- a/crypto/bn/bn_lcl.h
+++ b/crypto/bn/bn_lcl.h
@@ -250,14 +250,6 @@
}
-/* 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))
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index f63232b..85b72e0 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -286,6 +286,7 @@
void BN_init(BIGNUM *a)
{
memset(a,0,sizeof(BIGNUM));
+ bn_check_top(a);
}
BIGNUM *BN_new(void)
@@ -302,6 +303,7 @@
ret->neg=0;
ret->dmax=0;
ret->d=NULL;
+ bn_check_top(ret);
return(ret);
}
@@ -420,6 +422,7 @@
r = BN_dup(b);
}
+ bn_check_top(r);
return r;
}
@@ -462,6 +465,7 @@
A[0]=0;
assert(A == &(b->d[b->dmax]));
}
+ else if(b) bn_check_top(b);
return b;
}
@@ -479,6 +483,7 @@
/* now r == t || r == NULL */
if (r == NULL)
BN_free(t);
+ bn_check_top(r);
return r;
}
@@ -518,6 +523,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
/* 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 @@
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 @@
}
a->d[i]|=(((BN_ULONG)1)<<j);
+ bn_check_top(a);
return(1);
}
@@ -793,7 +806,7 @@
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 @@
a->top=w+1;
a->d[w]&= ~(BN_MASK2<<b);
}
- bn_fix_top(a);
+ bn_correct_top(a);
return(1);
}
diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c
index 5cf8248..61b7255 100644
--- a/crypto/bn/bn_mod.c
+++ b/crypto/bn/bn_mod.c
@@ -192,6 +192,7 @@
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_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_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 @@
}
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 @@
if (!BN_sub(r, r, m)) return 0;
}
}
+ bn_check_top(r);
return 1;
}
diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c
index c9ebdba..22d23cc 100644
--- a/crypto/bn/bn_mont.c
+++ b/crypto/bn/bn_mont.c
@@ -90,6 +90,7 @@
}
/* 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 @@
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 @@
if (!BN_usub(ret,ret,&(mont->N))) goto err;
}
retn=1;
+ bn_check_top(ret);
err:
BN_CTX_end(ctx);
return(retn);
diff --git a/crypto/bn/bn_mpi.c b/crypto/bn/bn_mpi.c
index 05fa9d1..a054d21 100644
--- a/crypto/bn/bn_mpi.c
+++ b/crypto/bn/bn_mpi.c
@@ -124,6 +124,7 @@
{
BN_clear_bit(a,BN_num_bits(a)-1);
}
+ bn_check_top(a);
return(a);
}
diff --git a/crypto/bn/bn_mul.c b/crypto/bn/bn_mul.c
index 6b633b9..5a92f9a 100644
--- a/crypto/bn/bn_mul.c
+++ b/crypto/bn/bn_mul.c
@@ -1090,11 +1090,12 @@
#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);
}
diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c
index ed148d8..2e03d07 100644
--- a/crypto/bn/bn_nist.c
+++ b/crypto/bn/bn_nist.c
@@ -358,14 +358,15 @@
#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 @@
#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 @@
#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 @@
#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 @@
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 @@
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;
}
diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c
index fd86393..4430e90 100644
--- a/crypto/bn/bn_prime.c
+++ b/crypto/bn/bn_prime.c
@@ -226,6 +226,7 @@
err:
BN_free(&t);
if (ctx != NULL) BN_CTX_free(ctx);
+ bn_check_top(ret);
return found;
}
@@ -363,6 +364,7 @@
}
/* 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 @@
}
}
if (!BN_add_word(rnd,delta)) return(0);
+ bn_check_top(rnd);
return(1);
}
@@ -431,6 +434,7 @@
ret=1;
err:
BN_CTX_end(ctx);
+ bn_check_top(rnd);
return(ret);
}
@@ -482,5 +486,6 @@
ret=1;
err:
BN_CTX_end(ctx);
+ bn_check_top(p);
return(ret);
}
diff --git a/crypto/bn/bn_print.c b/crypto/bn/bn_print.c
index 5f46b18..5b5eb8f 100644
--- a/crypto/bn/bn_print.c
+++ b/crypto/bn/bn_print.c
@@ -210,10 +210,11 @@
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 @@
}
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);
diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c
index 480817a..de5a1f0 100644
--- a/crypto/bn/bn_rand.c
+++ b/crypto/bn/bn_rand.c
@@ -204,6 +204,7 @@
OPENSSL_cleanse(buf,bytes);
OPENSSL_free(buf);
}
+ bn_check_top(rnd);
return(ret);
}
@@ -290,6 +291,7 @@
while (BN_cmp(r, range) >= 0);
}
+ bn_check_top(r);
return 1;
}
diff --git a/crypto/bn/bn_recp.c b/crypto/bn/bn_recp.c
index 22cbcfc..ea39677 100644
--- a/crypto/bn/bn_recp.c
+++ b/crypto/bn/bn_recp.c
@@ -123,6 +123,7 @@
ret = BN_div_recp(NULL,r,ca,recp,ctx);
err:
BN_CTX_end(ctx);
+ bn_check_top(r);
return(ret);
}
@@ -228,5 +229,6 @@
ret=len;
err:
BN_free(&t);
+ bn_check_top(r);
return(ret);
}
diff --git a/crypto/bn/bn_shift.c b/crypto/bn/bn_shift.c
index 70f785e..513e686 100644
--- a/crypto/bn/bn_shift.c
+++ b/crypto/bn/bn_shift.c
@@ -89,6 +89,7 @@
*rp=1;
r->top++;
}
+ bn_check_top(r);
return(1);
}
@@ -117,7 +118,8 @@
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 @@
/* 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 @@
*(t++) =(l>>rb)&BN_MASK2;
}
*t=0;
- bn_fix_top(r);
+ bn_correct_top(r);
+ bn_check_top(r);
return(1);
}
diff --git a/crypto/bn/bn_sqr.c b/crypto/bn/bn_sqr.c
index c1d0cca..ab678d1 100644
--- a/crypto/bn/bn_sqr.c
+++ b/crypto/bn/bn_sqr.c
@@ -145,6 +145,7 @@
ret = 1;
err:
BN_CTX_end(ctx);
+ bn_check_top(r);
return(ret);
}
diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c
index 463d4a8..5190270 100644
--- a/crypto/bn/bn_sqrt.c
+++ b/crypto/bn/bn_sqrt.c
@@ -86,6 +86,7 @@
BN_free(ret);
return NULL;
}
+ bn_check_top(ret);
return ret;
}
@@ -104,6 +105,7 @@
BN_free(ret);
return NULL;
}
+ bn_check_top(ret);
return ret;
}
@@ -384,5 +386,6 @@
ret = NULL;
}
BN_CTX_end(ctx);
+ bn_check_top(ret);
return ret;
}
diff --git a/crypto/bn/bn_word.c b/crypto/bn/bn_word.c
index 988e0ca..560a499 100644
--- a/crypto/bn/bn_word.c
+++ b/crypto/bn/bn_word.c
@@ -102,6 +102,7 @@
}
if ((a->top > 0) && (a->d[a->top-1] == 0))
a->top--;
+ bn_check_top(a);
return(ret);
}
@@ -136,6 +137,7 @@
}
if (i >= a->top)
a->top++;
+ bn_check_top(a);
return(1);
}
@@ -175,6 +177,7 @@
}
if ((a->d[i] == 0) && (i == (a->top-1)))
a->top--;
+ bn_check_top(a);
return(1);
}
@@ -197,6 +200,7 @@
}
}
}
+ bn_check_top(a);
return(1);
}