#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#ifdef HAVE_SYSLOG
# include <syslog.h>
#endif
#include "g10lib.h"
#include "gcrypt-testapi.h"
#include "cipher.h"
#include "stdmem.h"
#include "secmem.h"
static unsigned int debug_flags;
static int force_fips_mode;
static int any_init_done;
static void (*pre_syscall_func)(void);
static void (*post_syscall_func)(void);
static gcry_handler_alloc_t alloc_func;
static gcry_handler_alloc_t alloc_secure_func;
static gcry_handler_secure_check_t is_secure_func;
static gcry_handler_realloc_t realloc_func;
static gcry_handler_free_t free_func;
static gcry_handler_no_mem_t outofcore_handler;
static void *outofcore_handler_value;
static int no_secure_memory;
static gpg_err_code_t external_lock_test (int cmd);
static void
global_init (void)
{
gcry_error_t err = 0;
if (any_init_done)
return;
any_init_done = 1;
_gcry_set_preferred_rng_type (0);
if (!pre_syscall_func)
gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func);
_gcry_initialize_fips_mode (force_fips_mode);
_gcry_detect_hw_features ();
err = _gcry_cipher_init ();
if (err)
goto fail;
err = _gcry_md_init ();
if (err)
goto fail;
err = _gcry_mac_init ();
if (err)
goto fail;
err = _gcry_pk_init ();
if (err)
goto fail;
err = _gcry_primegen_init ();
if (err)
goto fail;
err = _gcry_secmem_module_init ();
if (err)
goto fail;
err = _gcry_mpi_init ();
if (err)
goto fail;
return;
fail:
BUG ();
}
int
_gcry_global_is_operational (void)
{
if (!any_init_done)
{
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
"missing initialization - please fix the application");
#endif
global_init ();
}
return _gcry_fips_is_operational ();
}
static const char*
parse_version_number( const char *s, int *number )
{
int val = 0;
if( *s == '0' && isdigit(s[1]) )
return NULL;
for ( ; isdigit(*s); s++ ) {
val *= 10;
val += *s - '0';
}
*number = val;
return val < 0? NULL : s;
}
static const char *
parse_version_string( const char *s, int *major, int *minor, int *micro )
{
s = parse_version_number( s, major );
if( !s || *s != '.' )
return NULL;
s++;
s = parse_version_number( s, minor );
if( !s || *s != '.' )
return NULL;
s++;
s = parse_version_number( s, micro );
if( !s )
return NULL;
return s;
}
const char *
_gcry_check_version (const char *req_version)
{
const char *ver = VERSION;
int my_major, my_minor, my_micro;
int rq_major, rq_minor, rq_micro;
const char *my_plvl;
if (req_version && req_version[0] == 1 && req_version[1] == 1)
return _gcry_compat_identification ();
global_init ();
if ( !req_version )
return ver;
my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
if ( !my_plvl )
return NULL;
if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro))
return NULL;
if ( my_major > rq_major
|| (my_major == rq_major && my_minor > rq_minor)
|| (my_major == rq_major && my_minor == rq_minor && my_micro > rq_micro)
|| (my_major == rq_major && my_minor == rq_minor
&& my_micro == rq_micro))
{
return ver;
}
return NULL;
}
static void
print_config (const char *what, gpgrt_stream_t fp)
{
int i;
const char *s;
if (!what || !strcmp (what, "version"))
{
gpgrt_fprintf (fp, "version:%s:%x:%s:%x:\n",
VERSION, GCRYPT_VERSION_NUMBER,
GPGRT_VERSION, GPGRT_VERSION_NUMBER);
}
if (!what || !strcmp (what, "cc"))
{
gpgrt_fprintf (fp, "cc:%d:%s:\n",
#if GPGRT_VERSION_NUMBER >= 0x011b00
GPGRT_GCC_VERSION
#else
_GPG_ERR_GCC_VERSION
#endif
,
#ifdef __clang__
"clang:" __VERSION__
#elif __GNUC__
"gcc:" __VERSION__
#else
":"
#endif
);
}
if (!what || !strcmp (what, "ciphers"))
gpgrt_fprintf (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
if (!what || !strcmp (what, "pubkeys"))
gpgrt_fprintf (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
if (!what || !strcmp (what, "digests"))
gpgrt_fprintf (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
if (!what || !strcmp (what, "rnd-mod"))
{
gpgrt_fprintf (fp, "rnd-mod:"
#if USE_RNDEGD
"egd:"
#endif
#if USE_RNDLINUX
"linux:"
#endif
#if USE_RNDUNIX
"unix:"
#endif
#if USE_RNDW32
"w32:"
#endif
"\n");
}
if (!what || !strcmp (what, "cpu-arch"))
{
gpgrt_fprintf (fp, "cpu-arch:"
#if defined(HAVE_CPU_ARCH_X86)
"x86"
#elif defined(HAVE_CPU_ARCH_ALPHA)
"alpha"
#elif defined(HAVE_CPU_ARCH_SPARC)
"sparc"
#elif defined(HAVE_CPU_ARCH_MIPS)
"mips"
#elif defined(HAVE_CPU_ARCH_M68K)
"m68k"
#elif defined(HAVE_CPU_ARCH_PPC)
"ppc"
#elif defined(HAVE_CPU_ARCH_ARM)
"arm"
#endif
":\n");
}
if (!what || !strcmp (what, "mpi-asm"))
gpgrt_fprintf (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
if (!what || !strcmp (what, "hwflist"))
{
unsigned int hwfeatures, afeature;
hwfeatures = _gcry_get_hw_features ();
gpgrt_fprintf (fp, "hwflist:");
for (i=0; (s = _gcry_enum_hw_features (i, &afeature)); i++)
if ((hwfeatures & afeature))
gpgrt_fprintf (fp, "%s:", s);
gpgrt_fprintf (fp, "\n");
}
if (!what || !strcmp (what, "fips-mode"))
{
gpgrt_fprintf (fp, "fips-mode:%c:%c:\n",
fips_mode ()? 'y':'n',
_gcry_enforced_fips_mode ()? 'y':'n' );
}
if (!what || !strcmp (what, "rng-type"))
{
unsigned int jver;
int active;
i = _gcry_get_rng_type (0);
switch (i)
{
case GCRY_RNG_TYPE_STANDARD: s = "standard"; break;
case GCRY_RNG_TYPE_FIPS: s = "fips"; break;
case GCRY_RNG_TYPE_SYSTEM: s = "system"; break;
default: BUG ();
}
jver = _gcry_rndjent_get_version (&active);
gpgrt_fprintf (fp, "rng-type:%s:%d:%u:%d:\n", s, i, jver, active);
}
}
char *
_gcry_get_config (int mode, const char *what)
{
gpgrt_stream_t fp;
int save_errno;
void *data;
char *p;
if (mode)
{
gpg_err_set_errno (EINVAL);
return NULL;
}
fp = gpgrt_fopenmem (0, "w+b,samethread");
if (!fp)
return NULL;
print_config (what, fp);
if (gpgrt_ferror (fp))
{
save_errno = errno;
gpgrt_fclose (fp);
gpg_err_set_errno (save_errno);
return NULL;
}
gpgrt_rewind (fp);
if (gpgrt_fclose_snatch (fp, &data, NULL))
{
save_errno = errno;
gpgrt_fclose (fp);
gpg_err_set_errno (save_errno);
return NULL;
}
if (!data)
{
gpg_err_set_errno (0);
return NULL;
}
if (what && (p = strchr (data, '\n')))
*p = 0;
return data;
}
gcry_err_code_t
_gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
{
static int init_finished = 0;
gcry_err_code_t rc = 0;
switch (cmd)
{
case GCRYCTL_ENABLE_M_GUARD:
_gcry_private_enable_m_guard ();
break;
case GCRYCTL_ENABLE_QUICK_RANDOM:
_gcry_set_preferred_rng_type (0);
_gcry_enable_quick_random_gen ();
break;
case GCRYCTL_FAKED_RANDOM_P:
if (_gcry_random_is_faked ())
rc = GPG_ERR_GENERAL;
break;
case GCRYCTL_DUMP_RANDOM_STATS:
_gcry_random_dump_stats ();
break;
case GCRYCTL_DUMP_MEMORY_STATS:
break;
case GCRYCTL_DUMP_SECMEM_STATS:
_gcry_secmem_dump_stats (0);
break;
case GCRYCTL_DROP_PRIVS:
global_init ();
_gcry_secmem_init (0);
break;
case GCRYCTL_DISABLE_SECMEM:
global_init ();
no_secure_memory = 1;
break;
case GCRYCTL_INIT_SECMEM:
global_init ();
_gcry_secmem_init (va_arg (arg_ptr, unsigned int));
if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED))
rc = GPG_ERR_GENERAL;
break;
case GCRYCTL_TERM_SECMEM:
global_init ();
_gcry_secmem_term ();
break;
case GCRYCTL_DISABLE_SECMEM_WARN:
_gcry_set_preferred_rng_type (0);
_gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
| GCRY_SECMEM_FLAG_NO_WARNING));
break;
case GCRYCTL_SUSPEND_SECMEM_WARN:
_gcry_set_preferred_rng_type (0);
_gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
| GCRY_SECMEM_FLAG_SUSPEND_WARNING));
break;
case GCRYCTL_RESUME_SECMEM_WARN:
_gcry_set_preferred_rng_type (0);
_gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
& ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
break;
case 78:
_gcry_secmem_set_auto_expand (va_arg (arg_ptr, unsigned int));
break;
case GCRYCTL_USE_SECURE_RNDPOOL:
global_init ();
_gcry_secure_random_alloc ();
break;
case GCRYCTL_SET_RANDOM_SEED_FILE:
_gcry_set_preferred_rng_type (0);
_gcry_set_random_seed_file (va_arg (arg_ptr, const char *));
break;
case GCRYCTL_UPDATE_RANDOM_SEED_FILE:
_gcry_set_preferred_rng_type (0);
if ( fips_is_operational () )
_gcry_update_random_seed_file ();
break;
case GCRYCTL_SET_VERBOSITY:
_gcry_set_preferred_rng_type (0);
_gcry_set_log_verbosity (va_arg (arg_ptr, int));
break;
case GCRYCTL_SET_DEBUG_FLAGS:
debug_flags |= va_arg (arg_ptr, unsigned int);
break;
case GCRYCTL_CLEAR_DEBUG_FLAGS:
debug_flags &= ~va_arg (arg_ptr, unsigned int);
break;
case GCRYCTL_DISABLE_INTERNAL_LOCKING:
global_init ();
break;
case GCRYCTL_ANY_INITIALIZATION_P:
if (any_init_done)
rc = GPG_ERR_GENERAL;
break;
case GCRYCTL_INITIALIZATION_FINISHED_P:
if (init_finished)
rc = GPG_ERR_GENERAL;
break;
case GCRYCTL_INITIALIZATION_FINISHED:
if (! init_finished)
{
global_init ();
_gcry_random_initialize (0);
init_finished = 1;
(void)fips_is_operational ();
}
break;
case GCRYCTL_SET_THREAD_CBS:
_gcry_set_preferred_rng_type (0);
global_init ();
break;
case GCRYCTL_FAST_POLL:
_gcry_set_preferred_rng_type (0);
_gcry_random_initialize (1);
if ( fips_is_operational () )
_gcry_fast_random_poll ();
break;
case GCRYCTL_SET_RNDEGD_SOCKET:
#if USE_RNDEGD
_gcry_set_preferred_rng_type (0);
rc = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
#else
rc = GPG_ERR_NOT_SUPPORTED;
#endif
break;
case GCRYCTL_SET_RANDOM_DAEMON_SOCKET:
_gcry_set_preferred_rng_type (0);
_gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *));
break;
case GCRYCTL_USE_RANDOM_DAEMON:
_gcry_set_preferred_rng_type (0);
_gcry_random_initialize (1);
_gcry_use_random_daemon (!! va_arg (arg_ptr, int));
break;
case GCRYCTL_CLOSE_RANDOM_DEVICE:
_gcry_random_close_fds ();
break;
case GCRYCTL_PRINT_CONFIG:
{
FILE *fp = va_arg (arg_ptr, FILE *);
char *tmpstr;
_gcry_set_preferred_rng_type (0);
tmpstr = _gcry_get_config (0, NULL);
if (tmpstr)
{
if (fp)
fputs (tmpstr, fp);
else
log_info ("%s", tmpstr);
xfree (tmpstr);
}
}
break;
case GCRYCTL_OPERATIONAL_P:
_gcry_set_preferred_rng_type (0);
if (_gcry_fips_test_operational ())
rc = GPG_ERR_GENERAL;
break;
case GCRYCTL_FIPS_MODE_P:
if (fips_mode ()
&& !_gcry_is_fips_mode_inactive ()
&& !no_secure_memory)
rc = GPG_ERR_GENERAL;
break;
case GCRYCTL_FORCE_FIPS_MODE:
_gcry_set_preferred_rng_type (0);
if (!any_init_done)
{
force_fips_mode = 1;
}
else
{
if (_gcry_fips_test_error_or_operational ())
_gcry_fips_run_selftests (1);
if (_gcry_fips_is_operational ())
rc = GPG_ERR_GENERAL;
}
break;
case GCRYCTL_SELFTEST:
global_init ();
rc = _gcry_fips_run_selftests (1);
break;
#if _GCRY_GCC_VERSION >= 40600
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wswitch"
#endif
case PRIV_CTL_INIT_EXTRNG_TEST:
rc = GPG_ERR_NOT_SUPPORTED;
break;
case PRIV_CTL_RUN_EXTRNG_TEST:
{
struct gcry_drbg_test_vector *test =
va_arg (arg_ptr, struct gcry_drbg_test_vector *);
unsigned char *buf = va_arg (arg_ptr, unsigned char *);
if (buf)
rc = _gcry_rngdrbg_cavs_test (test, buf);
else
rc = _gcry_rngdrbg_healthcheck_one (test);
}
break;
case PRIV_CTL_DEINIT_EXTRNG_TEST:
rc = GPG_ERR_NOT_SUPPORTED;
break;
case PRIV_CTL_EXTERNAL_LOCK_TEST:
rc = external_lock_test (va_arg (arg_ptr, int));
break;
case PRIV_CTL_DUMP_SECMEM_STATS:
_gcry_secmem_dump_stats (1);
break;
#if _GCRY_GCC_VERSION >= 40600
# pragma GCC diagnostic pop
#endif
case GCRYCTL_DISABLE_HWF:
{
const char *name = va_arg (arg_ptr, const char *);
rc = _gcry_disable_hw_feature (name);
}
break;
case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
if (!any_init_done)
{
_gcry_set_preferred_rng_type (0);
_gcry_set_enforced_fips_mode ();
}
else
rc = GPG_ERR_GENERAL;
break;
case GCRYCTL_SET_PREFERRED_RNG_TYPE:
{
int i = va_arg (arg_ptr, int);
if (i > 0)
_gcry_set_preferred_rng_type (i);
}
break;
case GCRYCTL_GET_CURRENT_RNG_TYPE:
{
int *ip = va_arg (arg_ptr, int*);
if (ip)
*ip = _gcry_get_rng_type (!any_init_done);
}
break;
case GCRYCTL_DISABLE_LOCKED_SECMEM:
_gcry_set_preferred_rng_type (0);
_gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
| GCRY_SECMEM_FLAG_NO_MLOCK));
break;
case GCRYCTL_DISABLE_PRIV_DROP:
_gcry_set_preferred_rng_type (0);
_gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
| GCRY_SECMEM_FLAG_NO_PRIV_DROP));
break;
case GCRYCTL_INACTIVATE_FIPS_FLAG:
case GCRYCTL_REACTIVATE_FIPS_FLAG:
rc = GPG_ERR_NOT_IMPLEMENTED;
break;
case GCRYCTL_DRBG_REINIT:
{
const char *flagstr = va_arg (arg_ptr, const char *);
gcry_buffer_t *pers = va_arg (arg_ptr, gcry_buffer_t *);
int npers = va_arg (arg_ptr, int);
if (va_arg (arg_ptr, void *) || npers < 0)
rc = GPG_ERR_INV_ARG;
else if (_gcry_get_rng_type (!any_init_done) != GCRY_RNG_TYPE_FIPS)
rc = GPG_ERR_NOT_SUPPORTED;
else
rc = _gcry_rngdrbg_reinit (flagstr, pers, npers);
}
break;
case GCRYCTL_REINIT_SYSCALL_CLAMP:
if (!pre_syscall_func)
gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func);
break;
default:
_gcry_set_preferred_rng_type (0);
rc = GPG_ERR_INV_OP;
}
return rc;
}
void
_gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
gcry_handler_alloc_t new_alloc_secure_func,
gcry_handler_secure_check_t new_is_secure_func,
gcry_handler_realloc_t new_realloc_func,
gcry_handler_free_t new_free_func)
{
global_init ();
if (fips_mode ())
{
_gcry_inactivate_fips_mode ("custom allocation handler");
}
alloc_func = new_alloc_func;
alloc_secure_func = new_alloc_secure_func;
is_secure_func = new_is_secure_func;
realloc_func = new_realloc_func;
free_func = new_free_func;
}
void
_gcry_set_outofcore_handler (int (*f)(void*, size_t, unsigned int), void *value)
{
global_init ();
if (fips_mode () )
{
log_info ("out of core handler ignored in FIPS mode\n");
return;
}
outofcore_handler = f;
outofcore_handler_value = value;
}
static int
get_no_secure_memory (void)
{
if (!no_secure_memory)
return 0;
if (_gcry_enforced_fips_mode ())
{
no_secure_memory = 0;
return 0;
}
return no_secure_memory;
}
static gcry_err_code_t
do_malloc (size_t n, unsigned int flags, void **mem)
{
gcry_err_code_t err = 0;
void *m;
if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ())
{
if (alloc_secure_func)
m = (*alloc_secure_func) (n);
else
m = _gcry_private_malloc_secure (n, !!(flags & GCRY_ALLOC_FLAG_XHINT));
}
else
{
if (alloc_func)
m = (*alloc_func) (n);
else
m = _gcry_private_malloc (n);
}
if (!m)
{
if (!errno)
gpg_err_set_errno (ENOMEM);
err = gpg_err_code_from_errno (errno);
}
else
*mem = m;
return err;
}
void *
_gcry_malloc (size_t n)
{
void *mem = NULL;
do_malloc (n, 0, &mem);
return mem;
}
static void *
_gcry_malloc_secure_core (size_t n, int xhint)
{
void *mem = NULL;
do_malloc (n, (GCRY_ALLOC_FLAG_SECURE | (xhint? GCRY_ALLOC_FLAG_XHINT:0)),
&mem);
return mem;
}
void *
_gcry_malloc_secure (size_t n)
{
return _gcry_malloc_secure_core (n, 0);
}
int
_gcry_is_secure (const void *a)
{
if (get_no_secure_memory ())
return 0;
if (is_secure_func)
return is_secure_func (a) ;
return _gcry_private_is_secure (a);
}
void
_gcry_check_heap( const void *a )
{
(void)a;
#if 0#endif
}
static void *
_gcry_realloc_core (void *a, size_t n, int xhint)
{
void *p;
if (!a)
return _gcry_malloc (n);
if (!n)
{
xfree (a);
return NULL;
}
if (realloc_func)
p = realloc_func (a, n);
else
p = _gcry_private_realloc (a, n, xhint);
if (!p && !errno)
gpg_err_set_errno (ENOMEM);
return p;
}
void *
_gcry_realloc (void *a, size_t n)
{
return _gcry_realloc_core (a, n, 0);
}
void
_gcry_free (void *p)
{
int save_errno;
if (!p)
return;
save_errno = errno;
if (free_func)
free_func (p);
else
_gcry_private_free (p);
if (save_errno)
gpg_err_set_errno (save_errno);
}
void *
_gcry_calloc (size_t n, size_t m)
{
size_t bytes;
void *p;
bytes = n * m;
if (m && bytes / m != n)
{
gpg_err_set_errno (ENOMEM);
return NULL;
}
p = _gcry_malloc (bytes);
if (p)
memset (p, 0, bytes);
return p;
}
void *
_gcry_calloc_secure (size_t n, size_t m)
{
size_t bytes;
void *p;
bytes = n * m;
if (m && bytes / m != n)
{
gpg_err_set_errno (ENOMEM);
return NULL;
}
p = _gcry_malloc_secure (bytes);
if (p)
memset (p, 0, bytes);
return p;
}
static char *
_gcry_strdup_core (const char *string, int xhint)
{
char *string_cp = NULL;
size_t string_n = 0;
string_n = strlen (string);
if (_gcry_is_secure (string))
string_cp = _gcry_malloc_secure_core (string_n + 1, xhint);
else
string_cp = _gcry_malloc (string_n + 1);
if (string_cp)
strcpy (string_cp, string);
return string_cp;
}
char *
_gcry_strdup (const char *string)
{
return _gcry_strdup_core (string, 0);
}
void *
_gcry_xmalloc( size_t n )
{
void *p;
while ( !(p = _gcry_malloc( n )) )
{
if ( fips_mode ()
|| !outofcore_handler
|| !outofcore_handler (outofcore_handler_value, n, 0) )
{
_gcry_fatal_error (gpg_err_code_from_errno (errno), NULL);
}
}
return p;
}
void *
_gcry_xrealloc( void *a, size_t n )
{
void *p;
while (!(p = _gcry_realloc_core (a, n, 1)))
{
if ( fips_mode ()
|| !outofcore_handler
|| !outofcore_handler (outofcore_handler_value, n,
_gcry_is_secure(a)? 3:2))
{
_gcry_fatal_error (gpg_err_code_from_errno (errno), NULL );
}
}
return p;
}
void *
_gcry_xmalloc_secure( size_t n )
{
void *p;
while (!(p = _gcry_malloc_secure_core (n, 1)))
{
if ( fips_mode ()
|| !outofcore_handler
|| !outofcore_handler (outofcore_handler_value, n, 1) )
{
_gcry_fatal_error (gpg_err_code_from_errno (errno),
_("out of core in secure memory"));
}
}
return p;
}
void *
_gcry_xcalloc( size_t n, size_t m )
{
size_t nbytes;
void *p;
nbytes = n * m;
if (m && nbytes / m != n)
{
gpg_err_set_errno (ENOMEM);
_gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
}
p = _gcry_xmalloc ( nbytes );
memset ( p, 0, nbytes );
return p;
}
void *
_gcry_xcalloc_secure( size_t n, size_t m )
{
size_t nbytes;
void *p;
nbytes = n * m;
if (m && nbytes / m != n)
{
gpg_err_set_errno (ENOMEM);
_gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
}
p = _gcry_xmalloc_secure ( nbytes );
memset ( p, 0, nbytes );
return p;
}
char *
_gcry_xstrdup (const char *string)
{
char *p;
while ( !(p = _gcry_strdup_core (string, 1)) )
{
size_t n = strlen (string);
int is_sec = !!_gcry_is_secure (string);
if (fips_mode ()
|| !outofcore_handler
|| !outofcore_handler (outofcore_handler_value, n, is_sec) )
{
_gcry_fatal_error (gpg_err_code_from_errno (errno),
is_sec? _("out of core in secure memory"):NULL);
}
}
return p;
}
void
_gcry_pre_syscall (void)
{
if (pre_syscall_func)
pre_syscall_func ();
}
void
_gcry_post_syscall (void)
{
if (post_syscall_func)
post_syscall_func ();
}
int
_gcry_get_debug_flag (unsigned int mask)
{
if ( fips_mode () )
return 0;
return (debug_flags & mask);
}
void
_gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
void *cb_data)
{
#if USE_DSA
_gcry_register_pk_dsa_progress (cb, cb_data);
#endif
#if USE_ELGAMAL
_gcry_register_pk_elg_progress (cb, cb_data);
#endif
_gcry_register_primegen_progress (cb, cb_data);
_gcry_register_random_progress (cb, cb_data);
}
static gpg_err_code_t
external_lock_test (int cmd)
{
GPGRT_LOCK_DEFINE (testlock);
gpg_err_code_t rc = 0;
switch (cmd)
{
case 30111:
rc = gpgrt_lock_init (&testlock);
break;
case 30112:
rc = gpgrt_lock_lock (&testlock);
break;
case 30113:
rc = gpgrt_lock_unlock (&testlock);
break;
case 30114:
rc = gpgrt_lock_destroy (&testlock);
break;
default:
rc = GPG_ERR_INV_OP;
break;
}
return rc;
}