[Opendnssec-develop] Thread safety

Roy Arends roy at nominet.org.uk
Wed Dec 3 23:51:44 UTC 2008

Rickard Bondesson wrote on 12/03/2008 01:18:39 PM:

> One comment in hsm-speed.c says:
> // Initialize Library
> // Note that we do not need mutex locking for thread safety,
> // since we're using one session per thread.
> But PKCS11 says:
> "A call to C_Initialize with pInitArgs set to NULL_PTR is treated 
> like a call to
> C_Initialize with pInitArgs pointing to a CK_C_INITIALIZE_ARGS which has 
> CreateMutex, DestroyMutex, LockMutex, UnlockMutex, and pReserved fields 
set to
> NULL_PTR, and has the flags field set to 0."
> And
> "1. If the flag isn?t set, and the function pointer fields aren?t 
> supplied (i.e., they all have
> the value NULL_PTR), that means that the application won?t be accessing 
> Cryptoki library from multiple threads simultaneously."
> This means that the HSM will not create any locking mechanisms for 
> its crucial components like its object store, which in my case are 
> shared between the sessions.

In general, when you have multiple threads, and all threads use the same 
object X and there is only one global session, you'd need to set a lock 
before calling C_SignInit and unlock it after C_SignFinal. Otherwise 
things go completely haywire.

However, using a session per thread makes sure that the call serie 
(C_SignInit, C_Sign) is orthogonal and independent from other call series. 
This is needed when you want to optimize the use of HSMs for speed. 
Needless to say, using mutex concepts will bog down performance 
significantly. Also see the section "Notes on PKCS11" from this article: 

> My SoftHSM will because of this fail, when the hsm-speed.c runs 
> multiple threads, due to multiple accesses to a single object. (The 
> failure is in the crypto lib when it accesses its key objects. The 
> lib is thread safe but not for a single object.)
> Which is the appropriate action? Should I, as a HSM, create locks 
> although the external application did not want me to do that? Or 
> should the hsm-speed.c be modified so that it either provides mutex 
> functions or tell the HSM to use its own mutex functions.

Modifying hsm-speed.c is always an option (since it is my code anyway), 
but consider that hsm-speed.c works, without exception on 5 different, 
completely independent PKCS11 libraries. 

This is what I can offer from the standard: section 6.7.6:

"... an application should never make multiple simultaneous function calls 
to Cryptoki which use a common session.  If multiple threads of an 
application attempt to use a common session concurrently in this fashion, 
Cryptoki does not define what happens."

(this implicitly says don't use multiple threads per session, use at most 
one thread per session.)

" This means that if multiple threads of an application all need to use 
Cryptoki to access a particular token, it might be appropriate for each 
thread to have its own session with the token, unless the application can 
ensure by some other means (e.g., by some locking mechanism) that no 
sessions are ever used by multiple threads simultaneously."

(Since I do not want to use a locking mechanism to avoid impact on 
performance, I was left with using a session per thread)

" This is true regardless of whether or not the Cryptoki library was 
initialized in a fashion which permits safe multi-threaded access to it. 
Even if it is safe to access the library from multiple threads 
simultaneously, it is still not necessarily safe to use a particular 
session from multiple threads simultaneously. "

(This actually shows that sharing a session across multiple threads is not 
recommended, not even safe).

Hope this helps a bit.


Roy Arends
Sr. Researcher
Nominet UK

More information about the Opendnssec-develop mailing list