LCOV - code coverage report
Current view: top level - src - global.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 459 0.0 %
Date: 2016-12-15 12:59:22 Functions: 0 34 0.0 %

          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           0 : global_init (void)
      91             : {
      92           0 :   gcry_error_t err = 0;
      93             : 
      94           0 :   if (any_init_done)
      95           0 :     return;
      96           0 :   any_init_done = 1;
      97             : 
      98             :   /* Tell the random module that we have seen an init call.  */
      99           0 :   _gcry_set_preferred_rng_type (0);
     100             : 
     101             :   /* Get the system call clamp functions.  */
     102           0 :   if (!pre_syscall_func)
     103           0 :     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           0 :   _gcry_initialize_fips_mode (force_fips_mode);
     108             : 
     109             :   /* Before we do any other initialization we need to test available
     110             :      hardware features.  */
     111           0 :   _gcry_detect_hw_features ();
     112             : 
     113             :   /* Initialize the modules - this is mainly allocating some memory and
     114             :      creating mutexes.  */
     115           0 :   err = _gcry_cipher_init ();
     116           0 :   if (err)
     117           0 :     goto fail;
     118           0 :   err = _gcry_md_init ();
     119           0 :   if (err)
     120           0 :     goto fail;
     121           0 :   err = _gcry_mac_init ();
     122           0 :   if (err)
     123           0 :     goto fail;
     124           0 :   err = _gcry_pk_init ();
     125           0 :   if (err)
     126           0 :     goto fail;
     127           0 :   err = _gcry_primegen_init ();
     128           0 :   if (err)
     129           0 :     goto fail;
     130           0 :   err = _gcry_secmem_module_init ();
     131           0 :   if (err)
     132           0 :     goto fail;
     133           0 :   err = _gcry_mpi_init ();
     134           0 :   if (err)
     135           0 :     goto fail;
     136             : 
     137           0 :   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           0 : _gcry_global_is_operational (void)
     163             : {
     164           0 :   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           0 :   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           0 : parse_version_number( const char *s, int *number )
     186             : {
     187           0 :     int val = 0;
     188             : 
     189           0 :     if( *s == '0' && isdigit(s[1]) )
     190           0 :         return NULL; /* leading zeros are not allowed */
     191           0 :     for ( ; isdigit(*s); s++ ) {
     192           0 :         val *= 10;
     193           0 :         val += *s - '0';
     194             :     }
     195           0 :     *number = val;
     196           0 :     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           0 : parse_version_string( const char *s, int *major, int *minor, int *micro )
     210             : {
     211           0 :     s = parse_version_number( s, major );
     212           0 :     if( !s || *s != '.' )
     213           0 :         return NULL;
     214           0 :     s++;
     215           0 :     s = parse_version_number( s, minor );
     216           0 :     if( !s || *s != '.' )
     217           0 :         return NULL;
     218           0 :     s++;
     219           0 :     s = parse_version_number( s, micro );
     220           0 :     if( !s )
     221           0 :         return NULL;
     222           0 :     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           0 : _gcry_check_version (const char *req_version)
     234             : {
     235           0 :     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           0 :     if (req_version && req_version[0] == 1 && req_version[1] == 1)
     241           0 :         return _gcry_compat_identification ();
     242             : 
     243             :     /* Initialize library.  */
     244           0 :     global_init ();
     245             : 
     246           0 :     if ( !req_version )
     247             :         /* Caller wants our version number.  */
     248           0 :         return ver;
     249             : 
     250             :     /* Parse own version number.  */
     251           0 :     my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
     252           0 :     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           0 :     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           0 :     if ( my_major > rq_major
     263           0 :         || (my_major == rq_major && my_minor > rq_minor)
     264           0 :         || (my_major == rq_major && my_minor == rq_minor                                                         && my_micro > rq_micro)
     265           0 :         || (my_major == rq_major && my_minor == rq_minor
     266           0 :                                  && my_micro == rq_micro))
     267             :       {
     268           0 :         return ver;
     269             :       }
     270             : 
     271           0 :     return NULL;
     272             : }
     273             : 
     274             : 
     275             : static void
     276           0 : 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           0 :   fnc (fp, "version:%s:\n", VERSION);
     283           0 :   fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
     284           0 :   fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
     285           0 :   fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
     286           0 :   fnc (fp, "rnd-mod:"
     287             : #if USE_RNDEGD
     288             :                 "egd:"
     289             : #endif
     290             : #if USE_RNDLINUX
     291             :                 "linux:"
     292             : #endif
     293             : #if USE_RNDUNIX
     294             :                 "unix:"
     295             : #endif
     296             : #if USE_RNDW32
     297             :                 "w32:"
     298             : #endif
     299             :        "\n");
     300           0 :   fnc (fp, "cpu-arch:"
     301             : #if defined(HAVE_CPU_ARCH_X86)
     302             :        "x86"
     303             : #elif defined(HAVE_CPU_ARCH_ALPHA)
     304             :        "alpha"
     305             : #elif defined(HAVE_CPU_ARCH_SPARC)
     306             :        "sparc"
     307             : #elif defined(HAVE_CPU_ARCH_MIPS)
     308             :        "mips"
     309             : #elif defined(HAVE_CPU_ARCH_M68K)
     310             :        "m68k"
     311             : #elif defined(HAVE_CPU_ARCH_PPC)
     312             :        "ppc"
     313             : #elif defined(HAVE_CPU_ARCH_ARM)
     314             :        "arm"
     315             : #endif
     316             :        ":\n");
     317           0 :   fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
     318           0 :   hwfeatures = _gcry_get_hw_features ();
     319           0 :   fnc (fp, "hwflist:");
     320           0 :   for (i=0; (s = _gcry_enum_hw_features (i, &afeature)); i++)
     321           0 :     if ((hwfeatures & afeature))
     322           0 :       fnc (fp, "%s:", s);
     323           0 :   fnc (fp, "\n");
     324             :   /* We use y/n instead of 1/0 for the simple reason that Emacsen's
     325             :      compile error parser would accidentally flag that line when printed
     326             :      during "make check" as an error.  */
     327           0 :   fnc (fp, "fips-mode:%c:%c:\n",
     328           0 :        fips_mode ()? 'y':'n',
     329           0 :        _gcry_enforced_fips_mode ()? 'y':'n' );
     330             :   /* The currently used RNG type.  */
     331             :   {
     332           0 :     i = _gcry_get_rng_type (0);
     333           0 :     switch (i)
     334             :       {
     335           0 :       case GCRY_RNG_TYPE_STANDARD: s = "standard"; break;
     336           0 :       case GCRY_RNG_TYPE_FIPS:     s = "fips"; break;
     337           0 :       case GCRY_RNG_TYPE_SYSTEM:   s = "system"; break;
     338           0 :       default: BUG ();
     339             :       }
     340           0 :     fnc (fp, "rng-type:%s:%d:\n", s, i);
     341             :   }
     342             : 
     343           0 : }
     344             : 
     345             : 
     346             : 
     347             : 
     348             : /* Command dispatcher function, acting as general control
     349             :    function.  */
     350             : gcry_err_code_t
     351           0 : _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
     352             : {
     353             :   static int init_finished = 0;
     354           0 :   gcry_err_code_t rc = 0;
     355             : 
     356           0 :   switch (cmd)
     357             :     {
     358             :     case GCRYCTL_ENABLE_M_GUARD:
     359           0 :       _gcry_private_enable_m_guard ();
     360           0 :       break;
     361             : 
     362             :     case GCRYCTL_ENABLE_QUICK_RANDOM:
     363           0 :       _gcry_set_preferred_rng_type (0);
     364           0 :       _gcry_enable_quick_random_gen ();
     365           0 :       break;
     366             : 
     367             :     case GCRYCTL_FAKED_RANDOM_P:
     368             :       /* Return an error if the RNG is faked one (e.g. enabled by
     369             :          ENABLE_QUICK_RANDOM. */
     370           0 :       if (_gcry_random_is_faked ())
     371           0 :         rc = GPG_ERR_GENERAL;  /* Use as TRUE value.  */
     372           0 :       break;
     373             : 
     374             :     case GCRYCTL_DUMP_RANDOM_STATS:
     375           0 :       _gcry_random_dump_stats ();
     376           0 :       break;
     377             : 
     378             :     case GCRYCTL_DUMP_MEMORY_STATS:
     379             :       /*m_print_stats("[fixme: prefix]");*/
     380           0 :       break;
     381             : 
     382             :     case GCRYCTL_DUMP_SECMEM_STATS:
     383           0 :       _gcry_secmem_dump_stats (0);
     384           0 :       break;
     385             : 
     386             :     case GCRYCTL_DROP_PRIVS:
     387           0 :       global_init ();
     388           0 :       _gcry_secmem_init (0);
     389           0 :       break;
     390             : 
     391             :     case GCRYCTL_DISABLE_SECMEM:
     392           0 :       global_init ();
     393           0 :       no_secure_memory = 1;
     394           0 :       break;
     395             : 
     396             :     case GCRYCTL_INIT_SECMEM:
     397           0 :       global_init ();
     398           0 :       _gcry_secmem_init (va_arg (arg_ptr, unsigned int));
     399           0 :       if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED))
     400           0 :         rc = GPG_ERR_GENERAL;
     401           0 :       break;
     402             : 
     403             :     case GCRYCTL_TERM_SECMEM:
     404           0 :       global_init ();
     405           0 :       _gcry_secmem_term ();
     406           0 :       break;
     407             : 
     408             :     case GCRYCTL_DISABLE_SECMEM_WARN:
     409           0 :       _gcry_set_preferred_rng_type (0);
     410           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     411             :                                | GCRY_SECMEM_FLAG_NO_WARNING));
     412           0 :       break;
     413             : 
     414             :     case GCRYCTL_SUSPEND_SECMEM_WARN:
     415           0 :       _gcry_set_preferred_rng_type (0);
     416           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     417             :                                | GCRY_SECMEM_FLAG_SUSPEND_WARNING));
     418           0 :       break;
     419             : 
     420             :     case GCRYCTL_RESUME_SECMEM_WARN:
     421           0 :       _gcry_set_preferred_rng_type (0);
     422           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     423             :                                & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
     424           0 :       break;
     425             : 
     426             :     case GCRYCTL_USE_SECURE_RNDPOOL:
     427           0 :       global_init ();
     428           0 :       _gcry_secure_random_alloc (); /* Put random number into secure memory. */
     429           0 :       break;
     430             : 
     431             :     case GCRYCTL_SET_RANDOM_SEED_FILE:
     432           0 :       _gcry_set_preferred_rng_type (0);
     433           0 :       _gcry_set_random_seed_file (va_arg (arg_ptr, const char *));
     434           0 :       break;
     435             : 
     436             :     case GCRYCTL_UPDATE_RANDOM_SEED_FILE:
     437           0 :       _gcry_set_preferred_rng_type (0);
     438           0 :       if ( fips_is_operational () )
     439           0 :         _gcry_update_random_seed_file ();
     440           0 :       break;
     441             : 
     442             :     case GCRYCTL_SET_VERBOSITY:
     443           0 :       _gcry_set_preferred_rng_type (0);
     444           0 :       _gcry_set_log_verbosity (va_arg (arg_ptr, int));
     445           0 :       break;
     446             : 
     447             :     case GCRYCTL_SET_DEBUG_FLAGS:
     448           0 :       debug_flags |= va_arg (arg_ptr, unsigned int);
     449           0 :       break;
     450             : 
     451             :     case GCRYCTL_CLEAR_DEBUG_FLAGS:
     452           0 :       debug_flags &= ~va_arg (arg_ptr, unsigned int);
     453           0 :       break;
     454             : 
     455             :     case GCRYCTL_DISABLE_INTERNAL_LOCKING:
     456             :       /* Not used anymore.  */
     457           0 :       global_init ();
     458           0 :       break;
     459             : 
     460             :     case GCRYCTL_ANY_INITIALIZATION_P:
     461           0 :       if (any_init_done)
     462           0 :         rc = GPG_ERR_GENERAL;
     463           0 :       break;
     464             : 
     465             :     case GCRYCTL_INITIALIZATION_FINISHED_P:
     466           0 :       if (init_finished)
     467           0 :         rc = GPG_ERR_GENERAL; /* Yes.  */
     468           0 :       break;
     469             : 
     470             :     case GCRYCTL_INITIALIZATION_FINISHED:
     471             :       /* This is a hook which should be used by an application after
     472             :          all initialization has been done and right before any threads
     473             :          are started.  It is not really needed but the only way to be
     474             :          really sure that all initialization for thread-safety has
     475             :          been done. */
     476           0 :       if (! init_finished)
     477             :         {
     478           0 :           global_init ();
     479             :           /* Do only a basic random initialization, i.e. init the
     480             :              mutexes. */
     481           0 :           _gcry_random_initialize (0);
     482           0 :           init_finished = 1;
     483             :           /* Force us into operational state if in FIPS mode.  */
     484           0 :           (void)fips_is_operational ();
     485             :         }
     486           0 :       break;
     487             : 
     488             :     case GCRYCTL_SET_THREAD_CBS:
     489             :       /* This is now a dummy call.  We used to install our own thread
     490             :          library here. */
     491           0 :       _gcry_set_preferred_rng_type (0);
     492           0 :       global_init ();
     493           0 :       break;
     494             : 
     495             :     case GCRYCTL_FAST_POLL:
     496           0 :       _gcry_set_preferred_rng_type (0);
     497             :       /* We need to do make sure that the random pool is really
     498             :          initialized so that the poll function is not a NOP. */
     499           0 :       _gcry_random_initialize (1);
     500             : 
     501           0 :       if ( fips_is_operational () )
     502           0 :         _gcry_fast_random_poll ();
     503           0 :       break;
     504             : 
     505             :     case GCRYCTL_SET_RNDEGD_SOCKET:
     506             : #if USE_RNDEGD
     507             :       _gcry_set_preferred_rng_type (0);
     508             :       rc = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
     509             : #else
     510           0 :       rc = GPG_ERR_NOT_SUPPORTED;
     511             : #endif
     512           0 :       break;
     513             : 
     514             :     case GCRYCTL_SET_RANDOM_DAEMON_SOCKET:
     515           0 :       _gcry_set_preferred_rng_type (0);
     516           0 :       _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *));
     517           0 :       break;
     518             : 
     519             :     case GCRYCTL_USE_RANDOM_DAEMON:
     520             :       /* We need to do make sure that the random pool is really
     521             :          initialized so that the poll function is not a NOP. */
     522           0 :       _gcry_set_preferred_rng_type (0);
     523           0 :       _gcry_random_initialize (1);
     524           0 :       _gcry_use_random_daemon (!! va_arg (arg_ptr, int));
     525           0 :       break;
     526             : 
     527             :     case GCRYCTL_CLOSE_RANDOM_DEVICE:
     528           0 :       _gcry_random_close_fds ();
     529           0 :       break;
     530             : 
     531             :       /* This command dumps information pertaining to the
     532             :          configuration of libgcrypt to the given stream.  It may be
     533             :          used before the initialization has been finished but not
     534             :          before a gcry_version_check. */
     535             :     case GCRYCTL_PRINT_CONFIG:
     536             :       {
     537           0 :         FILE *fp = va_arg (arg_ptr, FILE *);
     538           0 :         _gcry_set_preferred_rng_type (0);
     539           0 :         print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp);
     540             :       }
     541           0 :       break;
     542             : 
     543             :     case GCRYCTL_OPERATIONAL_P:
     544             :       /* Returns true if the library is in an operational state.  This
     545             :          is always true for non-fips mode.  */
     546           0 :       _gcry_set_preferred_rng_type (0);
     547           0 :       if (_gcry_fips_test_operational ())
     548           0 :         rc = GPG_ERR_GENERAL; /* Used as TRUE value */
     549           0 :       break;
     550             : 
     551             :     case GCRYCTL_FIPS_MODE_P:
     552           0 :       if (fips_mode ()
     553           0 :           && !_gcry_is_fips_mode_inactive ()
     554           0 :           && !no_secure_memory)
     555           0 :         rc = GPG_ERR_GENERAL; /* Used as TRUE value */
     556           0 :       break;
     557             : 
     558             :     case GCRYCTL_FORCE_FIPS_MODE:
     559             :       /* Performing this command puts the library into fips mode.  If
     560             :          the library has already been initialized into fips mode, a
     561             :          selftest is triggered.  It is not possible to put the libraty
     562             :          into fips mode after having passed the initialization. */
     563           0 :       _gcry_set_preferred_rng_type (0);
     564           0 :       if (!any_init_done)
     565             :         {
     566             :           /* Not yet intialized at all.  Set a flag so that we are put
     567             :              into fips mode during initialization.  */
     568           0 :           force_fips_mode = 1;
     569             :         }
     570             :       else
     571             :         {
     572             :           /* Already initialized.  If we are already operational we
     573             :              run a selftest.  If not we use the is_operational call to
     574             :              force us into operational state if possible.  */
     575           0 :           if (_gcry_fips_test_error_or_operational ())
     576           0 :             _gcry_fips_run_selftests (1);
     577           0 :           if (_gcry_fips_is_operational ())
     578           0 :             rc = GPG_ERR_GENERAL; /* Used as TRUE value */
     579             :       }
     580           0 :       break;
     581             : 
     582             :     case GCRYCTL_SELFTEST:
     583             :       /* Run a selftest.  This works in fips mode as well as in
     584             :          standard mode.  In contrast to the power-up tests, we use an
     585             :          extended version of the selftests. Returns 0 on success or an
     586             :          error code. */
     587           0 :       global_init ();
     588           0 :       rc = _gcry_fips_run_selftests (1);
     589           0 :       break;
     590             : 
     591             : #if _GCRY_GCC_VERSION >= 40600
     592             : # pragma GCC diagnostic push
     593             : # pragma GCC diagnostic ignored "-Wswitch"
     594             : #endif
     595             :     case PRIV_CTL_INIT_EXTRNG_TEST:  /* Init external random test.  */
     596           0 :       rc = GPG_ERR_NOT_SUPPORTED;
     597           0 :       break;
     598             :     case PRIV_CTL_RUN_EXTRNG_TEST:  /* Run external DRBG test.  */
     599             :       {
     600           0 :         struct gcry_drbg_test_vector *test =
     601             :           va_arg (arg_ptr, struct gcry_drbg_test_vector *);
     602           0 :         unsigned char *buf = va_arg (arg_ptr, unsigned char *);
     603             : 
     604           0 :         if (buf)
     605           0 :           rc = _gcry_rngdrbg_cavs_test (test, buf);
     606             :         else
     607           0 :           rc = _gcry_rngdrbg_healthcheck_one (test);
     608             :       }
     609           0 :       break;
     610             :     case PRIV_CTL_DEINIT_EXTRNG_TEST:  /* Deinit external random test.  */
     611           0 :       rc = GPG_ERR_NOT_SUPPORTED;
     612           0 :       break;
     613             :     case PRIV_CTL_EXTERNAL_LOCK_TEST:  /* Run external lock test */
     614           0 :       rc = external_lock_test (va_arg (arg_ptr, int));
     615           0 :       break;
     616             :     case PRIV_CTL_DUMP_SECMEM_STATS:
     617           0 :       _gcry_secmem_dump_stats (1);
     618           0 :       break;
     619             : #if _GCRY_GCC_VERSION >= 40600
     620             : # pragma GCC diagnostic pop
     621             : #endif
     622             : 
     623             :     case GCRYCTL_DISABLE_HWF:
     624             :       {
     625           0 :         const char *name = va_arg (arg_ptr, const char *);
     626           0 :         rc = _gcry_disable_hw_feature (name);
     627             :       }
     628           0 :       break;
     629             : 
     630             :     case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
     631           0 :       if (!any_init_done)
     632             :         {
     633             :           /* Not yet initialized at all.  Set the enforced fips mode flag */
     634           0 :           _gcry_set_preferred_rng_type (0);
     635           0 :           _gcry_set_enforced_fips_mode ();
     636             :         }
     637             :       else
     638           0 :         rc = GPG_ERR_GENERAL;
     639           0 :       break;
     640             : 
     641             :     case GCRYCTL_SET_PREFERRED_RNG_TYPE:
     642             :       /* This may be called before gcry_check_version.  */
     643             :       {
     644           0 :         int i = va_arg (arg_ptr, int);
     645             :         /* Note that we may not pass 0 to _gcry_set_preferred_rng_type.  */
     646           0 :         if (i > 0)
     647           0 :           _gcry_set_preferred_rng_type (i);
     648             :       }
     649           0 :       break;
     650             : 
     651             :     case GCRYCTL_GET_CURRENT_RNG_TYPE:
     652             :       {
     653           0 :         int *ip = va_arg (arg_ptr, int*);
     654           0 :         if (ip)
     655           0 :           *ip = _gcry_get_rng_type (!any_init_done);
     656             :       }
     657           0 :       break;
     658             : 
     659             :     case GCRYCTL_DISABLE_LOCKED_SECMEM:
     660           0 :       _gcry_set_preferred_rng_type (0);
     661           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     662             :                                | GCRY_SECMEM_FLAG_NO_MLOCK));
     663           0 :       break;
     664             : 
     665             :     case GCRYCTL_DISABLE_PRIV_DROP:
     666           0 :       _gcry_set_preferred_rng_type (0);
     667           0 :       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
     668             :                                | GCRY_SECMEM_FLAG_NO_PRIV_DROP));
     669           0 :       break;
     670             : 
     671             :     case GCRYCTL_INACTIVATE_FIPS_FLAG:
     672             :     case GCRYCTL_REACTIVATE_FIPS_FLAG:
     673           0 :       rc = GPG_ERR_NOT_IMPLEMENTED;
     674           0 :       break;
     675             : 
     676             :     case GCRYCTL_DRBG_REINIT:
     677             :       {
     678           0 :         const char *flagstr = va_arg (arg_ptr, const char *);
     679           0 :         gcry_buffer_t *pers = va_arg (arg_ptr, gcry_buffer_t *);
     680           0 :         int npers = va_arg (arg_ptr, int);
     681           0 :         if (va_arg (arg_ptr, void *) || npers < 0)
     682           0 :           rc = GPG_ERR_INV_ARG;
     683           0 :         else if (_gcry_get_rng_type (!any_init_done) != GCRY_RNG_TYPE_FIPS)
     684           0 :           rc = GPG_ERR_NOT_SUPPORTED;
     685             :         else
     686           0 :           rc = _gcry_rngdrbg_reinit (flagstr, pers, npers);
     687             :       }
     688           0 :       break;
     689             : 
     690             :     case GCRYCTL_REINIT_SYSCALL_CLAMP:
     691           0 :       if (!pre_syscall_func)
     692           0 :         gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func);
     693           0 :       break;
     694             : 
     695             :     default:
     696           0 :       _gcry_set_preferred_rng_type (0);
     697           0 :       rc = GPG_ERR_INV_OP;
     698             :     }
     699             : 
     700           0 :   return rc;
     701             : }
     702             : 
     703             : 
     704             : 
     705             : /* Set custom allocation handlers.  This is in general not useful
     706             :  * because the libgcrypt allocation functions are guaranteed to
     707             :  * provide proper allocation handlers which zeroize memory if needed.
     708             :  * NOTE: All 5 functions should be set.  */
     709             : void
     710           0 : _gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
     711             :                               gcry_handler_alloc_t new_alloc_secure_func,
     712             :                               gcry_handler_secure_check_t new_is_secure_func,
     713             :                               gcry_handler_realloc_t new_realloc_func,
     714             :                               gcry_handler_free_t new_free_func)
     715             : {
     716           0 :   global_init ();
     717             : 
     718           0 :   if (fips_mode ())
     719             :     {
     720             :       /* We do not want to enforce the fips mode, but merely set a
     721             :          flag so that the application may check whether it is still in
     722             :          fips mode.  */
     723           0 :       _gcry_inactivate_fips_mode ("custom allocation handler");
     724             :     }
     725             : 
     726           0 :   alloc_func = new_alloc_func;
     727           0 :   alloc_secure_func = new_alloc_secure_func;
     728           0 :   is_secure_func = new_is_secure_func;
     729           0 :   realloc_func = new_realloc_func;
     730           0 :   free_func = new_free_func;
     731           0 : }
     732             : 
     733             : 
     734             : 
     735             : /****************
     736             :  * Set an optional handler which is called in case the xmalloc functions
     737             :  * ran out of memory.  This handler may do one of these things:
     738             :  *   o free some memory and return true, so that the xmalloc function
     739             :  *     tries again.
     740             :  *   o Do whatever it like and return false, so that the xmalloc functions
     741             :  *     use the default fatal error handler.
     742             :  *   o Terminate the program and don't return.
     743             :  *
     744             :  * The handler function is called with 3 arguments:  The opaque value set with
     745             :  * this function, the requested memory size, and a flag with these bits
     746             :  * currently defined:
     747             :  *      bit 0 set = secure memory has been requested.
     748             :  */
     749             : void
     750           0 : _gcry_set_outofcore_handler (int (*f)(void*, size_t, unsigned int), void *value)
     751             : {
     752           0 :   global_init ();
     753             : 
     754           0 :   if (fips_mode () )
     755             :     {
     756           0 :       log_info ("out of core handler ignored in FIPS mode\n");
     757           0 :       return;
     758             :     }
     759             : 
     760           0 :   outofcore_handler = f;
     761           0 :   outofcore_handler_value = value;
     762             : }
     763             : 
     764             : /* Return the no_secure_memory flag.  */
     765             : static int
     766           0 : get_no_secure_memory (void)
     767             : {
     768           0 :   if (!no_secure_memory)
     769           0 :     return 0;
     770           0 :   if (_gcry_enforced_fips_mode ())
     771             :     {
     772           0 :       no_secure_memory = 0;
     773           0 :       return 0;
     774             :     }
     775           0 :   return no_secure_memory;
     776             : }
     777             : 
     778             : 
     779             : static gcry_err_code_t
     780           0 : do_malloc (size_t n, unsigned int flags, void **mem)
     781             : {
     782           0 :   gcry_err_code_t err = 0;
     783             :   void *m;
     784             : 
     785           0 :   if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ())
     786             :     {
     787           0 :       if (alloc_secure_func)
     788           0 :         m = (*alloc_secure_func) (n);
     789             :       else
     790           0 :         m = _gcry_private_malloc_secure (n, !!(flags & GCRY_ALLOC_FLAG_XHINT));
     791             :     }
     792             :   else
     793             :     {
     794           0 :       if (alloc_func)
     795           0 :         m = (*alloc_func) (n);
     796             :       else
     797           0 :         m = _gcry_private_malloc (n);
     798             :     }
     799             : 
     800           0 :   if (!m)
     801             :     {
     802             :       /* Make sure that ERRNO has been set in case a user supplied
     803             :          memory handler didn't it correctly. */
     804           0 :       if (!errno)
     805           0 :         gpg_err_set_errno (ENOMEM);
     806           0 :       err = gpg_err_code_from_errno (errno);
     807             :     }
     808             :   else
     809           0 :     *mem = m;
     810             : 
     811           0 :   return err;
     812             : }
     813             : 
     814             : void *
     815           0 : _gcry_malloc (size_t n)
     816             : {
     817           0 :   void *mem = NULL;
     818             : 
     819           0 :   do_malloc (n, 0, &mem);
     820             : 
     821           0 :   return mem;
     822             : }
     823             : 
     824             : static void *
     825           0 : _gcry_malloc_secure_core (size_t n, int xhint)
     826             : {
     827           0 :   void *mem = NULL;
     828             : 
     829           0 :   do_malloc (n, (GCRY_ALLOC_FLAG_SECURE | (xhint? GCRY_ALLOC_FLAG_XHINT:0)),
     830             :              &mem);
     831             : 
     832           0 :   return mem;
     833             : }
     834             : 
     835             : void *
     836           0 : _gcry_malloc_secure (size_t n)
     837             : {
     838           0 :   return _gcry_malloc_secure_core (n, 0);
     839             : }
     840             : 
     841             : int
     842           0 : _gcry_is_secure (const void *a)
     843             : {
     844           0 :   if (get_no_secure_memory ())
     845           0 :     return 0;
     846           0 :   if (is_secure_func)
     847           0 :     return is_secure_func (a) ;
     848           0 :   return _gcry_private_is_secure (a);
     849             : }
     850             : 
     851             : void
     852           0 : _gcry_check_heap( const void *a )
     853             : {
     854             :   (void)a;
     855             : 
     856             :     /* FIXME: implement this*/
     857             : #if 0
     858             :     if( some_handler )
     859             :         some_handler(a)
     860             :     else
     861             :         _gcry_private_check_heap(a)
     862             : #endif
     863           0 : }
     864             : 
     865             : static void *
     866           0 : _gcry_realloc_core (void *a, size_t n, int xhint)
     867             : {
     868             :   void *p;
     869             : 
     870             :   /* To avoid problems with non-standard realloc implementations and
     871             :      our own secmem_realloc, we divert to malloc and free here.  */
     872           0 :   if (!a)
     873           0 :     return _gcry_malloc (n);
     874           0 :   if (!n)
     875             :     {
     876           0 :       xfree (a);
     877           0 :       return NULL;
     878             :     }
     879             : 
     880           0 :   if (realloc_func)
     881           0 :     p = realloc_func (a, n);
     882             :   else
     883           0 :     p =  _gcry_private_realloc (a, n, xhint);
     884           0 :   if (!p && !errno)
     885           0 :     gpg_err_set_errno (ENOMEM);
     886           0 :   return p;
     887             : }
     888             : 
     889             : 
     890             : void *
     891           0 : _gcry_realloc (void *a, size_t n)
     892             : {
     893           0 :   return _gcry_realloc_core (a, n, 0);
     894             : }
     895             : 
     896             : 
     897             : void
     898           0 : _gcry_free (void *p)
     899             : {
     900             :   int save_errno;
     901             : 
     902           0 :   if (!p)
     903           0 :     return;
     904             : 
     905             :   /* In case ERRNO is set we better save it so that the free machinery
     906             :      may not accidentally change ERRNO.  We restore it only if it was
     907             :      already set to comply with the usual C semantic for ERRNO.  */
     908           0 :   save_errno = errno;
     909           0 :   if (free_func)
     910           0 :     free_func (p);
     911             :   else
     912           0 :     _gcry_private_free (p);
     913             : 
     914           0 :   if (save_errno)
     915           0 :     gpg_err_set_errno (save_errno);
     916             : }
     917             : 
     918             : void *
     919           0 : _gcry_calloc (size_t n, size_t m)
     920             : {
     921             :   size_t bytes;
     922             :   void *p;
     923             : 
     924           0 :   bytes = n * m; /* size_t is unsigned so the behavior on overflow is
     925             :                     defined. */
     926           0 :   if (m && bytes / m != n)
     927             :     {
     928           0 :       gpg_err_set_errno (ENOMEM);
     929           0 :       return NULL;
     930             :     }
     931             : 
     932           0 :   p = _gcry_malloc (bytes);
     933           0 :   if (p)
     934           0 :     memset (p, 0, bytes);
     935           0 :   return p;
     936             : }
     937             : 
     938             : void *
     939           0 : _gcry_calloc_secure (size_t n, size_t m)
     940             : {
     941             :   size_t bytes;
     942             :   void *p;
     943             : 
     944           0 :   bytes = n * m; /* size_t is unsigned so the behavior on overflow is
     945             :                     defined. */
     946           0 :   if (m && bytes / m != n)
     947             :     {
     948           0 :       gpg_err_set_errno (ENOMEM);
     949           0 :       return NULL;
     950             :     }
     951             : 
     952           0 :   p = _gcry_malloc_secure (bytes);
     953           0 :   if (p)
     954           0 :     memset (p, 0, bytes);
     955           0 :   return p;
     956             : }
     957             : 
     958             : 
     959             : static char *
     960           0 : _gcry_strdup_core (const char *string, int xhint)
     961             : {
     962           0 :   char *string_cp = NULL;
     963           0 :   size_t string_n = 0;
     964             : 
     965           0 :   string_n = strlen (string);
     966             : 
     967           0 :   if (_gcry_is_secure (string))
     968           0 :     string_cp = _gcry_malloc_secure_core (string_n + 1, xhint);
     969             :   else
     970           0 :     string_cp = _gcry_malloc (string_n + 1);
     971             : 
     972           0 :   if (string_cp)
     973           0 :     strcpy (string_cp, string);
     974             : 
     975           0 :   return string_cp;
     976             : }
     977             : 
     978             : /* Create and return a copy of the null-terminated string STRING.  If
     979             :  * it is contained in secure memory, the copy will be contained in
     980             :  * secure memory as well.  In an out-of-memory condition, NULL is
     981             :  * returned.  */
     982             : char *
     983           0 : _gcry_strdup (const char *string)
     984             : {
     985           0 :   return _gcry_strdup_core (string, 0);
     986             : }
     987             : 
     988             : void *
     989           0 : _gcry_xmalloc( size_t n )
     990             : {
     991             :   void *p;
     992             : 
     993           0 :   while ( !(p = _gcry_malloc( n )) )
     994             :     {
     995           0 :       if ( fips_mode ()
     996           0 :            || !outofcore_handler
     997           0 :            || !outofcore_handler (outofcore_handler_value, n, 0) )
     998             :         {
     999           0 :           _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL);
    1000             :         }
    1001             :     }
    1002           0 :     return p;
    1003             : }
    1004             : 
    1005             : void *
    1006           0 : _gcry_xrealloc( void *a, size_t n )
    1007             : {
    1008             :   void *p;
    1009             : 
    1010           0 :   while (!(p = _gcry_realloc_core (a, n, 1)))
    1011             :     {
    1012           0 :       if ( fips_mode ()
    1013           0 :            || !outofcore_handler
    1014           0 :            || !outofcore_handler (outofcore_handler_value, n,
    1015           0 :                                   _gcry_is_secure(a)? 3:2))
    1016             :         {
    1017           0 :           _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL );
    1018             :         }
    1019             :     }
    1020           0 :     return p;
    1021             : }
    1022             : 
    1023             : void *
    1024           0 : _gcry_xmalloc_secure( size_t n )
    1025             : {
    1026             :   void *p;
    1027             : 
    1028           0 :   while (!(p = _gcry_malloc_secure_core (n, 1)))
    1029             :     {
    1030           0 :       if ( fips_mode ()
    1031           0 :            || !outofcore_handler
    1032           0 :            || !outofcore_handler (outofcore_handler_value, n, 1) )
    1033             :         {
    1034           0 :           _gcry_fatal_error (gpg_err_code_from_errno (errno),
    1035             :                              _("out of core in secure memory"));
    1036             :         }
    1037             :     }
    1038           0 :   return p;
    1039             : }
    1040             : 
    1041             : 
    1042             : void *
    1043           0 : _gcry_xcalloc( size_t n, size_t m )
    1044             : {
    1045             :   size_t nbytes;
    1046             :   void *p;
    1047             : 
    1048           0 :   nbytes = n * m;
    1049           0 :   if (m && nbytes / m != n)
    1050             :     {
    1051           0 :       gpg_err_set_errno (ENOMEM);
    1052           0 :       _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
    1053             :     }
    1054             : 
    1055           0 :   p = _gcry_xmalloc ( nbytes );
    1056           0 :   memset ( p, 0, nbytes );
    1057           0 :   return p;
    1058             : }
    1059             : 
    1060             : void *
    1061           0 : _gcry_xcalloc_secure( size_t n, size_t m )
    1062             : {
    1063             :   size_t nbytes;
    1064             :   void *p;
    1065             : 
    1066           0 :   nbytes = n * m;
    1067           0 :   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           0 :   p = _gcry_xmalloc_secure ( nbytes );
    1074           0 :   memset ( p, 0, nbytes );
    1075           0 :   return p;
    1076             : }
    1077             : 
    1078             : char *
    1079           0 : _gcry_xstrdup (const char *string)
    1080             : {
    1081             :   char *p;
    1082             : 
    1083           0 :   while ( !(p = _gcry_strdup_core (string, 1)) )
    1084             :     {
    1085           0 :       size_t n = strlen (string);
    1086           0 :       int is_sec = !!_gcry_is_secure (string);
    1087             : 
    1088           0 :       if (fips_mode ()
    1089           0 :           || !outofcore_handler
    1090           0 :           || !outofcore_handler (outofcore_handler_value, n, is_sec) )
    1091             :         {
    1092           0 :           _gcry_fatal_error (gpg_err_code_from_errno (errno),
    1093             :                              is_sec? _("out of core in secure memory"):NULL);
    1094             :         }
    1095             :     }
    1096             : 
    1097           0 :   return p;
    1098             : }
    1099             : 
    1100             : 
    1101             : /* Used before blocking system calls.  */
    1102             : void
    1103           0 : _gcry_pre_syscall (void)
    1104             : {
    1105           0 :   if (pre_syscall_func)
    1106           0 :     pre_syscall_func ();
    1107           0 : }
    1108             : 
    1109             : 
    1110             : /* Used after blocking system calls.  */
    1111             : void
    1112           0 : _gcry_post_syscall (void)
    1113             : {
    1114           0 :   if (post_syscall_func)
    1115           0 :     post_syscall_func ();
    1116           0 : }
    1117             : 
    1118             : 
    1119             : int
    1120           0 : _gcry_get_debug_flag (unsigned int mask)
    1121             : {
    1122           0 :   if ( fips_mode () )
    1123           0 :     return 0;
    1124           0 :   return (debug_flags & mask);
    1125             : }
    1126             : 
    1127             : 
    1128             : 
    1129             : /* It is often useful to get some feedback of long running operations.
    1130             :    This function may be used to register a handler for this.
    1131             :    The callback function CB is used as:
    1132             : 
    1133             :    void cb (void *opaque, const char *what, int printchar,
    1134             :            int current, int total);
    1135             : 
    1136             :    Where WHAT is a string identifying the the type of the progress
    1137             :    output, PRINTCHAR the character usually printed, CURRENT the amount
    1138             :    of progress currently done and TOTAL the expected amount of
    1139             :    progress.  A value of 0 for TOTAL indicates that there is no
    1140             :    estimation available.
    1141             : 
    1142             :    Defined values for WHAT:
    1143             : 
    1144             :    "need_entropy"  X    0  number-of-bytes-required
    1145             :             When running low on entropy
    1146             :    "primegen"      '\n'  0 0
    1147             :            Prime generated
    1148             :                    '!'
    1149             :            Need to refresh the prime pool
    1150             :                    '<','>'
    1151             :            Number of bits adjusted
    1152             :                    '^'
    1153             :            Looking for a generator
    1154             :                    '.'
    1155             :            Fermat tests on 10 candidates failed
    1156             :                   ':'
    1157             :            Restart with a new random value
    1158             :                   '+'
    1159             :            Rabin Miller test passed
    1160             :    "pk_elg"        '+','-','.','\n'   0  0
    1161             :             Only used in debugging mode.
    1162             :    "pk_dsa"
    1163             :             Only used in debugging mode.
    1164             : */
    1165             : void
    1166           0 : _gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
    1167             :                             void *cb_data)
    1168             : {
    1169             : #if USE_DSA
    1170           0 :   _gcry_register_pk_dsa_progress (cb, cb_data);
    1171             : #endif
    1172             : #if USE_ELGAMAL
    1173           0 :   _gcry_register_pk_elg_progress (cb, cb_data);
    1174             : #endif
    1175           0 :   _gcry_register_primegen_progress (cb, cb_data);
    1176           0 :   _gcry_register_random_progress (cb, cb_data);
    1177           0 : }
    1178             : 
    1179             : 
    1180             : 
    1181             : /* This is a helper for the regression test suite to test Libgcrypt's locks.
    1182             :    It works using a one test lock with CMD controlling what to do:
    1183             : 
    1184             :      30111 - Allocate and init lock
    1185             :      30112 - Take lock
    1186             :      30113 - Release lock
    1187             :      30114 - Destroy lock.
    1188             : 
    1189             :    This function is used by tests/t-lock.c - it is not part of the
    1190             :    public API!
    1191             :  */
    1192             : static gpg_err_code_t
    1193           0 : external_lock_test (int cmd)
    1194             : {
    1195             :   GPGRT_LOCK_DEFINE (testlock);
    1196           0 :   gpg_err_code_t rc = 0;
    1197             : 
    1198           0 :   switch (cmd)
    1199             :     {
    1200             :     case 30111:  /* Init Lock.  */
    1201           0 :       rc = gpgrt_lock_init (&testlock);
    1202           0 :       break;
    1203             : 
    1204             :     case 30112:  /* Take Lock.  */
    1205           0 :       rc = gpgrt_lock_lock (&testlock);
    1206           0 :       break;
    1207             : 
    1208             :     case 30113:  /* Release Lock.  */
    1209           0 :       rc = gpgrt_lock_unlock (&testlock);
    1210           0 :       break;
    1211             : 
    1212             :     case 30114:  /* Destroy Lock.  */
    1213           0 :       rc = gpgrt_lock_destroy (&testlock);
    1214           0 :       break;
    1215             : 
    1216             :     default:
    1217           0 :       rc = GPG_ERR_INV_OP;
    1218           0 :       break;
    1219             :     }
    1220             : 
    1221           0 :   return rc;
    1222             : }

Generated by: LCOV version 1.12