1/*
2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19/* crypto/bn/bn_ctx.c */
20/* Written by Ulf Moeller for the OpenSSL project. */
21/* ====================================================================
22 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 *
28 * 1. Redistributions of source code must retain the above copyright
29 *    notice, this list of conditions and the following disclaimer.
30 *
31 * 2. Redistributions in binary form must reproduce the above copyright
32 *    notice, this list of conditions and the following disclaimer in
33 *    the documentation and/or other materials provided with the
34 *    distribution.
35 *
36 * 3. All advertising materials mentioning features or use of this
37 *    software must display the following acknowledgment:
38 *    "This product includes software developed by the OpenSSL Project
39 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
40 *
41 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
42 *    endorse or promote products derived from this software without
43 *    prior written permission. For written permission, please contact
44 *    openssl-core@openssl.org.
45 *
46 * 5. Products derived from this software may not be called "OpenSSL"
47 *    nor may "OpenSSL" appear in their names without prior written
48 *    permission of the OpenSSL Project.
49 *
50 * 6. Redistributions of any form whatsoever must retain the following
51 *    acknowledgment:
52 *    "This product includes software developed by the OpenSSL Project
53 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
56 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
59 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
60 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
61 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
66 * OF THE POSSIBILITY OF SUCH DAMAGE.
67 * ====================================================================
68 *
69 * This product includes cryptographic software written by Eric Young
70 * (eay@cryptsoft.com).  This product includes software written by Tim
71 * Hudson (tjh@cryptsoft.com).
72 *
73 */
74
75#ifndef BN_CTX_DEBUG
76# undef NDEBUG /* avoid conflicting definitions */
77# define NDEBUG
78#endif
79
80#include <stdio.h>
81#include <assert.h>
82#include "cryptlib.h"
83#include <openssl/bn.h>
84
85
86BN_CTX *BN_CTX_new(void)
87	{
88	BN_CTX *ret;
89
90	ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
91	if (ret == NULL)
92		{
93		BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
94		return(NULL);
95		}
96
97	BN_CTX_init(ret);
98	ret->flags=BN_FLG_MALLOCED;
99	return(ret);
100	}
101
102void BN_CTX_init(BN_CTX *ctx)
103	{
104	int i;
105	ctx->tos = 0;
106	ctx->flags = 0;
107	ctx->depth = 0;
108	ctx->too_many = 0;
109	for (i = 0; i < BN_CTX_NUM; i++)
110		BN_init(&(ctx->bn[i]));
111	}
112
113void BN_CTX_free(BN_CTX *ctx)
114	{
115	int i;
116
117	if (ctx == NULL) return;
118	assert(ctx->depth == 0);
119
120	for (i=0; i < BN_CTX_NUM; i++)
121		BN_clear_free(&(ctx->bn[i]));
122	if (ctx->flags & BN_FLG_MALLOCED)
123		Free(ctx);
124	}
125
126void BN_CTX_start(BN_CTX *ctx)
127	{
128	if (ctx->depth < BN_CTX_NUM_POS)
129		ctx->pos[ctx->depth] = ctx->tos;
130	ctx->depth++;
131	}
132
133BIGNUM *BN_CTX_get(BN_CTX *ctx)
134	{
135	if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM)
136		{
137		if (!ctx->too_many)
138			{
139			BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
140			/* disable error code until BN_CTX_end is called: */
141			ctx->too_many = 1;
142			}
143		return NULL;
144		}
145	return (&(ctx->bn[ctx->tos++]));
146	}
147
148void BN_CTX_end(BN_CTX *ctx)
149	{
150	if (ctx == NULL) return;
151	assert(ctx->depth > 0);
152	if (ctx->depth == 0)
153		/* should never happen, but we can tolerate it if not in
154		 * debug mode (could be a 'goto err' in the calling function
155		 * before BN_CTX_start was reached) */
156		BN_CTX_start(ctx);
157
158	ctx->too_many = 0;
159	ctx->depth--;
160	if (ctx->depth < BN_CTX_NUM_POS)
161		ctx->tos = ctx->pos[ctx->depth];
162	}
163