1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/lhash.h>
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "eng_int.h"
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The type of the items in the table */
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct st_engine_pile
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* The 'nid' of this algorithm/mode */
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int nid;
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* ENGINEs that implement this algorithm/mode. */
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(ENGINE) *sk;
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* The default ENGINE to perform this algorithm/mode. */
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *funct;
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int uptodate;
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} ENGINE_PILE;
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_LHASH_OF(ENGINE_PILE);
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The type exposed in eng_int.h */
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct st_engine_table
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ENGINE_PILE) piles;
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}; /* ENGINE_TABLE */
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromtypedef struct st_engine_pile_doall
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	engine_table_doall_cb *cb;
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void *arg;
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} ENGINE_PILE_DOALL;
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Global flags (ENGINE_TABLE_FLAG_***). */
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic unsigned int table_flags = 0;
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* API function manipulating 'table_flags' */
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned int ENGINE_get_table_flags(void)
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return table_flags;
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ENGINE_set_table_flags(unsigned int flags)
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	table_flags = flags;
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Internal functions for the "piles" hash table */
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic unsigned long engine_pile_hash(const ENGINE_PILE *c)
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return c->nid;
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return a->nid - b->nid;
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_table_check(ENGINE_TABLE **t, int create)
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ENGINE_PILE) *lh;
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(*t) return 1;
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!create) return 0;
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if((lh = lh_ENGINE_PILE_new()) == NULL)
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*t = (ENGINE_TABLE *)lh;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Privately exposed (via eng_int.h) functions for adding and/or removing
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ENGINEs from the implementation table */
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINE *e, const int *nids, int num_nids, int setdefault)
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 0, added = 0;
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE_PILE tmplate, *fnd;
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!(*table))
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		added = 1;
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!int_table_check(table, 1))
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(added)
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* The cleanup callback needs to be added */
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_cleanup_add_first(cleanup);
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(num_nids--)
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		tmplate.nid = *nids;
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!fnd)
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(!fnd) goto end;
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fnd->uptodate = 1;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fnd->nid = *nids;
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fnd->sk = sk_ENGINE_new_null();
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(!fnd->sk)
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				OPENSSL_free(fnd);
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto end;
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fnd->funct = NULL;
160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			(void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* A registration shouldn't add duplciate entries */
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(void)sk_ENGINE_delete_ptr(fnd->sk, e);
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* if 'setdefault', this ENGINE goes to the head of the list */
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!sk_ENGINE_push(fnd->sk, e))
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto end;
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* "touch" this ENGINE_PILE */
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fnd->uptodate = 0;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(setdefault)
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(!engine_unlocked_init(e))
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						ENGINE_R_INIT_FAILED);
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto end;
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(fnd->funct)
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				engine_unlocked_finish(fnd->funct, 0);
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fnd->funct = e;
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fnd->uptodate = 1;
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nids++;
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = 1;
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectend:
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int n;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Iterate the 'c->sk' stack removing any occurance of 'e' */
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(void)sk_ENGINE_delete(pile->sk, n);
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pile->uptodate = 0;
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(pile->funct == e)
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_unlocked_finish(e, 0);
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pile->funct = NULL;
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(int_table_check(table, 0))
210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		lh_ENGINE_PILE_doall_arg(&(*table)->piles,
211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					 LHASH_DOALL_ARG_FN(int_unregister_cb),
212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					 ENGINE, e);
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_cleanup_cb_doall(ENGINE_PILE *p)
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sk_ENGINE_free(p->sk);
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(p->funct)
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_unlocked_finish(p->funct, 0);
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(p);
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid engine_table_cleanup(ENGINE_TABLE **table)
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(*table)
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		lh_ENGINE_PILE_doall(&(*table)->piles,
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				     LHASH_DOALL_FN(int_cleanup_cb));
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		lh_ENGINE_PILE_free(&(*table)->piles);
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*table = NULL;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* return a functional reference for a given 'nid' */
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef ENGINE_TABLE_DEBUG
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *ret = NULL;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE_PILE tmplate, *fnd=NULL;
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int initres, loop = 0;
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!(*table))
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ENGINE_TABLE_DEBUG
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			"registered!\n", f, l, nid);
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
25798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	ERR_set_mark();
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Check again inside the lock otherwise we could race against cleanup
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * operations. But don't worry about a fprintf(stderr). */
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!int_table_check(table, 0)) goto end;
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tmplate.nid = nid;
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!fnd) goto end;
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(fnd->funct && engine_unlocked_init(fnd->funct))
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ENGINE_TABLE_DEBUG
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			"ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = fnd->funct;
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(fnd->uptodate)
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = fnd->funct;
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttrynext:
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = sk_ENGINE_value(fnd->sk, loop++);
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ret)
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ENGINE_TABLE_DEBUG
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				"registered implementations would initialise\n",
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				f, l, nid);
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Try to initialise the ENGINE? */
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		initres = engine_unlocked_init(ret);
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		initres = 0;
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(initres)
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Update 'funct' */
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if((fnd->funct != ret) && engine_unlocked_init(ret))
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* If there was a previous default we release it. */
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(fnd->funct)
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				engine_unlocked_finish(fnd->funct, 0);
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fnd->funct = ret;
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ENGINE_TABLE_DEBUG
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				"setting default to '%s'\n", f, l, nid, ret->id);
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ENGINE_TABLE_DEBUG
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				"newly initialised '%s'\n", f, l, nid, ret->id);
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	goto trynext;
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectend:
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If it failed, it is unlikely to succeed again until some future
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * registrations have taken place. In all cases, we cache. */
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(fnd) fnd->uptodate = 1;
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ENGINE_TABLE_DEBUG
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret)
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				"ENGINE '%s'\n", f, l, nid, ret->id);
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				"'no matching ENGINE'\n", f, l, nid);
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Whatever happened, any failed init()s are not failures in this
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * context, so clear our error state. */
33198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	ERR_pop_to_mark();
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Table enumeration */
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom								void *arg)
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ENGINE_PILE_DOALL dall;
347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dall.cb = cb;
348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dall.arg = arg;
349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				 ENGINE_PILE_DOALL, &dall);
351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
352