*
*/
+#ifndef BN_CTX_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
#include <stdio.h>
#include <assert.h>
#include "cryptlib.h"
{
BN_CTX *ret;
- ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
+ ret=(BN_CTX *)OPENSSL_malloc(sizeof(BN_CTX));
if (ret == NULL)
{
BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
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]));
}
for (i=0; i < BN_CTX_NUM; i++)
BN_clear_free(&(ctx->bn[i]));
if (ctx->flags & BN_FLG_MALLOCED)
- Free(ctx);
+ OPENSSL_free(ctx);
}
void BN_CTX_start(BN_CTX *ctx)
{
- ctx->pos[ctx->depth++] = ctx->tos;
+ if (ctx->depth < BN_CTX_NUM_POS)
+ ctx->pos[ctx->depth] = ctx->tos;
+ ctx->depth++;
}
+
BIGNUM *BN_CTX_get(BN_CTX *ctx)
{
- if (ctx->tos >= BN_CTX_NUM)
+ /* 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)
{
- BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ if (!ctx->too_many)
+ {
+ BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ /* disable error code until BN_CTX_end is called: */
+ ctx->too_many = 1;
+ }
return NULL;
}
return (&(ctx->bn[ctx->tos++]));
{
if (ctx == NULL) return;
assert(ctx->depth > 0);
+ if (ctx->depth == 0)
+ /* should never happen, but we can tolerate it if not in
+ * debug mode (could be a 'goto err' in the calling function
+ * before BN_CTX_start was reached) */
+ BN_CTX_start(ctx);
+
+ ctx->too_many = 0;
ctx->depth--;
- ctx->tos = ctx->pos[ctx->depth];
+ if (ctx->depth < BN_CTX_NUM_POS)
+ ctx->tos = ctx->pos[ctx->depth];
}