[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2. Preparation

To use Libgcrypt, you have to perform some changes to your sources and the build system. The necessary changes are small and explained in the following sections. At the end of this chapter, it is described how the library is initialized, and how the requirements of the library are verified.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.1 Header

All interfaces (data types and functions) of the library are defined in the header file `gcrypt.h'. You must include this in all source files using the library, either directly or through some other header file, like this:

 
#include <gcrypt.h>

The name space of Libgcrypt is gcry_* for function and type names and GCRY* for other symbols. In addition the same name prefixes with one prepended underscore are reserved for internal use and should never be used by an application. Note that Libgcrypt uses libgpg-error, which uses gpg_* as name space for function and type names and GPG_* for other symbols, including all the error codes.

Certain parts of gcrypt.h may be excluded by defining these macros:

GCRYPT_NO_MPI_MACROS

Do not define the shorthand macros mpi_* for gcry_mpi_*.

GCRYPT_NO_DEPRECATED

Do not include defintions for deprecated features. This is useful to make sure that no deprecated features are used.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2 Building sources

If you want to compile a source file including the `gcrypt.h' header file, you must make sure that the compiler can find it in the directory hierarchy. This is accomplished by adding the path to the directory in which the header file is located to the compilers include file search path (via the `-I' option).

However, the path to the include file is determined at the time the source is configured. To solve this problem, Libgcrypt ships with a small helper program libgcrypt-config that knows the path to the include file and other configuration options. The options that need to be added to the compiler invocation at compile time are output by the `--cflags' option to libgcrypt-config. The following example shows how it can be used at the command line:

 
gcc -c foo.c `libgcrypt-config --cflags`

Adding the output of `libgcrypt-config --cflags' to the compilers command line will ensure that the compiler can find the Libgcrypt header file.

A similar problem occurs when linking the program with the library. Again, the compiler has to find the library files. For this to work, the path to the library files has to be added to the library search path (via the `-L' option). For this, the option `--libs' to libgcrypt-config can be used. For convenience, this option also outputs all other options that are required to link the program with the Libgcrypt libraries (in particular, the `-lgcrypt' option). The example shows how to link `foo.o' with the Libgcrypt library to a program foo.

 
gcc -o foo foo.o `libgcrypt-config --libs`

Of course you can also combine both examples to a single command by specifying both options to libgcrypt-config:

 
gcc -o foo foo.c `libgcrypt-config --cflags --libs`

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.3 Building sources using Automake

It is much easier if you use GNU Automake instead of writing your own Makefiles. If you do that, you do not have to worry about finding and invoking the libgcrypt-config script at all. Libgcrypt provides an extension to Automake that does all the work for you.

Macro: AM_PATH_LIBGCRYPT ([minimum-version], [action-if-found], [action-if-not-found])

Check whether Libgcrypt (at least version minimum-version, if given) exists on the host system. If it is found, execute action-if-found, otherwise do action-if-not-found, if given.

Additionally, the function defines LIBGCRYPT_CFLAGS to the flags needed for compilation of the program to find the `gcrypt.h' header file, and LIBGCRYPT_LIBS to the linker flags needed to link the program to the Libgcrypt library.

You can use the defined Autoconf variables like this in your `Makefile.am':

 
AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS)
LDADD = $(LIBGCRYPT_LIBS)

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [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, with the exception of the GCRYCTL_SET_THREAD_CBS command (called via the gcry_control function). See section 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.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.5 Multi-Threading

As mentioned earlier, the Libgcrypt library is thread-safe if you adhere to the following requirements:

Libgcrypt contains convenient macros, which define the necessary thread callbacks for PThread and for GNU Pth:

GCRY_THREAD_OPTION_PTH_IMPL

This macro defines the following (static) symbols: gcry_pth_init, gcry_pth_mutex_init, gcry_pth_mutex_destroy, gcry_pth_mutex_lock, gcry_pth_mutex_unlock, gcry_pth_read, gcry_pth_write, gcry_pth_select, gcry_pth_waitpid, gcry_pth_accept, gcry_pth_connect, gcry_threads_pth.

After including this macro, gcry_control() shall be used with a command of GCRYCTL_SET_THREAD_CBS in order to register the thread callback structure named "gcry_threads_pth".

GCRY_THREAD_OPTION_PTHREAD_IMPL

This macro defines the following (static) symbols: gcry_pthread_mutex_init, gcry_pthread_mutex_destroy, gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock, gcry_threads_pthread.

After including this macro, gcry_control() shall be used with a command of GCRYCTL_SET_THREAD_CBS in order to register the thread callback structure named "gcry_threads_pthread".

Note that these macros need to be terminated with a semicolon. Keep in mind that these are convenient macros for C programmers; C++ programmers might have to wrap these macros in an "extern C" body.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.6 How to enable the FIPS mode

Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check the NIST database at http://csrc.nist.gov/groups/STM/cmvp/ to see what versions of Libgcrypt are approved.

Because FIPS 140 has certain restrictions on the use of cryptography which are not always wanted, Libgcrypt needs to be put into FIPS mode explicitly. Three alternative mechanisms are provided to switch Libgcrypt into this mode:

In addition to the standard FIPS mode, Libgcrypt may also be put into an Enforced FIPS mode by writing a non-zero value into the file `/etc/gcrypt/fips_enabled'. The Enforced FIPS mode helps to detect applications which don't fulfill all requirements for using Libgcrypt in FIPS mode (see section Description of the FIPS Mode).

Once Libgcrypt has been put into FIPS mode, it is not possible to switch back to standard mode without terminating the process first. If the logging verbosity level of Libgcrypt has been set to at least 2, the state transitions and the self-tests are logged.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated on January, 20 2010 using texi2html 1.76.