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