New functions BN_CTX_start(), BN_CTX_get(), BN_CTX_end() to access
authorUlf Möller <ulf@openssl.org>
Sat, 5 Feb 2000 14:17:32 +0000 (14:17 +0000)
committerUlf Möller <ulf@openssl.org>
Sat, 5 Feb 2000 14:17:32 +0000 (14:17 +0000)
temporary BIGNUMs. BN_CTX still uses a fixed number of BIGNUMs, but
the BN_CTX implementation could now easily be changed.

24 files changed:
CHANGES
crypto/bn/Makefile.ssl
crypto/bn/bn.h
crypto/bn/bn_ctx.c [new file with mode: 0644]
crypto/bn/bn_div.c
crypto/bn/bn_err.c
crypto/bn/bn_exp.c
crypto/bn/bn_exp2.c
crypto/bn/bn_gcd.c
crypto/bn/bn_lib.c
crypto/bn/bn_mont.c
crypto/bn/bn_mul.c
crypto/bn/bn_prime.c
crypto/bn/bn_recp.c
crypto/bn/bn_sqr.c
crypto/bn/old/bn_wmul.c
crypto/dh/dh_gen.c
crypto/dh/dh_key.c
crypto/dsa/dsa_gen.c
crypto/rsa/rsa_gen.c
crypto/rsa/rsa_lib.c
doc/crypto/BN_CTX_new.pod
doc/crypto/BN_CTX_start.pod [new file with mode: 0644]
doc/crypto/BN_add.pod

diff --git a/CHANGES b/CHANGES
index eab6eca939f17bb0909570709cb8f1acf4027de7..5480029ca3537c9db14bc8f6ef503e154c823844 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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
index 3427f9fa351d0edd4141e429e252951648fea951..94da20bd5a1b8f74607ca191306021621a90a644 100644 (file)
@@ -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
index 63606e1ac5519808dad78e196c0fa736c9a434e8..8ac8acd1165b7ae7f73db7d557e1ac2bb23db2ed 100644 (file)
@@ -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
 }
diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c
new file mode 100644 (file)
index 0000000..8b079e2
--- /dev/null
@@ -0,0 +1,123 @@
+/* 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];
+       }
index 39d7602c30f9b43e57e5aaeeec1010f72523139a..3505221a9667c2f1200ecf61d4aba32c3b83ef62 100644 (file)
 #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
index 73e80774e57b96e7de467c4c48e8addd6caed722..de3aaeb03419f94f434b76bac7e84f46dfa21f63 100644 (file)
@@ -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}
        };
 
index 2df1614ada17047acfcf0affab26d39169903a0c..8593ed0f392448be4fa96f8c4d7f0cba156fe4f4 100644 (file)
@@ -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);
index 2d7bf8997d48631174f3e1e3854e56f0369c03c6..4f4e9e329989d5b415bba73dd14eda0a245e7f83 100644 (file)
@@ -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++)
index 64a76f4498965b0e912eece66863edead0e46d27..398207196be841403cc5c2b3caf36e9c7cb8e9a4 100644 (file)
@@ -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);
        }
 
index e7349099680a28a845c02a6fb2b427974b35bd3d..8c62761d4c1ce90744188e76caa5abc5eeb43b3b 100644 (file)
@@ -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,
index dd691112c2f77cacfc30c0ea2057dc920d53f2db..35a30a0eeb4b9f00a241b784ae7a638adb7e12b0 100644 (file)
@@ -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);
        }
 
index 54414993db6f279fca0adfd6b940bb340ea807bb..36e9c4d9ffeae93f7bf0adedff317504eca4913b 100644 (file)
@@ -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)
index 25bafd1f9c85558bb3e44a71c4ed42de7afa4104..a5f01b92eb2f21ef1be2b6c91d0263cd84b13027 100644 (file)
@@ -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);
        }
index c1b0e230ea270193be9633a14c35e548dfec85e3..e1919e3ce68586a863603bc5a57a09c90022ec08 100644 (file)
@@ -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);
        } 
 
index 1874c14628a2199186438d9cf4a30e46af998458..fe00c5f69a01025918a5b06e271cfb52f269e415 100644 (file)
 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 */
index a467b2f17aa29a34464244c536bb5956c7844d91..3b484adf70ca852248bbe23f323addbc32ec04ee 100644 (file)
@@ -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);
        }
index f0ee43ed8708338ae0766583916de6613ab4a8eb..7a6a38fbb4849368beeff620a3611f9d0e6c60ef 100644 (file)
@@ -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);
index 4e6a0fc0ef35a6ac6ee4c5797181b4b05a3f753e..0c7eeaf260b359e8a017cf7249f53bab239f80f0 100644 (file)
@@ -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);
        }
index 65602dda77a399d314a8b86bde68fb392304c01f..2294a362d9954419cf92bd3d4176ce33ce8210d0 100644 (file)
@@ -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);
index 3ed6edd6a175d80938d4d98eba5f8a4ed6c082a2..95e636d3f0233e3148e13c545d626539e5ccc8a7 100644 (file)
@@ -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);
        
index c6b1a5989d988ecc70229b2c0dcbfccb5d7f29f7..074a4f5074b44e4b8aab81ef7cd9ced2bffd5ebd 100644 (file)
@@ -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);
        }
index 37a188e3c3d643def02fb846c28dd4b6f275f55a..2a02da03b9930689b8a1c89398169d55b4c7439a 100644 (file)
@@ -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
 
diff --git a/doc/crypto/BN_CTX_start.pod b/doc/crypto/BN_CTX_start.pod
new file mode 100644 (file)
index 0000000..3e10323
--- /dev/null
@@ -0,0 +1,49 @@
+=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
index 2f6a3b448f6fbdbbed0547b3047178edb9ea1d2b..e4230851e48686ab4550b63c77177ec85bc2e7ff 100644 (file)
@@ -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