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]

Reply via email to