### 3.1 Controlling the library ¶

Function: `gcry_error_t` gcry_control `(enum gcry_ctl_cmds cmd, ...)` ¶

  This function can be used to influence the general behavior of Libgcrypt in several ways. Depending on cmd, more arguments can or have to be provided.

  `GCRYCTL_ENABLE_M_GUARD; Arguments: none`

    This command was to enable the built-in memory guard, but not supported any more.

  `GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none`

    This command inhibits the use the very secure random quality level (`GCRY_VERY_STRONG_RANDOM`) and degrades all request down to `GCRY_STRONG_RANDOM`. In general this is not recommended. However, for some applications the extra quality random Libgcrypt tries to create is not justified and this option may help to get better performance. Please check with a crypto expert whether this option can be used for your application.

    This option can only be used at initialization time.

  `GCRYCTL_DUMP_RANDOM_STATS; Arguments: none`

    This command dumps random number generator related statistics to the library’s logging stream.

  `GCRYCTL_DUMP_MEMORY_STATS; Arguments: none`

    This command dumps memory management related statistics to the library’s logging stream.

  `GCRYCTL_DUMP_SECMEM_STATS; Arguments: none`

    This command dumps secure memory management related statistics to the library’s logging stream.

  `GCRYCTL_DROP_PRIVS; Arguments: none`

    This command disables the use of secure memory and drops the privileges of the current process. This command has not much use; the suggested way to disable secure memory is to use `GCRYCTL_DISABLE_SECMEM` right after initialization.

  `GCRYCTL_DISABLE_SECMEM; Arguments: none`

    This command disables the use of secure memory. In FIPS mode this command has no effect at all.

    Many applications do not require secure memory, so they should disable it right away. This command should be executed right after `gcry_check_version`.

  `GCRYCTL_DISABLE_LOCKED_SECMEM; Arguments: none`

    This command disables the use of the mlock call for secure memory. Disabling the use of mlock may for example be done if an encrypted swap space is in use. This command should be executed right after `gcry_check_version`. 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 (but will still be zeroed out on free).

  `GCRYCTL_DISABLE_PRIV_DROP; Arguments: none`

    This command sets a global flag to tell the secure memory subsystem that it shall not drop privileges after secure memory has been allocated. This command is commonly used right after `gcry_check_version` but may also be used right away at program startup. It won’t have an effect after the secure memory pool has been initialized. WARNING: A process running setuid(root) is a severe security risk. Processes making use of Libgcrypt or other complex code should drop these extra privileges as soon as possible. If this command has been used the caller is responsible for dropping the privileges.

  `GCRYCTL_INIT_SECMEM; Arguments: unsigned int nbytes`

    This command is used to allocate a pool of secure memory and thus enabling the use of secure memory. It also drops all extra privileges the process has (i.e., if it is run as setuid (root)). If the argument nbytes is 0, secure memory will be disabled. The minimum amount of secure memory allocated is currently 16384 bytes; you may thus use a value of 1 to request that default size.

  `GCRYCTL_AUTO_EXPAND_SECMEM; Arguments: unsigned int chunksize`

    This command enables on-the-fly expanding of the secure memory area. Note that by using functions like `gcry_xmalloc_secure` and `gcry_mpi_snew` will do this auto expanding anyway. The argument to this option is the suggested size for new secure memory areas. A larger size improves performance of all memory allocation and releasing functions. The given chunksize is rounded up to the next 32KiB. The drawback of auto expanding is that memory might be swapped out to disk; this can be fixed by configuring the system to use an encrypted swap space.

  `GCRYCTL_TERM_SECMEM; Arguments: none`

    This command zeroises the secure memory and destroys the handler. The secure memory pool may not be used anymore after running this command. If the secure memory pool has already been destroyed, this command has no effect. Applications might want to run this command from their exit handler to make sure that the secure memory gets properly destroyed. This command is not necessarily thread-safe but that should not be needed in cleanup code. It may be called from a signal handler.

  `GCRYCTL_DISABLE_SECMEM_WARN; Arguments: none`

    Disable warning messages about problems with the secure memory subsystem. This command should be run right after `gcry_check_version`.

  `GCRYCTL_SUSPEND_SECMEM_WARN; Arguments: none`

    Postpone warning messages from the secure memory subsystem. See the initialization example, on how to use it.

  `GCRYCTL_RESUME_SECMEM_WARN; Arguments: none`

    Resume warning messages from the secure memory subsystem. See the initialization example, on how to use it.

  `GCRYCTL_USE_SECURE_RNDPOOL; Arguments: none`

    This command tells the PRNG to store random numbers in secure memory. This command should be run right after `gcry_check_version` and not later than the command GCRYCTL_INIT_SECMEM. Note that in FIPS mode the secure memory is always used.

  `GCRYCTL_SET_RANDOM_SEED_FILE; Arguments: const char *filename`

    This command specifies the file, which is to be used as seed file for the PRNG. If the seed file is registered prior to initialization of the PRNG, the seed file’s content (if it exists and seems to be valid) is fed into the PRNG pool. After the seed file has been registered, the PRNG can be signalled to write out the PRNG pool’s content into the seed file with the following command.

  `GCRYCTL_UPDATE_RANDOM_SEED_FILE; Arguments: none`

    Write out the PRNG pool’s content into the registered seed file.

    Multiple instances of the applications sharing the same random seed file can be started in parallel, in which case they will read out the same pool and then race for updating it (the last update overwrites earlier updates). They will differentiate only by the weak entropy that is added in read_seed_file based on the PID and clock, and up to 16 bytes of weak random non-blockingly. The consequence is that the output of these different instances is correlated to some extent. In a perfect attack scenario, the attacker can control (or at least guess) the PID and clock of the application, and drain the system’s entropy pool to reduce the "up to 16 bytes" above to 0. Then the dependencies of the initial states of the pools are completely known. Note that this is not an issue if random of `GCRY_VERY_STRONG_RANDOM` quality is requested, as in this case enough extra entropy gets mixed. It is also not an issue when using rndgetentropy or rndoldlinux module, because the module guarantees to read full 16 bytes and thus there is no way for an attacker without kernel access to control these 16 bytes.

  `GCRYCTL_CLOSE_RANDOM_DEVICE; Arguments: none`

    Try to close the random device. If on Unix system you call fork(), the child process does no call exec(), and you do not intend to use Libgcrypt in the child, it might be useful to use this control code to close the inherited file descriptors of the random device. If Libgcrypt is later used again by the child, the device will be re-opened. On non-Unix systems this control code is ignored.

  `GCRYCTL_SET_VERBOSITY; Arguments: int level`

    This command sets the verbosity of the logging. A level of 0 disables all extra logging, whereas positive numbers enable more verbose logging. The level may be changed at any time but be aware that no memory synchronization is done so the effect of this command might not immediately show up in other threads. This command may even be used prior to `gcry_check_version`.

  `GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags`

    Set the debug flag bits as given by the argument. Be aware that no memory synchronization is done so the effect of this command might not immediately show up in other threads. The debug flags are not considered part of the API and thus may change without notice. As of now bit 0 enables debugging of cipher functions and bit 1 debugging of multi-precision-integers. This command may even be used prior to `gcry_check_version`.

  `GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags`

    Set the debug flag bits as given by the argument. Be aware that that no memory synchronization is done so the effect of this command might not immediately show up in other threads. This command may even be used prior to `gcry_check_version`.

  `GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none`

    This command does nothing. It exists only for backward compatibility.

  `GCRYCTL_ANY_INITIALIZATION_P; Arguments: none`

    This command returns true if the library has been basically initialized. Such a basic initialization happens implicitly with many commands to get certain internal subsystems running. The common and suggested way to do this basic initialization is by calling `gcry_check_version`.

  `GCRYCTL_INITIALIZATION_FINISHED; Arguments: none`

    This command tells the library that the application has finished the initialization.

  `GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none`

    This command returns true if the command `GCRYCTL_INITIALIZATION_FINISHED` has already been run.

  `GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops`

    This command is obsolete since version 1.6.

  `GCRYCTL_FAST_POLL; Arguments: none`

    Run a fast random poll.

  `GCRYCTL_SET_RNDEGD_SOCKET; Arguments: const char *filename`

    This command may be used to override the default name of the EGD socket to connect to. It may be used only during initialization as it is not thread safe. Changing the socket name again is not supported. The function may return an error if the given filename is too long for a local socket name.

    EGD is an alternative random gatherer, used only on systems lacking a proper random device.

  `GCRYCTL_PRINT_CONFIG; Arguments: FILE *stream`

    This command dumps information pertaining to the configuration of the library to the given stream. If `NULL` is given for stream, the log system is used. This command may be used before the initialization has been finished but not before a `gcry_check_version`. Note that the macro `estream_t` can be used instead of `gpgrt_stream_t`.

  `GCRYCTL_OPERATIONAL_P; Arguments: none`

    This command returns true if the library is in an operational state. This information makes sense only in FIPS mode. In contrast to other functions, this is a pure test function and won’t put the library into FIPS mode or change the internal state. This command may be used before the initialization has been finished but not before a `gcry_check_version`.

  `GCRYCTL_FIPS_MODE_P; Arguments: none`

    This command returns true if the library is in FIPS mode. Note, that this is no indication about the current state of the library. This command may be used before the initialization has been finished but not before a `gcry_check_version`. An application may use this command or the convenience macro below to check whether FIPS mode is actually active.

    Function: `int` gcry_fips_mode_active `(void)` ¶

      Returns true if the FIPS mode is active. Note that this is implemented as a macro.

  `GCRYCTL_FORCE_FIPS_MODE; Arguments: none`

    Running this command puts the library into FIPS mode. If the library is already in FIPS mode, a self-test is triggered and thus the library will be put into operational state. This command may be used before a call to `gcry_check_version` and that is actually the recommended way to let an application switch the library into FIPS mode. Note that Libgcrypt will reject an attempt to switch to FIPS mode during or after the initialization.

  `GCRYCTL_NO_FIPS_MODE; Arguments: none`

    Running this command puts the library into non-FIPS mode. This command may be used before a call to `gcry_check_version` and that is actually the recommended way to let an application switch the library into non-FIPS mode. Note that Libgcrypt will reject an attempt to switch to non-FIPS mode during or after the initialization.

  `GCRYCTL_SET_ENFORCED_FIPS_FLAG; Arguments: none`

    This command is obsolete and has no effect; do not use it.

  `GCRYCTL_SET_PREFERRED_RNG_TYPE; Arguments: int`

    These are advisory commands to select a certain random number generator. They are only advisory because libraries may not know what an application actually wants or vice versa. Thus Libgcrypt employs a priority check to select the actually used RNG. If an applications selects a lower priority RNG but a library requests a higher priority RNG, Libgcrypt will switch to the higher priority RNG. Applications and libraries should use these control codes before `gcry_check_version`. The available generators are:

    `GCRY_RNG_TYPE_STANDARD`

      A conservative standard generator based on the “Continuously Seeded Pseudo Random Number Generator” designed by Peter Gutmann.

    `GCRY_RNG_TYPE_FIPS`

      A deterministic random number generator conforming to the document “NIST-Recommended Random Number Generator Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES and AES Algorithms” (2005-01-31). This implementation uses the AES variant.

    `GCRY_RNG_TYPE_SYSTEM`

      A wrapper around the system’s native RNG. On Unix system these are usually the /dev/random and /dev/urandom devices.

    The default is `GCRY_RNG_TYPE_STANDARD` unless FIPS mode as been enabled; in which case `GCRY_RNG_TYPE_FIPS` is used and locked against further changes.

  `GCRYCTL_GET_CURRENT_RNG_TYPE; Arguments: int *`

    This command stores the type of the currently used RNG as an integer value at the provided address.

  `GCRYCTL_SELFTEST; Arguments: none`

    This may be used at anytime to have the library run all implemented self-tests. It works in standard and in FIPS mode. Returns 0 on success or an error code on failure.

  `GCRYCTL_DISABLE_HWF; Arguments: const char *name`

    Libgcrypt detects certain features of the CPU at startup time. For performance tests it is sometimes required not to use such a feature. This option may be used to disable a certain feature; i.e., Libgcrypt behaves as if this feature has not been detected. This call can be used several times to disable a set of features, or features may be given as a colon or comma delimited string. The special feature "all" can be used to disable all available features.

    Note that the detection code might be run if the feature has been disabled. This command must be used at initialization time; i.e., before calling `gcry_check_version`.

  `GCRYCTL_REINIT_SYSCALL_CLAMP; Arguments: none`

    Libgcrypt wraps blocking system calls with two functions calls (“system call clamp”) to give user land threading libraries a hook for re-scheduling. This works by reading the system call clamp from Libgpg-error at initialization time. However sometimes Libgcrypt needs to be initialized before the user land threading systems and at that point the system call clamp has not been registered with Libgpg-error and in turn Libgcrypt would not use them. The control code can be used to tell Libgcrypt that a system call clamp has now been registered with Libgpg-error and advise Libgcrypt to read the clamp again. Obviously this control code may only be used before a second thread is started in a process.

  `GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER; Arguments: enum gcry_cipher_algos [, enum gcry_cipher_modes]`

    Check if the given symmetric cipher and optional cipher mode combination is approved under the current FIPS 140-3 certification. If the combination is approved, this function returns `GPG_ERR_NO_ERROR`. Otherwise `GPG_ERR_NOT_SUPPORTED` is returned.

  `GCRYCTL_FIPS_SERVICE_INDICATOR_KDF; Arguments: enum gcry_kdf_algos`

    Check if the given KDF is approved under the current FIPS 140-3 certification. If the KDF is approved, this function returns `GPG_ERR_NO_ERROR`. Otherwise `GPG_ERR_NOT_SUPPORTED` is returned.

  `GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION; Arguments: const char *`

    Check if the given function is approved under the current FIPS 140-3 certification. If the function is approved, this function returns `GPG_ERR_NO_ERROR` (other restrictions might still apply). Otherwise `GPG_ERR_NOT_SUPPORTED` is returned.

  `GCRYCTL_FIPS_SERVICE_INDICATOR_MAC; Arguments: enum gcry_mac_algos`

    Check if the given MAC is approved under the current FIPS 140-3 certification. If the MAC is approved, this function returns `GPG_ERR_NO_ERROR`. Otherwise `GPG_ERR_NOT_SUPPORTED` is returned.

  `GCRYCTL_FIPS_SERVICE_INDICATOR_MD; Arguments: enum gcry_md_algos`

    Check if the given message digest algorithm is approved under the current FIPS 140-3 certification. If the algorithm is approved, this function returns `GPG_ERR_NO_ERROR`. Otherwise `GPG_ERR_NOT_SUPPORTED` is returned.

  `GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS; Arguments: const char *`

    Check if the given public key operation flag or s-expression object name is approved under the current FIPS 140-3 certification. If the flag is approved, this function returns `GPG_ERR_NO_ERROR`.

    Otherwise `GPG_ERR_NOT_SUPPORTED` is returned.

    For compound s-expression objects, if the object name is allowed, the user is responsible to check also the internal members. For example:

          gcry_sexp_t s_sig = NULL;
          gcry_md_hd_t hd = NULL;
          gcry_sexp_t s_sk = NULL;
          const char *data_tmpl = "(data(flags pss)(hash %s %b)(salt-length 1:0))";

          if (err = gcry_control(GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION, "gcry_md_open") &&
              err = gcry_control(GCRYCTL_FIPS_SERVICE_INDICATOR_MD, GCRY_MD_SHA512) &&
              err = gcry_md_open (&hd, GCRY_MD_SHA512, 0))
            {
              printf ("gcry_md_open failed: %s", gpg_strerror (err));
              return;
            }
          gcry_md_write (hd, buffer, buflen);

          /* initialize the key in s_sk */

          if (err = gcry_control(GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION, "gcry_pk_hash_sign") &&
              err = gcry_control(GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS, "data") &&
              err = gcry_control(GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS, "flags") &&
              err = gcry_control(GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS, "pss") &&
              err = gcry_control(GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS, "hash") &&
              err = gcry_control(GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS, "salt-length")
              err = gcry_pk_hash_sign (&s_sig, data_tmpl, s_sk, hd, NULL))
            {
              printf ("gcry_pk_hash_sign failed: %s", gpg_strerror (err));
              return;
            }
          /* ok */