Mailing List Archive

RE: [gnutls-dev] Re: living without global variables
>
> > Doesn't it? gnutls' global init function does _something_ with
> > Libgcrypt. How is that different?
>
> Gnutls handles the Libgcrypt initialization internally and thus
> requires that the user of gnutls has knowledge about the internal use
> of libgcrypt. If you are using libgcrypt in a threading environment
> the gnutls callers needs to make sure that Libgcrypt has been
> initialized correctly - the last time I checked, gnutls does not know
> the threading system in use and thus can't initialize
> Libgcrypt properly.
>
> With an initialization function similar to the one of Libgcrypt it
> would be possible to hide the use of Libgcrypt.
>
> We do not create thread specific versions of Libgcrypt because this
> would require all libs using Libgcrypt to also come in different
> flavors (plain, pthread, pth) - not very efficient. For certain OSes
> we might be able to do some trickery in detecting and initializing the
> threading lib in use but this is not portable.
>
> > Assuming you have to have global variables, of course.
>
> The major reason for global state is the entropy pool. Collecting
> entropy is a time consuming task and we can't do it for each new
> session. Another one is libgcrypt's "secure" memory allocation
> functions - obviously this can't be done on a per session base or
> delegated to a daemon. With encrypted swap you won't need it, but
> this OS feature is not yet in widespread use.
>
> Thus this is all a matter of telling libgcrypt to use the correct
> threading system.
>
> Unloading Libgcrypt is not possible unless all users agree on shutting
> down all threads (but one) using Libgcrypt, restoring all hooks and
> releasing all secure memory. Libgcrypt can't detect such a condition
> and this is the reason we don't provide a deinit function.
>
> For a plugin system one could use wrapper functions to provide a
> managed interface to libgcrypt. The problem is that you need to do
> this for most libraries which are subject to "unloading" and change
> all those libraries to use these wrapper functions. Writing a plugin
> system in a portable way is not easy. Frankly, I see no way to create
> in-process plugins without restricting the APIs a plugin may use.
> Creating plugins as separate processes is far easier, more secure and
> really portable.
>
>
> Shalom-Salam,
>
> Werner
>

There is also another possibility that can fix (I hope) all problems.
Mainly initializers in libgcrypt are functions that manage module
registrations. Module registrations just add entries to some linked
list. It would be possible to initialize these lists statically. Well,
let me explain with an example this solution. gcry_module is defined as

struct gcry_module
{
struct gcry_module *next; /* List pointers. */
struct gcry_module **prevp;
void *spec; /* The acctual specs. */
int flags; /* Associated flags. */
int counter; /* Use counter. */
unsigned int mod_id; /* ID of this module. */
};

we could define a statically handled list as

extern gcry_module _gcry_module1;
extern gcry_module _gcry_module2;

static gcry_module_t ciphers_registered = &_gcry_module1;

gcry_module _gcry_module1 = {
&_gcry_module2,
&ciphers_registered,
my_cipher_spec1, /* replace with correct value*/
FLAG_MODULE_STATIC_ALLOCATED, /* or whatever you decide */
0, /* ?? */
MODULE_ID_MIN
};

gcry_module _gcry_module2 = {
NULL,
&_gcry_module1.next,
my_cipher_spec2,
FLAG_MODULE_STATIC_ALLOCATED,
0, /* ?? */
MODULE_ID_MIN+1
};

This method use a static allocation (and in this case even a static
initialization but this can be changed as you like). Someone could
object that if a shared library adds some module dynamically to gcrypt
in this case we would still have a memory leak however is up to shared
library that register the module to release it.

Frediano Ziglio

_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
Re: [gnutls-dev] Re: living without global variables [ In reply to ]
On Tue, 3 Jan 2006 14:36:26 +0100, ZIGLIO, Frediano, VF-IT said:

> There is also another possibility that can fix (I hope) all problems.
> Mainly initializers in libgcrypt are functions that manage module
> registrations. Module registrations just add entries to some linked

Actually these are the less critical ones. For various other reasons
we need a locking mechanism anyway and thus the static tablle creation
does not really help.

If you are only working with GNU based system, you can try to init
Libgcrypt from the actual application (maybe even with a Libgcrypt
loader plugin) so that the other plugins will use the already loaded
and initialized Libgcrypt.

To get everything right all libraries between Libgcrypt and and the
application must be aware of the threading system in use. We tinkered
a lot with libgcrypt to make this as easy as possible and ventually
setlled for the current solution - it is by far the most portable one.
All other more automagically working implementations are either non
portable or lead to headaches when writing the build rules for larger
applications.


Shalom-Salam,

Werner





_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel