gcry_control(GCRYCTL_INIT_SECMEM,...)

Simon Josefsson jas@extundo.com
Sat, 25 Jan 2003 17:29:52 +0100


Werner Koch <wk@gnupg.org> writes:

>> library using libgcrypt decides at runtime whether libgcrypt, and in
>> particular secure memory, is needed at all, and 3) the application
>
> You can't do that because with the Linux kernel you need to run the
> program setuid and drop this privilige as ASAP.  There is no way to
> enclose the secure memory use in a library.

That seems bad.  Is there any work going on to make it possible for
user-level code to allocate secure memory from the kernel (possibly
via libc)?

If not, I fear that making applications setuid in order for secure
memory to be available creates more security problems than it solves.

>> implements a network protocol where the stderr print will confuse the
>> implementation at the other end and cause it to drop the connection.
>
> I can see that.  The way to avoid this is by setting up an error
> handler:
>
>   static void
>   my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
>   {
>     /* optionally do something with LEVEL. */
>     vfprintf (whereever, fmt, arg_ptr);
>   }
>
>   gcry_set_log_handler (my_gcry_logger, NULL);
>
> Well, there is again the problem who should set this up: the library
> or the application.

Yes, and ideally I'd like to hide these details from the application.

Put concisely, I guess what I want is this: If secure memory cannot be
used without support from the application using my library, I want to
use libgcrypt without secure memory, and for this to happen silently.

> So what I propose is to do a default init in your library and document
> what an application should better do; i.e. initialize Libgcrypt if
> at all possible.

This is what I'll do, with the "default init" being:

  if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P) == 0)
    {
      if (gcry_check_version (GCRYPT_VERSION) == NULL)
	return GSASL_GCRYPT_ERROR;
      if (gcry_control (GCRYCTL_DISABLE_SECMEM, NULL, 0) != GCRYERR_SUCCESS)
	return GSASL_GCRYPT_ERROR;
      if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED,
		       NULL, 0) != GCRYERR_SUCCESS)
	return GSASL_GCRYPT_ERROR;
    }

Quick testing suggests it does what I want.

Thanks.