diff options
Diffstat (limited to 'lib/libcrypto/bn/bn_ctx.c')
-rw-r--r-- | lib/libcrypto/bn/bn_ctx.c | 315 |
1 files changed, 166 insertions, 149 deletions
diff --git a/lib/libcrypto/bn/bn_ctx.c b/lib/libcrypto/bn/bn_ctx.c index ef67f4781cc..7407dade505 100644 --- a/lib/libcrypto/bn/bn_ctx.c +++ b/lib/libcrypto/bn/bn_ctx.c @@ -8,7 +8,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 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 @@ -88,21 +88,21 @@ /***********/ /* A bundle of bignums that can be linked with other bundles */ -typedef struct bignum_pool_item - { +typedef struct bignum_pool_item { /* The bignum values */ BIGNUM vals[BN_CTX_POOL_SIZE]; /* Linked-list admin */ struct bignum_pool_item *prev, *next; - } BN_POOL_ITEM; +} BN_POOL_ITEM; + /* A linked-list of bignums grouped in bundles */ -typedef struct bignum_pool - { +typedef struct bignum_pool { /* Linked-list admin */ BN_POOL_ITEM *head, *current, *tail; /* Stack depth and allocation size */ unsigned used, size; - } BN_POOL; +} BN_POOL; + static void BN_POOL_init(BN_POOL *); static void BN_POOL_finish(BN_POOL *); #ifndef OPENSSL_NO_DEPRECATED @@ -116,13 +116,13 @@ static void BN_POOL_release(BN_POOL *, unsigned int); /************/ /* A wrapper to manage the "stack frames" */ -typedef struct bignum_ctx_stack - { +typedef struct bignum_ctx_stack { /* Array of indexes into the bignum stack */ unsigned int *indexes; /* Number of stack frames, and the size of the allocated array */ unsigned int depth, size; - } BN_STACK; +} BN_STACK; + static void BN_STACK_init(BN_STACK *); static void BN_STACK_finish(BN_STACK *); #ifndef OPENSSL_NO_DEPRECATED @@ -136,8 +136,7 @@ static unsigned int BN_STACK_pop(BN_STACK *); /**********/ /* The opaque BN_CTX type */ -struct bignum_ctx - { +struct bignum_ctx { /* The bignum bundles */ BN_POOL pool; /* The "stack frames", if you will */ @@ -148,36 +147,38 @@ struct bignum_ctx int err_stack; /* Block "gets" until an "end" (compatibility behaviour) */ int too_many; - }; +}; /* Enable this to find BN_CTX bugs */ #ifdef BN_CTX_DEBUG static const char *ctxdbg_cur = NULL; -static void ctxdbg(BN_CTX *ctx) - { + +static void +ctxdbg(BN_CTX *ctx) +{ unsigned int bnidx = 0, fpidx = 0; BN_POOL_ITEM *item = ctx->pool.head; BN_STACK *stack = &ctx->stack; - fprintf(stderr,"(%08x): ", (unsigned int)ctx); - while(bnidx < ctx->used) - { - fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); - if(!(bnidx % BN_CTX_POOL_SIZE)) + + fprintf(stderr, "(%08x): ", (unsigned int)ctx); + while (bnidx < ctx->used) { + fprintf(stderr, "%03x ", + item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); + if (!(bnidx % BN_CTX_POOL_SIZE)) item = item->next; - } - fprintf(stderr,"\n"); + } + fprintf(stderr, "\n"); bnidx = 0; - fprintf(stderr," : "); - while(fpidx < stack->depth) - { - while(bnidx++ < stack->indexes[fpidx]) - fprintf(stderr," "); - fprintf(stderr,"^^^ "); + fprintf(stderr, " : "); + while (fpidx < stack->depth) { + while (bnidx++ < stack->indexes[fpidx]) + fprintf(stderr, " "); + fprintf(stderr, "^^^ "); bnidx++; fpidx++; - } - fprintf(stderr,"\n"); } + fprintf(stderr, "\n"); +} #define CTXDBG_ENTRY(str, ctx) do { \ ctxdbg_cur = (str); \ fprintf(stderr,"Starting %s\n", ctxdbg_cur); \ @@ -197,8 +198,9 @@ static void ctxdbg(BN_CTX *ctx) /* This function is an evil legacy and should not be used. This implementation * is WYSIWYG, though I've done my best. */ #ifndef OPENSSL_NO_DEPRECATED -void BN_CTX_init(BN_CTX *ctx) - { +void +BN_CTX_init(BN_CTX *ctx) +{ /* Assume the caller obtained the context via BN_CTX_new() and so is * trying to reset it for use. Nothing else makes sense, least of all * binary compatibility from a time when they could declare a static @@ -208,17 +210,18 @@ void BN_CTX_init(BN_CTX *ctx) ctx->used = 0; ctx->err_stack = 0; ctx->too_many = 0; - } +} #endif -BN_CTX *BN_CTX_new(void) - { +BN_CTX * +BN_CTX_new(void) +{ BN_CTX *ret = malloc(sizeof(BN_CTX)); - if(!ret) - { - BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE); + if (!ret) { + BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE); return NULL; - } + } + /* Initialise the structure */ BN_POOL_init(&ret->pool); BN_STACK_init(&ret->stack); @@ -226,229 +229,243 @@ BN_CTX *BN_CTX_new(void) ret->err_stack = 0; ret->too_many = 0; return ret; - } +} -void BN_CTX_free(BN_CTX *ctx) - { +void +BN_CTX_free(BN_CTX *ctx) +{ if (ctx == NULL) return; #ifdef BN_CTX_DEBUG { - BN_POOL_ITEM *pool = ctx->pool.head; - fprintf(stderr,"BN_CTX_free, stack-size=%d, pool-bignums=%d\n", - ctx->stack.size, ctx->pool.size); - fprintf(stderr,"dmaxs: "); - while(pool) { - unsigned loop = 0; - while(loop < BN_CTX_POOL_SIZE) - fprintf(stderr,"%02x ", pool->vals[loop++].dmax); - pool = pool->next; - } - fprintf(stderr,"\n"); + BN_POOL_ITEM *pool = ctx->pool.head; + fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n", + ctx->stack.size, ctx->pool.size); + fprintf(stderr, "dmaxs: "); + while (pool) { + unsigned loop = 0; + while (loop < BN_CTX_POOL_SIZE) + fprintf(stderr, "%02x ", + pool->vals[loop++].dmax); + pool = pool->next; + } + fprintf(stderr, "\n"); } #endif BN_STACK_finish(&ctx->stack); BN_POOL_finish(&ctx->pool); free(ctx); - } +} -void BN_CTX_start(BN_CTX *ctx) - { +void +BN_CTX_start(BN_CTX *ctx) +{ CTXDBG_ENTRY("BN_CTX_start", ctx); + /* If we're already overflowing ... */ - if(ctx->err_stack || ctx->too_many) + if (ctx->err_stack || ctx->too_many) ctx->err_stack++; /* (Try to) get a new frame pointer */ - else if(!BN_STACK_push(&ctx->stack, ctx->used)) - { - BNerr(BN_F_BN_CTX_START,BN_R_TOO_MANY_TEMPORARY_VARIABLES); + else if (!BN_STACK_push(&ctx->stack, ctx->used)) { + BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES); ctx->err_stack++; - } - CTXDBG_EXIT(ctx); } + CTXDBG_EXIT(ctx); +} -void BN_CTX_end(BN_CTX *ctx) - { +void +BN_CTX_end(BN_CTX *ctx) +{ CTXDBG_ENTRY("BN_CTX_end", ctx); - if(ctx->err_stack) + + if (ctx->err_stack) ctx->err_stack--; - else - { + else { unsigned int fp = BN_STACK_pop(&ctx->stack); /* Does this stack frame have anything to release? */ - if(fp < ctx->used) + if (fp < ctx->used) BN_POOL_release(&ctx->pool, ctx->used - fp); ctx->used = fp; /* Unjam "too_many" in case "get" had failed */ ctx->too_many = 0; - } - CTXDBG_EXIT(ctx); } + CTXDBG_EXIT(ctx); +} -BIGNUM *BN_CTX_get(BN_CTX *ctx) - { +BIGNUM * +BN_CTX_get(BN_CTX *ctx) +{ BIGNUM *ret; + CTXDBG_ENTRY("BN_CTX_get", ctx); - if(ctx->err_stack || ctx->too_many) return NULL; - if((ret = BN_POOL_get(&ctx->pool)) == NULL) - { + + if (ctx->err_stack || ctx->too_many) + return NULL; + if ((ret = BN_POOL_get(&ctx->pool)) == NULL) { /* Setting too_many prevents repeated "get" attempts from * cluttering the error stack. */ ctx->too_many = 1; - BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES); + BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES); return NULL; - } + } /* OK, make sure the returned bignum is "zero" */ BN_zero(ret); ctx->used++; CTXDBG_RET(ctx, ret); return ret; - } +} /************/ /* BN_STACK */ /************/ -static void BN_STACK_init(BN_STACK *st) - { +static void +BN_STACK_init(BN_STACK *st) +{ st->indexes = NULL; st->depth = st->size = 0; - } +} -static void BN_STACK_finish(BN_STACK *st) - { - if(st->size) free(st->indexes); - } +static void +BN_STACK_finish(BN_STACK *st) +{ + if (st->size) + free(st->indexes); +} #ifndef OPENSSL_NO_DEPRECATED -static void BN_STACK_reset(BN_STACK *st) - { +static void +BN_STACK_reset(BN_STACK *st) +{ st->depth = 0; - } +} #endif -static int BN_STACK_push(BN_STACK *st, unsigned int idx) - { - if(st->depth == st->size) +static int +BN_STACK_push(BN_STACK *st, unsigned int idx) +{ + if (st->depth == st->size) /* Need to expand */ - { + { unsigned int newsize = (st->size ? - (st->size * 3 / 2) : BN_CTX_START_FRAMES); + (st->size * 3 / 2) : BN_CTX_START_FRAMES); unsigned int *newitems = malloc(newsize * - sizeof(unsigned int)); - if(!newitems) return 0; - if(st->depth) + sizeof(unsigned int)); + if (!newitems) + return 0; + if (st->depth) memcpy(newitems, st->indexes, st->depth * - sizeof(unsigned int)); - if(st->size) free(st->indexes); + sizeof(unsigned int)); + if (st->size) + free(st->indexes); st->indexes = newitems; st->size = newsize; - } + } st->indexes[(st->depth)++] = idx; return 1; - } +} -static unsigned int BN_STACK_pop(BN_STACK *st) - { +static unsigned int +BN_STACK_pop(BN_STACK *st) +{ return st->indexes[--(st->depth)]; - } +} /***********/ /* BN_POOL */ /***********/ -static void BN_POOL_init(BN_POOL *p) - { +static void +BN_POOL_init(BN_POOL *p) +{ p->head = p->current = p->tail = NULL; p->used = p->size = 0; - } +} -static void BN_POOL_finish(BN_POOL *p) - { - while(p->head) - { +static void +BN_POOL_finish(BN_POOL *p) +{ + while (p->head) { unsigned int loop = 0; BIGNUM *bn = p->head->vals; - while(loop++ < BN_CTX_POOL_SIZE) - { - if(bn->d) BN_clear_free(bn); + while (loop++ < BN_CTX_POOL_SIZE) { + if (bn->d) + BN_clear_free(bn); bn++; - } + } p->current = p->head->next; free(p->head); p->head = p->current; - } } +} #ifndef OPENSSL_NO_DEPRECATED -static void BN_POOL_reset(BN_POOL *p) - { +static void +BN_POOL_reset(BN_POOL *p) +{ BN_POOL_ITEM *item = p->head; - while(item) - { + while (item) { unsigned int loop = 0; BIGNUM *bn = item->vals; - while(loop++ < BN_CTX_POOL_SIZE) - { - if(bn->d) BN_clear(bn); + while (loop++ < BN_CTX_POOL_SIZE) { + if (bn->d) + BN_clear(bn); bn++; - } - item = item->next; } + item = item->next; + } p->current = p->head; p->used = 0; - } +} #endif -static BIGNUM *BN_POOL_get(BN_POOL *p) - { - if(p->used == p->size) - { +static BIGNUM * +BN_POOL_get(BN_POOL *p) +{ + if (p->used == p->size) { BIGNUM *bn; unsigned int loop = 0; BN_POOL_ITEM *item = malloc(sizeof(BN_POOL_ITEM)); - if(!item) return NULL; + if (!item) + return NULL; /* Initialise the structure */ bn = item->vals; - while(loop++ < BN_CTX_POOL_SIZE) + while (loop++ < BN_CTX_POOL_SIZE) BN_init(bn++); item->prev = p->tail; item->next = NULL; /* Link it in */ - if(!p->head) + if (!p->head) p->head = p->current = p->tail = item; - else - { + else { p->tail->next = item; p->tail = item; p->current = item; - } + } p->size += BN_CTX_POOL_SIZE; p->used++; /* Return the first bignum from the new pool */ return item->vals; - } - if(!p->used) + } + if (!p->used) p->current = p->head; - else if((p->used % BN_CTX_POOL_SIZE) == 0) + else if ((p->used % BN_CTX_POOL_SIZE) == 0) p->current = p->current->next; return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE); - } +} -static void BN_POOL_release(BN_POOL *p, unsigned int num) - { +static void +BN_POOL_release(BN_POOL *p, unsigned int num) +{ unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE; + p->used -= num; - while(num--) - { + while (num--) { bn_check_top(p->current->vals + offset); - if(!offset) - { + if (!offset) { offset = BN_CTX_POOL_SIZE - 1; p->current = p->current->prev; - } - else + } else offset--; - } } - +} |