aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/bn
diff options
context:
space:
mode:
authorGeoff Thorpe <geoff@openssl.org>2003-11-04 22:54:49 +0000
committerGeoff Thorpe <geoff@openssl.org>2003-11-04 22:54:49 +0000
commitd870740cd75dd4f0cb66fb8c32653a7d47369706 (patch)
tree0c6cb1ce0b1083c96419c432d1f05c3dff51320d /crypto/bn
parentd8ec0dcf457f4dec39f137657b702fcbeaf5cc04 (diff)
downloadopenssl-d870740cd75dd4f0cb66fb8c32653a7d47369706.tar.gz
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.
Diffstat (limited to 'crypto/bn')
-rw-r--r--crypto/bn/bn.h78
-rw-r--r--crypto/bn/bn_add.c5
-rw-r--r--crypto/bn/bn_blind.c1
-rw-r--r--crypto/bn/bn_ctx.c5
-rw-r--r--crypto/bn/bn_div.c8
-rw-r--r--crypto/bn/bn_exp.c6
-rw-r--r--crypto/bn/bn_exp2.c1
-rw-r--r--crypto/bn/bn_gcd.c3
-rw-r--r--crypto/bn/bn_gf2m.c25
-rw-r--r--crypto/bn/bn_lcl.h8
-rw-r--r--crypto/bn/bn_lib.c21
-rw-r--r--crypto/bn/bn_mod.c5
-rw-r--r--crypto/bn/bn_mont.c4
-rw-r--r--crypto/bn/bn_mpi.c1
-rw-r--r--crypto/bn/bn_mul.c3
-rw-r--r--crypto/bn/bn_nist.c25
-rw-r--r--crypto/bn/bn_prime.c5
-rw-r--r--crypto/bn/bn_print.c6
-rw-r--r--crypto/bn/bn_rand.c2
-rw-r--r--crypto/bn/bn_recp.c2
-rw-r--r--crypto/bn/bn_shift.c10
-rw-r--r--crypto/bn/bn_sqr.c1
-rw-r--r--crypto/bn/bn_sqrt.c3
-rw-r--r--crypto/bn/bn_word.c4
24 files changed, 193 insertions, 39 deletions
diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h
index 44ba175247..d51c94f92f 100644
--- a/crypto/bn/bn.h
+++ b/crypto/bn/bn.h
@@ -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);
diff --git a/crypto/bn/bn_add.c b/crypto/bn/bn_add.c
index 6cba07e9f6..a13b8a11cb 100644
--- a/crypto/bn/bn_add.c
+++ b/crypto/bn/bn_add.c
@@ -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);
}
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c
index 2d287e6d1b..011d37f1ff 100644
--- a/crypto/bn/bn_blind.c
+++ b/crypto/bn/bn_blind.c
@@ -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);
}
diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c
index a0e7915fb9..7b5be7c435 100644
--- a/crypto/bn/bn_ctx.c
+++ b/crypto/bn/bn_ctx.c
@@ -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++]));
}
diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c
index 0fe58dbf69..ff218957b1 100644
--- a/crypto/bn/bn_div.c
+++ b/crypto/bn/bn_div.c
@@ -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);
}
diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c
index afdfd580fb..462d4dbc43 100644
--- a/crypto/bn/bn_exp.c
+++ b/crypto/bn/bn_exp.c
@@ -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);
}
diff --git a/crypto/bn/bn_exp2.c b/crypto/bn/bn_exp2.c
index 73ccd58a83..3bf7dafeee 100644
--- a/crypto/bn/bn_exp2.c
+++ b/crypto/bn/bn_exp2.c
@@ -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);
}
diff --git a/crypto/bn/bn_gcd.c b/crypto/bn/bn_gcd.c
index 7649f63fd2..f02e6fcdb4 100644
--- a/crypto/bn/bn_gcd.c
+++ b/crypto/bn/bn_gcd.c
@@ -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);
}
diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c
index 6edd8ab22b..0bb4f9b251 100644
--- a/crypto/bn/bn_gf2m.c
+++ b/crypto/bn/bn_gf2m.c
@@ -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;
}
diff --git a/crypto/bn/bn_lcl.h b/crypto/bn/bn_lcl.h
index 0c448724d5..4603b4f9f1 100644
--- a/crypto/bn/bn_lcl.h
+++ b/crypto/bn/bn_lcl.h
@@ -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))
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index f63232b9fb..85b72e0eeb 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -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);
}
diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c
index 5cf82480d7..61b7255098 100644
--- a/crypto/bn/bn_mod.c
+++ b/crypto/bn/bn_mod.c
@@ -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;
}
diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c
index c9ebdbaabe..22d23cc3d7 100644
--- a/crypto/bn/bn_mont.c
+++ b/crypto/bn/bn_mont.c
@@ -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);
diff --git a/crypto/bn/bn_mpi.c b/crypto/bn/bn_mpi.c
index 05fa9d1e9a..a054d21aed 100644
--- a/crypto/bn/bn_mpi.c
+++ b/crypto/bn/bn_mpi.c
@@ -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);
}
diff --git a/crypto/bn/bn_mul.c b/crypto/bn/bn_mul.c
index 6b633b90b0..5a92f9a335 100644
--- a/crypto/bn/bn_mul.c
+++ b/crypto/bn/bn_mul.c
@@ -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);
}
diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c
index ed148d845c..2e03d0709d 100644
--- a/crypto/bn/bn_nist.c
+++ b/crypto/bn/bn_nist.c
@@ -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;
}
diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c
index fd863933e5..4430e90df5 100644
--- a/crypto/bn/bn_prime.c
+++ b/crypto/bn/bn_prime.c
@@ -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);
}
diff --git a/crypto/bn/bn_print.c b/crypto/bn/bn_print.c
index 5f46b1826c..5b5eb8fc9c 100644
--- a/crypto/bn/bn_print.c
+++ b/crypto/bn/bn_print.c
@@ -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);
diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c
index 480817a4b6..de5a1f0c63 100644
--- a/crypto/bn/bn_rand.c
+++ b/crypto/bn/bn_rand.c
@@ -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;
}
diff --git a/crypto/bn/bn_recp.c b/crypto/bn/bn_recp.c
index 22cbcfc49b..ea39677bc0 100644
--- a/crypto/bn/bn_recp.c
+++ b/crypto/bn/bn_recp.c
@@ -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);
}
diff --git a/crypto/bn/bn_shift.c b/crypto/bn/bn_shift.c
index 70f785ea18..513e686f86 100644
--- a/crypto/bn/bn_shift.c
+++ b/crypto/bn/bn_shift.c
@@ -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);
}
diff --git a/crypto/bn/bn_sqr.c b/crypto/bn/bn_sqr.c
index c1d0cca438..ab678d1f30 100644
--- a/crypto/bn/bn_sqr.c
+++ b/crypto/bn/bn_sqr.c
@@ -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);
}
diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c
index 463d4a8139..51902703e1 100644
--- a/crypto/bn/bn_sqrt.c
+++ b/crypto/bn/bn_sqrt.c
@@ -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;
}
diff --git a/crypto/bn/bn_word.c b/crypto/bn/bn_word.c
index 988e0ca7b3..560a499692 100644
--- a/crypto/bn/bn_word.c
+++ b/crypto/bn/bn_word.c
@@ -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);
}