From d870740cd75dd4f0cb66fb8c32653a7d47369706 Mon Sep 17 00:00:00 2001 From: Geoff Thorpe Date: Tue, 4 Nov 2003 22:54:49 +0000 Subject: [PATCH] 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. --- CHANGES | 16 +++++++++ crypto/bn/bn.h | 78 +++++++++++++++++++++++++++++++++++++++++++- crypto/bn/bn_add.c | 5 ++- crypto/bn/bn_blind.c | 1 + crypto/bn/bn_ctx.c | 5 ++- crypto/bn/bn_div.c | 8 +++-- crypto/bn/bn_exp.c | 6 ++++ crypto/bn/bn_exp2.c | 1 + crypto/bn/bn_gcd.c | 3 ++ crypto/bn/bn_gf2m.c | 25 +++++++++++--- crypto/bn/bn_lcl.h | 8 ----- crypto/bn/bn_lib.c | 21 +++++++++--- crypto/bn/bn_mod.c | 5 +++ crypto/bn/bn_mont.c | 4 ++- crypto/bn/bn_mpi.c | 1 + crypto/bn/bn_mul.c | 3 +- crypto/bn/bn_nist.c | 25 ++++++++------ crypto/bn/bn_prime.c | 5 +++ crypto/bn/bn_print.c | 6 ++-- crypto/bn/bn_rand.c | 2 ++ crypto/bn/bn_recp.c | 2 ++ crypto/bn/bn_shift.c | 10 ++++-- crypto/bn/bn_sqr.c | 1 + crypto/bn/bn_sqrt.c | 3 ++ crypto/bn/bn_word.c | 4 +++ 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 + +#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; 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 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 -# 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)<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 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; 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 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); } -- GitLab