gcry_control(GCRYCTL_INIT_SECMEM,...)
Werner Koch
wk@gnupg.org
Thu, 23 Jan 2003 17:53:07 +0100
On Thu, 23 Jan 2003 15:14:17 +0100, Simon Josefsson said:
> gcry_control() prints warnings to stderr if called multiple times,
> which isn't always possible to avoid (consider two shared libraries
> each using libgcrypt without knowing about each other, linked into the
> same application). Would disabling the error message cause any
> problems?
No.
However you should never see this message because libgcrypt should
make sure that it is initialized only once - as early as possible and
definitely before you create another thread. The application must
decide whether secure memory is required or not. If there is no need
for it; the following code should be used:
/* Version check should be the very first gcry call because it
makes sure that constructor functrions are run. */
if (!gcry_check_version (GCRYPT_VERSION))
die ("version mismatch\n");
/* Many applications don't require secure memory, so they should
disable it right away. There won't be a problem unless one makes
use of a feature which requires secure memoery - in that case the
process would abort becuase the secmem is not initialized. */
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
/* .. add whatever initialization you want, but better don't make calls
to libgcrypt from more than one thread ... */
/* Tell Libgcrypt that initialization has completed. */
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
If you require secure memory, this code should be used:
if (!gcry_check_version (GCRYPT_VERSION))
die ("version mismatch\n");
/* We don't want to see any warnings, e.g. because we have not yet
parsed options which might be used to suppress such warnings */
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
/* ... */
/* Allocate a pool of 16k secure memory. This also drops priviliges
on some systems. */
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
/* It is now okay to let Libgcrypt complain when there was/is a problem
with the secure memory. */
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
/* Tell Libgcrypt that initialization has completed. */
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
This sounds a bit complicated but has the advantage that the caller
must decide whether he wants secure memory or not - there is no
default.
It is important that this initialization is not done by a library but
in the application. The library might want to check for finished
initialization using:
if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P))
return MYLIB_ERROR_LIBGCRYPT_NOT_INITIALIZED;
or as GNUTLS does it (while still single-threaded):
if (gcry_control( GCRYCTL_ANY_INITIALIZATION_P) == 0) {
/* for gcrypt in order to be able to allocate memory */
gcry_set_allocation_handler(gnutls_malloc, gnutls_secure_malloc,
_gnutls_is_secure_memory,
gnutls_realloc,
gnutls_free);
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL,0);
}
So the bottom line is that IMHO the message is useful.
Salam-Shalom,
Werner