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