There is a problem with the locking in the chil engine support in
openssl-engine-0.9.6a
In hw_ncipher.c
static int hwcrhk_mutex_init(HWCryptoHook_Mutex*
mt,HWCryptoHook_CallerContext *cactx)
static int
hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
should both return 0 for success NOT 1 as documented in the chil header
file - hwcryptohook.h
Furthermore when this is fixed I found that although
CRYPTO_get_new_dynlockid() did call my dynamic locking upcall function
CRYPTO_w_lock(mt->lockid) did not ! I didn't look too hard at the dynamic
locking code in cryptlib.c however I was concerned with the following code
that seems to decrement the reference count of the CRYPTO_dynlock pointer
twice:
void CRYPTO_destroy_dynlockid(int i)
{
CRYPTO_dynlock *pointer = NULL;
if (i)
i = -i-1;
if (dynlock_destroy_callback == NULL)
return;
CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
if (dyn_locks == NULL || i >=
sk_CRYPTO_dynlock_num(dyn_locks))
return;
pointer =
sk_CRYPTO_dynlock_value(dyn_locks, i);
if (pointer != NULL)
{
--pointer->references;
#ifdef REF_CHECK
if (pointer->references < 0)
{
fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference
count\n");
abort();
}
else
#endif
if (--(pointer->references) <= 0)
{
sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
}
else
pointer =
NULL;
}
CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
if (pointer)
{
dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
OPENSSL_free(pointer);
}
}
When I changed the hw_ncipher.c code to use static locks instead of dynamic
locks everything worked fine and the multithreaded application used the
chil library successfully under load.
I changed
---------------------------------------------------------------
static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
HWCryptoHook_CallerContext *cactx)
{
mt->lockid =
CRYPTO_get_new_dynlockid();
if (mt->lockid == 0)
return 0;
return 1;
}
static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
{
CRYPTO_w_lock(mt->lockid);
return 1;
}
void
hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
{
CRYPTO_w_unlock(mt->lockid);
}
static void
hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
{
CRYPTO_destroy_dynlockid(mt->lockid);
}
---------------------------------------------------------------
to
---------------------------------------------------------------
static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
HWCryptoHook_CallerContext *cactx)
{
return 0;
}
static int
hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
{
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
return 0;
}
void
hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
{
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
}
static void
hwcrhk_mutex_destroy(HWCryptoHook_Mutex
*mt){}
---------------------------------------------------------------
Obviously reusing the CRYPTO_LOCK_ENGINE lock is not ideal but shouldn't
impact on performance.
As an aside it would be really useful if openssl came with a multithreaded
test program so that we could catch these problems before openssl releases.
Regards,
Bertie
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]