Next: , Previous: Building sources using Automake, Up: Preparation


2.4 Initializing the library

Before the library can be used, it must initialize itself. This is achieved by invoking the function gcry_check_version described below.

Also, it is often desirable to check that the version of Libgcrypt used is indeed one which fits all requirements. Even with binary compatibility, new features may have been introduced, but due to problem with the dynamic linker an old version may actually be used. So you may want to check that the version is okay right after program startup.

— Function: const char * gcry_check_version (const char *req_version)

The function gcry_check_version initializes some subsystems used by Libgcrypt and must be invoked before any other function in the library, with the exception of the GCRYCTL_SET_THREAD_CBS command (called via the gcry_control function). See Multi-Threading.

Furthermore, this function returns the version number of the library. It can also verify that the version number is higher than a certain required version number req_version, if this value is not a null pointer.

Libgcrypt uses a concept known as secure memory, which is a region of memory set aside for storing sensitive data. Because such memory is a scarce resource, it needs to be setup in advanced to a fixed size. Further, most operating systems have special requirements on how that secure memory can be used. For example, it might be required to install an application as “setuid(root)” to allow allocating such memory. Libgcrypt requires a sequence of initialization steps to make sure that this works correctly. The following examples show the necessary steps.

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 should 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.