
simon at josefsson
Dec 5, 2008, 3:04 AM
Post #7 of 9
(2111 views)
Permalink
|
Werner Koch <wk [at] gnupg> writes: > On Thu, 4 Dec 2008 20:37, simon [at] josefsson said: > >> If I remove that code, using any application that uses the GnuTLS >> library with some functions just dies: >> >> jas [at] mocc:~/src/gnutls/src master$ ./certtool -p >> Generating a 2048 bit RSA private key... >> Ohhhh jeeee: operation is not possible without initialized secure memory > > Right, because it is not properly initialized. We need to fix the > application and not try to work around such problems. Application? GnuTLS is a library. We don't want to require all applications that use GnuTLS to call libgcrypt explicitly. > If you don't have a need for secure memory, for example if your > application does not use secret keys or other confidential data or it > runs in a controlled environment where key material floating around in > memory is not a problem, you - or weel the application - should > initialize Libgcrypt correctly. I recently updated the manual to make > this more clear. Here is an excerpt: > > | If you have to protect your keys or other information in memory > | against being swapped out to disk and to enable an automatic overwrite > | of used and freed memory, you need to initialize Libgcrypt this way: > | > | /* Version check should be the very first call because it > | makes sure that important subsystems are intialized. */ > | if (!gcry_check_version (GCRYPT_VERSION)) > | { > | fputs ("libgcrypt version mismatch\n", stderr); > | exit (2); > | } > | > | /* Disable secure memory. */ > | gcry_control (GCRYCTL_DISABLE_SECMEM, 0); > | > | /* ... If required, other initialization goes here. */ > | > | /* Tell Libgcrypt that initialization has completed. */ > | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); Ok, this would argue for the following solution: diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c index f59a47f..2c2a91f 100644 --- a/lib/gnutls_global.c +++ b/lib/gnutls_global.c @@ -222,8 +222,7 @@ gnutls_global_init (void) } /* 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_DISABLE_SECMEM, NULL, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0); > | > | If you have to protect your keys or other information in memory > | against being swapped out to disk and to enable an automatic overwrite > | of used and freed memory, you need to initialize Libgcrypt this way: This is the exact same text as above. What is the difference between these two modes? > | /* Version check should be the very first call because it > | makes sure that important subsystems are intialized. */ > | if (!gcry_check_version (GCRYPT_VERSION)) > | { > | fputs ("libgcrypt version mismatch\n", stderr); > | exit (2); > | } > | > | /* We don't want to see any warnings, e.g. because we have not yet > | parsed program options which might be used to suppress such > | warnings. */ > | gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); > | > | /* ... If required, other initialization goes here. Note that the > | process might still be running with increased privileges and that > | the secure memory has not been intialized. */ > | > | /* Allocate a pool of 16k secure memory. This make the secure memory > | available and also drops privileges where needed. */ > | 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); > | > | /* ... If required, other initialization goes here. */ > | > | /* Tell Libgcrypt that initialization has completed. */ > | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); What does "increased privileges" mean? Does the application needs to be setuid for this to work? That would also be a non-starter, we can't require all applications using GnuTLS to be setuid. > | It is important that these initialization steps are not done by a > | library but by the actual application. That seems like a non-starter for GnuTLS. If it is important for libgcrypt that GnuTLS doesn't initialize libgcrypt, it seems we can't really use libgcrypt in GnuTLS. > | A library using Libgcrypt might want to check for finished > | initialization using: > | > | if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) > | { > | fputs ("libgcrypt has not been initialized\n", stderr); > | abort (); > | } > | > | Instead of terminating the process, the library may instead print a > | warning and try to initialize Libgcrypt itself. This is what GnuTLS is doing now, except it is not printing a warning. What use is there in printing a warning? > I am sorry that these things are a bit complicated. However I believe > that we should better choose the safe side of things. The crypto > library is low-level foundation code and problems there would affect a > lot of applications. Better some applications break than applications > requiring real security are exploitable. The best would that things just work _and_ be secure. I don't see why it isn't possible to reach that goal here? /Simon _______________________________________________ Gcrypt-devel mailing list Gcrypt-devel [at] gnupg http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
|