[Opendnssec-develop] Thread safety
roy at nominet.org.uk
Thu Dec 4 00:51:44 CET 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
> NULL_PTR, and has the flags field set to 0."
> "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.
More information about the Opendnssec-develop