diff --git a/CHANGES b/CHANGES index d15740876..e3b0623c0 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 44ba17524..d51c94f92 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 + +#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 6cba07e9f..a13b8a11c 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 2d287e6d1..011d37f1f 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 a0e7915fb..7b5be7c43 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 0fe58dbf6..ff218957b 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 afdfd580f..462d4dbc4 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; itop = 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 0c448724d..4603b4f9f 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 -# 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 f63232b9f..85b72e0ee 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)<top <= i) return(0); a->d[i]&=(~(((BN_ULONG)1)<top=w+1; a->d[w]&= ~(BN_MASK2<= 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 c9ebdbaab..22d23cc3d 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 05fa9d1e9..a054d21ae 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 6b633b90b..5a92f9a33 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 ed148d845..2e03d0709 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 fd863933e..4430e90df 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 5f46b1826..5b5eb8fc9 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 480817a4b..de5a1f0c6 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 22cbcfc49..ea39677bc 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 70f785ea1..513e686f8 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; itop=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 c1d0cca43..ab678d1f3 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 463d4a813..51902703e 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 988e0ca7b..560a49969 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); }