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