+ /* 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);
+ 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)
+ {
+ st->indexes = NULL;
+ st->depth = st->size = 0;
+ }
+
+static void BN_STACK_finish(BN_STACK *st)
+ {
+ if(st->size) OPENSSL_free(st->indexes);
+ }
+
+#ifndef OPENSSL_NO_DEPRECATED
+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)
+ /* Need to expand */
+ {
+ unsigned int newsize = (st->size ?
+ (st->size * 3 / 2) : BN_CTX_START_FRAMES);
+ unsigned int *newitems = OPENSSL_malloc(newsize *
+ sizeof(unsigned int));
+ if(!newitems) return 0;
+ if(st->depth)
+ memcpy(newitems, st->indexes, st->depth *
+ sizeof(unsigned int));
+ if(st->size) OPENSSL_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)
+ {
+ return st->indexes[--(st->depth)];
+ }
+
+/***********/
+/* BN_POOL */
+/***********/
+
+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)
+ {
+ unsigned int loop = 0;
+ BIGNUM *bn = p->head->vals;
+ while(loop++ < BN_CTX_POOL_SIZE)