Next: , Previous: , Up: Preparation   [Contents][Index]


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. 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 initialized.
     #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
    {
      fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
         NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
      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 initialized.
     #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
    {
      fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
         NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
      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 initialized.  */

  /* Allocate a pool of 16k secure memory.  This makes the secure memory
     available and also drops privileges where needed.  Note that by
     using functions like gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt
     may expand the secure memory pool with memory which lacks the
     property of not being swapped out to disk.   */
  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.


Next: Multi-Threading, Previous: Building sources using Automake, Up: Preparation   [Contents][Index]