libgcrypt 1.1.93 released

Marcus Brinkmann marcus.brinkmann at ruhr-uni-bochum.de
Tue Mar 9 15:01:21 CET 2004


At Tue, 9 Mar 2004 14:21:49 +0100,
Brieuc Jeunhomme wrote:
> 
> >  Why no have a libgcrypt linked with both pthread and pth, but do no
> > locking, unless explicitely requested. That is an application that
> > uses pthread calls something like gcry_enable_pthread_locks() etc.
> > Is this a viable solution? 
> 
> It may be better to have a gcry_set_locking_function(), because some

As stated in my other mail, this interface would have to be passed
through all intermediate libraries.  IE, libldap would have to provide
an interface to set the locking function for gcrypt, and two or three
libraries inbetween as well.

> multithreaded applications do not use pthread nor pth. For instance,
> about a problem I have with gnutls, I had to develop a clone() based
> hack. libgcrypt shouldn't have to bother with the specific threading
> implemention the application uses, should it?

In general, a library might need to protect itself against concurrent
access from multiple application threads.  So, yes, it has to bother
with the threading model of the application in a very direct sense.

In addition, a library that is used in a user-level thread package
like pth might block in undesirable places (read(), write(),
select()...)  and should at these places instead yield to allow other
user-level threads a chance to run.  Again, it has to cooperate with
the thread package of the application.

Callbacks are a solution that can work, but with the above interface cost.
 
> > Since the only non-reentrant part is the random generator, an other 
> > solution would be to add a thread safe random number generator api 
> > (ie return handle of a pool), so the only one bothered with
> > locking is the application.
> 
> Why not simply read "/dev/urandom" on OSes where it is available?

The question is really much broader than getting randomness.  If it is
not randomness, it is locking of internal data structures or something
else.  In GnuPG, we pull all strings to achieve our goal: For example,
to fix ggcrypt, the global errno has been replaced with error return
values for all functions.  This is a natural interface change that
goes a long way towards thread-safeness.  However, sometimes this is
not possible, or rather only possible at extreme maintenance and/or
interface complexity costs.

Example: getenv() is not thread-safe.  I might be able to fork() and
use I/O to determine the environment variable.  That is possible
thread-safe, but expensive and a lot of work (= high costs).  It is
also error prone.

Example: You might be able to develop reentrant interfaces.  gpg-error
has a function gpg_strerror_r, which is thread-safe.  However, it is
much more difficult to use correctly that gpg_strerror.  Still, in
this case, we opted for this solution rather than to make gpg-error
thread aware.  In other cases, it is important to provide simple and
easy to use interfaces, and do the locking internally.  I don't know,
but for an entropy pool encapsulation and opaqueness sounds like a
good thing.  If I would work on a user allocated and maintained pool,
the user might accidently provide wrong arguments and destroy any
security he expects to get.

So, every case has to be considered individually, and we are certainly
doing this.  Maybe werner can tell you why the random pool in gcrypt
exists, and why it is internal arather than provided and managed by
the user.  In any case we are open to suggestions how to do it better,
although I doubt that in gcrypt's case just using /dev/urandom hits
the bullet (if it were that easy, I guess we'd be doing it already).

Thanks,
Marcus



More information about the Gcrypt-devel mailing list