1ebfedea0SLionel Sambuc /* ====================================================================
2ebfedea0SLionel Sambuc * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
3ebfedea0SLionel Sambuc *
4ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
5ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
6ebfedea0SLionel Sambuc * are met:
7ebfedea0SLionel Sambuc *
8ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
9ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
10ebfedea0SLionel Sambuc *
11ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
12ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in
13ebfedea0SLionel Sambuc * the documentation and/or other materials provided with the
14ebfedea0SLionel Sambuc * distribution.
15ebfedea0SLionel Sambuc *
16ebfedea0SLionel Sambuc * 3. All advertising materials mentioning features or use of this
17ebfedea0SLionel Sambuc * software must display the following acknowledgment:
18ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project
19ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20ebfedea0SLionel Sambuc *
21ebfedea0SLionel Sambuc * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22ebfedea0SLionel Sambuc * endorse or promote products derived from this software without
23ebfedea0SLionel Sambuc * prior written permission. For written permission, please contact
24ebfedea0SLionel Sambuc * licensing@OpenSSL.org.
25ebfedea0SLionel Sambuc *
26ebfedea0SLionel Sambuc * 5. Products derived from this software may not be called "OpenSSL"
27ebfedea0SLionel Sambuc * nor may "OpenSSL" appear in their names without prior written
28ebfedea0SLionel Sambuc * permission of the OpenSSL Project.
29ebfedea0SLionel Sambuc *
30ebfedea0SLionel Sambuc * 6. Redistributions of any form whatsoever must retain the following
31ebfedea0SLionel Sambuc * acknowledgment:
32ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project
33ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34ebfedea0SLionel Sambuc *
35ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36ebfedea0SLionel Sambuc * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38ebfedea0SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39ebfedea0SLionel Sambuc * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40ebfedea0SLionel Sambuc * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41ebfedea0SLionel Sambuc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42ebfedea0SLionel Sambuc * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44ebfedea0SLionel Sambuc * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45ebfedea0SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46ebfedea0SLionel Sambuc * OF THE POSSIBILITY OF SUCH DAMAGE.
47ebfedea0SLionel Sambuc * ====================================================================
48ebfedea0SLionel Sambuc *
49ebfedea0SLionel Sambuc * This product includes cryptographic software written by Eric Young
50ebfedea0SLionel Sambuc * (eay@cryptsoft.com). This product includes software written by Tim
51ebfedea0SLionel Sambuc * Hudson (tjh@cryptsoft.com).
52ebfedea0SLionel Sambuc *
53ebfedea0SLionel Sambuc */
54ebfedea0SLionel Sambuc
55ebfedea0SLionel Sambuc #include <stdio.h>
56ebfedea0SLionel Sambuc #include <openssl/bn.h>
57ebfedea0SLionel Sambuc #include <string.h>
58ebfedea0SLionel Sambuc
59ebfedea0SLionel Sambuc #include <openssl/e_os2.h>
60ebfedea0SLionel Sambuc #if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) || defined(__MINGW32__)
61ebfedea0SLionel Sambuc # include <sys/types.h>
62ebfedea0SLionel Sambuc # include <unistd.h>
63ebfedea0SLionel Sambuc #else
64ebfedea0SLionel Sambuc # include <process.h>
65ebfedea0SLionel Sambuc typedef int pid_t;
66ebfedea0SLionel Sambuc #endif
67ebfedea0SLionel Sambuc
68ebfedea0SLionel Sambuc #if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
69ebfedea0SLionel Sambuc # define getpid GetThreadID
70ebfedea0SLionel Sambuc extern int GetThreadID(void);
71ebfedea0SLionel Sambuc #elif defined(_WIN32) && !defined(__WATCOMC__)
72ebfedea0SLionel Sambuc # define getpid _getpid
73ebfedea0SLionel Sambuc #endif
74ebfedea0SLionel Sambuc
75ebfedea0SLionel Sambuc #include <openssl/crypto.h>
76ebfedea0SLionel Sambuc #include <openssl/dso.h>
77ebfedea0SLionel Sambuc #include <openssl/engine.h>
78ebfedea0SLionel Sambuc #include <openssl/buffer.h>
79ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_RSA
80ebfedea0SLionel Sambuc # include <openssl/rsa.h>
81ebfedea0SLionel Sambuc #endif
82ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_DSA
83ebfedea0SLionel Sambuc # include <openssl/dsa.h>
84ebfedea0SLionel Sambuc #endif
85ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_DH
86ebfedea0SLionel Sambuc # include <openssl/dh.h>
87ebfedea0SLionel Sambuc #endif
88ebfedea0SLionel Sambuc
89ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_HW
90ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_HW_AEP
91ebfedea0SLionel Sambuc # ifdef FLAT_INC
92ebfedea0SLionel Sambuc # include "aep.h"
93ebfedea0SLionel Sambuc # else
94ebfedea0SLionel Sambuc # include "vendor_defns/aep.h"
95ebfedea0SLionel Sambuc # endif
96ebfedea0SLionel Sambuc
97ebfedea0SLionel Sambuc # define AEP_LIB_NAME "aep engine"
98ebfedea0SLionel Sambuc # define FAIL_TO_SW 0x10101010
99ebfedea0SLionel Sambuc
100ebfedea0SLionel Sambuc # include "e_aep_err.c"
101ebfedea0SLionel Sambuc
102ebfedea0SLionel Sambuc static int aep_init(ENGINE *e);
103ebfedea0SLionel Sambuc static int aep_finish(ENGINE *e);
104ebfedea0SLionel Sambuc static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void));
105ebfedea0SLionel Sambuc static int aep_destroy(ENGINE *e);
106ebfedea0SLionel Sambuc
107ebfedea0SLionel Sambuc static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
108ebfedea0SLionel Sambuc static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
109ebfedea0SLionel Sambuc static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
110ebfedea0SLionel Sambuc static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
111ebfedea0SLionel Sambuc
112ebfedea0SLionel Sambuc /* BIGNUM stuff */
113ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
114ebfedea0SLionel Sambuc static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
115ebfedea0SLionel Sambuc const BIGNUM *m, BN_CTX *ctx);
116ebfedea0SLionel Sambuc
117ebfedea0SLionel Sambuc static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
118*0a6a1f1dSLionel Sambuc const BIGNUM *q, const BIGNUM *dmp1,
119*0a6a1f1dSLionel Sambuc const BIGNUM *dmq1, const BIGNUM *iqmp,
120*0a6a1f1dSLionel Sambuc BN_CTX *ctx);
121ebfedea0SLionel Sambuc # endif
122ebfedea0SLionel Sambuc
123ebfedea0SLionel Sambuc /* RSA stuff */
124ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
125*0a6a1f1dSLionel Sambuc static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
126*0a6a1f1dSLionel Sambuc BN_CTX *ctx);
127ebfedea0SLionel Sambuc # endif
128ebfedea0SLionel Sambuc
129ebfedea0SLionel Sambuc /* This function is aliased to mod_exp (with the mont stuff dropped). */
130ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
131ebfedea0SLionel Sambuc static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
132ebfedea0SLionel Sambuc const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
133ebfedea0SLionel Sambuc # endif
134ebfedea0SLionel Sambuc
135ebfedea0SLionel Sambuc /* DSA stuff */
136ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
137ebfedea0SLionel Sambuc static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
138ebfedea0SLionel Sambuc BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
139ebfedea0SLionel Sambuc BN_CTX *ctx, BN_MONT_CTX *in_mont);
140ebfedea0SLionel Sambuc
141ebfedea0SLionel Sambuc static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
142ebfedea0SLionel Sambuc const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
143ebfedea0SLionel Sambuc BN_MONT_CTX *m_ctx);
144ebfedea0SLionel Sambuc # endif
145ebfedea0SLionel Sambuc
146ebfedea0SLionel Sambuc /* DH stuff */
147ebfedea0SLionel Sambuc /* This function is aliased to mod_exp (with the DH and mont dropped). */
148ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
149ebfedea0SLionel Sambuc static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
150*0a6a1f1dSLionel Sambuc const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
151*0a6a1f1dSLionel Sambuc BN_MONT_CTX *m_ctx);
152ebfedea0SLionel Sambuc # endif
153ebfedea0SLionel Sambuc
154ebfedea0SLionel Sambuc /* rand stuff */
155ebfedea0SLionel Sambuc # ifdef AEPRAND
156ebfedea0SLionel Sambuc static int aep_rand(unsigned char *buf, int num);
157ebfedea0SLionel Sambuc static int aep_rand_status(void);
158ebfedea0SLionel Sambuc # endif
159ebfedea0SLionel Sambuc
160ebfedea0SLionel Sambuc /* Bignum conversion stuff */
161ebfedea0SLionel Sambuc static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32 *BigNumSize);
162ebfedea0SLionel Sambuc static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
163ebfedea0SLionel Sambuc unsigned char *AEP_BigNum);
164ebfedea0SLionel Sambuc static AEP_RV ConvertAEPBigNum(void *ArbBigNum, AEP_U32 BigNumSize,
165ebfedea0SLionel Sambuc unsigned char *AEP_BigNum);
166ebfedea0SLionel Sambuc
167ebfedea0SLionel Sambuc /* The definitions for control commands specific to this engine */
168ebfedea0SLionel Sambuc # define AEP_CMD_SO_PATH ENGINE_CMD_BASE
169*0a6a1f1dSLionel Sambuc static const ENGINE_CMD_DEFN aep_cmd_defns[] = {
170ebfedea0SLionel Sambuc {AEP_CMD_SO_PATH,
171ebfedea0SLionel Sambuc "SO_PATH",
172ebfedea0SLionel Sambuc "Specifies the path to the 'aep' shared library",
173*0a6a1f1dSLionel Sambuc ENGINE_CMD_FLAG_STRING},
174ebfedea0SLionel Sambuc {0, NULL, NULL, 0}
175ebfedea0SLionel Sambuc };
176ebfedea0SLionel Sambuc
177ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
178ebfedea0SLionel Sambuc /* Our internal RSA_METHOD that we provide pointers to */
179*0a6a1f1dSLionel Sambuc static RSA_METHOD aep_rsa = {
180ebfedea0SLionel Sambuc "Aep RSA method",
181ebfedea0SLionel Sambuc NULL, /* rsa_pub_encrypt */
182ebfedea0SLionel Sambuc NULL, /* rsa_pub_decrypt */
183ebfedea0SLionel Sambuc NULL, /* rsa_priv_encrypt */
184ebfedea0SLionel Sambuc NULL, /* rsa_priv_encrypt */
185ebfedea0SLionel Sambuc aep_rsa_mod_exp, /* rsa_mod_exp */
186ebfedea0SLionel Sambuc aep_mod_exp_mont, /* bn_mod_exp */
187ebfedea0SLionel Sambuc NULL, /* init */
188ebfedea0SLionel Sambuc NULL, /* finish */
189ebfedea0SLionel Sambuc 0, /* flags */
190ebfedea0SLionel Sambuc NULL, /* app_data */
191ebfedea0SLionel Sambuc NULL, /* rsa_sign */
192ebfedea0SLionel Sambuc NULL, /* rsa_verify */
193ebfedea0SLionel Sambuc NULL /* rsa_keygen */
194ebfedea0SLionel Sambuc };
195ebfedea0SLionel Sambuc # endif
196ebfedea0SLionel Sambuc
197ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
198ebfedea0SLionel Sambuc /* Our internal DSA_METHOD that we provide pointers to */
199*0a6a1f1dSLionel Sambuc static DSA_METHOD aep_dsa = {
200ebfedea0SLionel Sambuc "Aep DSA method",
201ebfedea0SLionel Sambuc NULL, /* dsa_do_sign */
202ebfedea0SLionel Sambuc NULL, /* dsa_sign_setup */
203ebfedea0SLionel Sambuc NULL, /* dsa_do_verify */
204ebfedea0SLionel Sambuc aep_dsa_mod_exp, /* dsa_mod_exp */
205ebfedea0SLionel Sambuc aep_mod_exp_dsa, /* bn_mod_exp */
206ebfedea0SLionel Sambuc NULL, /* init */
207ebfedea0SLionel Sambuc NULL, /* finish */
208ebfedea0SLionel Sambuc 0, /* flags */
209ebfedea0SLionel Sambuc NULL, /* app_data */
210ebfedea0SLionel Sambuc NULL, /* dsa_paramgen */
211ebfedea0SLionel Sambuc NULL /* dsa_keygen */
212ebfedea0SLionel Sambuc };
213ebfedea0SLionel Sambuc # endif
214ebfedea0SLionel Sambuc
215ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
216ebfedea0SLionel Sambuc /* Our internal DH_METHOD that we provide pointers to */
217*0a6a1f1dSLionel Sambuc static DH_METHOD aep_dh = {
218ebfedea0SLionel Sambuc "Aep DH method",
219ebfedea0SLionel Sambuc NULL,
220ebfedea0SLionel Sambuc NULL,
221ebfedea0SLionel Sambuc aep_mod_exp_dh,
222ebfedea0SLionel Sambuc NULL,
223ebfedea0SLionel Sambuc NULL,
224ebfedea0SLionel Sambuc 0,
225ebfedea0SLionel Sambuc NULL,
226ebfedea0SLionel Sambuc NULL
227ebfedea0SLionel Sambuc };
228ebfedea0SLionel Sambuc # endif
229ebfedea0SLionel Sambuc
230ebfedea0SLionel Sambuc # ifdef AEPRAND
231ebfedea0SLionel Sambuc /* our internal RAND_method that we provide pointers to */
232*0a6a1f1dSLionel Sambuc static RAND_METHOD aep_random = {
233*0a6a1f1dSLionel Sambuc /*
234*0a6a1f1dSLionel Sambuc * "AEP RAND method",
235*0a6a1f1dSLionel Sambuc */
236ebfedea0SLionel Sambuc NULL,
237ebfedea0SLionel Sambuc aep_rand,
238ebfedea0SLionel Sambuc NULL,
239ebfedea0SLionel Sambuc NULL,
240ebfedea0SLionel Sambuc aep_rand,
241ebfedea0SLionel Sambuc aep_rand_status,
242ebfedea0SLionel Sambuc };
243ebfedea0SLionel Sambuc # endif
244ebfedea0SLionel Sambuc
245*0a6a1f1dSLionel Sambuc /*
246*0a6a1f1dSLionel Sambuc * Define an array of structures to hold connections
247*0a6a1f1dSLionel Sambuc */
248ebfedea0SLionel Sambuc static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];
249ebfedea0SLionel Sambuc
250*0a6a1f1dSLionel Sambuc /*
251*0a6a1f1dSLionel Sambuc * Used to determine if this is a new process
252*0a6a1f1dSLionel Sambuc */
253ebfedea0SLionel Sambuc static pid_t recorded_pid = 0;
254ebfedea0SLionel Sambuc
255ebfedea0SLionel Sambuc # ifdef AEPRAND
256ebfedea0SLionel Sambuc static AEP_U8 rand_block[RAND_BLK_SIZE];
257ebfedea0SLionel Sambuc static AEP_U32 rand_block_bytes = 0;
258ebfedea0SLionel Sambuc # endif
259ebfedea0SLionel Sambuc
260ebfedea0SLionel Sambuc /* Constants used when creating the ENGINE */
261ebfedea0SLionel Sambuc static const char *engine_aep_id = "aep";
262ebfedea0SLionel Sambuc static const char *engine_aep_name = "Aep hardware engine support";
263ebfedea0SLionel Sambuc
264ebfedea0SLionel Sambuc static int max_key_len = 2176;
265ebfedea0SLionel Sambuc
266*0a6a1f1dSLionel Sambuc /*
267*0a6a1f1dSLionel Sambuc * This internal function is used by ENGINE_aep() and possibly by the
268*0a6a1f1dSLionel Sambuc * "dynamic" ENGINE support too
269*0a6a1f1dSLionel Sambuc */
bind_aep(ENGINE * e)270ebfedea0SLionel Sambuc static int bind_aep(ENGINE *e)
271ebfedea0SLionel Sambuc {
272ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
273ebfedea0SLionel Sambuc const RSA_METHOD *meth1;
274ebfedea0SLionel Sambuc # endif
275ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
276ebfedea0SLionel Sambuc const DSA_METHOD *meth2;
277ebfedea0SLionel Sambuc # endif
278ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
279ebfedea0SLionel Sambuc const DH_METHOD *meth3;
280ebfedea0SLionel Sambuc # endif
281ebfedea0SLionel Sambuc
282ebfedea0SLionel Sambuc if (!ENGINE_set_id(e, engine_aep_id) ||
283ebfedea0SLionel Sambuc !ENGINE_set_name(e, engine_aep_name) ||
284ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
285ebfedea0SLionel Sambuc !ENGINE_set_RSA(e, &aep_rsa) ||
286ebfedea0SLionel Sambuc # endif
287ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
288ebfedea0SLionel Sambuc !ENGINE_set_DSA(e, &aep_dsa) ||
289ebfedea0SLionel Sambuc # endif
290ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
291ebfedea0SLionel Sambuc !ENGINE_set_DH(e, &aep_dh) ||
292ebfedea0SLionel Sambuc # endif
293ebfedea0SLionel Sambuc # ifdef AEPRAND
294ebfedea0SLionel Sambuc !ENGINE_set_RAND(e, &aep_random) ||
295ebfedea0SLionel Sambuc # endif
296ebfedea0SLionel Sambuc !ENGINE_set_init_function(e, aep_init) ||
297ebfedea0SLionel Sambuc !ENGINE_set_destroy_function(e, aep_destroy) ||
298ebfedea0SLionel Sambuc !ENGINE_set_finish_function(e, aep_finish) ||
299ebfedea0SLionel Sambuc !ENGINE_set_ctrl_function(e, aep_ctrl) ||
300ebfedea0SLionel Sambuc !ENGINE_set_cmd_defns(e, aep_cmd_defns))
301ebfedea0SLionel Sambuc return 0;
302ebfedea0SLionel Sambuc
303ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
304*0a6a1f1dSLionel Sambuc /*
305*0a6a1f1dSLionel Sambuc * We know that the "PKCS1_SSLeay()" functions hook properly to the
306*0a6a1f1dSLionel Sambuc * aep-specific mod_exp and mod_exp_crt so we use those functions. NB: We
307*0a6a1f1dSLionel Sambuc * don't use ENGINE_openssl() or anything "more generic" because
308*0a6a1f1dSLionel Sambuc * something like the RSAref code may not hook properly, and if you own
309*0a6a1f1dSLionel Sambuc * one of these cards then you have the right to do RSA operations on it
310*0a6a1f1dSLionel Sambuc * anyway!
311*0a6a1f1dSLionel Sambuc */
312ebfedea0SLionel Sambuc meth1 = RSA_PKCS1_SSLeay();
313ebfedea0SLionel Sambuc aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
314ebfedea0SLionel Sambuc aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
315ebfedea0SLionel Sambuc aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
316ebfedea0SLionel Sambuc aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
317ebfedea0SLionel Sambuc # endif
318ebfedea0SLionel Sambuc
319ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
320*0a6a1f1dSLionel Sambuc /*
321*0a6a1f1dSLionel Sambuc * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits.
322*0a6a1f1dSLionel Sambuc */
323ebfedea0SLionel Sambuc meth2 = DSA_OpenSSL();
324ebfedea0SLionel Sambuc aep_dsa.dsa_do_sign = meth2->dsa_do_sign;
325ebfedea0SLionel Sambuc aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
326ebfedea0SLionel Sambuc aep_dsa.dsa_do_verify = meth2->dsa_do_verify;
327ebfedea0SLionel Sambuc
328ebfedea0SLionel Sambuc aep_dsa = *DSA_get_default_method();
329ebfedea0SLionel Sambuc aep_dsa.dsa_mod_exp = aep_dsa_mod_exp;
330ebfedea0SLionel Sambuc aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
331ebfedea0SLionel Sambuc # endif
332ebfedea0SLionel Sambuc
333ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
334ebfedea0SLionel Sambuc /* Much the same for Diffie-Hellman */
335ebfedea0SLionel Sambuc meth3 = DH_OpenSSL();
336ebfedea0SLionel Sambuc aep_dh.generate_key = meth3->generate_key;
337ebfedea0SLionel Sambuc aep_dh.compute_key = meth3->compute_key;
338ebfedea0SLionel Sambuc aep_dh.bn_mod_exp = meth3->bn_mod_exp;
339ebfedea0SLionel Sambuc # endif
340ebfedea0SLionel Sambuc
341ebfedea0SLionel Sambuc /* Ensure the aep error handling is set up */
342ebfedea0SLionel Sambuc ERR_load_AEPHK_strings();
343ebfedea0SLionel Sambuc
344ebfedea0SLionel Sambuc return 1;
345ebfedea0SLionel Sambuc }
346ebfedea0SLionel Sambuc
347ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DYNAMIC_ENGINE
bind_helper(ENGINE * e,const char * id)348ebfedea0SLionel Sambuc static int bind_helper(ENGINE *e, const char *id)
349ebfedea0SLionel Sambuc {
350ebfedea0SLionel Sambuc if (id && (strcmp(id, engine_aep_id) != 0))
351ebfedea0SLionel Sambuc return 0;
352ebfedea0SLionel Sambuc if (!bind_aep(e))
353ebfedea0SLionel Sambuc return 0;
354ebfedea0SLionel Sambuc return 1;
355ebfedea0SLionel Sambuc }
356*0a6a1f1dSLionel Sambuc
357ebfedea0SLionel Sambuc IMPLEMENT_DYNAMIC_CHECK_FN()
358ebfedea0SLionel Sambuc IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
359ebfedea0SLionel Sambuc # else
360ebfedea0SLionel Sambuc static ENGINE *engine_aep(void)
361ebfedea0SLionel Sambuc {
362ebfedea0SLionel Sambuc ENGINE *ret = ENGINE_new();
363ebfedea0SLionel Sambuc if (!ret)
364ebfedea0SLionel Sambuc return NULL;
365*0a6a1f1dSLionel Sambuc if (!bind_aep(ret)) {
366ebfedea0SLionel Sambuc ENGINE_free(ret);
367ebfedea0SLionel Sambuc return NULL;
368ebfedea0SLionel Sambuc }
369ebfedea0SLionel Sambuc return ret;
370ebfedea0SLionel Sambuc }
371ebfedea0SLionel Sambuc
372ebfedea0SLionel Sambuc void ENGINE_load_aep(void)
373ebfedea0SLionel Sambuc {
374ebfedea0SLionel Sambuc /* Copied from eng_[openssl|dyn].c */
375ebfedea0SLionel Sambuc ENGINE *toadd = engine_aep();
376*0a6a1f1dSLionel Sambuc if (!toadd)
377*0a6a1f1dSLionel Sambuc return;
378ebfedea0SLionel Sambuc ENGINE_add(toadd);
379ebfedea0SLionel Sambuc ENGINE_free(toadd);
380ebfedea0SLionel Sambuc ERR_clear_error();
381ebfedea0SLionel Sambuc }
382ebfedea0SLionel Sambuc # endif
383ebfedea0SLionel Sambuc
384*0a6a1f1dSLionel Sambuc /*
385*0a6a1f1dSLionel Sambuc * This is a process-global DSO handle used for loading and unloading the Aep
386*0a6a1f1dSLionel Sambuc * library. NB: This is only set (or unset) during an init() or finish() call
387*0a6a1f1dSLionel Sambuc * (reference counts permitting) and they're operating with global locks, so
388*0a6a1f1dSLionel Sambuc * this should be thread-safe implicitly.
389*0a6a1f1dSLionel Sambuc */
390ebfedea0SLionel Sambuc static DSO *aep_dso = NULL;
391ebfedea0SLionel Sambuc
392*0a6a1f1dSLionel Sambuc /*
393*0a6a1f1dSLionel Sambuc * These are the static string constants for the DSO file name and the
394*0a6a1f1dSLionel Sambuc * function symbol names to bind to.
395ebfedea0SLionel Sambuc */
396ebfedea0SLionel Sambuc static const char *AEP_LIBNAME = NULL;
get_AEP_LIBNAME(void)397ebfedea0SLionel Sambuc static const char *get_AEP_LIBNAME(void)
398ebfedea0SLionel Sambuc {
399ebfedea0SLionel Sambuc if (AEP_LIBNAME)
400ebfedea0SLionel Sambuc return AEP_LIBNAME;
401ebfedea0SLionel Sambuc return "aep";
402ebfedea0SLionel Sambuc }
403*0a6a1f1dSLionel Sambuc
free_AEP_LIBNAME(void)404ebfedea0SLionel Sambuc static void free_AEP_LIBNAME(void)
405ebfedea0SLionel Sambuc {
406ebfedea0SLionel Sambuc if (AEP_LIBNAME)
407ebfedea0SLionel Sambuc OPENSSL_free((void *)AEP_LIBNAME);
408ebfedea0SLionel Sambuc AEP_LIBNAME = NULL;
409ebfedea0SLionel Sambuc }
410*0a6a1f1dSLionel Sambuc
set_AEP_LIBNAME(const char * name)411ebfedea0SLionel Sambuc static long set_AEP_LIBNAME(const char *name)
412ebfedea0SLionel Sambuc {
413ebfedea0SLionel Sambuc free_AEP_LIBNAME();
414ebfedea0SLionel Sambuc return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
415ebfedea0SLionel Sambuc }
416ebfedea0SLionel Sambuc
417ebfedea0SLionel Sambuc static const char *AEP_F1 = "AEP_ModExp";
418ebfedea0SLionel Sambuc static const char *AEP_F2 = "AEP_ModExpCrt";
419ebfedea0SLionel Sambuc # ifdef AEPRAND
420ebfedea0SLionel Sambuc static const char *AEP_F3 = "AEP_GenRandom";
421ebfedea0SLionel Sambuc # endif
422ebfedea0SLionel Sambuc static const char *AEP_F4 = "AEP_Finalize";
423ebfedea0SLionel Sambuc static const char *AEP_F5 = "AEP_Initialize";
424ebfedea0SLionel Sambuc static const char *AEP_F6 = "AEP_OpenConnection";
425ebfedea0SLionel Sambuc static const char *AEP_F7 = "AEP_SetBNCallBacks";
426ebfedea0SLionel Sambuc static const char *AEP_F8 = "AEP_CloseConnection";
427ebfedea0SLionel Sambuc
428*0a6a1f1dSLionel Sambuc /*
429*0a6a1f1dSLionel Sambuc * These are the function pointers that are (un)set when the library has
430*0a6a1f1dSLionel Sambuc * successfully (un)loaded.
431*0a6a1f1dSLionel Sambuc */
432ebfedea0SLionel Sambuc static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL;
433ebfedea0SLionel Sambuc static t_AEP_CloseConnection *p_AEP_CloseConnection = NULL;
434ebfedea0SLionel Sambuc static t_AEP_ModExp *p_AEP_ModExp = NULL;
435ebfedea0SLionel Sambuc static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL;
436ebfedea0SLionel Sambuc # ifdef AEPRAND
437ebfedea0SLionel Sambuc static t_AEP_GenRandom *p_AEP_GenRandom = NULL;
438ebfedea0SLionel Sambuc # endif
439ebfedea0SLionel Sambuc static t_AEP_Initialize *p_AEP_Initialize = NULL;
440ebfedea0SLionel Sambuc static t_AEP_Finalize *p_AEP_Finalize = NULL;
441ebfedea0SLionel Sambuc static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL;
442ebfedea0SLionel Sambuc
443ebfedea0SLionel Sambuc /* (de)initialisation functions. */
aep_init(ENGINE * e)444ebfedea0SLionel Sambuc static int aep_init(ENGINE *e)
445ebfedea0SLionel Sambuc {
446ebfedea0SLionel Sambuc t_AEP_ModExp *p1;
447ebfedea0SLionel Sambuc t_AEP_ModExpCrt *p2;
448ebfedea0SLionel Sambuc # ifdef AEPRAND
449ebfedea0SLionel Sambuc t_AEP_GenRandom *p3;
450ebfedea0SLionel Sambuc # endif
451ebfedea0SLionel Sambuc t_AEP_Finalize *p4;
452ebfedea0SLionel Sambuc t_AEP_Initialize *p5;
453ebfedea0SLionel Sambuc t_AEP_OpenConnection *p6;
454ebfedea0SLionel Sambuc t_AEP_SetBNCallBacks *p7;
455ebfedea0SLionel Sambuc t_AEP_CloseConnection *p8;
456ebfedea0SLionel Sambuc
457ebfedea0SLionel Sambuc int to_return = 0;
458ebfedea0SLionel Sambuc
459*0a6a1f1dSLionel Sambuc if (aep_dso != NULL) {
460ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_ALREADY_LOADED);
461ebfedea0SLionel Sambuc goto err;
462ebfedea0SLionel Sambuc }
463ebfedea0SLionel Sambuc /* Attempt to load libaep.so. */
464ebfedea0SLionel Sambuc
465ebfedea0SLionel Sambuc aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0);
466ebfedea0SLionel Sambuc
467*0a6a1f1dSLionel Sambuc if (aep_dso == NULL) {
468ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_NOT_LOADED);
469ebfedea0SLionel Sambuc goto err;
470ebfedea0SLionel Sambuc }
471ebfedea0SLionel Sambuc
472ebfedea0SLionel Sambuc if (!(p1 = (t_AEP_ModExp *) DSO_bind_func(aep_dso, AEP_F1)) ||
473ebfedea0SLionel Sambuc !(p2 = (t_AEP_ModExpCrt *) DSO_bind_func(aep_dso, AEP_F2)) ||
474ebfedea0SLionel Sambuc # ifdef AEPRAND
475ebfedea0SLionel Sambuc !(p3 = (t_AEP_GenRandom *) DSO_bind_func(aep_dso, AEP_F3)) ||
476ebfedea0SLionel Sambuc # endif
477ebfedea0SLionel Sambuc !(p4 = (t_AEP_Finalize *) DSO_bind_func(aep_dso, AEP_F4)) ||
478ebfedea0SLionel Sambuc !(p5 = (t_AEP_Initialize *) DSO_bind_func(aep_dso, AEP_F5)) ||
479ebfedea0SLionel Sambuc !(p6 = (t_AEP_OpenConnection *) DSO_bind_func(aep_dso, AEP_F6)) ||
480ebfedea0SLionel Sambuc !(p7 = (t_AEP_SetBNCallBacks *) DSO_bind_func(aep_dso, AEP_F7)) ||
481*0a6a1f1dSLionel Sambuc !(p8 = (t_AEP_CloseConnection *) DSO_bind_func(aep_dso, AEP_F8))) {
482ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_NOT_LOADED);
483ebfedea0SLionel Sambuc goto err;
484ebfedea0SLionel Sambuc }
485ebfedea0SLionel Sambuc
486ebfedea0SLionel Sambuc /* Copy the pointers */
487ebfedea0SLionel Sambuc
488ebfedea0SLionel Sambuc p_AEP_ModExp = p1;
489ebfedea0SLionel Sambuc p_AEP_ModExpCrt = p2;
490ebfedea0SLionel Sambuc # ifdef AEPRAND
491ebfedea0SLionel Sambuc p_AEP_GenRandom = p3;
492ebfedea0SLionel Sambuc # endif
493ebfedea0SLionel Sambuc p_AEP_Finalize = p4;
494ebfedea0SLionel Sambuc p_AEP_Initialize = p5;
495ebfedea0SLionel Sambuc p_AEP_OpenConnection = p6;
496ebfedea0SLionel Sambuc p_AEP_SetBNCallBacks = p7;
497ebfedea0SLionel Sambuc p_AEP_CloseConnection = p8;
498ebfedea0SLionel Sambuc
499ebfedea0SLionel Sambuc to_return = 1;
500ebfedea0SLionel Sambuc
501ebfedea0SLionel Sambuc return to_return;
502ebfedea0SLionel Sambuc
503ebfedea0SLionel Sambuc err:
504ebfedea0SLionel Sambuc
505ebfedea0SLionel Sambuc if (aep_dso)
506ebfedea0SLionel Sambuc DSO_free(aep_dso);
507ebfedea0SLionel Sambuc aep_dso = NULL;
508ebfedea0SLionel Sambuc
509ebfedea0SLionel Sambuc p_AEP_OpenConnection = NULL;
510ebfedea0SLionel Sambuc p_AEP_ModExp = NULL;
511ebfedea0SLionel Sambuc p_AEP_ModExpCrt = NULL;
512ebfedea0SLionel Sambuc # ifdef AEPRAND
513ebfedea0SLionel Sambuc p_AEP_GenRandom = NULL;
514ebfedea0SLionel Sambuc # endif
515ebfedea0SLionel Sambuc p_AEP_Initialize = NULL;
516ebfedea0SLionel Sambuc p_AEP_Finalize = NULL;
517ebfedea0SLionel Sambuc p_AEP_SetBNCallBacks = NULL;
518ebfedea0SLionel Sambuc p_AEP_CloseConnection = NULL;
519ebfedea0SLionel Sambuc
520ebfedea0SLionel Sambuc return to_return;
521ebfedea0SLionel Sambuc }
522ebfedea0SLionel Sambuc
523ebfedea0SLionel Sambuc /* Destructor (complements the "ENGINE_aep()" constructor) */
aep_destroy(ENGINE * e)524ebfedea0SLionel Sambuc static int aep_destroy(ENGINE *e)
525ebfedea0SLionel Sambuc {
526ebfedea0SLionel Sambuc free_AEP_LIBNAME();
527ebfedea0SLionel Sambuc ERR_unload_AEPHK_strings();
528ebfedea0SLionel Sambuc return 1;
529ebfedea0SLionel Sambuc }
530ebfedea0SLionel Sambuc
aep_finish(ENGINE * e)531ebfedea0SLionel Sambuc static int aep_finish(ENGINE *e)
532ebfedea0SLionel Sambuc {
533ebfedea0SLionel Sambuc int to_return = 0, in_use;
534ebfedea0SLionel Sambuc AEP_RV rv;
535ebfedea0SLionel Sambuc
536*0a6a1f1dSLionel Sambuc if (aep_dso == NULL) {
537ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_NOT_LOADED);
538ebfedea0SLionel Sambuc goto err;
539ebfedea0SLionel Sambuc }
540ebfedea0SLionel Sambuc
541ebfedea0SLionel Sambuc rv = aep_close_all_connections(0, &in_use);
542*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
543ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_CLOSE_HANDLES_FAILED);
544ebfedea0SLionel Sambuc goto err;
545ebfedea0SLionel Sambuc }
546*0a6a1f1dSLionel Sambuc if (in_use) {
547ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_CONNECTIONS_IN_USE);
548ebfedea0SLionel Sambuc goto err;
549ebfedea0SLionel Sambuc }
550ebfedea0SLionel Sambuc
551ebfedea0SLionel Sambuc rv = p_AEP_Finalize();
552*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
553ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_FINALIZE_FAILED);
554ebfedea0SLionel Sambuc goto err;
555ebfedea0SLionel Sambuc }
556ebfedea0SLionel Sambuc
557*0a6a1f1dSLionel Sambuc if (!DSO_free(aep_dso)) {
558ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_UNIT_FAILURE);
559ebfedea0SLionel Sambuc goto err;
560ebfedea0SLionel Sambuc }
561ebfedea0SLionel Sambuc
562ebfedea0SLionel Sambuc aep_dso = NULL;
563ebfedea0SLionel Sambuc p_AEP_CloseConnection = NULL;
564ebfedea0SLionel Sambuc p_AEP_OpenConnection = NULL;
565ebfedea0SLionel Sambuc p_AEP_ModExp = NULL;
566ebfedea0SLionel Sambuc p_AEP_ModExpCrt = NULL;
567ebfedea0SLionel Sambuc # ifdef AEPRAND
568ebfedea0SLionel Sambuc p_AEP_GenRandom = NULL;
569ebfedea0SLionel Sambuc # endif
570ebfedea0SLionel Sambuc p_AEP_Initialize = NULL;
571ebfedea0SLionel Sambuc p_AEP_Finalize = NULL;
572ebfedea0SLionel Sambuc p_AEP_SetBNCallBacks = NULL;
573ebfedea0SLionel Sambuc
574ebfedea0SLionel Sambuc to_return = 1;
575ebfedea0SLionel Sambuc err:
576ebfedea0SLionel Sambuc return to_return;
577ebfedea0SLionel Sambuc }
578ebfedea0SLionel Sambuc
aep_ctrl(ENGINE * e,int cmd,long i,void * p,void (* f)(void))579ebfedea0SLionel Sambuc static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
580ebfedea0SLionel Sambuc {
581ebfedea0SLionel Sambuc int initialised = ((aep_dso == NULL) ? 0 : 1);
582*0a6a1f1dSLionel Sambuc switch (cmd) {
583ebfedea0SLionel Sambuc case AEP_CMD_SO_PATH:
584*0a6a1f1dSLionel Sambuc if (p == NULL) {
585*0a6a1f1dSLionel Sambuc AEPHKerr(AEPHK_F_AEP_CTRL, ERR_R_PASSED_NULL_PARAMETER);
586ebfedea0SLionel Sambuc return 0;
587ebfedea0SLionel Sambuc }
588*0a6a1f1dSLionel Sambuc if (initialised) {
589*0a6a1f1dSLionel Sambuc AEPHKerr(AEPHK_F_AEP_CTRL, AEPHK_R_ALREADY_LOADED);
590ebfedea0SLionel Sambuc return 0;
591ebfedea0SLionel Sambuc }
592ebfedea0SLionel Sambuc return set_AEP_LIBNAME((const char *)p);
593ebfedea0SLionel Sambuc default:
594ebfedea0SLionel Sambuc break;
595ebfedea0SLionel Sambuc }
596ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_CTRL, AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
597ebfedea0SLionel Sambuc return 0;
598ebfedea0SLionel Sambuc }
599ebfedea0SLionel Sambuc
aep_mod_exp(BIGNUM * r,const BIGNUM * a,const BIGNUM * p,const BIGNUM * m,BN_CTX * ctx)600ebfedea0SLionel Sambuc static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
601ebfedea0SLionel Sambuc const BIGNUM *m, BN_CTX *ctx)
602ebfedea0SLionel Sambuc {
603ebfedea0SLionel Sambuc int to_return = 0;
604ebfedea0SLionel Sambuc int r_len = 0;
605ebfedea0SLionel Sambuc AEP_CONNECTION_HNDL hConnection;
606ebfedea0SLionel Sambuc AEP_RV rv;
607ebfedea0SLionel Sambuc
608ebfedea0SLionel Sambuc r_len = BN_num_bits(m);
609ebfedea0SLionel Sambuc
610ebfedea0SLionel Sambuc /* Perform in software if modulus is too large for hardware. */
611ebfedea0SLionel Sambuc
612ebfedea0SLionel Sambuc if (r_len > max_key_len) {
613ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
614ebfedea0SLionel Sambuc return BN_mod_exp(r, a, p, m, ctx);
615ebfedea0SLionel Sambuc }
616ebfedea0SLionel Sambuc
617*0a6a1f1dSLionel Sambuc /*
618*0a6a1f1dSLionel Sambuc * Grab a connection from the pool
619*0a6a1f1dSLionel Sambuc */
620ebfedea0SLionel Sambuc rv = aep_get_connection(&hConnection);
621*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
622ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_GET_HANDLE_FAILED);
623ebfedea0SLionel Sambuc return BN_mod_exp(r, a, p, m, ctx);
624ebfedea0SLionel Sambuc }
625ebfedea0SLionel Sambuc
626*0a6a1f1dSLionel Sambuc /*
627*0a6a1f1dSLionel Sambuc * To the card with the mod exp
628*0a6a1f1dSLionel Sambuc */
629*0a6a1f1dSLionel Sambuc rv = p_AEP_ModExp(hConnection, (void *)a, (void *)p, (void *)m, (void *)r,
630*0a6a1f1dSLionel Sambuc NULL);
631ebfedea0SLionel Sambuc
632*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
633ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_MOD_EXP_FAILED);
634ebfedea0SLionel Sambuc rv = aep_close_connection(hConnection);
635ebfedea0SLionel Sambuc return BN_mod_exp(r, a, p, m, ctx);
636ebfedea0SLionel Sambuc }
637ebfedea0SLionel Sambuc
638*0a6a1f1dSLionel Sambuc /*
639*0a6a1f1dSLionel Sambuc * Return the connection to the pool
640*0a6a1f1dSLionel Sambuc */
641ebfedea0SLionel Sambuc rv = aep_return_connection(hConnection);
642*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
643ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_RETURN_CONNECTION_FAILED);
644ebfedea0SLionel Sambuc goto err;
645ebfedea0SLionel Sambuc }
646ebfedea0SLionel Sambuc
647ebfedea0SLionel Sambuc to_return = 1;
648ebfedea0SLionel Sambuc err:
649ebfedea0SLionel Sambuc return to_return;
650ebfedea0SLionel Sambuc }
651ebfedea0SLionel Sambuc
652ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
aep_mod_exp_crt(BIGNUM * r,const BIGNUM * a,const BIGNUM * p,const BIGNUM * q,const BIGNUM * dmp1,const BIGNUM * dmq1,const BIGNUM * iqmp,BN_CTX * ctx)653ebfedea0SLionel Sambuc static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
654ebfedea0SLionel Sambuc const BIGNUM *q, const BIGNUM *dmp1,
655*0a6a1f1dSLionel Sambuc const BIGNUM *dmq1, const BIGNUM *iqmp,
656*0a6a1f1dSLionel Sambuc BN_CTX *ctx)
657ebfedea0SLionel Sambuc {
658ebfedea0SLionel Sambuc AEP_RV rv = AEP_R_OK;
659ebfedea0SLionel Sambuc AEP_CONNECTION_HNDL hConnection;
660ebfedea0SLionel Sambuc
661*0a6a1f1dSLionel Sambuc /*
662*0a6a1f1dSLionel Sambuc * Grab a connection from the pool
663*0a6a1f1dSLionel Sambuc */
664ebfedea0SLionel Sambuc rv = aep_get_connection(&hConnection);
665*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
666ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_GET_HANDLE_FAILED);
667ebfedea0SLionel Sambuc return FAIL_TO_SW;
668ebfedea0SLionel Sambuc }
669ebfedea0SLionel Sambuc
670*0a6a1f1dSLionel Sambuc /*
671*0a6a1f1dSLionel Sambuc * To the card with the mod exp
672*0a6a1f1dSLionel Sambuc */
673*0a6a1f1dSLionel Sambuc rv = p_AEP_ModExpCrt(hConnection, (void *)a, (void *)p, (void *)q,
674*0a6a1f1dSLionel Sambuc (void *)dmp1, (void *)dmq1, (void *)iqmp, (void *)r,
675*0a6a1f1dSLionel Sambuc NULL);
676*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
677ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_MOD_EXP_CRT_FAILED);
678ebfedea0SLionel Sambuc rv = aep_close_connection(hConnection);
679ebfedea0SLionel Sambuc return FAIL_TO_SW;
680ebfedea0SLionel Sambuc }
681ebfedea0SLionel Sambuc
682*0a6a1f1dSLionel Sambuc /*
683*0a6a1f1dSLionel Sambuc * Return the connection to the pool
684*0a6a1f1dSLionel Sambuc */
685ebfedea0SLionel Sambuc rv = aep_return_connection(hConnection);
686*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
687ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_RETURN_CONNECTION_FAILED);
688ebfedea0SLionel Sambuc goto err;
689ebfedea0SLionel Sambuc }
690ebfedea0SLionel Sambuc
691ebfedea0SLionel Sambuc err:
692ebfedea0SLionel Sambuc return rv;
693ebfedea0SLionel Sambuc }
694ebfedea0SLionel Sambuc # endif
695ebfedea0SLionel Sambuc
696ebfedea0SLionel Sambuc # ifdef AEPRAND
aep_rand(unsigned char * buf,int len)697ebfedea0SLionel Sambuc static int aep_rand(unsigned char *buf, int len)
698ebfedea0SLionel Sambuc {
699ebfedea0SLionel Sambuc AEP_RV rv = AEP_R_OK;
700ebfedea0SLionel Sambuc AEP_CONNECTION_HNDL hConnection;
701ebfedea0SLionel Sambuc
702ebfedea0SLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_RAND);
703ebfedea0SLionel Sambuc
704*0a6a1f1dSLionel Sambuc /*
705*0a6a1f1dSLionel Sambuc * Can the request be serviced with what's already in the buffer?
706*0a6a1f1dSLionel Sambuc */
707*0a6a1f1dSLionel Sambuc if (len <= rand_block_bytes) {
708ebfedea0SLionel Sambuc memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
709ebfedea0SLionel Sambuc rand_block_bytes -= len;
710ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
711*0a6a1f1dSLionel Sambuc } else
712*0a6a1f1dSLionel Sambuc /*
713*0a6a1f1dSLionel Sambuc * If not the get another block of random bytes
714*0a6a1f1dSLionel Sambuc */
715ebfedea0SLionel Sambuc {
716ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
717ebfedea0SLionel Sambuc
718ebfedea0SLionel Sambuc rv = aep_get_connection(&hConnection);
719*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
720ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_HANDLE_FAILED);
721ebfedea0SLionel Sambuc goto err_nounlock;
722ebfedea0SLionel Sambuc }
723ebfedea0SLionel Sambuc
724*0a6a1f1dSLionel Sambuc if (len > RAND_BLK_SIZE) {
725ebfedea0SLionel Sambuc rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
726*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
727ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_RANDOM_FAILED);
728ebfedea0SLionel Sambuc goto err_nounlock;
729ebfedea0SLionel Sambuc }
730*0a6a1f1dSLionel Sambuc } else {
731ebfedea0SLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_RAND);
732ebfedea0SLionel Sambuc
733*0a6a1f1dSLionel Sambuc rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2,
734*0a6a1f1dSLionel Sambuc &rand_block[0], NULL);
735*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
736ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_RANDOM_FAILED);
737ebfedea0SLionel Sambuc
738ebfedea0SLionel Sambuc goto err;
739ebfedea0SLionel Sambuc }
740ebfedea0SLionel Sambuc
741ebfedea0SLionel Sambuc rand_block_bytes = RAND_BLK_SIZE;
742ebfedea0SLionel Sambuc
743ebfedea0SLionel Sambuc memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
744ebfedea0SLionel Sambuc rand_block_bytes -= len;
745ebfedea0SLionel Sambuc
746ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
747ebfedea0SLionel Sambuc }
748ebfedea0SLionel Sambuc
749ebfedea0SLionel Sambuc rv = aep_return_connection(hConnection);
750*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
751ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_RETURN_CONNECTION_FAILED);
752ebfedea0SLionel Sambuc
753ebfedea0SLionel Sambuc goto err_nounlock;
754ebfedea0SLionel Sambuc }
755ebfedea0SLionel Sambuc }
756ebfedea0SLionel Sambuc
757ebfedea0SLionel Sambuc return 1;
758ebfedea0SLionel Sambuc err:
759ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
760ebfedea0SLionel Sambuc err_nounlock:
761ebfedea0SLionel Sambuc return 0;
762ebfedea0SLionel Sambuc }
763ebfedea0SLionel Sambuc
aep_rand_status(void)764ebfedea0SLionel Sambuc static int aep_rand_status(void)
765ebfedea0SLionel Sambuc {
766ebfedea0SLionel Sambuc return 1;
767ebfedea0SLionel Sambuc }
768ebfedea0SLionel Sambuc # endif
769ebfedea0SLionel Sambuc
770ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
aep_rsa_mod_exp(BIGNUM * r0,const BIGNUM * I,RSA * rsa,BN_CTX * ctx)771ebfedea0SLionel Sambuc static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
772ebfedea0SLionel Sambuc {
773ebfedea0SLionel Sambuc int to_return = 0;
774ebfedea0SLionel Sambuc AEP_RV rv = AEP_R_OK;
775ebfedea0SLionel Sambuc
776*0a6a1f1dSLionel Sambuc if (!aep_dso) {
777ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP, AEPHK_R_NOT_LOADED);
778ebfedea0SLionel Sambuc goto err;
779ebfedea0SLionel Sambuc }
780ebfedea0SLionel Sambuc
781*0a6a1f1dSLionel Sambuc /*
782*0a6a1f1dSLionel Sambuc * See if we have all the necessary bits for a crt
783*0a6a1f1dSLionel Sambuc */
784*0a6a1f1dSLionel Sambuc if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) {
785*0a6a1f1dSLionel Sambuc rv = aep_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, rsa->dmq1,
786*0a6a1f1dSLionel Sambuc rsa->iqmp, ctx);
787ebfedea0SLionel Sambuc
788ebfedea0SLionel Sambuc if (rv == FAIL_TO_SW) {
789ebfedea0SLionel Sambuc const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
790ebfedea0SLionel Sambuc to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx);
791ebfedea0SLionel Sambuc goto err;
792*0a6a1f1dSLionel Sambuc } else if (rv != AEP_R_OK)
793ebfedea0SLionel Sambuc goto err;
794*0a6a1f1dSLionel Sambuc } else {
795*0a6a1f1dSLionel Sambuc if (!rsa->d || !rsa->n) {
796ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP, AEPHK_R_MISSING_KEY_COMPONENTS);
797ebfedea0SLionel Sambuc goto err;
798ebfedea0SLionel Sambuc }
799ebfedea0SLionel Sambuc
800ebfedea0SLionel Sambuc rv = aep_mod_exp(r0, I, rsa->d, rsa->n, ctx);
801ebfedea0SLionel Sambuc if (rv != AEP_R_OK)
802ebfedea0SLionel Sambuc goto err;
803ebfedea0SLionel Sambuc
804ebfedea0SLionel Sambuc }
805ebfedea0SLionel Sambuc
806ebfedea0SLionel Sambuc to_return = 1;
807ebfedea0SLionel Sambuc
808ebfedea0SLionel Sambuc err:
809ebfedea0SLionel Sambuc return to_return;
810ebfedea0SLionel Sambuc }
811ebfedea0SLionel Sambuc # endif
812ebfedea0SLionel Sambuc
813ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
aep_dsa_mod_exp(DSA * dsa,BIGNUM * rr,BIGNUM * a1,BIGNUM * p1,BIGNUM * a2,BIGNUM * p2,BIGNUM * m,BN_CTX * ctx,BN_MONT_CTX * in_mont)814ebfedea0SLionel Sambuc static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
815ebfedea0SLionel Sambuc BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
816ebfedea0SLionel Sambuc BN_CTX *ctx, BN_MONT_CTX *in_mont)
817ebfedea0SLionel Sambuc {
818ebfedea0SLionel Sambuc BIGNUM t;
819ebfedea0SLionel Sambuc int to_return = 0;
820ebfedea0SLionel Sambuc BN_init(&t);
821ebfedea0SLionel Sambuc
822ebfedea0SLionel Sambuc /* let rr = a1 ^ p1 mod m */
823*0a6a1f1dSLionel Sambuc if (!aep_mod_exp(rr, a1, p1, m, ctx))
824*0a6a1f1dSLionel Sambuc goto end;
825ebfedea0SLionel Sambuc /* let t = a2 ^ p2 mod m */
826*0a6a1f1dSLionel Sambuc if (!aep_mod_exp(&t, a2, p2, m, ctx))
827*0a6a1f1dSLionel Sambuc goto end;
828ebfedea0SLionel Sambuc /* let rr = rr * t mod m */
829*0a6a1f1dSLionel Sambuc if (!BN_mod_mul(rr, rr, &t, m, ctx))
830*0a6a1f1dSLionel Sambuc goto end;
831ebfedea0SLionel Sambuc to_return = 1;
832ebfedea0SLionel Sambuc end:
833ebfedea0SLionel Sambuc BN_free(&t);
834ebfedea0SLionel Sambuc return to_return;
835ebfedea0SLionel Sambuc }
836ebfedea0SLionel Sambuc
aep_mod_exp_dsa(DSA * dsa,BIGNUM * r,BIGNUM * a,const BIGNUM * p,const BIGNUM * m,BN_CTX * ctx,BN_MONT_CTX * m_ctx)837ebfedea0SLionel Sambuc static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
838ebfedea0SLionel Sambuc const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
839ebfedea0SLionel Sambuc BN_MONT_CTX *m_ctx)
840ebfedea0SLionel Sambuc {
841ebfedea0SLionel Sambuc return aep_mod_exp(r, a, p, m, ctx);
842ebfedea0SLionel Sambuc }
843ebfedea0SLionel Sambuc # endif
844ebfedea0SLionel Sambuc
845ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
846ebfedea0SLionel Sambuc /* This function is aliased to mod_exp (with the mont stuff dropped). */
aep_mod_exp_mont(BIGNUM * r,const BIGNUM * a,const BIGNUM * p,const BIGNUM * m,BN_CTX * ctx,BN_MONT_CTX * m_ctx)847ebfedea0SLionel Sambuc static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
848ebfedea0SLionel Sambuc const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
849ebfedea0SLionel Sambuc {
850ebfedea0SLionel Sambuc return aep_mod_exp(r, a, p, m, ctx);
851ebfedea0SLionel Sambuc }
852ebfedea0SLionel Sambuc # endif
853ebfedea0SLionel Sambuc
854ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
855ebfedea0SLionel Sambuc /* This function is aliased to mod_exp (with the dh and mont dropped). */
aep_mod_exp_dh(const DH * dh,BIGNUM * r,const BIGNUM * a,const BIGNUM * p,const BIGNUM * m,BN_CTX * ctx,BN_MONT_CTX * m_ctx)856ebfedea0SLionel Sambuc static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
857ebfedea0SLionel Sambuc const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
858ebfedea0SLionel Sambuc BN_MONT_CTX *m_ctx)
859ebfedea0SLionel Sambuc {
860ebfedea0SLionel Sambuc return aep_mod_exp(r, a, p, m, ctx);
861ebfedea0SLionel Sambuc }
862ebfedea0SLionel Sambuc # endif
863ebfedea0SLionel Sambuc
aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)864ebfedea0SLionel Sambuc static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
865ebfedea0SLionel Sambuc {
866ebfedea0SLionel Sambuc int count;
867ebfedea0SLionel Sambuc AEP_RV rv = AEP_R_OK;
868ebfedea0SLionel Sambuc
869*0a6a1f1dSLionel Sambuc /*
870*0a6a1f1dSLionel Sambuc * Get the current process id
871*0a6a1f1dSLionel Sambuc */
872ebfedea0SLionel Sambuc pid_t curr_pid;
873ebfedea0SLionel Sambuc
874ebfedea0SLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
875ebfedea0SLionel Sambuc
876ebfedea0SLionel Sambuc curr_pid = getpid();
877ebfedea0SLionel Sambuc
878*0a6a1f1dSLionel Sambuc /*
879*0a6a1f1dSLionel Sambuc * Check if this is the first time this is being called from the current
880*0a6a1f1dSLionel Sambuc * process
881*0a6a1f1dSLionel Sambuc */
882*0a6a1f1dSLionel Sambuc if (recorded_pid != curr_pid) {
883*0a6a1f1dSLionel Sambuc /*
884*0a6a1f1dSLionel Sambuc * Remember our pid so we can check if we're in a new process
885*0a6a1f1dSLionel Sambuc */
886ebfedea0SLionel Sambuc recorded_pid = curr_pid;
887ebfedea0SLionel Sambuc
888*0a6a1f1dSLionel Sambuc /*
889*0a6a1f1dSLionel Sambuc * Call Finalize to make sure we have not inherited some data from a
890*0a6a1f1dSLionel Sambuc * parent process
891*0a6a1f1dSLionel Sambuc */
892ebfedea0SLionel Sambuc p_AEP_Finalize();
893ebfedea0SLionel Sambuc
894*0a6a1f1dSLionel Sambuc /*
895*0a6a1f1dSLionel Sambuc * Initialise the AEP API
896*0a6a1f1dSLionel Sambuc */
897ebfedea0SLionel Sambuc rv = p_AEP_Initialize(NULL);
898ebfedea0SLionel Sambuc
899*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
900ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_INIT_FAILURE);
901ebfedea0SLionel Sambuc recorded_pid = 0;
902ebfedea0SLionel Sambuc goto end;
903ebfedea0SLionel Sambuc }
904ebfedea0SLionel Sambuc
905*0a6a1f1dSLionel Sambuc /*
906*0a6a1f1dSLionel Sambuc * Set the AEP big num call back functions
907*0a6a1f1dSLionel Sambuc */
908ebfedea0SLionel Sambuc rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
909ebfedea0SLionel Sambuc &ConvertAEPBigNum);
910ebfedea0SLionel Sambuc
911*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
912*0a6a1f1dSLionel Sambuc AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,
913*0a6a1f1dSLionel Sambuc AEPHK_R_SETBNCALLBACK_FAILURE);
914ebfedea0SLionel Sambuc recorded_pid = 0;
915ebfedea0SLionel Sambuc goto end;
916ebfedea0SLionel Sambuc }
917ebfedea0SLionel Sambuc # ifdef AEPRAND
918*0a6a1f1dSLionel Sambuc /*
919*0a6a1f1dSLionel Sambuc * Reset the rand byte count
920*0a6a1f1dSLionel Sambuc */
921ebfedea0SLionel Sambuc rand_block_bytes = 0;
922ebfedea0SLionel Sambuc # endif
923ebfedea0SLionel Sambuc
924*0a6a1f1dSLionel Sambuc /*
925*0a6a1f1dSLionel Sambuc * Init the structures
926*0a6a1f1dSLionel Sambuc */
927*0a6a1f1dSLionel Sambuc for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) {
928ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_state = NotConnected;
929ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_hndl = 0;
930ebfedea0SLionel Sambuc }
931ebfedea0SLionel Sambuc
932*0a6a1f1dSLionel Sambuc /*
933*0a6a1f1dSLionel Sambuc * Open a connection
934*0a6a1f1dSLionel Sambuc */
935ebfedea0SLionel Sambuc rv = p_AEP_OpenConnection(phConnection);
936ebfedea0SLionel Sambuc
937*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
938ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_UNIT_FAILURE);
939ebfedea0SLionel Sambuc recorded_pid = 0;
940ebfedea0SLionel Sambuc goto end;
941ebfedea0SLionel Sambuc }
942ebfedea0SLionel Sambuc
943ebfedea0SLionel Sambuc aep_app_conn_table[0].conn_state = InUse;
944ebfedea0SLionel Sambuc aep_app_conn_table[0].conn_hndl = *phConnection;
945ebfedea0SLionel Sambuc goto end;
946ebfedea0SLionel Sambuc }
947*0a6a1f1dSLionel Sambuc /*
948*0a6a1f1dSLionel Sambuc * Check the existing connections to see if we can find a free one
949*0a6a1f1dSLionel Sambuc */
950*0a6a1f1dSLionel Sambuc for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) {
951*0a6a1f1dSLionel Sambuc if (aep_app_conn_table[count].conn_state == Connected) {
952ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_state = InUse;
953ebfedea0SLionel Sambuc *phConnection = aep_app_conn_table[count].conn_hndl;
954ebfedea0SLionel Sambuc goto end;
955ebfedea0SLionel Sambuc }
956ebfedea0SLionel Sambuc }
957*0a6a1f1dSLionel Sambuc /*
958*0a6a1f1dSLionel Sambuc * If no connections available, we're going to have to try to open a new
959*0a6a1f1dSLionel Sambuc * one
960*0a6a1f1dSLionel Sambuc */
961*0a6a1f1dSLionel Sambuc for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) {
962*0a6a1f1dSLionel Sambuc if (aep_app_conn_table[count].conn_state == NotConnected) {
963*0a6a1f1dSLionel Sambuc /*
964*0a6a1f1dSLionel Sambuc * Open a connection
965*0a6a1f1dSLionel Sambuc */
966ebfedea0SLionel Sambuc rv = p_AEP_OpenConnection(phConnection);
967ebfedea0SLionel Sambuc
968*0a6a1f1dSLionel Sambuc if (rv != AEP_R_OK) {
969ebfedea0SLionel Sambuc AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_UNIT_FAILURE);
970ebfedea0SLionel Sambuc goto end;
971ebfedea0SLionel Sambuc }
972ebfedea0SLionel Sambuc
973ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_state = InUse;
974ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_hndl = *phConnection;
975ebfedea0SLionel Sambuc goto end;
976ebfedea0SLionel Sambuc }
977ebfedea0SLionel Sambuc }
978ebfedea0SLionel Sambuc rv = AEP_R_GENERAL_ERROR;
979ebfedea0SLionel Sambuc end:
980ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
981ebfedea0SLionel Sambuc return rv;
982ebfedea0SLionel Sambuc }
983ebfedea0SLionel Sambuc
aep_return_connection(AEP_CONNECTION_HNDL hConnection)984ebfedea0SLionel Sambuc static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
985ebfedea0SLionel Sambuc {
986ebfedea0SLionel Sambuc int count;
987ebfedea0SLionel Sambuc
988ebfedea0SLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
989ebfedea0SLionel Sambuc
990*0a6a1f1dSLionel Sambuc /*
991*0a6a1f1dSLionel Sambuc * Find the connection item that matches this connection handle
992*0a6a1f1dSLionel Sambuc */
993*0a6a1f1dSLionel Sambuc for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) {
994*0a6a1f1dSLionel Sambuc if (aep_app_conn_table[count].conn_hndl == hConnection) {
995ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_state = Connected;
996ebfedea0SLionel Sambuc break;
997ebfedea0SLionel Sambuc }
998ebfedea0SLionel Sambuc }
999ebfedea0SLionel Sambuc
1000ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
1001ebfedea0SLionel Sambuc
1002ebfedea0SLionel Sambuc return AEP_R_OK;
1003ebfedea0SLionel Sambuc }
1004ebfedea0SLionel Sambuc
aep_close_connection(AEP_CONNECTION_HNDL hConnection)1005ebfedea0SLionel Sambuc static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
1006ebfedea0SLionel Sambuc {
1007ebfedea0SLionel Sambuc int count;
1008ebfedea0SLionel Sambuc AEP_RV rv = AEP_R_OK;
1009ebfedea0SLionel Sambuc
1010ebfedea0SLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
1011ebfedea0SLionel Sambuc
1012*0a6a1f1dSLionel Sambuc /*
1013*0a6a1f1dSLionel Sambuc * Find the connection item that matches this connection handle
1014*0a6a1f1dSLionel Sambuc */
1015*0a6a1f1dSLionel Sambuc for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) {
1016*0a6a1f1dSLionel Sambuc if (aep_app_conn_table[count].conn_hndl == hConnection) {
1017ebfedea0SLionel Sambuc rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
1018ebfedea0SLionel Sambuc if (rv != AEP_R_OK)
1019ebfedea0SLionel Sambuc goto end;
1020ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_state = NotConnected;
1021ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_hndl = 0;
1022ebfedea0SLionel Sambuc break;
1023ebfedea0SLionel Sambuc }
1024ebfedea0SLionel Sambuc }
1025ebfedea0SLionel Sambuc
1026ebfedea0SLionel Sambuc end:
1027ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
1028ebfedea0SLionel Sambuc return rv;
1029ebfedea0SLionel Sambuc }
1030ebfedea0SLionel Sambuc
aep_close_all_connections(int use_engine_lock,int * in_use)1031ebfedea0SLionel Sambuc static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
1032ebfedea0SLionel Sambuc {
1033ebfedea0SLionel Sambuc int count;
1034ebfedea0SLionel Sambuc AEP_RV rv = AEP_R_OK;
1035ebfedea0SLionel Sambuc
1036ebfedea0SLionel Sambuc *in_use = 0;
1037*0a6a1f1dSLionel Sambuc if (use_engine_lock)
1038*0a6a1f1dSLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
1039*0a6a1f1dSLionel Sambuc for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) {
1040*0a6a1f1dSLionel Sambuc switch (aep_app_conn_table[count].conn_state) {
1041ebfedea0SLionel Sambuc case Connected:
1042ebfedea0SLionel Sambuc rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
1043ebfedea0SLionel Sambuc if (rv != AEP_R_OK)
1044ebfedea0SLionel Sambuc goto end;
1045ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_state = NotConnected;
1046ebfedea0SLionel Sambuc aep_app_conn_table[count].conn_hndl = 0;
1047ebfedea0SLionel Sambuc break;
1048ebfedea0SLionel Sambuc case InUse:
1049ebfedea0SLionel Sambuc (*in_use)++;
1050ebfedea0SLionel Sambuc break;
1051ebfedea0SLionel Sambuc case NotConnected:
1052ebfedea0SLionel Sambuc break;
1053ebfedea0SLionel Sambuc }
1054ebfedea0SLionel Sambuc }
1055ebfedea0SLionel Sambuc end:
1056*0a6a1f1dSLionel Sambuc if (use_engine_lock)
1057*0a6a1f1dSLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
1058ebfedea0SLionel Sambuc return rv;
1059ebfedea0SLionel Sambuc }
1060ebfedea0SLionel Sambuc
1061*0a6a1f1dSLionel Sambuc /*
1062*0a6a1f1dSLionel Sambuc * BigNum call back functions, used to convert OpenSSL bignums into AEP
1063*0a6a1f1dSLionel Sambuc * bignums. Note only 32bit Openssl build support
1064*0a6a1f1dSLionel Sambuc */
1065ebfedea0SLionel Sambuc
GetBigNumSize(AEP_VOID_PTR ArbBigNum,AEP_U32 * BigNumSize)1066ebfedea0SLionel Sambuc static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32 *BigNumSize)
1067ebfedea0SLionel Sambuc {
1068ebfedea0SLionel Sambuc BIGNUM *bn;
1069ebfedea0SLionel Sambuc
1070*0a6a1f1dSLionel Sambuc /*
1071*0a6a1f1dSLionel Sambuc * Cast the ArbBigNum pointer to our BIGNUM struct
1072*0a6a1f1dSLionel Sambuc */
1073ebfedea0SLionel Sambuc bn = (BIGNUM *)ArbBigNum;
1074ebfedea0SLionel Sambuc
1075ebfedea0SLionel Sambuc # ifdef SIXTY_FOUR_BIT_LONG
1076ebfedea0SLionel Sambuc *BigNumSize = bn->top << 3;
1077ebfedea0SLionel Sambuc # else
1078*0a6a1f1dSLionel Sambuc /*
1079*0a6a1f1dSLionel Sambuc * Size of the bignum in bytes is equal to the bn->top (no of 32 bit
1080*0a6a1f1dSLionel Sambuc * words) multiplies by 4
1081*0a6a1f1dSLionel Sambuc */
1082ebfedea0SLionel Sambuc *BigNumSize = bn->top << 2;
1083ebfedea0SLionel Sambuc # endif
1084ebfedea0SLionel Sambuc
1085ebfedea0SLionel Sambuc return AEP_R_OK;
1086ebfedea0SLionel Sambuc }
1087ebfedea0SLionel Sambuc
MakeAEPBigNum(AEP_VOID_PTR ArbBigNum,AEP_U32 BigNumSize,unsigned char * AEP_BigNum)1088ebfedea0SLionel Sambuc static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
1089ebfedea0SLionel Sambuc unsigned char *AEP_BigNum)
1090ebfedea0SLionel Sambuc {
1091ebfedea0SLionel Sambuc BIGNUM *bn;
1092ebfedea0SLionel Sambuc
1093ebfedea0SLionel Sambuc # ifndef SIXTY_FOUR_BIT_LONG
1094ebfedea0SLionel Sambuc unsigned char *buf;
1095ebfedea0SLionel Sambuc int i;
1096ebfedea0SLionel Sambuc # endif
1097ebfedea0SLionel Sambuc
1098*0a6a1f1dSLionel Sambuc /*
1099*0a6a1f1dSLionel Sambuc * Cast the ArbBigNum pointer to our BIGNUM struct
1100*0a6a1f1dSLionel Sambuc */
1101ebfedea0SLionel Sambuc bn = (BIGNUM *)ArbBigNum;
1102ebfedea0SLionel Sambuc
1103ebfedea0SLionel Sambuc # ifdef SIXTY_FOUR_BIT_LONG
1104ebfedea0SLionel Sambuc memcpy(AEP_BigNum, bn->d, BigNumSize);
1105ebfedea0SLionel Sambuc # else
1106*0a6a1f1dSLionel Sambuc /*
1107*0a6a1f1dSLionel Sambuc * Must copy data into a (monotone) least significant byte first format
1108*0a6a1f1dSLionel Sambuc * performing endian conversion if necessary
1109*0a6a1f1dSLionel Sambuc */
1110*0a6a1f1dSLionel Sambuc for (i = 0; i < bn->top; i++) {
1111ebfedea0SLionel Sambuc buf = (unsigned char *)&bn->d[i];
1112ebfedea0SLionel Sambuc
1113ebfedea0SLionel Sambuc *((AEP_U32 *)AEP_BigNum) = (AEP_U32)
1114ebfedea0SLionel Sambuc ((unsigned)buf[1] << 8 | buf[0]) |
1115ebfedea0SLionel Sambuc ((unsigned)buf[3] << 8 | buf[2]) << 16;
1116ebfedea0SLionel Sambuc
1117ebfedea0SLionel Sambuc AEP_BigNum += 4;
1118ebfedea0SLionel Sambuc }
1119ebfedea0SLionel Sambuc # endif
1120ebfedea0SLionel Sambuc
1121ebfedea0SLionel Sambuc return AEP_R_OK;
1122ebfedea0SLionel Sambuc }
1123ebfedea0SLionel Sambuc
1124*0a6a1f1dSLionel Sambuc /*
1125*0a6a1f1dSLionel Sambuc * Turn an AEP Big Num back to a user big num
1126*0a6a1f1dSLionel Sambuc */
ConvertAEPBigNum(void * ArbBigNum,AEP_U32 BigNumSize,unsigned char * AEP_BigNum)1127ebfedea0SLionel Sambuc static AEP_RV ConvertAEPBigNum(void *ArbBigNum, AEP_U32 BigNumSize,
1128ebfedea0SLionel Sambuc unsigned char *AEP_BigNum)
1129ebfedea0SLionel Sambuc {
1130ebfedea0SLionel Sambuc BIGNUM *bn;
1131ebfedea0SLionel Sambuc # ifndef SIXTY_FOUR_BIT_LONG
1132ebfedea0SLionel Sambuc int i;
1133ebfedea0SLionel Sambuc # endif
1134ebfedea0SLionel Sambuc
1135ebfedea0SLionel Sambuc bn = (BIGNUM *)ArbBigNum;
1136ebfedea0SLionel Sambuc
1137*0a6a1f1dSLionel Sambuc /*
1138*0a6a1f1dSLionel Sambuc * Expand the result bn so that it can hold our big num. Size is in bits
1139*0a6a1f1dSLionel Sambuc */
1140ebfedea0SLionel Sambuc bn_expand(bn, (int)(BigNumSize << 3));
1141ebfedea0SLionel Sambuc
1142ebfedea0SLionel Sambuc # ifdef SIXTY_FOUR_BIT_LONG
1143ebfedea0SLionel Sambuc bn->top = BigNumSize >> 3;
1144ebfedea0SLionel Sambuc
1145ebfedea0SLionel Sambuc if ((BigNumSize & 7) != 0)
1146ebfedea0SLionel Sambuc bn->top++;
1147ebfedea0SLionel Sambuc
1148ebfedea0SLionel Sambuc memset(bn->d, 0, bn->top << 3);
1149ebfedea0SLionel Sambuc
1150ebfedea0SLionel Sambuc memcpy(bn->d, AEP_BigNum, BigNumSize);
1151ebfedea0SLionel Sambuc # else
1152ebfedea0SLionel Sambuc bn->top = BigNumSize >> 2;
1153ebfedea0SLionel Sambuc
1154*0a6a1f1dSLionel Sambuc for (i = 0; i < bn->top; i++) {
1155ebfedea0SLionel Sambuc bn->d[i] = (AEP_U32)
1156ebfedea0SLionel Sambuc ((unsigned)AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
1157ebfedea0SLionel Sambuc ((unsigned)AEP_BigNum[1] << 8 | AEP_BigNum[0]);
1158ebfedea0SLionel Sambuc AEP_BigNum += 4;
1159ebfedea0SLionel Sambuc }
1160ebfedea0SLionel Sambuc # endif
1161ebfedea0SLionel Sambuc
1162ebfedea0SLionel Sambuc return AEP_R_OK;
1163ebfedea0SLionel Sambuc }
1164ebfedea0SLionel Sambuc
1165ebfedea0SLionel Sambuc # endif /* !OPENSSL_NO_HW_AEP */
1166ebfedea0SLionel Sambuc #endif /* !OPENSSL_NO_HW */
1167