提交 9b141126 编写于 作者: U Ulf Möller

New functions BN_CTX_start(), BN_CTX_get(), BN_CTX_end() to access

temporary BIGNUMs. BN_CTX still uses a fixed number of BIGNUMs, but
the BN_CTX implementation could now easily be changed.
上级 7e708ebe
...@@ -4,6 +4,14 @@ ...@@ -4,6 +4,14 @@
Changes between 0.9.4 and 0.9.5 [xx XXX 2000] Changes between 0.9.4 and 0.9.5 [xx XXX 2000]
*) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to
get temporary BIGNUMs from a BN_CTX.
[Ulf Möller]
*) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont()
for p == 0.
[Ulf Möller]
*) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and
include a #define from the old name to the new. The original intent include a #define from the old name to the new. The original intent
was that statically linked binaries could for example just call was that statically linked binaries could for example just call
......
...@@ -34,12 +34,12 @@ TEST=bntest.c exptest.c ...@@ -34,12 +34,12 @@ TEST=bntest.c exptest.c
APPS= APPS=
LIB=$(TOP)/libcrypto.a LIB=$(TOP)/libcrypto.a
LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_mul.c \ LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c \
bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \ bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c bn_recp.c bn_mont.c \ bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c bn_recp.c bn_mont.c \
bn_mpi.c bn_exp2.c bn_mpi.c bn_exp2.c
LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_mul.o \ LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o \
bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \ bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \
bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) bn_recp.o bn_mont.o \ bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) bn_recp.o bn_mont.o \
bn_mpi.o bn_exp2.o bn_mpi.o bn_exp2.o
......
...@@ -245,6 +245,8 @@ typedef struct bignum_ctx ...@@ -245,6 +245,8 @@ typedef struct bignum_ctx
int tos; int tos;
BIGNUM bn[BN_CTX_NUM+1]; BIGNUM bn[BN_CTX_NUM+1];
int flags; int flags;
int depth;
int pos[BN_CTX_NUM+1];
} BN_CTX; } BN_CTX;
typedef struct bn_blinding_st typedef struct bn_blinding_st
...@@ -335,6 +337,9 @@ char * BN_options(void); ...@@ -335,6 +337,9 @@ char * BN_options(void);
BN_CTX *BN_CTX_new(void); BN_CTX *BN_CTX_new(void);
void BN_CTX_init(BN_CTX *c); void BN_CTX_init(BN_CTX *c);
void BN_CTX_free(BN_CTX *c); void BN_CTX_free(BN_CTX *c);
void BN_CTX_start(BN_CTX *ctx);
BIGNUM *BN_CTX_get(BN_CTX *ctx);
void BN_CTX_end(BN_CTX *ctx);
int BN_rand(BIGNUM *rnd, int bits, int top,int bottom); int BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
int BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom); int BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
int BN_num_bits(const BIGNUM *a); int BN_num_bits(const BIGNUM *a);
...@@ -463,6 +468,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, ...@@ -463,6 +468,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
#define BN_F_BN_BLINDING_UPDATE 103 #define BN_F_BN_BLINDING_UPDATE 103
#define BN_F_BN_BN2DEC 104 #define BN_F_BN_BN2DEC 104
#define BN_F_BN_BN2HEX 105 #define BN_F_BN_BN2HEX 105
#define BN_F_BN_CTX_GET 116
#define BN_F_BN_CTX_NEW 106 #define BN_F_BN_CTX_NEW 106
#define BN_F_BN_DIV 107 #define BN_F_BN_DIV 107
#define BN_F_BN_EXPAND2 108 #define BN_F_BN_EXPAND2 108
...@@ -484,6 +490,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, ...@@ -484,6 +490,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
#define BN_R_INVALID_LENGTH 106 #define BN_R_INVALID_LENGTH 106
#define BN_R_NOT_INITIALIZED 107 #define BN_R_NOT_INITIALIZED 107
#define BN_R_NO_INVERSE 108 #define BN_R_NO_INVERSE 108
#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109
#ifdef __cplusplus #ifdef __cplusplus
} }
......
/* crypto/bn/bn_ctx.c */
/* Written by Ulf Moeller for the OpenSSL project. */
/* ====================================================================
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <assert.h>
#include "cryptlib.h"
#include <openssl/bn.h>
BN_CTX *BN_CTX_new(void)
{
BN_CTX *ret;
ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
if (ret == NULL)
{
BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
}
BN_CTX_init(ret);
ret->flags=BN_FLG_MALLOCED;
return(ret);
}
void BN_CTX_init(BN_CTX *ctx)
{
int i;
ctx->tos = 0;
ctx->flags = 0;
ctx->depth = 0;
for (i = 0; i < BN_CTX_NUM; i++)
BN_init(&(ctx->bn[i]));
}
void BN_CTX_free(BN_CTX *ctx)
{
int i;
if (ctx == NULL) return;
assert(ctx->depth == 0);
for (i=0; i < BN_CTX_NUM; i++)
BN_clear_free(&(ctx->bn[i]));
if (ctx->flags & BN_FLG_MALLOCED)
Free(ctx);
}
void BN_CTX_start(BN_CTX *ctx)
{
ctx->pos[ctx->depth++] = ctx->tos;
}
BIGNUM *BN_CTX_get(BN_CTX *ctx)
{
if (ctx->tos >= BN_CTX_NUM)
{
BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
return NULL;
}
return (&(ctx->bn[ctx->tos++]));
}
void BN_CTX_end(BN_CTX *ctx)
{
if (ctx == NULL) return;
assert(ctx->depth > 0);
ctx->depth--;
ctx->tos = ctx->pos[ctx->depth];
}
...@@ -62,11 +62,12 @@ ...@@ -62,11 +62,12 @@
#include "bn_lcl.h" #include "bn_lcl.h"
/* The old slow way */ /* The old slow way */
#if 0 #if 1
int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
BN_CTX *ctx) BN_CTX *ctx)
{ {
int i,nm,nd; int i,nm,nd;
int ret = 0;
BIGNUM *D; BIGNUM *D;
bn_check_top(m); bn_check_top(m);
...@@ -85,14 +86,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, ...@@ -85,14 +86,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
return(1); return(1);
} }
D= &(ctx->bn[ctx->tos]); BN_CTX_start(ctx);
if (dv == NULL) dv= &(ctx->bn[ctx->tos+1]); D = BN_CTX_get(ctx);
if (rem == NULL) rem= &(ctx->bn[ctx->tos+2]); if (dv == NULL) dv = BN_CTX_get(ctx);
if (rem == NULL) rem = BN_CTX_get(ctx);
if (D == NULL || dv == NULL || rem == NULL)
goto end;
nd=BN_num_bits(d); nd=BN_num_bits(d);
nm=BN_num_bits(m); nm=BN_num_bits(m);
if (BN_copy(D,d) == NULL) return(0); if (BN_copy(D,d) == NULL) goto end;
if (BN_copy(rem,m) == NULL) return(0); if (BN_copy(rem,m) == NULL) goto end;
/* The next 2 are needed so we can do a dv->d[0]|=1 later /* The next 2 are needed so we can do a dv->d[0]|=1 later
* since BN_lshift1 will only work once there is a value :-) */ * since BN_lshift1 will only work once there is a value :-) */
...@@ -100,21 +104,24 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, ...@@ -100,21 +104,24 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
bn_wexpand(dv,1); bn_wexpand(dv,1);
dv->top=1; dv->top=1;
if (!BN_lshift(D,D,nm-nd)) return(0); if (!BN_lshift(D,D,nm-nd)) goto end;
for (i=nm-nd; i>=0; i--) for (i=nm-nd; i>=0; i--)
{ {
if (!BN_lshift1(dv,dv)) return(0); if (!BN_lshift1(dv,dv)) goto end;
if (BN_ucmp(rem,D) >= 0) if (BN_ucmp(rem,D) >= 0)
{ {
dv->d[0]|=1; dv->d[0]|=1;
if (!BN_usub(rem,rem,D)) return(0); if (!BN_usub(rem,rem,D)) goto end;
} }
/* CAN IMPROVE (and have now :=) */ /* CAN IMPROVE (and have now :=) */
if (!BN_rshift1(D,D)) return(0); if (!BN_rshift1(D,D)) goto end;
} }
rem->neg=BN_is_zero(rem)?0:m->neg; rem->neg=BN_is_zero(rem)?0:m->neg;
dv->neg=m->neg^d->neg; dv->neg=m->neg^d->neg;
return(1); ret = 1;
end:
BN_CTX_end(ctx);
return(ret);
} }
#else #else
...@@ -145,13 +152,15 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, ...@@ -145,13 +152,15 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
return(1); return(1);
} }
tmp= &(ctx->bn[ctx->tos]); BN_CTX_start(ctx);
tmp=BN_CTX_get(ctx);
tmp->neg=0; tmp->neg=0;
snum= &(ctx->bn[ctx->tos+1]); snum=BN_CTX_get(ctx);
sdiv= &(ctx->bn[ctx->tos+2]); sdiv=BN_CTX_get(ctx);
if (dv == NULL) if (dv == NULL)
res= &(ctx->bn[ctx->tos+3]); res=BN_CTX_get(ctx);
else res=dv; else res=dv;
if (res == NULL) goto err;
/* First we normalise the numbers */ /* First we normalise the numbers */
norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
...@@ -329,8 +338,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, ...@@ -329,8 +338,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
BN_rshift(rm,snum,norm_shift); BN_rshift(rm,snum,norm_shift);
rm->neg=num->neg; rm->neg=num->neg;
} }
BN_CTX_end(ctx);
return(1); return(1);
err: err:
BN_CX_end(ctx);
return(0); return(0);
} }
...@@ -346,22 +357,27 @@ int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) ...@@ -346,22 +357,27 @@ int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
if (BN_ucmp(m,d) < 0) if (BN_ucmp(m,d) < 0)
return((BN_copy(rem,m) == NULL)?0:1); return((BN_copy(rem,m) == NULL)?0:1);
dv= &(ctx->bn[ctx->tos]); BN_CTX_start(ctx);
dv=BN_CTX_get(ctx);
if (!BN_copy(rem,m)) return(0); if (!BN_copy(rem,m)) goto err;
nm=BN_num_bits(rem); nm=BN_num_bits(rem);
nd=BN_num_bits(d); nd=BN_num_bits(d);
if (!BN_lshift(dv,d,nm-nd)) return(0); if (!BN_lshift(dv,d,nm-nd)) goto err;
for (i=nm-nd; i>=0; i--) for (i=nm-nd; i>=0; i--)
{ {
if (BN_cmp(rem,dv) >= 0) if (BN_cmp(rem,dv) >= 0)
{ {
if (!BN_sub(rem,rem,dv)) return(0); if (!BN_sub(rem,rem,dv)) goto err;
} }
if (!BN_rshift1(dv,dv)) return(0); if (!BN_rshift1(dv,dv)) goto err;
} }
BN_CTX_end(ctx);
return(1); return(1);
err:
BN_CTX_end(ctx);
return(0);
#else #else
return(BN_div(NULL,rem,m,d,ctx)); return(BN_div(NULL,rem,m,d,ctx));
#endif #endif
......
...@@ -71,6 +71,7 @@ static ERR_STRING_DATA BN_str_functs[]= ...@@ -71,6 +71,7 @@ static ERR_STRING_DATA BN_str_functs[]=
{ERR_PACK(0,BN_F_BN_BLINDING_UPDATE,0), "BN_BLINDING_update"}, {ERR_PACK(0,BN_F_BN_BLINDING_UPDATE,0), "BN_BLINDING_update"},
{ERR_PACK(0,BN_F_BN_BN2DEC,0), "BN_bn2dec"}, {ERR_PACK(0,BN_F_BN_BN2DEC,0), "BN_bn2dec"},
{ERR_PACK(0,BN_F_BN_BN2HEX,0), "BN_bn2hex"}, {ERR_PACK(0,BN_F_BN_BN2HEX,0), "BN_bn2hex"},
{ERR_PACK(0,BN_F_BN_CTX_GET,0), "BN_CTX_GET"},
{ERR_PACK(0,BN_F_BN_CTX_NEW,0), "BN_CTX_new"}, {ERR_PACK(0,BN_F_BN_CTX_NEW,0), "BN_CTX_new"},
{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"}, {ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"},
{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"}, {ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"},
...@@ -95,6 +96,7 @@ static ERR_STRING_DATA BN_str_reasons[]= ...@@ -95,6 +96,7 @@ static ERR_STRING_DATA BN_str_reasons[]=
{BN_R_INVALID_LENGTH ,"invalid length"}, {BN_R_INVALID_LENGTH ,"invalid length"},
{BN_R_NOT_INITIALIZED ,"not initialized"}, {BN_R_NOT_INITIALIZED ,"not initialized"},
{BN_R_NO_INVERSE ,"no inverse"}, {BN_R_NO_INVERSE ,"no inverse"},
{BN_R_TOO_MANY_TEMPORARY_VARIABLES ,"too many temporary variables"},
{0,NULL} {0,NULL}
}; };
......
...@@ -72,7 +72,8 @@ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) ...@@ -72,7 +72,8 @@ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
bn_check_top(b); bn_check_top(b);
bn_check_top(m); bn_check_top(m);
t= &(ctx->bn[ctx->tos++]); BN_CTX_start(ctx);
if ((t = BN_CTX_get(ctx)) == NULL) goto err;
if (a == b) if (a == b)
{ if (!BN_sqr(t,a,ctx)) goto err; } { if (!BN_sqr(t,a,ctx)) goto err; }
else else
...@@ -80,7 +81,7 @@ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) ...@@ -80,7 +81,7 @@ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
if (!BN_mod(ret,t,m,ctx)) goto err; if (!BN_mod(ret,t,m,ctx)) goto err;
r=1; r=1;
err: err:
ctx->tos--; BN_CTX_end(ctx);
return(r); return(r);
} }
...@@ -91,8 +92,10 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) ...@@ -91,8 +92,10 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
int i,bits,ret=0; int i,bits,ret=0;
BIGNUM *v,*tmp; BIGNUM *v,*tmp;
v= &(ctx->bn[ctx->tos++]); BN_CTX_start(ctx);
tmp= &(ctx->bn[ctx->tos++]); v = BN_CTX_get(ctx);
tmp = BN_CTX_get(ctx);
if (v == NULL || tmp == NULL) goto err;
if (BN_copy(v,a) == NULL) goto err; if (BN_copy(v,a) == NULL) goto err;
bits=BN_num_bits(p); bits=BN_num_bits(p);
...@@ -113,7 +116,7 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) ...@@ -113,7 +116,7 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
} }
ret=1; ret=1;
err: err:
ctx->tos-=2; BN_CTX_end(ctx);
return(ret); return(ret);
} }
...@@ -122,15 +125,15 @@ err: ...@@ -122,15 +125,15 @@ err:
/* this one works - simple but works */ /* this one works - simple but works */
int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
{ {
int i,bits,ret=0,tos; int i,bits,ret=0;
BIGNUM *v,*rr; BIGNUM *v,*rr;
tos=ctx->tos; BN_CTX_start(ctx);
v= &(ctx->bn[ctx->tos++]);
if ((r == a) || (r == p)) if ((r == a) || (r == p))
rr= &(ctx->bn[ctx->tos++]); rr = BN_CTX_get(ctx);
else else
rr=r; rr = r;
if ((v = BN_CTX_get(ctx)) == NULL) goto err;
if (BN_copy(v,a) == NULL) goto err; if (BN_copy(v,a) == NULL) goto err;
bits=BN_num_bits(p); bits=BN_num_bits(p);
...@@ -149,8 +152,8 @@ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) ...@@ -149,8 +152,8 @@ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
} }
ret=1; ret=1;
err: err:
ctx->tos=tos;
if (r != rr) BN_copy(r,rr); if (r != rr) BN_copy(r,rr);
BN_CTX_end(ctx);
return(ret); return(ret);
} }
...@@ -193,7 +196,6 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, ...@@ -193,7 +196,6 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BIGNUM val[TABLE_SIZE]; BIGNUM val[TABLE_SIZE];
BN_RECP_CTX recp; BN_RECP_CTX recp;
aa= &(ctx->bn[ctx->tos++]);
bits=BN_num_bits(p); bits=BN_num_bits(p);
if (bits == 0) if (bits == 0)
...@@ -201,6 +203,10 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, ...@@ -201,6 +203,10 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BN_one(r); BN_one(r);
return(1); return(1);
} }
BN_CTX_start(ctx);
if ((aa = BN_CTX_get(ctx)) == NULL) goto err;
BN_RECP_CTX_init(&recp); BN_RECP_CTX_init(&recp);
if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
...@@ -289,7 +295,7 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, ...@@ -289,7 +295,7 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
} }
ret=1; ret=1;
err: err:
ctx->tos--; BN_CTX_end(ctx);
for (i=0; i<ts; i++) for (i=0; i<ts; i++)
BN_clear_free(&(val[i])); BN_clear_free(&(val[i]));
BN_RECP_CTX_free(&recp); BN_RECP_CTX_free(&recp);
...@@ -317,14 +323,16 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p, ...@@ -317,14 +323,16 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
return(0); return(0);
} }
d= &(ctx->bn[ctx->tos++]);
r= &(ctx->bn[ctx->tos++]);
bits=BN_num_bits(p); bits=BN_num_bits(p);
if (bits == 0) if (bits == 0)
{ {
BN_one(r); BN_one(rr);
return(1); return(1);
} }
BN_CTX_start(ctx);
d = BN_CTX_get(ctx);
r = BN_CTX_get(ctx);
if (d == NULL || r == NULL) goto err;
/* If this is not done, things will break in the montgomery /* If this is not done, things will break in the montgomery
* part */ * part */
...@@ -432,7 +440,7 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p, ...@@ -432,7 +440,7 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
ret=1; ret=1;
err: err:
if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
ctx->tos-=2; BN_CTX_end(ctx);
for (i=0; i<ts; i++) for (i=0; i<ts; i++)
BN_clear_free(&(val[i])); BN_clear_free(&(val[i]));
return(ret); return(ret);
...@@ -448,7 +456,6 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, ...@@ -448,7 +456,6 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
BIGNUM *d; BIGNUM *d;
BIGNUM val[TABLE_SIZE]; BIGNUM val[TABLE_SIZE];
d= &(ctx->bn[ctx->tos++]);
bits=BN_num_bits(p); bits=BN_num_bits(p);
if (bits == 0) if (bits == 0)
...@@ -457,6 +464,9 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, ...@@ -457,6 +464,9 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
return(1); return(1);
} }
BN_CTX_start(ctx);
if ((d = BN_CTX_get(ctx)) == NULL) goto err;
BN_init(&(val[0])); BN_init(&(val[0]));
ts=1; ts=1;
if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */ if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
...@@ -541,7 +551,7 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, ...@@ -541,7 +551,7 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
} }
ret=1; ret=1;
err: err:
ctx->tos--; BN_CTX_end(ctx);
for (i=0; i<ts; i++) for (i=0; i<ts; i++)
BN_clear_free(&(val[i])); BN_clear_free(&(val[i]));
return(ret); return(ret);
......
...@@ -35,15 +35,19 @@ int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2, ...@@ -35,15 +35,19 @@ int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2,
BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
return(0); return(0);
} }
d= &(ctx->bn[ctx->tos++]);
r= &(ctx->bn[ctx->tos++]);
bits1=BN_num_bits(p1); bits1=BN_num_bits(p1);
bits2=BN_num_bits(p2); bits2=BN_num_bits(p2);
if ((bits1 == 0) && (bits2 == 0)) if ((bits1 == 0) && (bits2 == 0))
{ {
BN_one(r); BN_one(rr);
return(1); return(1);
} }
BN_CTX_start(ctx);
d = BN_CTX_get(ctx);
r = BN_CTX_get(ctx);
if (d == NULL || r == NULL) goto err;
bits=(bits1 > bits2)?bits1:bits2; bits=(bits1 > bits2)?bits1:bits2;
/* If this is not done, things will break in the montgomery /* If this is not done, things will break in the montgomery
...@@ -183,7 +187,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2, ...@@ -183,7 +187,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2,
ret=1; ret=1;
err: err:
if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
ctx->tos-=2; BN_CTX_end(ctx);
for (i=0; i<ts; i++) for (i=0; i<ts; i++)
{ {
for (j=0; j<ts; j++) for (j=0; j<ts; j++)
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
#include "bn_lcl.h" #include "bn_lcl.h"
static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx) int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx)
{ {
BIGNUM *a,*b,*t; BIGNUM *a,*b,*t;
...@@ -69,8 +70,10 @@ int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx) ...@@ -69,8 +70,10 @@ int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx)
bn_check_top(in_a); bn_check_top(in_a);
bn_check_top(in_b); bn_check_top(in_b);
a= &(ctx->bn[ctx->tos]); BN_CTX_start(ctx);
b= &(ctx->bn[ctx->tos+1]); a = BN_CTX_get(ctx);
b = BN_CTX_get(ctx);
if (a == NULL || b == NULL) goto err;
if (BN_copy(a,in_a) == NULL) goto err; if (BN_copy(a,in_a) == NULL) goto err;
if (BN_copy(b,in_b) == NULL) goto err; if (BN_copy(b,in_b) == NULL) goto err;
...@@ -82,6 +85,7 @@ int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx) ...@@ -82,6 +85,7 @@ int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx)
if (BN_copy(r,t) == NULL) goto err; if (BN_copy(r,t) == NULL) goto err;
ret=1; ret=1;
err: err:
BN_CTX_end(ctx);
return(ret); return(ret);
} }
...@@ -142,20 +146,22 @@ err: ...@@ -142,20 +146,22 @@ err:
/* solves ax == 1 (mod n) */ /* solves ax == 1 (mod n) */
BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
{ {
BIGNUM *A,*B,*X,*Y,*M,*D,*R; BIGNUM *A,*B,*X,*Y,*M,*D,*R=NULL;
BIGNUM *T,*ret=NULL; BIGNUM *T,*ret=NULL;
int sign; int sign;
bn_check_top(a); bn_check_top(a);
bn_check_top(n); bn_check_top(n);
A= &(ctx->bn[ctx->tos]); BN_CTX_start(ctx);
B= &(ctx->bn[ctx->tos+1]); A = BN_CTX_get(ctx);
X= &(ctx->bn[ctx->tos+2]); B = BN_CTX_get(ctx);
D= &(ctx->bn[ctx->tos+3]); X = BN_CTX_get(ctx);
M= &(ctx->bn[ctx->tos+4]); D = BN_CTX_get(ctx);
Y= &(ctx->bn[ctx->tos+5]); M = BN_CTX_get(ctx);
ctx->tos+=6; Y = BN_CTX_get(ctx);
if (Y == NULL) goto err;
if (in == NULL) if (in == NULL)
R=BN_new(); R=BN_new();
else else
...@@ -198,7 +204,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) ...@@ -198,7 +204,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
ret=R; ret=R;
err: err:
if ((ret == NULL) && (in == NULL)) BN_free(R); if ((ret == NULL) && (in == NULL)) BN_free(R);
ctx->tos-=6; BN_CTX_end(ctx);
return(ret); return(ret);
} }
...@@ -304,43 +304,6 @@ BIGNUM *BN_new(void) ...@@ -304,43 +304,6 @@ BIGNUM *BN_new(void)
return(ret); return(ret);
} }
BN_CTX *BN_CTX_new(void)
{
BN_CTX *ret;
ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
if (ret == NULL)
{
BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
}
BN_CTX_init(ret);
ret->flags=BN_FLG_MALLOCED;
return(ret);
}
void BN_CTX_init(BN_CTX *ctx)
{
memset(ctx,0,sizeof(BN_CTX));
ctx->tos=0;
ctx->flags=0;
}
void BN_CTX_free(BN_CTX *c)
{
int i;
if(c == NULL)
return;
for (i=0; i<BN_CTX_NUM; i++)
BN_clear_free(&(c->bn[i]));
if (c->flags & BN_FLG_MALLOCED)
Free(c);
}
/* This is an internal function that should not be used in applications. /* This is an internal function that should not be used in applications.
* It ensures that 'b' has enough room for a 'bits' bit number. It is * It ensures that 'b' has enough room for a 'bits' bit number. It is
* mostly used by the various BIGNUM routines. If there is an error, * mostly used by the various BIGNUM routines. If there is an error,
......
...@@ -72,9 +72,10 @@ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, ...@@ -72,9 +72,10 @@ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
{ {
BIGNUM *tmp,*tmp2; BIGNUM *tmp,*tmp2;
tmp= &(ctx->bn[ctx->tos]); BN_CTX_start(ctx);
tmp2= &(ctx->bn[ctx->tos]); tmp = BN_CTX_get(ctx);
ctx->tos+=2; tmp2 = BN_CTX_get(ctx);
if (tmp == NULL || tmp2 == NULL) goto err;
bn_check_top(tmp); bn_check_top(tmp);
bn_check_top(tmp2); bn_check_top(tmp2);
...@@ -98,16 +99,20 @@ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, ...@@ -98,16 +99,20 @@ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
} }
/* reduce from aRR to aR */ /* reduce from aRR to aR */
if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
ctx->tos-=2; BN_CTX_end(ctx);
return(1); return(1);
err: err:
return(0); return(0);
} }
#define BN_RECURSION_MONT
int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
BN_CTX *ctx) BN_CTX *ctx)
{ {
int retn=0; int retn=0;
BN_CTX_start(ctx);
#ifdef BN_RECURSION_MONT #ifdef BN_RECURSION_MONT
if (mont->use_word) if (mont->use_word)
#endif #endif
...@@ -116,7 +121,7 @@ int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, ...@@ -116,7 +121,7 @@ int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
BN_ULONG *ap,*np,*rp,n0,v,*nrp; BN_ULONG *ap,*np,*rp,n0,v,*nrp;
int al,nl,max,i,x,ri; int al,nl,max,i,x,ri;
r= &(ctx->bn[ctx->tos]); if ((r = BN_CTX_get(ctx)) == NULL) goto err;
if (!BN_copy(r,a)) goto err; if (!BN_copy(r,a)) goto err;
n= &(mont->N); n= &(mont->N);
...@@ -210,9 +215,9 @@ printf("word BN_from_montgomery %d * %d\n",nl,nl); ...@@ -210,9 +215,9 @@ printf("word BN_from_montgomery %d * %d\n",nl,nl);
{ {
BIGNUM *t1,*t2; BIGNUM *t1,*t2;
t1=&(ctx->bn[ctx->tos]); t1 = BN_CTX_get(ctx);
t2=&(ctx->bn[ctx->tos+1]); t2 = BN_CTX_get(ctx);
ctx->tos+=2; if (t1 == NULL || t2 == NULL) goto err;
if (!BN_copy(t1,a)) goto err; if (!BN_copy(t1,a)) goto err;
BN_mask_bits(t1,mont->ri); BN_mask_bits(t1,mont->ri);
...@@ -226,11 +231,11 @@ printf("word BN_from_montgomery %d * %d\n",nl,nl); ...@@ -226,11 +231,11 @@ printf("word BN_from_montgomery %d * %d\n",nl,nl);
if (BN_ucmp(ret,&mont->N) >= 0) if (BN_ucmp(ret,&mont->N) >= 0)
BN_usub(ret,ret,&mont->N); BN_usub(ret,ret,&mont->N);
ctx->tos-=2;
retn=1; retn=1;
} }
#endif #endif
err: err:
BN_CTX_end(ctx);
return(retn); return(retn);
} }
......
...@@ -585,10 +585,13 @@ printf("BN_mul %d * %d\n",a->top,b->top); ...@@ -585,10 +585,13 @@ printf("BN_mul %d * %d\n",a->top,b->top);
} }
top=al+bl; top=al+bl;
BN_CTX_start(ctx);
if ((r == a) || (r == b)) if ((r == a) || (r == b))
rr= &(ctx->bn[ctx->tos+1]); {
if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
}
else else
rr=r; rr = r;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
if (al == bl) if (al == bl)
...@@ -596,14 +599,14 @@ printf("BN_mul %d * %d\n",a->top,b->top); ...@@ -596,14 +599,14 @@ printf("BN_mul %d * %d\n",a->top,b->top);
# ifdef BN_MUL_COMBA # ifdef BN_MUL_COMBA
/* if (al == 4) /* if (al == 4)
{ {
if (bn_wexpand(rr,8) == NULL) return(0); if (bn_wexpand(rr,8) == NULL) goto err;
rr->top=8; rr->top=8;
bn_mul_comba4(rr->d,a->d,b->d); bn_mul_comba4(rr->d,a->d,b->d);
goto end; goto end;
} }
else */ if (al == 8) else */ if (al == 8)
{ {
if (bn_wexpand(rr,16) == NULL) return(0); if (bn_wexpand(rr,16) == NULL) goto err;
rr->top=16; rr->top=16;
bn_mul_comba8(rr->d,a->d,b->d); bn_mul_comba8(rr->d,a->d,b->d);
goto end; goto end;
...@@ -614,7 +617,7 @@ printf("BN_mul %d * %d\n",a->top,b->top); ...@@ -614,7 +617,7 @@ printf("BN_mul %d * %d\n",a->top,b->top);
if (al < BN_MULL_SIZE_NORMAL) if (al < BN_MULL_SIZE_NORMAL)
#endif #endif
{ {
if (bn_wexpand(rr,top) == NULL) return(0); if (bn_wexpand(rr,top) == NULL) goto err;
rr->top=top; rr->top=top;
bn_mul_normal(rr->d,a->d,al,b->d,bl); bn_mul_normal(rr->d,a->d,al,b->d,bl);
goto end; goto end;
...@@ -627,7 +630,7 @@ printf("BN_mul %d * %d\n",a->top,b->top); ...@@ -627,7 +630,7 @@ printf("BN_mul %d * %d\n",a->top,b->top);
#ifdef BN_RECURSION #ifdef BN_RECURSION
else if ((al < BN_MULL_SIZE_NORMAL) || (bl < BN_MULL_SIZE_NORMAL)) else if ((al < BN_MULL_SIZE_NORMAL) || (bl < BN_MULL_SIZE_NORMAL))
{ {
if (bn_wexpand(rr,top) == NULL) return(0); if (bn_wexpand(rr,top) == NULL) goto err;
rr->top=top; rr->top=top;
bn_mul_normal(rr->d,a->d,al,b->d,bl); bn_mul_normal(rr->d,a->d,al,b->d,bl);
goto end; goto end;
...@@ -653,7 +656,7 @@ printf("BN_mul %d * %d\n",a->top,b->top); ...@@ -653,7 +656,7 @@ printf("BN_mul %d * %d\n",a->top,b->top);
#endif #endif
/* asymmetric and >= 4 */ /* asymmetric and >= 4 */
if (bn_wexpand(rr,top) == NULL) return(0); if (bn_wexpand(rr,top) == NULL) goto err;
rr->top=top; rr->top=top;
bn_mul_normal(rr->d,a->d,al,b->d,bl); bn_mul_normal(rr->d,a->d,al,b->d,bl);
...@@ -666,7 +669,7 @@ symmetric: ...@@ -666,7 +669,7 @@ symmetric:
j=BN_num_bits_word((BN_ULONG)al); j=BN_num_bits_word((BN_ULONG)al);
j=1<<(j-1); j=1<<(j-1);
k=j+j; k=j+j;
t= &(ctx->bn[ctx->tos]); t = BN_CTX_get(ctx);
if (al == j) /* exact multiple */ if (al == j) /* exact multiple */
{ {
bn_wexpand(t,k*2); bn_wexpand(t,k*2);
...@@ -693,7 +696,11 @@ end: ...@@ -693,7 +696,11 @@ end:
#endif #endif
bn_fix_top(rr); bn_fix_top(rr);
if (r != rr) BN_copy(r,rr); if (r != rr) BN_copy(r,rr);
BN_CTX_end(ctx);
return(1); return(1);
err:
BN_CTX_end(ctx);
return(0);
} }
void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
......
...@@ -244,19 +244,23 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks, ...@@ -244,19 +244,23 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
else else
if ((ctx=BN_CTX_new()) == NULL) if ((ctx=BN_CTX_new()) == NULL)
goto err; goto err;
BN_CTX_start(ctx);
/* A := abs(a) */ /* A := abs(a) */
if (a->neg) if (a->neg)
{ {
BIGNUM *t = &(ctx->bn[ctx->tos++]); BIGNUM *t;
if ((t = BN_CTX_get(ctx)) == NULL) goto err;
BN_copy(t, a); BN_copy(t, a);
t->neg = 0; t->neg = 0;
A = t; A = t;
} }
else else
A = a; A = a;
A1 = &(ctx->bn[ctx->tos++]); A1 = BN_CTX_get(ctx);
A1_odd = &(ctx->bn[ctx->tos++]); A1_odd = BN_CTX_get(ctx);
check = &(ctx->bn[ctx->tos++]);; check = BN_CTX_get(ctx);
if (check == NULL) goto err;
/* compute A1 := A - 1 */ /* compute A1 := A - 1 */
if (!BN_copy(A1, A)) if (!BN_copy(A1, A))
...@@ -305,14 +309,12 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks, ...@@ -305,14 +309,12 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
} }
ret=1; ret=1;
err: err:
if (ctx_passed != NULL) if (ctx != NULL)
{ {
ctx_passed->tos -= 3; /* A1, A1_odd, check */ BN_CTX_end(ctx);
if (a != A) if (ctx_passed == NULL)
--ctx_passed->tos; /* A */ BN_CTX_free(ctx);
} }
else if (ctx != NULL)
BN_CTX_free(ctx);
if (mont != NULL) if (mont != NULL)
BN_MONT_CTX_free(mont); BN_MONT_CTX_free(mont);
...@@ -380,7 +382,8 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem, ...@@ -380,7 +382,8 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
int i,ret=0; int i,ret=0;
BIGNUM *t1; BIGNUM *t1;
t1= &(ctx->bn[ctx->tos++]); BN_CTX_start(ctx);
if ((t1 = BN_CTX_get(ctx)) == NULL) goto err;
if (!BN_rand(rnd,bits,0,1)) goto err; if (!BN_rand(rnd,bits,0,1)) goto err;
...@@ -406,7 +409,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem, ...@@ -406,7 +409,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
} }
ret=1; ret=1;
err: err:
ctx->tos--; BN_CTX_end(ctx);
return(ret); return(ret);
} }
...@@ -414,12 +417,14 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd, ...@@ -414,12 +417,14 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd,
BIGNUM *rem, BN_CTX *ctx) BIGNUM *rem, BN_CTX *ctx)
{ {
int i,ret=0; int i,ret=0;
BIGNUM *t1,*qadd=NULL,*q=NULL; BIGNUM *t1,*qadd,*q;
bits--; bits--;
t1= &(ctx->bn[ctx->tos++]); BN_CTX_start(ctx);
q= &(ctx->bn[ctx->tos++]); t1 = BN_CTX_get(ctx);
qadd= &(ctx->bn[ctx->tos++]); q = BN_CTX_get(ctx);
qadd = BN_CTX_get(ctx);
if (qadd == NULL) goto err;
if (!BN_rshift1(qadd,padd)) goto err; if (!BN_rshift1(qadd,padd)) goto err;
...@@ -455,6 +460,6 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd, ...@@ -455,6 +460,6 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd,
} }
ret=1; ret=1;
err: err:
ctx->tos-=3; BN_CTX_end(ctx);
return(ret); return(ret);
} }
...@@ -106,7 +106,8 @@ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp, ...@@ -106,7 +106,8 @@ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,
int ret=0; int ret=0;
BIGNUM *a; BIGNUM *a;
a= &(ctx->bn[ctx->tos++]); BN_CTX_start(ctx);
if ((a = BN_CTX_get(ctx)) == NULL) goto err;
if (y != NULL) if (y != NULL)
{ {
if (x == y) if (x == y)
...@@ -120,33 +121,34 @@ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp, ...@@ -120,33 +121,34 @@ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,
BN_div_recp(NULL,r,a,recp,ctx); BN_div_recp(NULL,r,a,recp,ctx);
ret=1; ret=1;
err: err:
ctx->tos--; BN_CTX_end(ctx);
return(ret); return(ret);
} }
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp, int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp,
BN_CTX *ctx) BN_CTX *ctx)
{ {
int i,j,tos,ret=0,ex; int i,j,ret=0,ex;
BIGNUM *a,*b,*d,*r; BIGNUM *a,*b,*d,*r;
tos=ctx->tos; BN_CTX_start(ctx);
a= &(ctx->bn[ctx->tos++]); a=BN_CTX_get(ctx);
b= &(ctx->bn[ctx->tos++]); b=BN_CTX_get(ctx);
if (dv != NULL) if (dv != NULL)
d=dv; d=dv;
else else
d= &(ctx->bn[ctx->tos++]); d=BN_CTX_get(ctx);
if (rem != NULL) if (rem != NULL)
r=rem; r=rem;
else else
r= &(ctx->bn[ctx->tos++]); r=BN_CTX_get(ctx);
if (a == NULL || b == NULL || d == NULL || r == NULL) goto err;
if (BN_ucmp(m,&(recp->N)) < 0) if (BN_ucmp(m,&(recp->N)) < 0)
{ {
BN_zero(d); BN_zero(d);
BN_copy(r,m); BN_copy(r,m);
ctx->tos=tos; BN_CTX_end(ctx);
return(1); return(1);
} }
...@@ -200,7 +202,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp, ...@@ -200,7 +202,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp,
d->neg=m->neg^recp->N.neg; d->neg=m->neg^recp->N.neg;
ret=1; ret=1;
err: err:
ctx->tos=tos; BN_CTX_end(ctx);
return(ret); return(ret);
} }
......
...@@ -65,14 +65,13 @@ ...@@ -65,14 +65,13 @@
int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx) int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx)
{ {
int max,al; int max,al;
int ret = 0;
BIGNUM *tmp,*rr; BIGNUM *tmp,*rr;
#ifdef BN_COUNT #ifdef BN_COUNT
printf("BN_sqr %d * %d\n",a->top,a->top); printf("BN_sqr %d * %d\n",a->top,a->top);
#endif #endif
bn_check_top(a); bn_check_top(a);
tmp= &(ctx->bn[ctx->tos]);
rr=(a != r)?r: (&ctx->bn[ctx->tos+1]);
al=a->top; al=a->top;
if (al <= 0) if (al <= 0)
...@@ -81,8 +80,13 @@ printf("BN_sqr %d * %d\n",a->top,a->top); ...@@ -81,8 +80,13 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
return(1); return(1);
} }
BN_CTX_start(ctx);
rr=(a != r) ? r : BN_CTX_get(ctx);
tmp=BN_CTX_get(ctx);
if (tmp == NULL) goto err;
max=(al+al); max=(al+al);
if (bn_wexpand(rr,max+1) == NULL) return(0); if (bn_wexpand(rr,max+1) == NULL) goto err;
r->neg=0; r->neg=0;
if (al == 4) if (al == 4)
...@@ -120,18 +124,18 @@ printf("BN_sqr %d * %d\n",a->top,a->top); ...@@ -120,18 +124,18 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
k=j+j; k=j+j;
if (al == j) if (al == j)
{ {
if (bn_wexpand(a,k*2) == NULL) return(0); if (bn_wexpand(a,k*2) == NULL) goto err;
if (bn_wexpand(tmp,k*2) == NULL) return(0); if (bn_wexpand(tmp,k*2) == NULL) goto err;
bn_sqr_recursive(rr->d,a->d,al,tmp->d); bn_sqr_recursive(rr->d,a->d,al,tmp->d);
} }
else else
{ {
if (bn_wexpand(tmp,max) == NULL) return(0); if (bn_wexpand(tmp,max) == NULL) goto err;
bn_sqr_normal(rr->d,a->d,al,tmp->d); bn_sqr_normal(rr->d,a->d,al,tmp->d);
} }
} }
#else #else
if (bn_wexpand(tmp,max) == NULL) return(0); if (bn_wexpand(tmp,max) == NULL) goto err;
bn_sqr_normal(rr->d,a->d,al,tmp->d); bn_sqr_normal(rr->d,a->d,al,tmp->d);
#endif #endif
} }
...@@ -139,7 +143,10 @@ printf("BN_sqr %d * %d\n",a->top,a->top); ...@@ -139,7 +143,10 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
rr->top=max; rr->top=max;
if ((max > 0) && (rr->d[max-1] == 0)) rr->top--; if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
if (rr != r) BN_copy(r,rr); if (rr != r) BN_copy(r,rr);
return(1); ret = 1;
err:
BN_CTX_end(ctx);
return(ret);
} }
/* tmp must have 2*n words */ /* tmp must have 2*n words */
......
...@@ -17,6 +17,7 @@ printf("bn_mull %d * %d\n",a->top,b->top); ...@@ -17,6 +17,7 @@ printf("bn_mull %d * %d\n",a->top,b->top);
bn_check_top(a); bn_check_top(a);
bn_check_top(b); bn_check_top(b);
bn_check_top(r); bn_check_top(r);
BN_CTX_start(ctx);
al=a->top; al=a->top;
bl=b->top; bl=b->top;
...@@ -85,7 +86,7 @@ symetric: ...@@ -85,7 +86,7 @@ symetric:
j=BN_num_bits_word((BN_ULONG)al); j=BN_num_bits_word((BN_ULONG)al);
j=1<<(j-1); j=1<<(j-1);
k=j+j; k=j+j;
t= &(ctx->bn[ctx->tos]); t = BN_CTX_get(ctx);
if (al == j) /* exact multiple */ if (al == j) /* exact multiple */
{ {
bn_wexpand(t,k*2); bn_wexpand(t,k*2);
...@@ -107,6 +108,7 @@ symetric: ...@@ -107,6 +108,7 @@ symetric:
r->top=top; r->top=top;
} }
end: end:
BN_CTX_end(ctx);
bn_fix_top(r); bn_fix_top(r);
return(1); return(1);
} }
......
...@@ -95,9 +95,10 @@ DH *DH_generate_parameters(int prime_len, int generator, ...@@ -95,9 +95,10 @@ DH *DH_generate_parameters(int prime_len, int generator,
if (ret == NULL) goto err; if (ret == NULL) goto err;
ctx=BN_CTX_new(); ctx=BN_CTX_new();
if (ctx == NULL) goto err; if (ctx == NULL) goto err;
t1= &(ctx->bn[0]); BN_CTX_start(ctx);
t2= &(ctx->bn[1]); t1 = BN_CTX_get(ctx);
ctx->tos=2; t2 = BN_CTX_get(ctx);
if (t1 == NULL || t2 == NULL) goto err;
if (generator == DH_GENERATOR_2) if (generator == DH_GENERATOR_2)
{ {
...@@ -138,7 +139,11 @@ err: ...@@ -138,7 +139,11 @@ err:
ok=0; ok=0;
} }
if (ctx != NULL) BN_CTX_free(ctx); if (ctx != NULL)
{
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (!ok && (ret != NULL)) if (!ok && (ret != NULL))
{ {
DH_free(ret); DH_free(ret);
......
...@@ -161,7 +161,8 @@ static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh) ...@@ -161,7 +161,8 @@ static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh)
int ret= -1; int ret= -1;
BN_CTX_init(&ctx); BN_CTX_init(&ctx);
tmp= &(ctx.bn[ctx.tos++]); BN_CTX_start(&ctx);
tmp = BN_CTX_get(&ctx);
if (dh->priv_key == NULL) if (dh->priv_key == NULL)
{ {
...@@ -184,6 +185,7 @@ static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh) ...@@ -184,6 +185,7 @@ static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh)
ret=BN_bn2bin(tmp,key); ret=BN_bn2bin(tmp,key);
err: err:
BN_CTX_end(&ctx);
BN_CTX_free(&ctx); BN_CTX_free(&ctx);
return(ret); return(ret);
} }
......
...@@ -116,14 +116,15 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, ...@@ -116,14 +116,15 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
if ((mont=BN_MONT_CTX_new()) == NULL) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
r0= &(ctx2->bn[0]); BN_CTX_start(ctx2);
g= &(ctx2->bn[1]); r0 = BN_CTX_get(ctx2);
W= &(ctx2->bn[2]); g = BN_CTX_get(ctx2);
q= &(ctx2->bn[3]); W = BN_CTX_get(ctx2);
X= &(ctx2->bn[4]); q = BN_CTX_get(ctx2);
c= &(ctx2->bn[5]); X = BN_CTX_get(ctx2);
p= &(ctx2->bn[6]); c = BN_CTX_get(ctx2);
test= &(ctx2->bn[7]); p = BN_CTX_get(ctx2);
test = BN_CTX_get(ctx2);
BN_lshift(test,BN_value_one(),bits-1); BN_lshift(test,BN_value_one(),bits-1);
...@@ -168,8 +169,6 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, ...@@ -168,8 +169,6 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
/* step 4 */ /* step 4 */
r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random); r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random);
if (ctx3->tos)
goto err;
if (r > 0) if (r > 0)
break; break;
if (r != 0) if (r != 0)
...@@ -283,7 +282,11 @@ err: ...@@ -283,7 +282,11 @@ err:
if (h_ret != NULL) *h_ret=h; if (h_ret != NULL) *h_ret=h;
} }
if (ctx != NULL) BN_CTX_free(ctx); if (ctx != NULL) BN_CTX_free(ctx);
if (ctx2 != NULL) BN_CTX_free(ctx2); if (ctx2 != NULL)
{
BN_CTX_end(ctx2);
BN_CTX_free(ctx2);
}
if (ctx3 != NULL) BN_CTX_free(ctx3); if (ctx3 != NULL) BN_CTX_free(ctx3);
if (mont != NULL) BN_MONT_CTX_free(mont); if (mont != NULL) BN_MONT_CTX_free(mont);
return(ok?ret:NULL); return(ok?ret:NULL);
......
...@@ -74,11 +74,12 @@ RSA *RSA_generate_key(int bits, unsigned long e_value, ...@@ -74,11 +74,12 @@ RSA *RSA_generate_key(int bits, unsigned long e_value,
if (ctx == NULL) goto err; if (ctx == NULL) goto err;
ctx2=BN_CTX_new(); ctx2=BN_CTX_new();
if (ctx2 == NULL) goto err; if (ctx2 == NULL) goto err;
r0= &(ctx->bn[0]); BN_CTX_start(ctx);
r1= &(ctx->bn[1]); r0 = BN_CTX_get(ctx);
r2= &(ctx->bn[2]); r1 = BN_CTX_get(ctx);
r3= &(ctx->bn[3]); r2 = BN_CTX_get(ctx);
ctx->tos+=4; r3 = BN_CTX_get(ctx);
if (r3 == NULL) goto err;
bitsp=(bits+1)/2; bitsp=(bits+1)/2;
bitsq=bits-bitsp; bitsq=bits-bitsp;
...@@ -181,6 +182,7 @@ err: ...@@ -181,6 +182,7 @@ err:
RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN); RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN);
ok=0; ok=0;
} }
BN_CTX_end(ctx);
BN_CTX_free(ctx); BN_CTX_free(ctx);
BN_CTX_free(ctx2); BN_CTX_free(ctx2);
......
...@@ -269,19 +269,19 @@ int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx) ...@@ -269,19 +269,19 @@ int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
if (rsa->blinding != NULL) if (rsa->blinding != NULL)
BN_BLINDING_free(rsa->blinding); BN_BLINDING_free(rsa->blinding);
A= &(ctx->bn[0]); BN_CTX_start(ctx);
ctx->tos++; A = BN_CTX_get(ctx);
if (!BN_rand(A,BN_num_bits(rsa->n)-1,1,0)) goto err; if (!BN_rand(A,BN_num_bits(rsa->n)-1,1,0)) goto err;
if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
goto err; goto err;
rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n); rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n);
ctx->tos--;
rsa->flags|=RSA_FLAG_BLINDING; rsa->flags|=RSA_FLAG_BLINDING;
BN_free(Ai); BN_free(Ai);
ret=1; ret=1;
err: err:
BN_CTX_end(ctx);
if (ctx != p_ctx) BN_CTX_free(ctx); if (ctx != p_ctx) BN_CTX_free(ctx);
return(ret); return(ret);
} }
......
...@@ -38,7 +38,8 @@ BN_CTX_init() and BN_CTX_free() have no return values. ...@@ -38,7 +38,8 @@ BN_CTX_init() and BN_CTX_free() have no return values.
=head1 SEE ALSO =head1 SEE ALSO
L<bn(3)|bn(3)>, L<err(3)|err(3)>, L<BN_add(3)|BN_add(3)> L<bn(3)|bn(3)>, L<err(3)|err(3)>, L<BN_add(3)|BN_add(3)>,
L<BN_CTX_start(3)|BN_CTX_start(3)>
=head1 HISTORY =head1 HISTORY
......
=pod
=head1 NAME
BN_CTX_start, BN_CTX_get, BN_CTX_end - use temporary BIGNUM variables
=head1 SYNOPSIS
#include <openssl/bn.h>
void BN_CTX_start(BN_CTX *ctx);
BIGNUM *BN_CTX_get(BN_CTX *ctx);
void BN_CTX_end(BN_CTX *ctx);
=head1 DESCRIPTION
These functions are used to obtain temporary B<BIGNUM> variables from
a B<BN_CTX> in order to save the overhead of repeatedly creating and
freeing B<BIGNUM>s in functions that are called from inside a loop.
A function must call BN_CTX_start() first. Then, BN_CTX_get() may be
called repeatedly to obtain temporary B<BIGNUM>s. All BN_CTX_get()
calls must be made before calling any other functions that use the
B<ctx> as an argument.
Finally, BN_CTX_end() must be called before returning from the function.
When BN_CTX_end() is called, the B<BIGNUM> pointers obtained from
BN_CTX_get() become invalid.
=head1 RETURN VALUES
BN_CTX_start() and BN_CTX_end() return no values.
BN_CTX_get() returns a pointer to the B<BIGNUM>, or B<NULL> on error.
Once BN_CTX_get() has failed, the subsequent calls will return B<NULL>
as well, so it is sufficient to check the return value of the last
BN_CTX_get() call.
=head1 SEE ALSO
L<BN_CTX_new(3)|BN_CTX_new(3)>
=head1 HISTORY
BN_CTX_start(), BN_CTX_get() and BN_CTX_end() were added in OpenSSL 0.9.5.
=cut
...@@ -40,6 +40,7 @@ B<r> may be the same B<BIGNUM> as B<a> or B<b>. ...@@ -40,6 +40,7 @@ B<r> may be the same B<BIGNUM> as B<a> or B<b>.
BN_sub() subtracts B<b> from B<a> and places the result in B<r> (C<r=a-b>). BN_sub() subtracts B<b> from B<a> and places the result in B<r> (C<r=a-b>).
BN_mul() multiplies B<a> and B<b> and places the result in B<r> (C<r=a*b>). BN_mul() multiplies B<a> and B<b> and places the result in B<r> (C<r=a*b>).
B<r> may be the same B<BIGNUM> as B<a> or B<b>.
For multiplication by powers of 2, use L<BN_lshift(3)|BN_lshift(3)>. For multiplication by powers of 2, use L<BN_lshift(3)|BN_lshift(3)>.
BN_div() divides B<a> by B<d> and places the result in B<dv> and the BN_div() divides B<a> by B<d> and places the result in B<dv> and the
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册