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