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