Use of custom memory allocators
Werner Koch
wk at gnupg.org
Thu Dec 4 22:08:05 CET 2008
On Thu, 4 Dec 2008 20:37, simon at josefsson.org said:
> If I remove that code, using any application that uses the GnuTLS
> library with some functions just dies:
>
> jas at mocca:~/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.
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);
|
| 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);
| }
|
| /* 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);
|
| It is important that these initialization steps are not done by a
| library but by the actual application. 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. See also the section on
| multi-threading below for more pitfalls.
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.
Salam-Shalom,
Werner
--
Die Gedanken sind frei. Auschnahme regelt ein Bundeschgesetz.
More information about the Gcrypt-devel
mailing list