1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/bn/bn_ctx.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Written by Ulf Moeller for the OpenSSL project. */
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1998-2004 The OpenSSL Project.  All rights reserved.
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@openssl.org.
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef NDEBUG
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define NDEBUG
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <assert.h>
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "bn_lcl.h"
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* TODO list
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * check they can be safely removed.
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  - Check +1 and other ugliness in BN_from_montgomery()
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * appropriate 'block' size that will be honoured by bn_expand_internal() to
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prevent piddly little reallocations. OTOH, profiling bignum expansions in
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * BN_CTX doesn't show this to be a big issue.
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* How many bignums are in each "pool item"; */
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define BN_CTX_POOL_SIZE	16
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The stack frame info is resizing, set a first-time expansion size; */
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define BN_CTX_START_FRAMES	32
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/***********/
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BN_POOL */
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/***********/
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* A bundle of bignums that can be linked with other bundles */
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct bignum_pool_item
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* The bignum values */
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM vals[BN_CTX_POOL_SIZE];
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Linked-list admin */
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bignum_pool_item *prev, *next;
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} BN_POOL_ITEM;
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* A linked-list of bignums grouped in bundles */
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct bignum_pool
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Linked-list admin */
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_POOL_ITEM *head, *current, *tail;
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Stack depth and allocation size */
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned used, size;
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} BN_POOL;
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void		BN_POOL_init(BN_POOL *);
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void		BN_POOL_finish(BN_POOL *);
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DEPRECATED
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void		BN_POOL_reset(BN_POOL *);
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIGNUM *		BN_POOL_get(BN_POOL *);
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void		BN_POOL_release(BN_POOL *, unsigned int);
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/************/
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BN_STACK */
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/************/
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* A wrapper to manage the "stack frames" */
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct bignum_ctx_stack
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Array of indexes into the bignum stack */
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int *indexes;
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Number of stack frames, and the size of the allocated array */
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int depth, size;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} BN_STACK;
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void		BN_STACK_init(BN_STACK *);
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void		BN_STACK_finish(BN_STACK *);
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DEPRECATED
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void		BN_STACK_reset(BN_STACK *);
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int		BN_STACK_push(BN_STACK *, unsigned int);
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic unsigned int	BN_STACK_pop(BN_STACK *);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/**********/
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BN_CTX */
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/**********/
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The opaque BN_CTX type */
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct bignum_ctx
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* The bignum bundles */
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_POOL pool;
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* The "stack frames", if you will */
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_STACK stack;
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* The number of bignums currently assigned */
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int used;
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Depth of stack overflow */
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int err_stack;
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Block "gets" until an "end" (compatibility behaviour) */
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int too_many;
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Enable this to find BN_CTX bugs */
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef BN_CTX_DEBUG
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic const char *ctxdbg_cur = NULL;
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void ctxdbg(BN_CTX *ctx)
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int bnidx = 0, fpidx = 0;
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_POOL_ITEM *item = ctx->pool.head;
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_STACK *stack = &ctx->stack;
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"(%08x): ", (unsigned int)ctx);
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(bnidx < ctx->used)
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!(bnidx % BN_CTX_POOL_SIZE))
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			item = item->next;
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"\n");
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bnidx = 0;
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"          : ");
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(fpidx < stack->depth)
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(bnidx++ < stack->indexes[fpidx])
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			fprintf(stderr,"    ");
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		fprintf(stderr,"^^^ ");
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bnidx++;
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fpidx++;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"\n");
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define CTXDBG_ENTRY(str, ctx)	do { \
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctxdbg_cur = (str); \
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctxdbg(ctx); \
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				} while(0)
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define CTXDBG_EXIT(ctx)	do { \
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctxdbg(ctx); \
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				} while(0)
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define CTXDBG_RET(ctx,ret)
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define CTXDBG_ENTRY(str, ctx)
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define CTXDBG_EXIT(ctx)
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define CTXDBG_RET(ctx,ret)
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This function is an evil legacy and should not be used. This implementation
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * is WYSIWYG, though I've done my best. */
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DEPRECATED
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_CTX_init(BN_CTX *ctx)
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Assume the caller obtained the context via BN_CTX_new() and so is
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * trying to reset it for use. Nothing else makes sense, least of all
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * binary compatibility from a time when they could declare a static
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * variable. */
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_POOL_reset(&ctx->pool);
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_STACK_reset(&ctx->stack);
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->used = 0;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->err_stack = 0;
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->too_many = 0;
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBN_CTX *BN_CTX_new(void)
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ret)
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Initialise the structure */
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_POOL_init(&ret->pool);
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_STACK_init(&ret->stack);
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret->used = 0;
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret->err_stack = 0;
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret->too_many = 0;
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_CTX_free(BN_CTX *ctx)
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx == NULL)
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef BN_CTX_DEBUG
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_POOL_ITEM *pool = ctx->pool.head;
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->stack.size, ctx->pool.size);
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"dmaxs: ");
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(pool) {
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned loop = 0;
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(loop < BN_CTX_POOL_SIZE)
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fprintf(stderr,"%02x ", pool->vals[loop++].dmax);
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pool = pool->next;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"\n");
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_STACK_finish(&ctx->stack);
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_POOL_finish(&ctx->pool);
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(ctx);
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_CTX_start(BN_CTX *ctx)
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CTXDBG_ENTRY("BN_CTX_start", ctx);
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If we're already overflowing ... */
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ctx->err_stack || ctx->too_many)
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->err_stack++;
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* (Try to) get a new frame pointer */
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if(!BN_STACK_push(&ctx->stack, ctx->used))
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BNerr(BN_F_BN_CTX_START,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->err_stack++;
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CTXDBG_EXIT(ctx);
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_CTX_end(BN_CTX *ctx)
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CTXDBG_ENTRY("BN_CTX_end", ctx);
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ctx->err_stack)
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->err_stack--;
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned int fp = BN_STACK_pop(&ctx->stack);
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Does this stack frame have anything to release? */
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(fp < ctx->used)
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BN_POOL_release(&ctx->pool, ctx->used - fp);
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->used = fp;
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Unjam "too_many" in case "get" had failed */
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->too_many = 0;
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CTXDBG_EXIT(ctx);
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIGNUM *BN_CTX_get(BN_CTX *ctx)
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM *ret;
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CTXDBG_ENTRY("BN_CTX_get", ctx);
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ctx->err_stack || ctx->too_many) return NULL;
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((ret = BN_POOL_get(&ctx->pool)) == NULL)
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Setting too_many prevents repeated "get" attempts from
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * cluttering the error stack. */
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->too_many = 1;
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* OK, make sure the returned bignum is "zero" */
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_zero(ret);
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->used++;
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CTXDBG_RET(ctx, ret);
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/************/
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BN_STACK */
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/************/
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void BN_STACK_init(BN_STACK *st)
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	st->indexes = NULL;
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	st->depth = st->size = 0;
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void BN_STACK_finish(BN_STACK *st)
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(st->size) OPENSSL_free(st->indexes);
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DEPRECATED
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void BN_STACK_reset(BN_STACK *st)
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	st->depth = 0;
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int BN_STACK_push(BN_STACK *st, unsigned int idx)
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(st->depth == st->size)
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Need to expand */
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned int newsize = (st->size ?
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(st->size * 3 / 2) : BN_CTX_START_FRAMES);
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned int *newitems = OPENSSL_malloc(newsize *
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						sizeof(unsigned int));
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!newitems) return 0;
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(st->depth)
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(newitems, st->indexes, st->depth *
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						sizeof(unsigned int));
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(st->size) OPENSSL_free(st->indexes);
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		st->indexes = newitems;
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		st->size = newsize;
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	st->indexes[(st->depth)++] = idx;
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic unsigned int BN_STACK_pop(BN_STACK *st)
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return st->indexes[--(st->depth)];
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/***********/
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BN_POOL */
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/***********/
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void BN_POOL_init(BN_POOL *p)
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p->head = p->current = p->tail = NULL;
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p->used = p->size = 0;
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void BN_POOL_finish(BN_POOL *p)
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(p->head)
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned int loop = 0;
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIGNUM *bn = p->head->vals;
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(loop++ < BN_CTX_POOL_SIZE)
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(bn->d) BN_clear_free(bn);
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			bn++;
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p->current = p->head->next;
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(p->head);
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p->head = p->current;
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DEPRECATED
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void BN_POOL_reset(BN_POOL *p)
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_POOL_ITEM *item = p->head;
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(item)
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned int loop = 0;
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIGNUM *bn = item->vals;
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(loop++ < BN_CTX_POOL_SIZE)
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(bn->d) BN_clear(bn);
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			bn++;
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		item = item->next;
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p->current = p->head;
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p->used = 0;
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIGNUM *BN_POOL_get(BN_POOL *p)
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(p->used == p->size)
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIGNUM *bn;
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned int loop = 0;
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM));
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!item) return NULL;
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Initialise the structure */
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bn = item->vals;
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(loop++ < BN_CTX_POOL_SIZE)
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BN_init(bn++);
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		item->prev = p->tail;
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		item->next = NULL;
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Link it in */
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!p->head)
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p->head = p->current = p->tail = item;
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p->tail->next = item;
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p->tail = item;
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p->current = item;
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p->size += BN_CTX_POOL_SIZE;
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p->used++;
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Return the first bignum from the new pool */
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return item->vals;
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!p->used)
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p->current = p->head;
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if((p->used % BN_CTX_POOL_SIZE) == 0)
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p->current = p->current->next;
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void BN_POOL_release(BN_POOL *p, unsigned int num)
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p->used -= num;
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(num--)
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bn_check_top(p->current->vals + offset);
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!offset)
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			offset = BN_CTX_POOL_SIZE - 1;
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p->current = p->current->prev;
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			offset--;
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
455