提交 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 @@
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
include a #define from the old name to the new. The original intent
was that statically linked binaries could for example just call
......
......@@ -34,12 +34,12 @@ TEST=bntest.c exptest.c
APPS=
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_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
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_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
......
......@@ -245,6 +245,8 @@ typedef struct bignum_ctx
int tos;
BIGNUM bn[BN_CTX_NUM+1];
int flags;
int depth;
int pos[BN_CTX_NUM+1];
} BN_CTX;
typedef struct bn_blinding_st
......@@ -335,6 +337,9 @@ char * BN_options(void);
BN_CTX *BN_CTX_new(void);
void BN_CTX_init(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_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
int BN_num_bits(const BIGNUM *a);
......@@ -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_BN2DEC 104
#define BN_F_BN_BN2HEX 105
#define BN_F_BN_CTX_GET 116
#define BN_F_BN_CTX_NEW 106
#define BN_F_BN_DIV 107
#define BN_F_BN_EXPAND2 108
......@@ -484,6 +490,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
#define BN_R_INVALID_LENGTH 106
#define BN_R_NOT_INITIALIZED 107
#define BN_R_NO_INVERSE 108
#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109
#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 @@
#include "bn_lcl.h"
/* The old slow way */
#if 0
#if 1
int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
BN_CTX *ctx)
{
int i,nm,nd;
int ret = 0;
BIGNUM *D;
bn_check_top(m);
......@@ -85,14 +86,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
return(1);
}
D= &(ctx->bn[ctx->tos]);
if (dv == NULL) dv= &(ctx->bn[ctx->tos+1]);
if (rem == NULL) rem= &(ctx->bn[ctx->tos+2]);
BN_CTX_start(ctx);
D = BN_CTX_get(ctx);
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);
nm=BN_num_bits(m);
if (BN_copy(D,d) == NULL) return(0);
if (BN_copy(rem,m) == NULL) return(0);
if (BN_copy(D,d) == NULL) goto end;
if (BN_copy(rem,m) == NULL) goto end;
/* 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 :-) */
......@@ -100,21 +104,24 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
bn_wexpand(dv,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--)
{
if (!BN_lshift1(dv,dv)) return(0);
if (!BN_lshift1(dv,dv)) goto end;
if (BN_ucmp(rem,D) >= 0)
{
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 :=) */
if (!BN_rshift1(D,D)) return(0);
if (!BN_rshift1(D,D)) goto end;
}
rem->neg=BN_is_zero(rem)?0:m->neg;
dv->neg=m->neg^d->neg;
return(1);
ret = 1;
end:
BN_CTX_end(ctx);
return(ret);
}
#else
......@@ -145,13 +152,15 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
return(1);
}
tmp= &(ctx->bn[ctx->tos]);
BN_CTX_start(ctx);
tmp=BN_CTX_get(ctx);
tmp->neg=0;
snum= &(ctx->bn[ctx->tos+1]);
sdiv= &(ctx->bn[ctx->tos+2]);
snum=BN_CTX_get(ctx);
sdiv=BN_CTX_get(ctx);
if (dv == NULL)
res= &(ctx->bn[ctx->tos+3]);
res=BN_CTX_get(ctx);
else res=dv;
if (res == NULL) goto err;
/* First we normalise the numbers */
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,
BN_rshift(rm,snum,norm_shift);
rm->neg=num->neg;
}
BN_CTX_end(ctx);
return(1);
err:
BN_CX_end(ctx);
return(0);
}
......@@ -346,22 +357,27 @@ int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
if (BN_ucmp(m,d) < 0)
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);
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--)
{
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);
err:
BN_CTX_end(ctx);
return(0);
#else
return(BN_div(NULL,rem,m,d,ctx));
#endif
......
......@@ -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_BN2DEC,0), "BN_bn2dec"},
{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_DIV,0), "BN_div"},
{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"},
......@@ -95,6 +96,7 @@ static ERR_STRING_DATA BN_str_reasons[]=
{BN_R_INVALID_LENGTH ,"invalid length"},
{BN_R_NOT_INITIALIZED ,"not initialized"},
{BN_R_NO_INVERSE ,"no inverse"},
{BN_R_TOO_MANY_TEMPORARY_VARIABLES ,"too many temporary variables"},
{0,NULL}
};
......
......@@ -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(m);
t= &(ctx->bn[ctx->tos++]);
BN_CTX_start(ctx);
if ((t = BN_CTX_get(ctx)) == NULL) goto err;
if (a == b)
{ if (!BN_sqr(t,a,ctx)) goto err; }
else
......@@ -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;
r=1;
err:
ctx->tos--;
BN_CTX_end(ctx);
return(r);
}
......@@ -91,8 +92,10 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
int i,bits,ret=0;
BIGNUM *v,*tmp;
v= &(ctx->bn[ctx->tos++]);
tmp= &(ctx->bn[ctx->tos++]);
BN_CTX_start(ctx);
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;
bits=BN_num_bits(p);
......@@ -113,7 +116,7 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
}
ret=1;
err:
ctx->tos-=2;
BN_CTX_end(ctx);
return(ret);
}
......@@ -122,15 +125,15 @@ err:
/* this one works - simple but works */
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;
tos=ctx->tos;
v= &(ctx->bn[ctx->tos++]);
BN_CTX_start(ctx);
if ((r == a) || (r == p))
rr= &(ctx->bn[ctx->tos++]);
rr = BN_CTX_get(ctx);
else
rr=r;
rr = r;
if ((v = BN_CTX_get(ctx)) == NULL) goto err;
if (BN_copy(v,a) == NULL) goto err;
bits=BN_num_bits(p);
......@@ -149,8 +152,8 @@ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
}
ret=1;
err:
ctx->tos=tos;
if (r != rr) BN_copy(r,rr);
BN_CTX_end(ctx);
return(ret);
}
......@@ -193,7 +196,6 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BIGNUM val[TABLE_SIZE];
BN_RECP_CTX recp;
aa= &(ctx->bn[ctx->tos++]);
bits=BN_num_bits(p);
if (bits == 0)
......@@ -201,6 +203,10 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BN_one(r);
return(1);
}
BN_CTX_start(ctx);
if ((aa = BN_CTX_get(ctx)) == NULL) goto err;
BN_RECP_CTX_init(&recp);
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,
}
ret=1;
err:
ctx->tos--;
BN_CTX_end(ctx);
for (i=0; i<ts; i++)
BN_clear_free(&(val[i]));
BN_RECP_CTX_free(&recp);
......@@ -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);
return(0);
}
d= &(ctx->bn[ctx->tos++]);
r= &(ctx->bn[ctx->tos++]);
bits=BN_num_bits(p);
if (bits == 0)
{
BN_one(r);
BN_one(rr);
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
* part */
......@@ -432,7 +440,7 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
ret=1;
err:
if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
ctx->tos-=2;
BN_CTX_end(ctx);
for (i=0; i<ts; i++)
BN_clear_free(&(val[i]));
return(ret);
......@@ -448,7 +456,6 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
BIGNUM *d;
BIGNUM val[TABLE_SIZE];
d= &(ctx->bn[ctx->tos++]);
bits=BN_num_bits(p);
if (bits == 0)
......@@ -457,6 +464,9 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
return(1);
}
BN_CTX_start(ctx);
if ((d = BN_CTX_get(ctx)) == NULL) goto err;
BN_init(&(val[0]));
ts=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,
}
ret=1;
err:
ctx->tos--;
BN_CTX_end(ctx);
for (i=0; i<ts; i++)
BN_clear_free(&(val[i]));
return(ret);
......
......@@ -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);
return(0);
}
d= &(ctx->bn[ctx->tos++]);
r= &(ctx->bn[ctx->tos++]);
bits1=BN_num_bits(p1);
bits2=BN_num_bits(p2);
if ((bits1 == 0) && (bits2 == 0))
{
BN_one(r);
BN_one(rr);
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;
/* 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,
ret=1;
err:
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 (j=0; j<ts; j++)
......
......@@ -61,6 +61,7 @@
#include "bn_lcl.h"
static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx)
{
BIGNUM *a,*b,*t;
......@@ -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_b);
a= &(ctx->bn[ctx->tos]);
b= &(ctx->bn[ctx->tos+1]);
BN_CTX_start(ctx);
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(b,in_b) == NULL) goto err;
......@@ -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;
ret=1;
err:
BN_CTX_end(ctx);
return(ret);
}
......@@ -142,20 +146,22 @@ err:
/* solves ax == 1 (mod n) */
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;
int sign;
bn_check_top(a);
bn_check_top(n);
A= &(ctx->bn[ctx->tos]);
B= &(ctx->bn[ctx->tos+1]);
X= &(ctx->bn[ctx->tos+2]);
D= &(ctx->bn[ctx->tos+3]);
M= &(ctx->bn[ctx->tos+4]);
Y= &(ctx->bn[ctx->tos+5]);
ctx->tos+=6;
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
D = BN_CTX_get(ctx);
M = BN_CTX_get(ctx);
Y = BN_CTX_get(ctx);
if (Y == NULL) goto err;
if (in == NULL)
R=BN_new();
else
......@@ -198,7 +204,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
ret=R;
err:
if ((ret == NULL) && (in == NULL)) BN_free(R);
ctx->tos-=6;
BN_CTX_end(ctx);
return(ret);
}
......@@ -304,43 +304,6 @@ BIGNUM *BN_new(void)
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.
* 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,
......
......@@ -72,9 +72,10 @@ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
{
BIGNUM *tmp,*tmp2;
tmp= &(ctx->bn[ctx->tos]);
tmp2= &(ctx->bn[ctx->tos]);
ctx->tos+=2;
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
tmp2 = BN_CTX_get(ctx);
if (tmp == NULL || tmp2 == NULL) goto err;
bn_check_top(tmp);
bn_check_top(tmp2);
......@@ -98,16 +99,20 @@ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
}
/* reduce from aRR to aR */
if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
ctx->tos-=2;
BN_CTX_end(ctx);
return(1);
err:
return(0);
}
#define BN_RECURSION_MONT
int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
BN_CTX *ctx)
{
int retn=0;
BN_CTX_start(ctx);
#ifdef BN_RECURSION_MONT
if (mont->use_word)
#endif
......@@ -116,7 +121,7 @@ int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
BN_ULONG *ap,*np,*rp,n0,v,*nrp;
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;
n= &(mont->N);
......@@ -210,9 +215,9 @@ printf("word BN_from_montgomery %d * %d\n",nl,nl);
{
BIGNUM *t1,*t2;
t1=&(ctx->bn[ctx->tos]);
t2=&(ctx->bn[ctx->tos+1]);
ctx->tos+=2;
t1 = BN_CTX_get(ctx);
t2 = BN_CTX_get(ctx);
if (t1 == NULL || t2 == NULL) goto err;
if (!BN_copy(t1,a)) goto err;
BN_mask_bits(t1,mont->ri);
......@@ -226,11 +231,11 @@ printf("word BN_from_montgomery %d * %d\n",nl,nl);
if (BN_ucmp(ret,&mont->N) >= 0)
BN_usub(ret,ret,&mont->N);
ctx->tos-=2;
retn=1;
}
#endif
err:
BN_CTX_end(ctx);
return(retn);
}
......
......@@ -585,10 +585,13 @@ printf("BN_mul %d * %d\n",a->top,b->top);
}
top=al+bl;
BN_CTX_start(ctx);
if ((r == a) || (r == b))
rr= &(ctx->bn[ctx->tos+1]);
{
if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
}
else
rr=r;
rr = r;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
if (al == bl)
......@@ -596,14 +599,14 @@ printf("BN_mul %d * %d\n",a->top,b->top);
# ifdef BN_MUL_COMBA
/* if (al == 4)
{
if (bn_wexpand(rr,8) == NULL) return(0);
if (bn_wexpand(rr,8) == NULL) goto err;
rr->top=8;
bn_mul_comba4(rr->d,a->d,b->d);
goto end;
}
else */ if (al == 8)
{
if (bn_wexpand(rr,16) == NULL) return(0);
if (bn_wexpand(rr,16) == NULL) goto err;
rr->top=16;
bn_mul_comba8(rr->d,a->d,b->d);
goto end;
......@@ -614,7 +617,7 @@ printf("BN_mul %d * %d\n",a->top,b->top);
if (al < BN_MULL_SIZE_NORMAL)
#endif
{
if (bn_wexpand(rr,top) == NULL) return(0);
if (bn_wexpand(rr,top) == NULL) goto err;
rr->top=top;
bn_mul_normal(rr->d,a->d,al,b->d,bl);
goto end;
......@@ -627,7 +630,7 @@ printf("BN_mul %d * %d\n",a->top,b->top);
#ifdef BN_RECURSION
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;
bn_mul_normal(rr->d,a->d,al,b->d,bl);
goto end;
......@@ -653,7 +656,7 @@ printf("BN_mul %d * %d\n",a->top,b->top);
#endif
/* asymmetric and >= 4 */
if (bn_wexpand(rr,top) == NULL) return(0);
if (bn_wexpand(rr,top) == NULL) goto err;
rr->top=top;
bn_mul_normal(rr->d,a->d,al,b->d,bl);
......@@ -666,7 +669,7 @@ symmetric:
j=BN_num_bits_word((BN_ULONG)al);
j=1<<(j-1);
k=j+j;
t= &(ctx->bn[ctx->tos]);
t = BN_CTX_get(ctx);
if (al == j) /* exact multiple */
{
bn_wexpand(t,k*2);
......@@ -693,7 +696,11 @@ end:
#endif
bn_fix_top(rr);
if (r != rr) BN_copy(r,rr);
BN_CTX_end(ctx);
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)
......
......@@ -244,19 +244,23 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
else
if ((ctx=BN_CTX_new()) == NULL)
goto err;
BN_CTX_start(ctx);
/* A := abs(a) */
if (a->neg)
{
BIGNUM *t = &(ctx->bn[ctx->tos++]);
BIGNUM *t;
if ((t = BN_CTX_get(ctx)) == NULL) goto err;
BN_copy(t, a);
t->neg = 0;
A = t;
}
else
A = a;
A1 = &(ctx->bn[ctx->tos++]);
A1_odd = &(ctx->bn[ctx->tos++]);
check = &(ctx->bn[ctx->tos++]);;
A1 = BN_CTX_get(ctx);
A1_odd = BN_CTX_get(ctx);
check = BN_CTX_get(ctx);
if (check == NULL) goto err;
/* compute A1 := A - 1 */
if (!BN_copy(A1, A))
......@@ -305,14 +309,12 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
}
ret=1;
err:
if (ctx_passed != NULL)
if (ctx != NULL)
{
ctx_passed->tos -= 3; /* A1, A1_odd, check */
if (a != A)
--ctx_passed->tos; /* A */
BN_CTX_end(ctx);
if (ctx_passed == NULL)
BN_CTX_free(ctx);
}
else if (ctx != NULL)
BN_CTX_free(ctx);
if (mont != NULL)
BN_MONT_CTX_free(mont);
......@@ -380,7 +382,8 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
int i,ret=0;
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;
......@@ -406,7 +409,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
}
ret=1;
err:
ctx->tos--;
BN_CTX_end(ctx);
return(ret);
}
......@@ -414,12 +417,14 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd,
BIGNUM *rem, BN_CTX *ctx)
{
int i,ret=0;
BIGNUM *t1,*qadd=NULL,*q=NULL;
BIGNUM *t1,*qadd,*q;
bits--;
t1= &(ctx->bn[ctx->tos++]);
q= &(ctx->bn[ctx->tos++]);
qadd= &(ctx->bn[ctx->tos++]);
BN_CTX_start(ctx);
t1 = BN_CTX_get(ctx);
q = BN_CTX_get(ctx);
qadd = BN_CTX_get(ctx);
if (qadd == NULL) 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,
}
ret=1;
err:
ctx->tos-=3;
BN_CTX_end(ctx);
return(ret);
}
......@@ -106,7 +106,8 @@ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,
int ret=0;
BIGNUM *a;
a= &(ctx->bn[ctx->tos++]);
BN_CTX_start(ctx);
if ((a = BN_CTX_get(ctx)) == NULL) goto err;
if (y != NULL)
{
if (x == y)
......@@ -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);
ret=1;
err:
ctx->tos--;
BN_CTX_end(ctx);
return(ret);
}
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp,
BN_CTX *ctx)
{
int i,j,tos,ret=0,ex;
int i,j,ret=0,ex;
BIGNUM *a,*b,*d,*r;
tos=ctx->tos;
a= &(ctx->bn[ctx->tos++]);
b= &(ctx->bn[ctx->tos++]);
BN_CTX_start(ctx);
a=BN_CTX_get(ctx);
b=BN_CTX_get(ctx);
if (dv != NULL)
d=dv;
else
d= &(ctx->bn[ctx->tos++]);
d=BN_CTX_get(ctx);
if (rem != NULL)
r=rem;
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)
{
BN_zero(d);
BN_copy(r,m);
ctx->tos=tos;
BN_CTX_end(ctx);
return(1);
}
......@@ -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;
ret=1;
err:
ctx->tos=tos;
BN_CTX_end(ctx);
return(ret);
}
......
......@@ -65,14 +65,13 @@
int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx)
{
int max,al;
int ret = 0;
BIGNUM *tmp,*rr;
#ifdef BN_COUNT
printf("BN_sqr %d * %d\n",a->top,a->top);
#endif
bn_check_top(a);
tmp= &(ctx->bn[ctx->tos]);
rr=(a != r)?r: (&ctx->bn[ctx->tos+1]);
al=a->top;
if (al <= 0)
......@@ -81,8 +80,13 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
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);
if (bn_wexpand(rr,max+1) == NULL) return(0);
if (bn_wexpand(rr,max+1) == NULL) goto err;
r->neg=0;
if (al == 4)
......@@ -120,18 +124,18 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
k=j+j;
if (al == j)
{
if (bn_wexpand(a,k*2) == NULL) return(0);
if (bn_wexpand(tmp,k*2) == NULL) return(0);
if (bn_wexpand(a,k*2) == NULL) goto err;
if (bn_wexpand(tmp,k*2) == NULL) goto err;
bn_sqr_recursive(rr->d,a->d,al,tmp->d);
}
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);
}
}
#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);
#endif
}
......@@ -139,7 +143,10 @@ printf("BN_sqr %d * %d\n",a->top,a->top);
rr->top=max;
if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
if (rr != r) BN_copy(r,rr);
return(1);
ret = 1;
err:
BN_CTX_end(ctx);
return(ret);
}
/* tmp must have 2*n words */
......
......@@ -17,6 +17,7 @@ printf("bn_mull %d * %d\n",a->top,b->top);
bn_check_top(a);
bn_check_top(b);
bn_check_top(r);
BN_CTX_start(ctx);
al=a->top;
bl=b->top;
......@@ -85,7 +86,7 @@ symetric:
j=BN_num_bits_word((BN_ULONG)al);
j=1<<(j-1);
k=j+j;
t= &(ctx->bn[ctx->tos]);
t = BN_CTX_get(ctx);
if (al == j) /* exact multiple */
{
bn_wexpand(t,k*2);
......@@ -107,6 +108,7 @@ symetric:
r->top=top;
}
end:
BN_CTX_end(ctx);
bn_fix_top(r);
return(1);
}
......
......@@ -95,9 +95,10 @@ DH *DH_generate_parameters(int prime_len, int generator,
if (ret == NULL) goto err;
ctx=BN_CTX_new();
if (ctx == NULL) goto err;
t1= &(ctx->bn[0]);
t2= &(ctx->bn[1]);
ctx->tos=2;
BN_CTX_start(ctx);
t1 = BN_CTX_get(ctx);
t2 = BN_CTX_get(ctx);
if (t1 == NULL || t2 == NULL) goto err;
if (generator == DH_GENERATOR_2)
{
......@@ -138,7 +139,11 @@ err:
ok=0;
}
if (ctx != NULL) BN_CTX_free(ctx);
if (ctx != NULL)
{
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (!ok && (ret != NULL))
{
DH_free(ret);
......
......@@ -161,7 +161,8 @@ static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh)
int ret= -1;
BN_CTX_init(&ctx);
tmp= &(ctx.bn[ctx.tos++]);
BN_CTX_start(&ctx);
tmp = BN_CTX_get(&ctx);
if (dh->priv_key == NULL)
{
......@@ -184,6 +185,7 @@ static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh)
ret=BN_bn2bin(tmp,key);
err:
BN_CTX_end(&ctx);
BN_CTX_free(&ctx);
return(ret);
}
......
......@@ -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;
r0= &(ctx2->bn[0]);
g= &(ctx2->bn[1]);
W= &(ctx2->bn[2]);
q= &(ctx2->bn[3]);
X= &(ctx2->bn[4]);
c= &(ctx2->bn[5]);
p= &(ctx2->bn[6]);
test= &(ctx2->bn[7]);
BN_CTX_start(ctx2);
r0 = BN_CTX_get(ctx2);
g = BN_CTX_get(ctx2);
W = BN_CTX_get(ctx2);
q = BN_CTX_get(ctx2);
X = BN_CTX_get(ctx2);
c = BN_CTX_get(ctx2);
p = BN_CTX_get(ctx2);
test = BN_CTX_get(ctx2);
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,
/* step 4 */
r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random);
if (ctx3->tos)
goto err;
if (r > 0)
break;
if (r != 0)
......@@ -283,7 +282,11 @@ err:
if (h_ret != NULL) *h_ret=h;
}
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 (mont != NULL) BN_MONT_CTX_free(mont);
return(ok?ret:NULL);
......
......@@ -74,11 +74,12 @@ RSA *RSA_generate_key(int bits, unsigned long e_value,
if (ctx == NULL) goto err;
ctx2=BN_CTX_new();
if (ctx2 == NULL) goto err;
r0= &(ctx->bn[0]);
r1= &(ctx->bn[1]);
r2= &(ctx->bn[2]);
r3= &(ctx->bn[3]);
ctx->tos+=4;
BN_CTX_start(ctx);
r0 = BN_CTX_get(ctx);
r1 = BN_CTX_get(ctx);
r2 = BN_CTX_get(ctx);
r3 = BN_CTX_get(ctx);
if (r3 == NULL) goto err;
bitsp=(bits+1)/2;
bitsq=bits-bitsp;
......@@ -181,6 +182,7 @@ err:
RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN);
ok=0;
}
BN_CTX_end(ctx);
BN_CTX_free(ctx);
BN_CTX_free(ctx2);
......
......@@ -269,19 +269,19 @@ int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
if (rsa->blinding != NULL)
BN_BLINDING_free(rsa->blinding);
A= &(ctx->bn[0]);
ctx->tos++;
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
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 (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
goto err;
rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n);
ctx->tos--;
rsa->flags|=RSA_FLAG_BLINDING;
BN_free(Ai);
ret=1;
err:
BN_CTX_end(ctx);
if (ctx != p_ctx) BN_CTX_free(ctx);
return(ret);
}
......
......@@ -38,7 +38,8 @@ BN_CTX_init() and BN_CTX_free() have no return values.
=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
......
=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>.
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>).
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)>.
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.
先完成此消息的编辑!
想要评论请 注册