summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES16
-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
25 files changed, 209 insertions, 39 deletions
diff --git a/CHANGES b/CHANGES
index d157408763..e3b0623c0d 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 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