1 /* crypto/engine/hw_aep.c */
4 /* ====================================================================
5 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
33 * 6. Redistributions of any form whatsoever must retain the following
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
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 * ====================================================================
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).
59 #include <openssl/bn.h>
62 #include <openssl/e_os.h>
70 #include <openssl/crypto.h>
72 #include <openssl/dso.h>
73 #include "engine_int.h"
74 #include <openssl/engine.h>
81 #include "vendor_defns/aep.h"
84 static int aep_init(void);
85 static int aep_finish(void);
87 static AEP_RV
aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection
);
88 static AEP_RV
aep_return_connection(AEP_CONNECTION_HNDL hConnection
);
89 static AEP_RV
aep_close_connection(AEP_CONNECTION_HNDL hConnection
);
90 static AEP_RV
aep_close_all_connections(int use_engine_lock
, int *in_use
);
93 static int aep_mod_exp(BIGNUM
*r
, BIGNUM
*a
, const BIGNUM
*p
,
94 const BIGNUM
*m
, BN_CTX
*ctx
);
95 static AEP_RV
aep_mod_exp_crt(BIGNUM
*r
, const BIGNUM
*a
,
96 const BIGNUM
*p
, const BIGNUM
*q
,
97 const BIGNUM
*dmp1
, const BIGNUM
*dmq1
,
98 const BIGNUM
*iqmp
, BN_CTX
*ctx
);
102 static int aep_rsa_mod_exp(BIGNUM
*r0
, BIGNUM
*I
, RSA
*rsa
);
105 /* This function is aliased to mod_exp (with the mont stuff dropped). */
106 static int aep_mod_exp_mont(BIGNUM
*r
, BIGNUM
*a
, const BIGNUM
*p
,
107 const BIGNUM
*m
, BN_CTX
*ctx
, BN_MONT_CTX
*m_ctx
);
111 static int aep_dsa_mod_exp(DSA
*dsa
, BIGNUM
*rr
, BIGNUM
*a1
,
112 BIGNUM
*p1
, BIGNUM
*a2
, BIGNUM
*p2
, BIGNUM
*m
,
113 BN_CTX
*ctx
, BN_MONT_CTX
*in_mont
);
115 static int aep_mod_exp_dsa(DSA
*dsa
, BIGNUM
*r
, BIGNUM
*a
,
116 const BIGNUM
*p
, const BIGNUM
*m
, BN_CTX
*ctx
,
122 /* This function is aliased to mod_exp (with the DH and mont dropped). */
123 static int aep_mod_exp_dh(DH
*dh
, BIGNUM
*r
, BIGNUM
*a
, const BIGNUM
*p
,
124 const BIGNUM
*m
, BN_CTX
*ctx
, BN_MONT_CTX
*m_ctx
);
129 static int aep_rand(unsigned char *buf
, int num
);
130 static int aep_rand_status(void);
133 /* Bignum conversion stuff */
134 static AEP_RV
GetBigNumSize(AEP_VOID_PTR ArbBigNum
, AEP_U32
* BigNumSize
);
135 static AEP_RV
MakeAEPBigNum(AEP_VOID_PTR ArbBigNum
, AEP_U32 BigNumSize
,
136 unsigned char* AEP_BigNum
);
137 static AEP_RV
ConvertAEPBigNum(void* ArbBigNum
, AEP_U32 BigNumSize
,
138 unsigned char* AEP_BigNum
);
142 /* Our internal RSA_METHOD that we provide pointers to */
143 static RSA_METHOD aep_rsa
=
146 NULL
, /*rsa_pub_encrypt*/
147 NULL
, /*rsa_pub_decrypt*/
148 NULL
, /*rsa_priv_encrypt*/
149 NULL
, /*rsa_priv_encrypt*/
150 aep_rsa_mod_exp
, /*rsa_mod_exp*/
151 aep_mod_exp_mont
, /*bn_mod_exp*/
162 /* Our internal DSA_METHOD that we provide pointers to */
163 static DSA_METHOD aep_dsa
=
166 NULL
, /* dsa_do_sign */
167 NULL
, /* dsa_sign_setup */
168 NULL
, /* dsa_do_verify */
169 aep_dsa_mod_exp
, /* dsa_mod_exp */
170 aep_mod_exp_dsa
, /* bn_mod_exp */
179 /* Our internal DH_METHOD that we provide pointers to */
180 static DH_METHOD aep_dh
=
194 /* our internal RAND_method that we provide pointers to */
195 static RAND_METHOD aep_random
=
197 /*"AEP RAND method", */
207 /* Our ENGINE structure. */
208 static ENGINE engine_aep
=
211 "Aep hardware engine support",
224 NULL
, /* no ctrl() */
225 NULL
, /* no load_privkey() */
226 NULL
, /* no load_pubkey() */
228 0, 0, /* no references */
229 NULL
, NULL
/* unlinked */
232 /*Define an array of structures to hold connections*/
233 static AEP_CONNECTION_ENTRY aep_app_conn_table
[MAX_PROCESS_CONNECTIONS
];
235 /*Used to determine if this is a new process*/
236 static pid_t recorded_pid
= 0;
239 static AEP_U8 rand_block
[RAND_BLK_SIZE
];
240 static AEP_U32 rand_block_bytes
= 0;
243 static int max_key_len
= 2176;
246 /* As this is only ever called once, there's no need for locking
247 * (indeed - the lock will already be held by our caller!!!) */
260 /* We know that the "PKCS1_SSLeay()" functions hook properly
261 * to the aep-specific mod_exp and mod_exp_crt so we use
262 * those functions. NB: We don't use ENGINE_openssl() or
263 * anything "more generic" because something like the RSAref
264 * code may not hook properly, and if you own one of these
265 * cards then you have the right to do RSA operations on it
268 meth1
= RSA_PKCS1_SSLeay();
269 aep_rsa
.rsa_pub_enc
= meth1
->rsa_pub_enc
;
270 aep_rsa
.rsa_pub_dec
= meth1
->rsa_pub_dec
;
271 aep_rsa
.rsa_priv_enc
= meth1
->rsa_priv_enc
;
272 aep_rsa
.rsa_priv_dec
= meth1
->rsa_priv_dec
;
276 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
279 meth2
= DSA_OpenSSL();
280 aep_dsa
.dsa_do_sign
= meth2
->dsa_do_sign
;
281 aep_dsa
.dsa_sign_setup
= meth2
->dsa_sign_setup
;
282 aep_dsa
.dsa_do_verify
= meth2
->dsa_do_verify
;
284 aep_dsa
= *DSA_get_default_openssl_method();
285 aep_dsa
.dsa_mod_exp
= aep_dsa_mod_exp
;
286 aep_dsa
.bn_mod_exp
= aep_mod_exp_dsa
;
289 /* Much the same for Diffie-Hellman */
291 meth3
= DH_OpenSSL();
292 aep_dh
.generate_key
= meth3
->generate_key
;
293 aep_dh
.compute_key
= meth3
->compute_key
;
294 aep_dh
.bn_mod_exp
= meth3
->bn_mod_exp
;
300 /* This is a process-global DSO handle used for loading and unloading
301 * the Aep library. NB: This is only set (or unset) during an
302 * init() or finish() call (reference counts permitting) and they're
303 * operating with global locks, so this should be thread-safe
305 static DSO
*aep_dso
= NULL
;
307 /* These are the static string constants for the DSO file name and the function
308 * symbol names to bind to.
310 static const char *AEP_LIBNAME
= "aep";
312 static const char *AEP_F1
= "AEP_ModExp";
313 static const char *AEP_F2
= "AEP_ModExpCrt";
315 static const char *AEP_F3
= "AEP_GenRandom";
317 static const char *AEP_F4
= "AEP_Finalize";
318 static const char *AEP_F5
= "AEP_Initialize";
319 static const char *AEP_F6
= "AEP_OpenConnection";
320 static const char *AEP_F7
= "AEP_SetBNCallBacks";
321 static const char *AEP_F8
= "AEP_CloseConnection";
323 /* These are the function pointers that are (un)set when the library has
324 * successfully (un)loaded. */
325 static t_AEP_OpenConnection
*p_AEP_OpenConnection
= NULL
;
326 static t_AEP_CloseConnection
*p_AEP_CloseConnection
= NULL
;
327 static t_AEP_ModExp
*p_AEP_ModExp
= NULL
;
328 static t_AEP_ModExpCrt
*p_AEP_ModExpCrt
= NULL
;
330 static t_AEP_GenRandom
*p_AEP_GenRandom
= NULL
;
332 static t_AEP_Initialize
*p_AEP_Initialize
= NULL
;
333 static t_AEP_Finalize
*p_AEP_Finalize
= NULL
;
334 static t_AEP_SetBNCallBacks
*p_AEP_SetBNCallBacks
= NULL
;
336 /* (de)initialisation functions. */
337 static int aep_init(void)
345 t_AEP_Initialize
*p5
;
346 t_AEP_OpenConnection
*p6
;
347 t_AEP_SetBNCallBacks
*p7
;
348 t_AEP_CloseConnection
*p8
;
355 ENGINEerr(ENGINE_F_AEP_INIT
,ENGINE_R_ALREADY_LOADED
);
358 /* Attempt to load libaep.so. */
360 aep_dso
= DSO_load(NULL
, AEP_LIBNAME
, NULL
,
361 DSO_FLAG_NAME_TRANSLATION
);
365 ENGINEerr(ENGINE_F_AEP_INIT
,ENGINE_R_DSO_FAILURE
);
369 if(!(p1
= (t_AEP_ModExp
*) DSO_bind_func( aep_dso
,AEP_F1
)) ||
370 !(p2
= (t_AEP_ModExpCrt
*) DSO_bind_func( aep_dso
,AEP_F2
)) ||
372 !(p3
= (t_AEP_GenRandom
*) DSO_bind_func( aep_dso
,AEP_F3
)) ||
374 !(p4
= (t_AEP_Finalize
*) DSO_bind_func( aep_dso
,AEP_F4
)) ||
375 !(p5
= (t_AEP_Initialize
*) DSO_bind_func( aep_dso
,AEP_F5
)) ||
376 !(p6
= (t_AEP_OpenConnection
*) DSO_bind_func( aep_dso
,AEP_F6
)) ||
377 !(p7
= (t_AEP_SetBNCallBacks
*) DSO_bind_func( aep_dso
,AEP_F7
)) ||
378 !(p8
= (t_AEP_CloseConnection
*) DSO_bind_func( aep_dso
,AEP_F8
)))
381 ENGINEerr(ENGINE_F_AEP_INIT
,ENGINE_R_DSO_FAILURE
);
385 /* Copy the pointers */
388 p_AEP_ModExpCrt
= p2
;
390 p_AEP_GenRandom
= p3
;
393 p_AEP_Initialize
= p5
;
394 p_AEP_OpenConnection
= p6
;
395 p_AEP_SetBNCallBacks
= p7
;
396 p_AEP_CloseConnection
= p8
;
407 p_AEP_OpenConnection
= NULL
;
409 p_AEP_ModExpCrt
= NULL
;
411 p_AEP_GenRandom
= NULL
;
413 p_AEP_Initialize
= NULL
;
414 p_AEP_Finalize
= NULL
;
415 p_AEP_SetBNCallBacks
= NULL
;
416 p_AEP_CloseConnection
= NULL
;
422 static int aep_finish(void)
424 int to_return
= 0, in_use
;
429 ENGINEerr(ENGINE_F_AEP_FINISH
,ENGINE_R_NOT_LOADED
);
433 rv
= aep_close_all_connections(0, &in_use
);
436 ENGINEerr(ENGINE_F_AEP_FINISH
,ENGINE_R_CLOSE_HANDLES_FAILED
);
441 ENGINEerr(ENGINE_F_AEP_FINISH
,ENGINE_R_CONNECTIONS_IN_USE
);
445 rv
= p_AEP_Finalize();
448 ENGINEerr(ENGINE_F_AEP_FINISH
,ENGINE_R_FINALIZE_FAILED
);
453 if(!DSO_free(aep_dso
))
455 ENGINEerr(ENGINE_F_AEP_FINISH
,ENGINE_R_DSO_FAILURE
);
460 p_AEP_CloseConnection
= NULL
;
461 p_AEP_OpenConnection
= NULL
;
463 p_AEP_ModExpCrt
= NULL
;
465 p_AEP_GenRandom
= NULL
;
467 p_AEP_Initialize
= NULL
;
468 p_AEP_Finalize
= NULL
;
469 p_AEP_SetBNCallBacks
= NULL
;
476 static int aep_mod_exp(BIGNUM
*r
, BIGNUM
*a
, const BIGNUM
*p
,
477 const BIGNUM
*m
, BN_CTX
*ctx
)
481 AEP_CONNECTION_HNDL hConnection
;
484 r_len
= BN_num_bits(m
);
486 /* Perform in software if modulus is too large for hardware. */
488 if (r_len
> max_key_len
)
491 e
= ENGINE_openssl();
492 to_return
= e
->bn_mod_exp(r
, a
, p
, m
, ctx
);
496 /*Grab a connection from the pool*/
497 rv
= aep_get_connection(&hConnection
);
501 ENGINEerr(ENGINE_F_AEP_MOD_EXP
,ENGINE_R_GET_HANDLE_FAILED
);
503 e
= ENGINE_openssl();
504 to_return
= e
->bn_mod_exp(r
, a
, p
, m
, ctx
);
508 /*To the card with the mod exp*/
509 rv
= p_AEP_ModExp(hConnection
,(void*)a
, (void*)p
,(void*)m
, (void*)r
,NULL
);
515 aep_close_connection(hConnection
);
517 ENGINEerr(ENGINE_F_AEP_MOD_EXP
,ENGINE_R_MOD_EXP_FAILED
);
519 e
= ENGINE_openssl();
520 to_return
= e
->bn_mod_exp(r
, a
, p
, m
, ctx
);
525 /*Return the connection to the pool*/
526 rv
= aep_return_connection(hConnection
);
529 ENGINEerr(ENGINE_F_AEP_RAND
,ENGINE_R_RETURN_CONNECTION_FAILED
);
538 static AEP_RV
aep_mod_exp_crt(BIGNUM
*r
, const BIGNUM
*a
,
539 const BIGNUM
*p
, const BIGNUM
*q
,
540 const BIGNUM
*dmp1
,const BIGNUM
*dmq1
,
541 const BIGNUM
*iqmp
, BN_CTX
*ctx
)
543 AEP_RV rv
= AEP_R_OK
;
544 AEP_CONNECTION_HNDL hConnection
;
546 /* Perform in software if modulus is too large for hardware. */
548 if (BN_num_bits(p
) > max_key_len
|| BN_num_bits(q
) > max_key_len
){
550 e
= ENGINE_openssl();
551 rv
= e
->bn_mod_exp_crt(r
, a
, p
, q
, dmp1
, dmq1
, iqmp
, ctx
);
555 /*Grab a connection from the pool*/
556 rv
= aep_get_connection(&hConnection
);
561 ENGINEerr(ENGINE_F_AEP_MOD_EXP_CRT
,ENGINE_R_GET_HANDLE_FAILED
);
563 e
= ENGINE_openssl();
565 if (e
->bn_mod_exp_crt(r
, a
, p
, q
, dmp1
, dmq1
, iqmp
, ctx
) > 0)
568 rv
= AEP_R_GENERAL_ERROR
;
573 /*To the card with the mod exp*/
574 rv
= p_AEP_ModExpCrt(hConnection
,(void*)a
, (void*)p
, (void*)q
, (void*)dmp1
,(void*)dmq1
,
575 (void*)iqmp
,(void*)r
,NULL
);
580 aep_close_connection(hConnection
);
582 ENGINEerr(ENGINE_F_AEP_MOD_EXP_CRT
,ENGINE_R_MOD_EXP_CRT_FAILED
);
584 e
= ENGINE_openssl();
586 if (e
->bn_mod_exp_crt(r
, a
, p
, q
, dmp1
, dmq1
, iqmp
, ctx
) > 0)
589 rv
= AEP_R_GENERAL_ERROR
;
594 /*Return the connection to the pool*/
595 rv
= aep_return_connection(hConnection
);
598 ENGINEerr(ENGINE_F_AEP_RAND
,ENGINE_R_RETURN_CONNECTION_FAILED
);
607 static int aep_rand(unsigned char *buf
,int len
)
609 AEP_RV rv
= AEP_R_OK
;
610 AEP_CONNECTION_HNDL hConnection
;
612 CRYPTO_w_lock(CRYPTO_LOCK_RAND
);
614 /*Can the request be serviced with what's already in the buffer?*/
615 if (len
<= rand_block_bytes
)
617 memcpy(buf
, &rand_block
[RAND_BLK_SIZE
- rand_block_bytes
], len
);
618 rand_block_bytes
-= len
;
619 CRYPTO_w_unlock(CRYPTO_LOCK_RAND
);
622 /*If not the get another block of random bytes*/
624 CRYPTO_w_unlock(CRYPTO_LOCK_RAND
);
626 rv
= aep_get_connection(&hConnection
);
629 ENGINEerr(ENGINE_F_AEP_RAND
,ENGINE_R_GET_HANDLE_FAILED
);
633 if (len
> RAND_BLK_SIZE
)
635 rv
= p_AEP_GenRandom(hConnection
, len
, 2, buf
, NULL
);
638 ENGINEerr(ENGINE_F_AEP_RAND
,ENGINE_R_GET_RANDOM_FAILED
);
644 CRYPTO_w_lock(CRYPTO_LOCK_RAND
);
646 rv
= p_AEP_GenRandom(hConnection
, RAND_BLK_SIZE
, 2, &rand_block
[0], NULL
);
649 ENGINEerr(ENGINE_F_AEP_RAND
,ENGINE_R_GET_RANDOM_FAILED
);
654 rand_block_bytes
= RAND_BLK_SIZE
;
655 memcpy(buf
, &rand_block
[RAND_BLK_SIZE
- rand_block_bytes
], len
);
656 rand_block_bytes
-= len
;
658 CRYPTO_w_unlock(CRYPTO_LOCK_RAND
);
661 rv
= aep_return_connection(hConnection
);
664 ENGINEerr(ENGINE_F_AEP_RAND
,ENGINE_R_RETURN_CONNECTION_FAILED
);
672 CRYPTO_w_unlock(CRYPTO_LOCK_RAND
);
677 static int aep_rand_status(void)
684 static int aep_rsa_mod_exp(BIGNUM
*r0
, BIGNUM
*I
, RSA
*rsa
)
688 AEP_RV rv
= AEP_R_OK
;
690 if ((ctx
= BN_CTX_new()) == NULL
)
695 ENGINEerr(ENGINE_F_AEP_RSA_MOD_EXP
,ENGINE_R_NOT_LOADED
);
699 /*See if we have all the necessary bits for a crt*/
700 if (rsa
->q
&& rsa
->dmp1
&& rsa
->dmq1
&& rsa
->iqmp
)
702 rv
= aep_mod_exp_crt(r0
,I
,rsa
->p
,rsa
->q
, rsa
->dmp1
,rsa
->dmq1
,rsa
->iqmp
,ctx
);
708 if (!rsa
->d
|| !rsa
->n
)
710 ENGINEerr(ENGINE_F_AEP_RSA_MOD_EXP
,ENGINE_R_MISSING_KEY_COMPONENTS
);
714 rv
= aep_mod_exp(r0
,I
,rsa
->d
,rsa
->n
,ctx
);
730 static int aep_dsa_mod_exp(DSA
*dsa
, BIGNUM
*rr
, BIGNUM
*a1
,
731 BIGNUM
*p1
, BIGNUM
*a2
, BIGNUM
*p2
, BIGNUM
*m
,
732 BN_CTX
*ctx
, BN_MONT_CTX
*in_mont
)
738 /* let rr = a1 ^ p1 mod m */
739 if (!aep_mod_exp(rr
,a1
,p1
,m
,ctx
)) goto end
;
740 /* let t = a2 ^ p2 mod m */
741 if (!aep_mod_exp(&t
,a2
,p2
,m
,ctx
)) goto end
;
742 /* let rr = rr * t mod m */
743 if (!BN_mod_mul(rr
,rr
,&t
,m
,ctx
)) goto end
;
751 static int aep_mod_exp_dsa(DSA
*dsa
, BIGNUM
*r
, BIGNUM
*a
,
752 const BIGNUM
*p
, const BIGNUM
*m
, BN_CTX
*ctx
,
755 return aep_mod_exp(r
, a
, p
, m
, ctx
);
760 /* This function is aliased to mod_exp (with the mont stuff dropped). */
761 static int aep_mod_exp_mont(BIGNUM
*r
, BIGNUM
*a
, const BIGNUM
*p
,
762 const BIGNUM
*m
, BN_CTX
*ctx
, BN_MONT_CTX
*m_ctx
)
764 return aep_mod_exp(r
, a
, p
, m
, ctx
);
769 /* This function is aliased to mod_exp (with the dh and mont dropped). */
770 static int aep_mod_exp_dh(DH
*dh
, BIGNUM
*r
, BIGNUM
*a
, const BIGNUM
*p
,
771 const BIGNUM
*m
, BN_CTX
*ctx
, BN_MONT_CTX
*m_ctx
)
773 return aep_mod_exp(r
, a
, p
, m
, ctx
);
777 static AEP_RV
aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection
)
780 AEP_RV rv
= AEP_R_OK
;
782 /*Get the current process id*/
785 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE
);
789 /*Check if this is the first time this is being called from the current
791 if (recorded_pid
!= curr_pid
)
793 /*Remember our pid so we can check if we're in a new process*/
794 recorded_pid
= curr_pid
;
796 /*Call Finalize to make sure we have not inherited some data from a parent
800 /*Initialise the AEP API*/
801 rv
= p_AEP_Initialize(NULL
);
805 ENGINEerr(ENGINE_F_AEP_INIT
,ENGINE_R_AEP_INIT_FAILURE
);
810 /*Set the AEP big num call back functions*/
811 rv
= p_AEP_SetBNCallBacks(&GetBigNumSize
, &MakeAEPBigNum
, &ConvertAEPBigNum
);
816 ENGINEerr(ENGINE_F_AEP_INIT
,ENGINE_R_SETBNCALLBACK_FAILURE
);
822 /*Reset the rand byte count*/
823 rand_block_bytes
= 0;
826 /*Init the structures*/
827 for (count
= 0;count
< MAX_PROCESS_CONNECTIONS
;count
++)
829 aep_app_conn_table
[count
].conn_state
= NotConnected
;
830 aep_app_conn_table
[count
].conn_hndl
= 0;
833 /*Open a connection*/
834 rv
= p_AEP_OpenConnection(phConnection
);
838 ENGINEerr(ENGINE_F_AEP_INIT
,ENGINE_R_UNIT_FAILURE
);
843 aep_app_conn_table
[0].conn_state
= InUse
;
844 aep_app_conn_table
[0].conn_hndl
= *phConnection
;
847 /*Check the existing connections to see if we can find a free one*/
848 for (count
= 0;count
< MAX_PROCESS_CONNECTIONS
;count
++)
851 if (aep_app_conn_table
[count
].conn_state
== Connected
)
853 aep_app_conn_table
[count
].conn_state
= InUse
;
854 *phConnection
= aep_app_conn_table
[count
].conn_hndl
;
858 /*If no connections available, we're going to have to try to open a new one*/
859 for (count
= 0;count
< MAX_PROCESS_CONNECTIONS
;count
++)
861 if (aep_app_conn_table
[count
].conn_state
== NotConnected
)
863 /*Open a connection*/
864 rv
= p_AEP_OpenConnection(phConnection
);
868 ENGINEerr(ENGINE_F_AEP_INIT
,ENGINE_R_UNIT_FAILURE
);
872 aep_app_conn_table
[count
].conn_state
= InUse
;
874 aep_app_conn_table
[count
].conn_hndl
= *phConnection
;
879 rv
= AEP_R_GENERAL_ERROR
;
881 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE
);
886 static AEP_RV
aep_return_connection(AEP_CONNECTION_HNDL hConnection
)
890 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE
);
892 /*Find the connection item that matches this connection handle*/
893 for(count
= 0;count
< MAX_PROCESS_CONNECTIONS
;count
++)
895 if (aep_app_conn_table
[count
].conn_hndl
== hConnection
)
897 aep_app_conn_table
[count
].conn_state
= Connected
;
902 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE
);
907 static AEP_RV
aep_close_connection(AEP_CONNECTION_HNDL hConnection
)
910 AEP_RV rv
= AEP_R_OK
;
912 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE
);
914 /*Find the connection item that matches this connection handle*/
915 for(count
= 0;count
< MAX_PROCESS_CONNECTIONS
;count
++)
917 if (aep_app_conn_table
[count
].conn_hndl
== hConnection
)
919 rv
= p_AEP_CloseConnection(aep_app_conn_table
[count
].conn_hndl
);
922 aep_app_conn_table
[count
].conn_state
= NotConnected
;
923 aep_app_conn_table
[count
].conn_hndl
= 0;
929 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE
);
933 static AEP_RV
aep_close_all_connections(int use_engine_lock
, int *in_use
)
936 AEP_RV rv
= AEP_R_OK
;
939 if (use_engine_lock
) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE
);
940 for (count
= 0;count
< MAX_PROCESS_CONNECTIONS
;count
++)
942 switch (aep_app_conn_table
[count
].conn_state
)
945 rv
= p_AEP_CloseConnection(aep_app_conn_table
[count
].conn_hndl
);
948 aep_app_conn_table
[count
].conn_state
= NotConnected
;
949 aep_app_conn_table
[count
].conn_hndl
= 0;
959 if (use_engine_lock
) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE
);
963 /*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
964 Note only 32bit Openssl build support*/
966 static AEP_RV
GetBigNumSize(AEP_VOID_PTR ArbBigNum
, AEP_U32
* BigNumSize
)
970 /*Cast the ArbBigNum pointer to our BIGNUM struct*/
971 bn
= (BIGNUM
*) ArbBigNum
;
973 #ifdef SIXTY_FOUR_BIT_LONG
974 *BigNumSize
= bn
->top
<< 3;
976 /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
977 words) multiplies by 4*/
978 *BigNumSize
= bn
->top
<< 2;
984 static AEP_RV
MakeAEPBigNum(AEP_VOID_PTR ArbBigNum
, AEP_U32 BigNumSize
,
985 unsigned char* AEP_BigNum
)
989 #ifndef SIXTY_FOUR_BIT_LONG
994 /*Cast the ArbBigNum pointer to our BIGNUM struct*/
995 bn
= (BIGNUM
*) ArbBigNum
;
997 #ifdef SIXTY_FOUR_BIT_LONG
998 memcpy(AEP_BigNum
, bn
->d
, BigNumSize
);
1000 /*Must copy data into a (monotone) least significant byte first format
1001 performing endian conversion if necessary*/
1002 for(i
=0;i
<bn
->top
;i
++)
1004 buf
= (unsigned char*)&bn
->d
[i
];
1006 *((AEP_U32
*)AEP_BigNum
) = (AEP_U32
)
1007 ((unsigned) buf
[1] << 8 | buf
[0]) |
1008 ((unsigned) buf
[3] << 8 | buf
[2]) << 16;
1017 /*Turn an AEP Big Num back to a user big num*/
1018 static AEP_RV
ConvertAEPBigNum(void* ArbBigNum
, AEP_U32 BigNumSize
,
1019 unsigned char* AEP_BigNum
)
1022 #ifndef SIXTY_FOUR_BIT_LONG
1026 bn
= (BIGNUM
*)ArbBigNum
;
1028 /*Expand the result bn so that it can hold our big num. Size is in bits*/
1029 bn_expand(bn
, (int)(BigNumSize
<< 3));
1031 #ifdef SIXTY_FOUR_BIT_LONG
1032 bn
->top
= BigNumSize
>> 3;
1034 if((BigNumSize
& 7) != 0)
1037 memset(bn
->d
, 0, bn
->top
<< 3);
1039 memcpy(bn
->d
, AEP_BigNum
, BigNumSize
);
1041 bn
->top
= BigNumSize
>> 2;
1043 for(i
=0;i
<bn
->top
;i
++)
1045 bn
->d
[i
] = (AEP_U32
)
1046 ((unsigned) AEP_BigNum
[3] << 8 | AEP_BigNum
[2]) << 16 |
1047 ((unsigned) AEP_BigNum
[1] << 8 | AEP_BigNum
[0]);
1055 #endif /* !NO_HW_AEP */