LCOV - code coverage report
Current view: top level - src - global.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 266 460 57.8 %
Date: 2017-03-02 16:44:37 Functions: 31 34 91.2 %

          Line data    Source code
       1             : /* global.c  -  global control functions
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
       3             :  *               2004, 2005, 2006, 2008, 2011,
       4             :  *               2012  Free Software Foundation, Inc.
       5             :  * Copyright (C) 2013, 2014 g10 Code GmbH
       6             :  *
       7             :  * This file is part of Libgcrypt.
       8             :  *
       9             :  * Libgcrypt is free software; you can redistribute it and/or modify
      10             :  * it under the terms of the GNU Lesser general Public License as
      11             :  * published by the Free Software Foundation; either version 2.1 of
      12             :  * the License, or (at your option) any later version.
      13             :  *
      14             :  * Libgcrypt is distributed in the hope that it will be useful,
      15             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :  * GNU Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public
      20             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      21             :  */
      22             : 
      23             : #include <config.h>
      24             : 
      25             : #include <stdio.h>
      26             : #include <stdlib.h>
      27             : #include <string.h>
      28             : #include <stdarg.h>
      29             : #include <ctype.h>
      30             : #include <limits.h>
      31             : #include <errno.h>
      32             : #include <unistd.h>
      33             : #ifdef HAVE_SYSLOG
      34             : # include <syslog.h>
      35             : #endif /*HAVE_SYSLOG*/
      36             : 
      37             : #include "g10lib.h"
      38             : #include "gcrypt-testapi.h"
      39             : #include "cipher.h"
      40             : #include "stdmem.h" /* our own memory allocator */
      41             : #include "secmem.h" /* our own secmem allocator */
      42             : 
      43             : 
      44             : 
      45             : 
      46             : /****************
      47             :  * flag bits: 0 : general cipher debug
      48             :  *            1 : general MPI debug
      49             :  */
      50             : static unsigned int debug_flags;
      51             : 
      52             : /* gcry_control (GCRYCTL_SET_FIPS_MODE), sets this flag so that the
      53             :    initialization code switched fips mode on.  */
      54             : static int force_fips_mode;
      55             : 
      56             : /* Controlled by global_init().  */
      57             : static int any_init_done;
      58             : 
      59             : /*
      60             :  * Functions called before and after blocking syscalls.
      61             :  * Initialized by global_init and used via
      62             :  * _gcry_pre_syscall and _gcry_post_syscall.
      63             :  */
      64             : static void (*pre_syscall_func)(void);
      65             : static void (*post_syscall_func)(void);
      66             : 
      67             : 
      68             : /* Memory management. */
      69             : 
      70             : static gcry_handler_alloc_t alloc_func;
      71             : static gcry_handler_alloc_t alloc_secure_func;
      72             : static gcry_handler_secure_check_t is_secure_func;
      73             : static gcry_handler_realloc_t realloc_func;
      74             : static gcry_handler_free_t free_func;
      75             : static gcry_handler_no_mem_t outofcore_handler;
      76             : static void *outofcore_handler_value;
      77             : static int no_secure_memory;
      78             : 
      79             : /* Prototypes.  */
      80             : static gpg_err_code_t external_lock_test (int cmd);
      81             : 
      82             : 
      83             : 
      84             : 
      85             : /* This is our handmade constructor.  It gets called by any function
      86             :    likely to be called at startup.  The suggested way for an
      87             :    application to make sure that this has been called is by using
      88             :    gcry_check_version. */
      89             : static void
      90         106 : global_init (void)
      91             : {
      92         106 :   gcry_error_t err = 0;
      93             : 
      94         106 :   if (any_init_done)
      95          72 :     return;
      96          34 :   any_init_done = 1;
      97             : 
      98             :   /* Tell the random module that we have seen an init call.  */
      99          34 :   _gcry_set_preferred_rng_type (0);
     100             : 
     101             :   /* Get the system call clamp functions.  */
     102          34 :   if (!pre_syscall_func)
     103          34 :     gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func);
     104             : 
     105             :   /* See whether the system is in FIPS mode.  This needs to come as
     106             :      early as possible but after ATH has been initialized.  */
     107          34 :   _gcry_initialize_fips_mode (force_fips_mode);
     108             : 
     109             :   /* Before we do any other initialization we need to test available
     110             :      hardware features.  */
     111          34 :   _gcry_detect_hw_features ();
     112             : 
     113             :   /* Initialize the modules - this is mainly allocating some memory and
     114             :      creating mutexes.  */
     115          34 :   err = _gcry_cipher_init ();
     116          34 :   if (err)
     117           0 :     goto fail;
     118          34 :   err = _gcry_md_init ();
     119          34 :   if (err)
     120           0 :     goto fail;
     121          34 :   err = _gcry_mac_init ();
     122          34 :   if (err)
     123           0 :     goto fail;
     124          34 :   err = _gcry_pk_init ();
     125          34 :   if (err)
     126           0 :     goto fail;
     127          34 :   err = _gcry_primegen_init ();
     128          34 :   if (err)
     129           0 :     goto fail;
     130          34 :   err = _gcry_secmem_module_init ();
     131          34 :   if (err)
     132           0 :     goto fail;
     133          34 :   err = _gcry_mpi_init ();
     134          34 :   if (err)
     135           0 :     goto fail;
     136             : 
     137          34 :   return;
     138             : 
     139             :  fail:
     140           0 :   BUG ();
     141             : }
     142             : 
     143             : 
     144             : /* This function is called by the macro fips_is_operational and makes
     145             :    sure that the minimal initialization has been done.  This is far
     146             :    from a perfect solution and hides problems with an improper
     147             :    initialization but at least in single-threaded mode it should work
     148             :    reliable.
     149             : 
     150             :    The reason we need this is that a lot of applications don't use
     151             :    Libgcrypt properly by not running any initialization code at all.
     152             :    They just call a Libgcrypt function and that is all what they want.
     153             :    Now with the FIPS mode, that has the side effect of entering FIPS
     154             :    mode (for security reasons, FIPS mode is the default if no
     155             :    initialization has been done) and bailing out immediately because
     156             :    the FSM is in the wrong state.  If we always run the init code,
     157             :    Libgcrypt can test for FIPS mode and at least if not in FIPS mode,
     158             :    it will behave as before.  Note that this on-the-fly initialization
     159             :    is only done for the cryptographic functions subject to FIPS mode
     160             :    and thus not all API calls will do such an initialization.  */
     161             : int
     162    39962994 : _gcry_global_is_operational (void)
     163             : {
     164    39962994 :   if (!any_init_done)
     165             :     {
     166             : #ifdef HAVE_SYSLOG
     167           0 :       syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
     168             :               "missing initialization - please fix the application");
     169             : #endif /*HAVE_SYSLOG*/
     170           0 :       global_init ();
     171             :     }
     172    39962994 :   return _gcry_fips_is_operational ();
     173             : }
     174             : 
     175             : 
     176             : 
     177             : 
     178             : /* Version number parsing.  */
     179             : 
     180             : /* This function parses the first portion of the version number S and
     181             :    stores it in *NUMBER.  On success, this function returns a pointer
     182             :    into S starting with the first character, which is not part of the
     183             :    initial number portion; on failure, NULL is returned.  */
     184             : static const char*
     185         180 : parse_version_number( const char *s, int *number )
     186             : {
     187         180 :     int val = 0;
     188             : 
     189         180 :     if( *s == '0' && isdigit(s[1]) )
     190           0 :         return NULL; /* leading zeros are not allowed */
     191         360 :     for ( ; isdigit(*s); s++ ) {
     192         180 :         val *= 10;
     193         180 :         val += *s - '0';
     194             :     }
     195         180 :     *number = val;
     196         180 :     return val < 0? NULL : s;
     197             : }
     198             : 
     199             : /* This function breaks up the complete string-representation of the
     200             :    version number S, which is of the following struture: <major
     201             :    number>.<minor number>.<micro number><patch level>.  The major,
     202             :    minor and micro number components will be stored in *MAJOR, *MINOR
     203             :    and *MICRO.
     204             : 
     205             :    On success, the last component, the patch level, will be returned;
     206             :    in failure, NULL will be returned.  */
     207             : 
     208             : static const char *
     209          60 : parse_version_string( const char *s, int *major, int *minor, int *micro )
     210             : {
     211          60 :     s = parse_version_number( s, major );
     212          60 :     if( !s || *s != '.' )
     213           0 :         return NULL;
     214          60 :     s++;
     215          60 :     s = parse_version_number( s, minor );
     216          60 :     if( !s || *s != '.' )
     217           0 :         return NULL;
     218          60 :     s++;
     219          60 :     s = parse_version_number( s, micro );
     220          60 :     if( !s )
     221           0 :         return NULL;
     222          60 :     return s; /* patchlevel */
     223             : }
     224             : 
     225             : /* If REQ_VERSION is non-NULL, check that the version of the library
     226             :    is at minimum the requested one.  Returns the string representation
     227             :    of the library version if the condition is satisfied; return NULL
     228             :    if the requested version is newer than that of the library.
     229             : 
     230             :    If a NULL is passed to this function, no check is done, but the
     231             :    string representation of the library is simply returned.  */
     232             : const char *
     233          36 : _gcry_check_version (const char *req_version)
     234             : {
     235          36 :     const char *ver = VERSION;
     236             :     int my_major, my_minor, my_micro;
     237             :     int rq_major, rq_minor, rq_micro;
     238             :     const char *my_plvl;
     239             : 
     240          36 :     if (req_version && req_version[0] == 1 && req_version[1] == 1)
     241           0 :         return _gcry_compat_identification ();
     242             : 
     243             :     /* Initialize library.  */
     244          36 :     global_init ();
     245             : 
     246          36 :     if ( !req_version )
     247             :         /* Caller wants our version number.  */
     248           6 :         return ver;
     249             : 
     250             :     /* Parse own version number.  */
     251          30 :     my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
     252          30 :     if ( !my_plvl )
     253             :         /* very strange our own version is bogus.  Shouldn't we use
     254             :            assert() here and bail out in case this happens?  -mo.  */
     255           0 :         return NULL;
     256             : 
     257             :     /* Parse requested version number.  */
     258          30 :     if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro))
     259           0 :       return NULL;  /* req version string is invalid, this can happen.  */
     260             : 
     261             :     /* Compare version numbers.  */
     262          30 :     if ( my_major > rq_major
     263          30 :         || (my_major == rq_major && my_minor > rq_minor)
     264          29 :         || (my_major == rq_major && my_minor == rq_minor                                                         && my_micro > rq_micro)
     265          29 :         || (my_major == rq_major && my_minor == rq_minor
     266          29 :                                  && my_micro == rq_micro))
     267             :       {
     268          30 :         return ver;
     269             :       }
     270             : 
     271           0 :     return NULL;
     272             : }
     273             : 
     274             : 
     275             : static void
     276           1 : print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
     277             : {
     278             :   unsigned int hwfeatures, afeature;
     279             :   int i;
     280             :   const char *s;
     281             : 
     282           1 :   fnc (fp, "version:%s:%x:%s:%x:\n",
     283             :        VERSION, GCRYPT_VERSION_NUMBER,
     284             :        GPGRT_VERSION, GPGRT_VERSION_NUMBER);
     285           1 :   fnc (fp, "cc:%d:%s:\n",
     286             : #if GPGRT_VERSION_NUMBER >= 0x011b00 /* 1.27 */
     287             :        GPGRT_GCC_VERSION
     288             : #else
     289             :        _GPG_ERR_GCC_VERSION /* Due to a bug in gpg-error.h.  */
     290             : #endif
     291             :        ,
     292             : #ifdef __clang__
     293             :        "clang:" __VERSION__
     294             : #elif __GNUC__
     295             :        "gcc:" __VERSION__
     296             : #else
     297             :        ":"
     298             : #endif
     299             :        );
     300             : 
     301           1 :   fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
     302           1 :   fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
     303           1 :   fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
     304           1 :   fnc (fp, "rnd-mod:"
     305             : #if USE_RNDEGD
     306             :                 "egd:"
     307             : #endif
     308             : #if USE_RNDLINUX
     309             :                 "linux:"
     310             : #endif
     311             : #if USE_RNDUNIX
     312             :                 "unix:"
     313             : #endif
     314             : #if USE_RNDW32
     315             :                 "w32:"
     316             : #endif
     317             :        "\n");
     318           1 :   fnc (fp, "cpu-arch:"
     319             : #if defined(HAVE_CPU_ARCH_X86)
     320             :        "x86"
     321             : #elif defined(HAVE_CPU_ARCH_ALPHA)
     322             :        "alpha"
     323             : #elif defined(HAVE_CPU_ARCH_SPARC)
     324             :        "sparc"
     325             : #elif defined(HAVE_CPU_ARCH_MIPS)
     326             :        "mips"
     327             : #elif defined(HAVE_CPU_ARCH_M68K)
     328             :        "m68k"
     329             : #elif defined(HAVE_CPU_ARCH_PPC)
     330             :        "ppc"
     331             : #elif defined(HAVE_CPU_ARCH_ARM)
     332             :        "arm"
     333             : #endif
     334             :        ":\n");
     335           1 :   fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
     336           1 :   hwfeatures = _gcry_get_hw_features ();
     337           1 :   fnc (fp, "hwflist:");
     338          21 :   for (i=0; (s = _gcry_enum_hw_features (i, &afeature)); i++)
     339          20 :     if ((hwfeatures & afeature))
     340           7 :       fnc (fp, "%s:", s);
     341           1 :   fnc (fp, "\n");
     342             :   /* We use y/n instead of 1/0 for the simple reason that Emacsen's
     343             :      compile error parser would accidentally flag that line when printed
     344             :      during "make check" as an error.  */
     345           2 :   fnc (fp, "fips-mode:%c:%c:\n",
     346           1 :        fips_mode ()? 'y':'n',
     347           1 :        _gcry_enforced_fips_mode ()? 'y':'n' );
     348             :   /* The currently used RNG type.  */
     349             :   {
     350           1 :     i = _gcry_get_rng_type (0);
     351           1 :     switch (i)
     352             :       {
     353           1 :       case GCRY_RNG_TYPE_STANDARD: s = "standard"; break;
     354           0 :       case GCRY_RNG_TYPE_FIPS:     s = "fips"; break;
     355           0 :       case GCRY_RNG_TYPE_SYSTEM:   s = "system"; break;
     356           0 :       default: BUG ();
     357             :       }
     358           1 :     fnc (fp, "rng-type:%s:%d:\n", s, i);
     359             :   }
     360             : 
     361           1 : }
     362             : 
     363             : 
     364             : 
     365             : 
     366             : /* Command dispatcher function, acting as general control
     367             :    function.  */
     368             : gcry_err_code_t
     369       24553 : _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
     370             : {
     371             :   static int init_finished = 0;
     372       24553 :   gcry_err_code_t rc = 0;
     373             : 
     374       24553 :   switch (cmd)
     375             :     {
     376             :     case GCRYCTL_ENABLE_M_GUARD:
     377           0 :       _gcry_private_enable_m_guard ();
     378           5 :       break;
     379             : 
     380             :     case GCRYCTL_ENABLE_QUICK_RANDOM:
     381          18 :       _gcry_set_preferred_rng_type (0);
     382          18 :       _gcry_enable_quick_random_gen ();
     383          18 :       break;
     384             : 
     385             :     case GCRYCTL_FAKED_RANDOM_P:
     386             :       /* Return an error if the RNG is faked one (e.g. enabled by
     387             :          ENABLE_QUICK_RANDOM. */
     388           0 :       if (_gcry_random_is_faked ())
     389           0 :         rc = GPG_ERR_GENERAL;  /* Use as TRUE value.  */
     390           0 :       break;
     391             : 
     392             :     case GCRYCTL_DUMP_RANDOM_STATS:
     393           0 :       _gcry_random_dump_stats ();
     394           0 :       break;
     395             : 
     396             :     case GCRYCTL_DUMP_MEMORY_STATS:
     397             :       /*m_print_stats("[fixme: prefix]");*/
     398           0 :       break;
     399             : 
     400             :     case GCRYCTL_DUMP_SECMEM_STATS:
     401           0 :       _gcry_secmem_dump_stats (0);
     402           0 :       break;
     403             : 
     404             :     case GCRYCTL_DROP_PRIVS:
     405           0 :       global_init ();
     406           0 :       _gcry_secmem_init (0);
     407           0 :       break;
     408             : 
     409             :     case GCRYCTL_DISABLE_SECMEM:
     410          32 :       global_init ();
     411          32 :       no_secure_memory = 1;
     412          32 :       break;
     413             : 
     414             :     case GCRYCTL_INIT_SECMEM:
     415           2 :       global_init ();
     416           2 :       _gcry_secmem_init (va_arg (arg_ptr, unsigned int));
     417           2 :       if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED))
     418           0 :         rc = GPG_ERR_GENERAL;
     419           2 :       break;
     420             : 
     421             :     case GCRYCTL_TERM_SECMEM:
     422           1 :       global_init ();
     423           1 :       _gcry_secmem_term ();
     424           1 :       break;
     425             : 
     426             :     case GCRYCTL_DISABLE_SECMEM_WARN:
     427           2 :       _gcry_set_preferred_rng_type (0);
     428           2 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     429             :                                | GCRY_SECMEM_FLAG_NO_WARNING));
     430           2 :       break;
     431             : 
     432             :     case GCRYCTL_SUSPEND_SECMEM_WARN:
     433           0 :       _gcry_set_preferred_rng_type (0);
     434           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     435             :                                | GCRY_SECMEM_FLAG_SUSPEND_WARNING));
     436           0 :       break;
     437             : 
     438             :     case GCRYCTL_RESUME_SECMEM_WARN:
     439           0 :       _gcry_set_preferred_rng_type (0);
     440           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     441             :                                & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
     442           0 :       break;
     443             : 
     444             :     case GCRYCTL_USE_SECURE_RNDPOOL:
     445           0 :       global_init ();
     446           0 :       _gcry_secure_random_alloc (); /* Put random number into secure memory. */
     447           0 :       break;
     448             : 
     449             :     case GCRYCTL_SET_RANDOM_SEED_FILE:
     450           0 :       _gcry_set_preferred_rng_type (0);
     451           0 :       _gcry_set_random_seed_file (va_arg (arg_ptr, const char *));
     452           0 :       break;
     453             : 
     454             :     case GCRYCTL_UPDATE_RANDOM_SEED_FILE:
     455           0 :       _gcry_set_preferred_rng_type (0);
     456           0 :       if ( fips_is_operational () )
     457           0 :         _gcry_update_random_seed_file ();
     458           0 :       break;
     459             : 
     460             :     case GCRYCTL_SET_VERBOSITY:
     461           7 :       _gcry_set_preferred_rng_type (0);
     462           7 :       _gcry_set_log_verbosity (va_arg (arg_ptr, int));
     463           7 :       break;
     464             : 
     465             :     case GCRYCTL_SET_DEBUG_FLAGS:
     466           0 :       debug_flags |= va_arg (arg_ptr, unsigned int);
     467           0 :       break;
     468             : 
     469             :     case GCRYCTL_CLEAR_DEBUG_FLAGS:
     470           0 :       debug_flags &= ~va_arg (arg_ptr, unsigned int);
     471           0 :       break;
     472             : 
     473             :     case GCRYCTL_DISABLE_INTERNAL_LOCKING:
     474             :       /* Not used anymore.  */
     475           0 :       global_init ();
     476           0 :       break;
     477             : 
     478             :     case GCRYCTL_ANY_INITIALIZATION_P:
     479           0 :       if (any_init_done)
     480           0 :         rc = GPG_ERR_GENERAL;
     481           0 :       break;
     482             : 
     483             :     case GCRYCTL_INITIALIZATION_FINISHED_P:
     484           0 :       if (init_finished)
     485           0 :         rc = GPG_ERR_GENERAL; /* Yes.  */
     486           0 :       break;
     487             : 
     488             :     case GCRYCTL_INITIALIZATION_FINISHED:
     489             :       /* This is a hook which should be used by an application after
     490             :          all initialization has been done and right before any threads
     491             :          are started.  It is not really needed but the only way to be
     492             :          really sure that all initialization for thread-safety has
     493             :          been done. */
     494          32 :       if (! init_finished)
     495             :         {
     496          32 :           global_init ();
     497             :           /* Do only a basic random initialization, i.e. init the
     498             :              mutexes. */
     499          32 :           _gcry_random_initialize (0);
     500          32 :           init_finished = 1;
     501             :           /* Force us into operational state if in FIPS mode.  */
     502          32 :           (void)fips_is_operational ();
     503             :         }
     504          32 :       break;
     505             : 
     506             :     case GCRYCTL_SET_THREAD_CBS:
     507             :       /* This is now a dummy call.  We used to install our own thread
     508             :          library here. */
     509           0 :       _gcry_set_preferred_rng_type (0);
     510           0 :       global_init ();
     511           0 :       break;
     512             : 
     513             :     case GCRYCTL_FAST_POLL:
     514           0 :       _gcry_set_preferred_rng_type (0);
     515             :       /* We need to do make sure that the random pool is really
     516             :          initialized so that the poll function is not a NOP. */
     517           0 :       _gcry_random_initialize (1);
     518             : 
     519           0 :       if ( fips_is_operational () )
     520           0 :         _gcry_fast_random_poll ();
     521           0 :       break;
     522             : 
     523             :     case GCRYCTL_SET_RNDEGD_SOCKET:
     524             : #if USE_RNDEGD
     525             :       _gcry_set_preferred_rng_type (0);
     526             :       rc = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
     527             : #else
     528           0 :       rc = GPG_ERR_NOT_SUPPORTED;
     529             : #endif
     530           0 :       break;
     531             : 
     532             :     case GCRYCTL_SET_RANDOM_DAEMON_SOCKET:
     533           0 :       _gcry_set_preferred_rng_type (0);
     534           0 :       _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *));
     535           0 :       break;
     536             : 
     537             :     case GCRYCTL_USE_RANDOM_DAEMON:
     538             :       /* We need to do make sure that the random pool is really
     539             :          initialized so that the poll function is not a NOP. */
     540           0 :       _gcry_set_preferred_rng_type (0);
     541           0 :       _gcry_random_initialize (1);
     542           0 :       _gcry_use_random_daemon (!! va_arg (arg_ptr, int));
     543           0 :       break;
     544             : 
     545             :     case GCRYCTL_CLOSE_RANDOM_DEVICE:
     546           0 :       _gcry_random_close_fds ();
     547           0 :       break;
     548             : 
     549             :       /* This command dumps information pertaining to the
     550             :          configuration of libgcrypt to the given stream.  It may be
     551             :          used before the initialization has been finished but not
     552             :          before a gcry_version_check. */
     553             :     case GCRYCTL_PRINT_CONFIG:
     554             :       {
     555           1 :         FILE *fp = va_arg (arg_ptr, FILE *);
     556           1 :         _gcry_set_preferred_rng_type (0);
     557           1 :         print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp);
     558             :       }
     559           1 :       break;
     560             : 
     561             :     case GCRYCTL_OPERATIONAL_P:
     562             :       /* Returns true if the library is in an operational state.  This
     563             :          is always true for non-fips mode.  */
     564           0 :       _gcry_set_preferred_rng_type (0);
     565           0 :       if (_gcry_fips_test_operational ())
     566           0 :         rc = GPG_ERR_GENERAL; /* Used as TRUE value */
     567           0 :       break;
     568             : 
     569             :     case GCRYCTL_FIPS_MODE_P:
     570         116 :       if (fips_mode ()
     571           4 :           && !_gcry_is_fips_mode_inactive ()
     572           4 :           && !no_secure_memory)
     573           4 :         rc = GPG_ERR_GENERAL; /* Used as TRUE value */
     574         116 :       break;
     575             : 
     576             :     case GCRYCTL_FORCE_FIPS_MODE:
     577             :       /* Performing this command puts the library into fips mode.  If
     578             :          the library has already been initialized into fips mode, a
     579             :          selftest is triggered.  It is not possible to put the libraty
     580             :          into fips mode after having passed the initialization. */
     581           0 :       _gcry_set_preferred_rng_type (0);
     582           0 :       if (!any_init_done)
     583             :         {
     584             :           /* Not yet intialized at all.  Set a flag so that we are put
     585             :              into fips mode during initialization.  */
     586           0 :           force_fips_mode = 1;
     587             :         }
     588             :       else
     589             :         {
     590             :           /* Already initialized.  If we are already operational we
     591             :              run a selftest.  If not we use the is_operational call to
     592             :              force us into operational state if possible.  */
     593           0 :           if (_gcry_fips_test_error_or_operational ())
     594           0 :             _gcry_fips_run_selftests (1);
     595           0 :           if (_gcry_fips_is_operational ())
     596           0 :             rc = GPG_ERR_GENERAL; /* Used as TRUE value */
     597             :       }
     598           0 :       break;
     599             : 
     600             :     case GCRYCTL_SELFTEST:
     601             :       /* Run a selftest.  This works in fips mode as well as in
     602             :          standard mode.  In contrast to the power-up tests, we use an
     603             :          extended version of the selftests. Returns 0 on success or an
     604             :          error code. */
     605           2 :       global_init ();
     606           2 :       rc = _gcry_fips_run_selftests (1);
     607           2 :       break;
     608             : 
     609             : #if _GCRY_GCC_VERSION >= 40600
     610             : # pragma GCC diagnostic push
     611             : # pragma GCC diagnostic ignored "-Wswitch"
     612             : #endif
     613             :     case PRIV_CTL_INIT_EXTRNG_TEST:  /* Init external random test.  */
     614           0 :       rc = GPG_ERR_NOT_SUPPORTED;
     615           0 :       break;
     616             :     case PRIV_CTL_RUN_EXTRNG_TEST:  /* Run external DRBG test.  */
     617             :       {
     618           0 :         struct gcry_drbg_test_vector *test =
     619             :           va_arg (arg_ptr, struct gcry_drbg_test_vector *);
     620           0 :         unsigned char *buf = va_arg (arg_ptr, unsigned char *);
     621             : 
     622           0 :         if (buf)
     623           0 :           rc = _gcry_rngdrbg_cavs_test (test, buf);
     624             :         else
     625           0 :           rc = _gcry_rngdrbg_healthcheck_one (test);
     626             :       }
     627           0 :       break;
     628             :     case PRIV_CTL_DEINIT_EXTRNG_TEST:  /* Deinit external random test.  */
     629           0 :       rc = GPG_ERR_NOT_SUPPORTED;
     630           0 :       break;
     631             :     case PRIV_CTL_EXTERNAL_LOCK_TEST:  /* Run external lock test */
     632       24245 :       rc = external_lock_test (va_arg (arg_ptr, int));
     633       24148 :       break;
     634             :     case PRIV_CTL_DUMP_SECMEM_STATS:
     635           0 :       _gcry_secmem_dump_stats (1);
     636           0 :       break;
     637             : #if _GCRY_GCC_VERSION >= 40600
     638             : # pragma GCC diagnostic pop
     639             : #endif
     640             : 
     641             :     case GCRYCTL_DISABLE_HWF:
     642             :       {
     643           1 :         const char *name = va_arg (arg_ptr, const char *);
     644           1 :         rc = _gcry_disable_hw_feature (name);
     645             :       }
     646           1 :       break;
     647             : 
     648             :     case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
     649           0 :       if (!any_init_done)
     650             :         {
     651             :           /* Not yet initialized at all.  Set the enforced fips mode flag */
     652           0 :           _gcry_set_preferred_rng_type (0);
     653           0 :           _gcry_set_enforced_fips_mode ();
     654             :         }
     655             :       else
     656           0 :         rc = GPG_ERR_GENERAL;
     657           0 :       break;
     658             : 
     659             :     case GCRYCTL_SET_PREFERRED_RNG_TYPE:
     660             :       /* This may be called before gcry_check_version.  */
     661             :       {
     662          30 :         int i = va_arg (arg_ptr, int);
     663             :         /* Note that we may not pass 0 to _gcry_set_preferred_rng_type.  */
     664          30 :         if (i > 0)
     665          30 :           _gcry_set_preferred_rng_type (i);
     666             :       }
     667          30 :       break;
     668             : 
     669             :     case GCRYCTL_GET_CURRENT_RNG_TYPE:
     670             :       {
     671          64 :         int *ip = va_arg (arg_ptr, int*);
     672          64 :         if (ip)
     673          64 :           *ip = _gcry_get_rng_type (!any_init_done);
     674             :       }
     675          64 :       break;
     676             : 
     677             :     case GCRYCTL_DISABLE_LOCKED_SECMEM:
     678           0 :       _gcry_set_preferred_rng_type (0);
     679           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     680             :                                | GCRY_SECMEM_FLAG_NO_MLOCK));
     681           0 :       break;
     682             : 
     683             :     case GCRYCTL_DISABLE_PRIV_DROP:
     684           0 :       _gcry_set_preferred_rng_type (0);
     685           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     686             :                                | GCRY_SECMEM_FLAG_NO_PRIV_DROP));
     687           0 :       break;
     688             : 
     689             :     case GCRYCTL_INACTIVATE_FIPS_FLAG:
     690             :     case GCRYCTL_REACTIVATE_FIPS_FLAG:
     691           0 :       rc = GPG_ERR_NOT_IMPLEMENTED;
     692           0 :       break;
     693             : 
     694             :     case GCRYCTL_DRBG_REINIT:
     695             :       {
     696           0 :         const char *flagstr = va_arg (arg_ptr, const char *);
     697           0 :         gcry_buffer_t *pers = va_arg (arg_ptr, gcry_buffer_t *);
     698           0 :         int npers = va_arg (arg_ptr, int);
     699           0 :         if (va_arg (arg_ptr, void *) || npers < 0)
     700           0 :           rc = GPG_ERR_INV_ARG;
     701           0 :         else if (_gcry_get_rng_type (!any_init_done) != GCRY_RNG_TYPE_FIPS)
     702           0 :           rc = GPG_ERR_NOT_SUPPORTED;
     703             :         else
     704           0 :           rc = _gcry_rngdrbg_reinit (flagstr, pers, npers);
     705             :       }
     706           0 :       break;
     707             : 
     708             :     case GCRYCTL_REINIT_SYSCALL_CLAMP:
     709           0 :       if (!pre_syscall_func)
     710           0 :         gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func);
     711           0 :       break;
     712             : 
     713             :     default:
     714           0 :       _gcry_set_preferred_rng_type (0);
     715           0 :       rc = GPG_ERR_INV_OP;
     716             :     }
     717             : 
     718       24461 :   return rc;
     719             : }
     720             : 
     721             : 
     722             : 
     723             : /* Set custom allocation handlers.  This is in general not useful
     724             :  * because the libgcrypt allocation functions are guaranteed to
     725             :  * provide proper allocation handlers which zeroize memory if needed.
     726             :  * NOTE: All 5 functions should be set.  */
     727             : void
     728           0 : _gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
     729             :                               gcry_handler_alloc_t new_alloc_secure_func,
     730             :                               gcry_handler_secure_check_t new_is_secure_func,
     731             :                               gcry_handler_realloc_t new_realloc_func,
     732             :                               gcry_handler_free_t new_free_func)
     733             : {
     734           0 :   global_init ();
     735             : 
     736           0 :   if (fips_mode ())
     737             :     {
     738             :       /* We do not want to enforce the fips mode, but merely set a
     739             :          flag so that the application may check whether it is still in
     740             :          fips mode.  */
     741           0 :       _gcry_inactivate_fips_mode ("custom allocation handler");
     742             :     }
     743             : 
     744           0 :   alloc_func = new_alloc_func;
     745           0 :   alloc_secure_func = new_alloc_secure_func;
     746           0 :   is_secure_func = new_is_secure_func;
     747           0 :   realloc_func = new_realloc_func;
     748           0 :   free_func = new_free_func;
     749           0 : }
     750             : 
     751             : 
     752             : 
     753             : /****************
     754             :  * Set an optional handler which is called in case the xmalloc functions
     755             :  * ran out of memory.  This handler may do one of these things:
     756             :  *   o free some memory and return true, so that the xmalloc function
     757             :  *     tries again.
     758             :  *   o Do whatever it like and return false, so that the xmalloc functions
     759             :  *     use the default fatal error handler.
     760             :  *   o Terminate the program and don't return.
     761             :  *
     762             :  * The handler function is called with 3 arguments:  The opaque value set with
     763             :  * this function, the requested memory size, and a flag with these bits
     764             :  * currently defined:
     765             :  *      bit 0 set = secure memory has been requested.
     766             :  */
     767             : void
     768           1 : _gcry_set_outofcore_handler (int (*f)(void*, size_t, unsigned int), void *value)
     769             : {
     770           1 :   global_init ();
     771             : 
     772           1 :   if (fips_mode () )
     773             :     {
     774           0 :       log_info ("out of core handler ignored in FIPS mode\n");
     775           0 :       return;
     776             :     }
     777             : 
     778           1 :   outofcore_handler = f;
     779           1 :   outofcore_handler_value = value;
     780             : }
     781             : 
     782             : /* Return the no_secure_memory flag.  */
     783             : static int
     784     1132474 : get_no_secure_memory (void)
     785             : {
     786     1132474 :   if (!no_secure_memory)
     787         631 :     return 0;
     788     1131843 :   if (_gcry_enforced_fips_mode ())
     789             :     {
     790           0 :       no_secure_memory = 0;
     791           0 :       return 0;
     792             :     }
     793     1131843 :   return no_secure_memory;
     794             : }
     795             : 
     796             : 
     797             : static gcry_err_code_t
     798    90880717 : do_malloc (size_t n, unsigned int flags, void **mem)
     799             : {
     800    90880717 :   gcry_err_code_t err = 0;
     801             :   void *m;
     802             : 
     803    90880717 :   if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ())
     804             :     {
     805         364 :       if (alloc_secure_func)
     806           0 :         m = (*alloc_secure_func) (n);
     807             :       else
     808         182 :         m = _gcry_private_malloc_secure (n, !!(flags & GCRY_ALLOC_FLAG_XHINT));
     809             :     }
     810             :   else
     811             :     {
     812    90880535 :       if (alloc_func)
     813           0 :         m = (*alloc_func) (n);
     814             :       else
     815    90880535 :         m = _gcry_private_malloc (n);
     816             :     }
     817             : 
     818    90880717 :   if (!m)
     819             :     {
     820             :       /* Make sure that ERRNO has been set in case a user supplied
     821             :          memory handler didn't it correctly. */
     822           1 :       if (!errno)
     823           0 :         gpg_err_set_errno (ENOMEM);
     824           1 :       err = gpg_err_code_from_errno (errno);
     825             :     }
     826             :   else
     827    90880716 :     *mem = m;
     828             : 
     829    90880717 :   return err;
     830             : }
     831             : 
     832             : void *
     833    90162933 : _gcry_malloc (size_t n)
     834             : {
     835    90162933 :   void *mem = NULL;
     836             : 
     837    90162933 :   do_malloc (n, 0, &mem);
     838             : 
     839    90162933 :   return mem;
     840             : }
     841             : 
     842             : static void *
     843      717784 : _gcry_malloc_secure_core (size_t n, int xhint)
     844             : {
     845      717784 :   void *mem = NULL;
     846             : 
     847      717784 :   do_malloc (n, (GCRY_ALLOC_FLAG_SECURE | (xhint? GCRY_ALLOC_FLAG_XHINT:0)),
     848             :              &mem);
     849             : 
     850      717784 :   return mem;
     851             : }
     852             : 
     853             : void *
     854        4745 : _gcry_malloc_secure (size_t n)
     855             : {
     856        4745 :   return _gcry_malloc_secure_core (n, 0);
     857             : }
     858             : 
     859             : int
     860      414690 : _gcry_is_secure (const void *a)
     861             : {
     862      414690 :   if (get_no_secure_memory ())
     863      414241 :     return 0;
     864         449 :   if (is_secure_func)
     865           0 :     return is_secure_func (a) ;
     866         449 :   return _gcry_private_is_secure (a);
     867             : }
     868             : 
     869             : void
     870           0 : _gcry_check_heap( const void *a )
     871             : {
     872             :   (void)a;
     873             : 
     874             :     /* FIXME: implement this*/
     875             : #if 0
     876             :     if( some_handler )
     877             :         some_handler(a)
     878             :     else
     879             :         _gcry_private_check_heap(a)
     880             : #endif
     881           0 : }
     882             : 
     883             : static void *
     884      231506 : _gcry_realloc_core (void *a, size_t n, int xhint)
     885             : {
     886             :   void *p;
     887             : 
     888             :   /* To avoid problems with non-standard realloc implementations and
     889             :      our own secmem_realloc, we divert to malloc and free here.  */
     890      231506 :   if (!a)
     891           0 :     return _gcry_malloc (n);
     892      231506 :   if (!n)
     893             :     {
     894           0 :       xfree (a);
     895           0 :       return NULL;
     896             :     }
     897             : 
     898      231506 :   if (realloc_func)
     899           0 :     p = realloc_func (a, n);
     900             :   else
     901      231506 :     p =  _gcry_private_realloc (a, n, xhint);
     902      231506 :   if (!p && !errno)
     903           0 :     gpg_err_set_errno (ENOMEM);
     904      231506 :   return p;
     905             : }
     906             : 
     907             : 
     908             : void *
     909       17987 : _gcry_realloc (void *a, size_t n)
     910             : {
     911       17987 :   return _gcry_realloc_core (a, n, 0);
     912             : }
     913             : 
     914             : 
     915             : void
     916    90899391 : _gcry_free (void *p)
     917             : {
     918             :   int save_errno;
     919             : 
     920    90899391 :   if (!p)
     921       20006 :     return;
     922             : 
     923             :   /* In case ERRNO is set we better save it so that the free machinery
     924             :      may not accidentally change ERRNO.  We restore it only if it was
     925             :      already set to comply with the usual C semantic for ERRNO.  */
     926    90879385 :   save_errno = errno;
     927    90879385 :   if (free_func)
     928           0 :     free_func (p);
     929             :   else
     930    90879385 :     _gcry_private_free (p);
     931             : 
     932    90879385 :   if (save_errno)
     933    90879377 :     gpg_err_set_errno (save_errno);
     934             : }
     935             : 
     936             : void *
     937       10465 : _gcry_calloc (size_t n, size_t m)
     938             : {
     939             :   size_t bytes;
     940             :   void *p;
     941             : 
     942       10465 :   bytes = n * m; /* size_t is unsigned so the behavior on overflow is
     943             :                     defined. */
     944       10465 :   if (m && bytes / m != n)
     945             :     {
     946           0 :       gpg_err_set_errno (ENOMEM);
     947           0 :       return NULL;
     948             :     }
     949             : 
     950       10465 :   p = _gcry_malloc (bytes);
     951       10465 :   if (p)
     952       10465 :     memset (p, 0, bytes);
     953       10465 :   return p;
     954             : }
     955             : 
     956             : void *
     957        1221 : _gcry_calloc_secure (size_t n, size_t m)
     958             : {
     959             :   size_t bytes;
     960             :   void *p;
     961             : 
     962        1221 :   bytes = n * m; /* size_t is unsigned so the behavior on overflow is
     963             :                     defined. */
     964        1221 :   if (m && bytes / m != n)
     965             :     {
     966           0 :       gpg_err_set_errno (ENOMEM);
     967           0 :       return NULL;
     968             :     }
     969             : 
     970        1221 :   p = _gcry_malloc_secure (bytes);
     971        1221 :   if (p)
     972        1221 :     memset (p, 0, bytes);
     973        1221 :   return p;
     974             : }
     975             : 
     976             : 
     977             : static char *
     978        9242 : _gcry_strdup_core (const char *string, int xhint)
     979             : {
     980        9242 :   char *string_cp = NULL;
     981        9242 :   size_t string_n = 0;
     982             : 
     983        9242 :   string_n = strlen (string);
     984             : 
     985        9242 :   if (_gcry_is_secure (string))
     986           0 :     string_cp = _gcry_malloc_secure_core (string_n + 1, xhint);
     987             :   else
     988        9242 :     string_cp = _gcry_malloc (string_n + 1);
     989             : 
     990        9242 :   if (string_cp)
     991        9242 :     strcpy (string_cp, string);
     992             : 
     993        9242 :   return string_cp;
     994             : }
     995             : 
     996             : /* Create and return a copy of the null-terminated string STRING.  If
     997             :  * it is contained in secure memory, the copy will be contained in
     998             :  * secure memory as well.  In an out-of-memory condition, NULL is
     999             :  * returned.  */
    1000             : char *
    1001           0 : _gcry_strdup (const char *string)
    1002             : {
    1003           0 :   return _gcry_strdup_core (string, 0);
    1004             : }
    1005             : 
    1006             : void *
    1007    89605789 : _gcry_xmalloc( size_t n )
    1008             : {
    1009             :   void *p;
    1010             : 
    1011   179211578 :   while ( !(p = _gcry_malloc( n )) )
    1012             :     {
    1013           0 :       if ( fips_mode ()
    1014           0 :            || !outofcore_handler
    1015           0 :            || !outofcore_handler (outofcore_handler_value, n, 0) )
    1016             :         {
    1017           0 :           _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL);
    1018             :         }
    1019             :     }
    1020    89605789 :     return p;
    1021             : }
    1022             : 
    1023             : void *
    1024      213519 : _gcry_xrealloc( void *a, size_t n )
    1025             : {
    1026             :   void *p;
    1027             : 
    1028      427038 :   while (!(p = _gcry_realloc_core (a, n, 1)))
    1029             :     {
    1030           0 :       if ( fips_mode ()
    1031           0 :            || !outofcore_handler
    1032           0 :            || !outofcore_handler (outofcore_handler_value, n,
    1033           0 :                                   _gcry_is_secure(a)? 3:2))
    1034             :         {
    1035           0 :           _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL );
    1036             :         }
    1037             :     }
    1038      213519 :     return p;
    1039             : }
    1040             : 
    1041             : void *
    1042      713039 : _gcry_xmalloc_secure( size_t n )
    1043             : {
    1044             :   void *p;
    1045             : 
    1046     1426078 :   while (!(p = _gcry_malloc_secure_core (n, 1)))
    1047             :     {
    1048           0 :       if ( fips_mode ()
    1049           0 :            || !outofcore_handler
    1050           0 :            || !outofcore_handler (outofcore_handler_value, n, 1) )
    1051             :         {
    1052           0 :           _gcry_fatal_error (gpg_err_code_from_errno (errno),
    1053             :                              _("out of core in secure memory"));
    1054             :         }
    1055             :     }
    1056      713039 :   return p;
    1057             : }
    1058             : 
    1059             : 
    1060             : void *
    1061       79401 : _gcry_xcalloc( size_t n, size_t m )
    1062             : {
    1063             :   size_t nbytes;
    1064             :   void *p;
    1065             : 
    1066       79401 :   nbytes = n * m;
    1067       79401 :   if (m && nbytes / m != n)
    1068             :     {
    1069           0 :       gpg_err_set_errno (ENOMEM);
    1070           0 :       _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
    1071             :     }
    1072             : 
    1073       79401 :   p = _gcry_xmalloc ( nbytes );
    1074       79401 :   memset ( p, 0, nbytes );
    1075       79401 :   return p;
    1076             : }
    1077             : 
    1078             : void *
    1079        1307 : _gcry_xcalloc_secure( size_t n, size_t m )
    1080             : {
    1081             :   size_t nbytes;
    1082             :   void *p;
    1083             : 
    1084        1307 :   nbytes = n * m;
    1085        1307 :   if (m && nbytes / m != n)
    1086             :     {
    1087           0 :       gpg_err_set_errno (ENOMEM);
    1088           0 :       _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
    1089             :     }
    1090             : 
    1091        1307 :   p = _gcry_xmalloc_secure ( nbytes );
    1092        1307 :   memset ( p, 0, nbytes );
    1093        1307 :   return p;
    1094             : }
    1095             : 
    1096             : char *
    1097        9242 : _gcry_xstrdup (const char *string)
    1098             : {
    1099             :   char *p;
    1100             : 
    1101       18484 :   while ( !(p = _gcry_strdup_core (string, 1)) )
    1102             :     {
    1103           0 :       size_t n = strlen (string);
    1104           0 :       int is_sec = !!_gcry_is_secure (string);
    1105             : 
    1106           0 :       if (fips_mode ()
    1107           0 :           || !outofcore_handler
    1108           0 :           || !outofcore_handler (outofcore_handler_value, n, is_sec) )
    1109             :         {
    1110           0 :           _gcry_fatal_error (gpg_err_code_from_errno (errno),
    1111             :                              is_sec? _("out of core in secure memory"):NULL);
    1112             :         }
    1113             :     }
    1114             : 
    1115        9242 :   return p;
    1116             : }
    1117             : 
    1118             : 
    1119             : /* Used before blocking system calls.  */
    1120             : void
    1121         458 : _gcry_pre_syscall (void)
    1122             : {
    1123         458 :   if (pre_syscall_func)
    1124           0 :     pre_syscall_func ();
    1125         458 : }
    1126             : 
    1127             : 
    1128             : /* Used after blocking system calls.  */
    1129             : void
    1130         458 : _gcry_post_syscall (void)
    1131             : {
    1132         458 :   if (post_syscall_func)
    1133           0 :     post_syscall_func ();
    1134         458 : }
    1135             : 
    1136             : 
    1137             : int
    1138       36824 : _gcry_get_debug_flag (unsigned int mask)
    1139             : {
    1140       36824 :   if ( fips_mode () )
    1141           0 :     return 0;
    1142       36824 :   return (debug_flags & mask);
    1143             : }
    1144             : 
    1145             : 
    1146             : 
    1147             : /* It is often useful to get some feedback of long running operations.
    1148             :    This function may be used to register a handler for this.
    1149             :    The callback function CB is used as:
    1150             : 
    1151             :    void cb (void *opaque, const char *what, int printchar,
    1152             :            int current, int total);
    1153             : 
    1154             :    Where WHAT is a string identifying the the type of the progress
    1155             :    output, PRINTCHAR the character usually printed, CURRENT the amount
    1156             :    of progress currently done and TOTAL the expected amount of
    1157             :    progress.  A value of 0 for TOTAL indicates that there is no
    1158             :    estimation available.
    1159             : 
    1160             :    Defined values for WHAT:
    1161             : 
    1162             :    "need_entropy"  X    0  number-of-bytes-required
    1163             :             When running low on entropy
    1164             :    "primegen"      '\n'  0 0
    1165             :            Prime generated
    1166             :                    '!'
    1167             :            Need to refresh the prime pool
    1168             :                    '<','>'
    1169             :            Number of bits adjusted
    1170             :                    '^'
    1171             :            Looking for a generator
    1172             :                    '.'
    1173             :            Fermat tests on 10 candidates failed
    1174             :                   ':'
    1175             :            Restart with a new random value
    1176             :                   '+'
    1177             :            Rabin Miller test passed
    1178             :    "pk_elg"        '+','-','.','\n'   0  0
    1179             :             Only used in debugging mode.
    1180             :    "pk_dsa"
    1181             :             Only used in debugging mode.
    1182             : */
    1183             : void
    1184           1 : _gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
    1185             :                             void *cb_data)
    1186             : {
    1187             : #if USE_DSA
    1188           1 :   _gcry_register_pk_dsa_progress (cb, cb_data);
    1189             : #endif
    1190             : #if USE_ELGAMAL
    1191           1 :   _gcry_register_pk_elg_progress (cb, cb_data);
    1192             : #endif
    1193           1 :   _gcry_register_primegen_progress (cb, cb_data);
    1194           1 :   _gcry_register_random_progress (cb, cb_data);
    1195           1 : }
    1196             : 
    1197             : 
    1198             : 
    1199             : /* This is a helper for the regression test suite to test Libgcrypt's locks.
    1200             :    It works using a one test lock with CMD controlling what to do:
    1201             : 
    1202             :      30111 - Allocate and init lock
    1203             :      30112 - Take lock
    1204             :      30113 - Release lock
    1205             :      30114 - Destroy lock.
    1206             : 
    1207             :    This function is used by tests/t-lock.c - it is not part of the
    1208             :    public API!
    1209             :  */
    1210             : static gpg_err_code_t
    1211       25274 : external_lock_test (int cmd)
    1212             : {
    1213             :   GPGRT_LOCK_DEFINE (testlock);
    1214       25274 :   gpg_err_code_t rc = 0;
    1215             : 
    1216       25274 :   switch (cmd)
    1217             :     {
    1218             :     case 30111:  /* Init Lock.  */
    1219           2 :       rc = gpgrt_lock_init (&testlock);
    1220           0 :       break;
    1221             : 
    1222             :     case 30112:  /* Take Lock.  */
    1223       12479 :       rc = gpgrt_lock_lock (&testlock);
    1224       12791 :       break;
    1225             : 
    1226             :     case 30113:  /* Release Lock.  */
    1227       12791 :       rc = gpgrt_lock_unlock (&testlock);
    1228       12573 :       break;
    1229             : 
    1230             :     case 30114:  /* Destroy Lock.  */
    1231           2 :       rc = gpgrt_lock_destroy (&testlock);
    1232           2 :       break;
    1233             : 
    1234             :     default:
    1235           0 :       rc = GPG_ERR_INV_OP;
    1236           0 :       break;
    1237             :     }
    1238             : 
    1239       24163 :   return rc;
    1240             : }

Generated by: LCOV version 1.13