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