More changes coming out of the bignum auditing. BN_CTX_get() should ideally
[openssl.git] / crypto / bn / bn_ctx.c
index b1a8d7571e83a23389ea0c2c8d6c34d9df72b55a..9366ce6d7f2a8165bbbeabfd975bfbce6dda7398 100644 (file)
  *
  */
 
-#ifndef BN_CTX_DEBUG
-# undef NDEBUG /* avoid conflicting definitions */
-# define NDEBUG
+#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
+#ifndef NDEBUG
+#define NDEBUG
+#endif
 #endif
 
 #include <stdio.h>
 #include <assert.h>
+
 #include "cryptlib.h"
-#include <openssl/bn.h>
+#include "bn_lcl.h"
+
+/* BN_CTX structure details */
+#define BN_CTX_NUM     32
+#define BN_CTX_NUM_POS 12
+struct bignum_ctx
+       {
+       int tos;
+       BIGNUM bn[BN_CTX_NUM];
+       int flags;
+       int depth;
+       int pos[BN_CTX_NUM_POS];
+       int too_many;
+       };
 
+#ifndef OPENSSL_NO_DEPRECATED
+void BN_CTX_init(BN_CTX *ctx)
+#else
+static void BN_CTX_init(BN_CTX *ctx)
+#endif
+       {
+#if 0 /* explicit version */
+       int i;
+       ctx->tos = 0;
+       ctx->flags = 0;
+       ctx->depth = 0;
+       ctx->too_many = 0;
+       for (i = 0; i < BN_CTX_NUM; i++)
+               BN_init(&(ctx->bn[i]));
+#else
+       memset(ctx, 0, sizeof *ctx);
+#endif
+       }
 
 BN_CTX *BN_CTX_new(void)
        {
@@ -81,17 +114,6 @@ BN_CTX *BN_CTX_new(void)
        return(ret);
        }
 
-void BN_CTX_init(BN_CTX *ctx)
-       {
-       int i;
-       ctx->tos = 0;
-       ctx->flags = 0;
-       ctx->depth = 0;
-       ctx->too_many = 0;
-       for (i = 0; i < BN_CTX_NUM; i++)
-               BN_init(&(ctx->bn[i]));
-       }
-
 void BN_CTX_free(BN_CTX *ctx)
        {
        int i;
@@ -99,8 +121,11 @@ void BN_CTX_free(BN_CTX *ctx)
        if (ctx == NULL) return;
        assert(ctx->depth == 0);
 
-       for (i=0; i < BN_CTX_NUM; i++)
-               BN_clear_free(&(ctx->bn[i]));
+       for (i=0; i < BN_CTX_NUM; i++) {
+               bn_check_top(&(ctx->bn[i]));
+               if (ctx->bn[i].d)
+                       BN_clear_free(&(ctx->bn[i]));
+       }
        if (ctx->flags & BN_FLG_MALLOCED)
                OPENSSL_free(ctx);
        }
@@ -112,8 +137,14 @@ void BN_CTX_start(BN_CTX *ctx)
        ctx->depth++;
        }
 
+
 BIGNUM *BN_CTX_get(BN_CTX *ctx)
        {
+       /* Note: If BN_CTX_get is ever changed to allocate BIGNUMs dynamically,
+        * make sure that if BN_CTX_get fails once it will return NULL again
+        * until BN_CTX_end is called.  (This is so that callers have to check
+        * only the last return value.)
+        */
        if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM)
                {
                if (!ctx->too_many)
@@ -124,6 +155,8 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx)
                        }
                return NULL;
                }
+       /* always return a 'zeroed' bignum */
+       ctx->bn[ctx->tos].top = 0;
        return (&(ctx->bn[ctx->tos++]));
        }
 
@@ -140,5 +173,10 @@ void BN_CTX_end(BN_CTX *ctx)
        ctx->too_many = 0;
        ctx->depth--;
        if (ctx->depth < BN_CTX_NUM_POS)
+#ifndef BN_DEBUG
                ctx->tos = ctx->pos[ctx->depth];
+#else
+               while(ctx->tos > ctx->pos[ctx->depth])
+                       bn_check_top(&ctx->bn[--(ctx->tos)]);
+#endif
        }