update libgcrypt to 1.8.6

This commit is contained in:
yanan-rock 2020-07-26 23:27:48 +08:00
parent 0fc2049311
commit e08115e53e
7 changed files with 8735 additions and 225 deletions

View File

@ -1,196 +1,7 @@
diff -up libgcrypt-1.8.3/cipher/md.c.fips-ctor libgcrypt-1.8.3/cipher/md.c
--- libgcrypt-1.8.3/cipher/md.c.fips-ctor 2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.3/cipher/md.c 2018-07-12 13:02:49.599423390 +0200
@@ -411,11 +411,8 @@ md_enable (gcry_md_hd_t hd, int algorith
if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
{
- _gcry_inactivate_fips_mode ("MD5 used");
if (_gcry_enforced_fips_mode () )
{
- /* We should never get to here because we do not register
- MD5 in enforced fips mode. But better throw an error. */
err = GPG_ERR_DIGEST_ALGO;
}
}
diff -up libgcrypt-1.8.3/src/fips.c.fips-ctor libgcrypt-1.8.3/src/fips.c
--- libgcrypt-1.8.3/src/fips.c.fips-ctor 2018-07-12 13:02:49.589423158 +0200
+++ libgcrypt-1.8.3/src/fips.c 2018-07-12 13:08:45.955663998 +0200
@@ -91,6 +91,31 @@ static void fips_new_state (enum module_
+/* Initialize the FSM lock - this function may only
+ be called once and is intended to be run from the library
+ constructor */
+void
+_gcry_initialize_fsm_lock (void)
+{
+ gpg_error_t err;
+ /* Intitialize the lock to protect the FSM. */
+ err = gpgrt_lock_init (&fsm_lock);
+ if (err)
+ {
+ /* If that fails we can't do anything but abort the
+ process. We need to use log_info so that the FSM won't
+ get involved. */
+ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
+ gpg_strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "creating FSM lock failed: %s - abort",
+ gpg_strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+}
+
/* Check whether the OS is in FIPS mode and record that in a module
local variable. If FORCE is passed as true, fips mode will be
enabled anyway. Note: This function is not thread-safe and should
@@ -100,7 +125,6 @@ void
_gcry_initialize_fips_mode (int force)
{
static int done;
- gpg_error_t err;
/* Make sure we are not accidentally called twice. */
if (done)
@@ -179,24 +203,6 @@ _gcry_initialize_fips_mode (int force)
/* Yes, we are in FIPS mode. */
FILE *fp;
- /* Intitialize the lock to protect the FSM. */
- err = gpgrt_lock_init (&fsm_lock);
- if (err)
- {
- /* If that fails we can't do anything but abort the
- process. We need to use log_info so that the FSM won't
- get involved. */
- log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
- gpg_strerror (err));
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
- "creating FSM lock failed: %s - abort",
- gpg_strerror (err));
-#endif /*HAVE_SYSLOG*/
- abort ();
- }
-
-
/* If the FIPS force files exists, is readable and has a number
!= 0 on its first line, we enable the enforced fips mode. */
fp = fopen (FIPS_FORCE_FILE, "r");
@@ -359,16 +365,20 @@ _gcry_fips_is_operational (void)
{
int result;
- if (!fips_mode ())
+ lock_fsm ();
+ if (current_state == STATE_POWERON && !fips_mode ())
+ /* If we are at this point in POWERON state it means the FIPS
+ module installation was not completed. (/etc/system-fips
+ is not present.) */
result = 1;
else
{
- lock_fsm ();
- if (current_state == STATE_INIT)
+ if (current_state == STATE_INIT || current_state == STATE_SELFTEST)
{
- /* If we are still in the INIT state, we need to run the
- selftests so that the FSM can eventually get into
- operational state. Given that we would need a 2-phase
+ /* If we are still in the INIT (or SELFTEST) state,
+ we need to run (or finish) the selftests so
+ that the FSM can eventually get into operational
+ state. Given that we would need a 2-phase
initialization of libgcrypt, but that has traditionally
not been enforced, we use this on demand self-test
checking. Note that Proper applications would do the
@@ -384,9 +394,11 @@ _gcry_fips_is_operational (void)
lock_fsm ();
}
- result = (current_state == STATE_OPERATIONAL);
- unlock_fsm ();
+ result = (current_state == STATE_OPERATIONAL) || !fips_mode ();
+ /* We always run the selftests but ignore the result
+ in non-FIPS mode. */
}
+ unlock_fsm ();
return result;
}
@@ -709,9 +721,25 @@ _gcry_fips_run_selftests (int extended)
{
enum module_states result = STATE_ERROR;
gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
+ int in_poweron;
- if (fips_mode ())
- fips_new_state (STATE_SELFTEST);
+ lock_fsm ();
+ in_poweron = (current_state == STATE_POWERON);
+ unlock_fsm ();
+
+ fips_new_state (STATE_SELFTEST);
+
+ /* We first check the integrity of the binary.
+ If run from the constructor we are in POWERON state,
+ we return and finish the remaining selftests before
+ real use of the library. It will be in the POWERON
+ state meanwhile. */
+ if (in_poweron)
+ if (check_binary_integrity ())
+ goto leave;
+
+ if (in_poweron)
+ return 0;
if (run_cipher_selftests (extended))
goto leave;
@@ -730,18 +758,12 @@ _gcry_fips_run_selftests (int extended)
if (run_pubkey_selftests (extended))
goto leave;
- /* Now check the integrity of the binary. We do this this after
- having checked the HMAC code. */
- if (check_binary_integrity ())
- goto leave;
-
/* All selftests passed. */
result = STATE_OPERATIONAL;
ec = 0;
leave:
- if (fips_mode ())
- fips_new_state (result);
+ fips_new_state (result);
return ec;
}
@@ -797,6 +819,7 @@ fips_new_state (enum module_states new_s
{
case STATE_POWERON:
if (new_state == STATE_INIT
+ || new_state == STATE_SELFTEST
|| new_state == STATE_ERROR
|| new_state == STATE_FATALERROR)
ok = 1;
@@ -811,6 +834,8 @@ fips_new_state (enum module_states new_s
case STATE_SELFTEST:
if (new_state == STATE_OPERATIONAL
+ || new_state == STATE_INIT
+ || new_state == STATE_SELFTEST
|| new_state == STATE_ERROR
|| new_state == STATE_FATALERROR)
ok = 1;
diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c
--- libgcrypt-1.8.3/src/global.c.fips-ctor 2017-11-23 19:25:58.000000000 +0100 --- libgcrypt-1.8.3/src/global.c.fips-ctor 2017-11-23 19:25:58.000000000 +0100
+++ libgcrypt-1.8.3/src/global.c 2018-07-12 13:02:49.599423390 +0200 +++ libgcrypt-1.8.3/src/global.c 2020-04-17 16:29:59.258218015 +0200
@@ -141,6 +141,29 @@ global_init (void) @@ -141,6 +141,34 @@ global_init (void)
} }
@ -202,25 +13,30 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c
+{ +{
+ int rv; + int rv;
+ +
+ /* We always need the FSM lock to be functional. */
+ _gcry_initialize_fsm_lock ();
+
+ rv = access (FIPS_MODULE_PATH, F_OK); + rv = access (FIPS_MODULE_PATH, F_OK);
+ if (rv < 0 && errno != ENOENT) + if (rv < 0 && errno != ENOENT)
+ rv = 0; + rv = 0;
+ +
+ if (!rv) + if (!rv)
+ { + {
+ /* We run the integrity check at this point. The remaining + int no_secmem_save;
+ selftests are run before use of the library by application. */ +
+ /* it should be always 0 at this point but let's keep on the safe side */
+ no_secmem_save = no_secure_memory;
+ no_secure_memory = 1;
+ /* force selftests */
+ global_init();
+ _gcry_fips_run_selftests (0); + _gcry_fips_run_selftests (0);
+ if (!fips_mode())
+ _gcry_random_close_fds ();
+ no_secure_memory = no_secmem_save;
+ } + }
+} +}
+ +
/* This function is called by the macro fips_is_operational and makes /* This function is called by the macro fips_is_operational and makes
sure that the minimal initialization has been done. This is far sure that the minimal initialization has been done. This is far
from a perfect solution and hides problems with an improper from a perfect solution and hides problems with an improper
@@ -671,8 +694,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, @@ -671,8 +699,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
case GCRYCTL_FIPS_MODE_P: case GCRYCTL_FIPS_MODE_P:
if (fips_mode () if (fips_mode ()
@ -230,24 +46,15 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c
rc = GPG_ERR_GENERAL; /* Used as TRUE value */ rc = GPG_ERR_GENERAL; /* Used as TRUE value */
break; break;
@@ -749,7 +771,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, @@ -749,9 +776,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
break; break;
case GCRYCTL_SET_ENFORCED_FIPS_FLAG: case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
- if (!any_init_done) - if (!any_init_done)
+ if (fips_mode ()) + if (fips_mode ())
{ {
/* Not yet initialized at all. Set the enforced fips mode flag */ - /* Not yet initialized at all. Set the enforced fips mode flag */
+ /* We are in FIPS mode, we can set the enforced fips mode flag. */
_gcry_set_preferred_rng_type (0); _gcry_set_preferred_rng_type (0);
diff -up libgcrypt-1.8.3/src/g10lib.h.fips-ctor libgcrypt-1.8.3/src/g10lib.h _gcry_set_enforced_fips_mode ();
--- libgcrypt-1.8.3/src/g10lib.h.fips-ctor 2017-11-23 19:16:58.000000000 +0100 }
+++ libgcrypt-1.8.3/src/g10lib.h 2018-07-12 13:02:49.600423413 +0200
@@ -422,6 +422,8 @@ gpg_err_code_t _gcry_sexp_vextract_param
/*-- fips.c --*/
+void _gcry_initialize_fsm_lock (void);
+
void _gcry_initialize_fips_mode (int force);
int _gcry_fips_mode (void);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,139 @@
diff -up libgcrypt-1.8.5/src/fips.c.fips-module libgcrypt-1.8.5/src/fips.c
--- libgcrypt-1.8.5/src/fips.c.fips-module 2020-04-20 19:07:45.924919645 +0200
+++ libgcrypt-1.8.5/src/fips.c 2020-04-20 19:10:33.690722470 +0200
@@ -35,10 +35,6 @@
#include "hmac256.h"
-/* The name of the file used to force libgcrypt into fips mode. */
-#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
-
-
/* The states of the finite state machine used in fips mode. */
enum module_states
{
@@ -122,54 +118,6 @@ _gcry_initialize_fips_mode (int force)
goto leave;
}
- /* For testing the system it is useful to override the system
- provided detection of the FIPS mode and force FIPS mode using a
- file. The filename is hardwired so that there won't be any
- confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
- actually used. The file itself may be empty. */
- if ( !access (FIPS_FORCE_FILE, F_OK) )
- {
- gcry_assert (!no_fips_mode_required);
- goto leave;
- }
-
- /* Checking based on /proc file properties. */
- {
- static const char procfname[] = "/proc/sys/crypto/fips_enabled";
- FILE *fp;
- int saved_errno;
-
- fp = fopen (procfname, "r");
- if (fp)
- {
- char line[256];
-
- if (fgets (line, sizeof line, fp) && atoi (line))
- {
- /* System is in fips mode. */
- fclose (fp);
- gcry_assert (!no_fips_mode_required);
- goto leave;
- }
- fclose (fp);
- }
- else if ((saved_errno = errno) != ENOENT
- && saved_errno != EACCES
- && !access ("/proc/version", F_OK) )
- {
- /* Problem reading the fips file despite that we have the proc
- file system. We better stop right away. */
- log_info ("FATAL: error reading `%s' in libgcrypt: %s\n",
- procfname, strerror (saved_errno));
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
- "reading `%s' failed: %s - abort",
- procfname, strerror (saved_errno));
-#endif /*HAVE_SYSLOG*/
- abort ();
- }
- }
-
/* Fips not not requested, set flag. */
no_fips_mode_required = 1;
diff -up libgcrypt-1.8.5/src/g10lib.h.fips-module libgcrypt-1.8.5/src/g10lib.h
--- libgcrypt-1.8.5/src/g10lib.h.fips-module 2020-04-20 19:07:45.918919759 +0200
+++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 19:11:05.003125740 +0200
@@ -422,6 +422,9 @@ gpg_err_code_t _gcry_sexp_vextract_param
/*-- fips.c --*/
+/* The name of the file used to force libgcrypt into fips mode. */
+#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
+
void _gcry_initialize_fips_mode (int force);
int _gcry_fips_mode (void);
diff -up libgcrypt-1.8.5/src/global.c.fips-module libgcrypt-1.8.5/src/global.c
--- libgcrypt-1.8.5/src/global.c.fips-module 2020-04-20 19:07:45.919919741 +0200
+++ libgcrypt-1.8.5/src/global.c 2020-04-20 19:07:45.950919149 +0200
@@ -160,6 +160,53 @@ void __attribute__ ((constructor)) _gcry
rv = access (FIPS_MODULE_PATH, F_OK);
if (rv < 0 && errno != ENOENT)
rv = 0;
+
+ /* For testing the system it is useful to override the system
+ provided detection of the FIPS mode and force FIPS mode using a
+ file. The filename is hardwired so that there won't be any
+ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
+ actually used. The file itself may be empty. */
+ if ( !access (FIPS_FORCE_FILE, F_OK) )
+ {
+ rv = 0;
+ force_fips_mode = 1;
+ }
+
+ /* Checking based on /proc file properties. */
+ {
+ static const char procfname[] = "/proc/sys/crypto/fips_enabled";
+ FILE *fp;
+ int saved_errno;
+
+ fp = fopen (procfname, "r");
+ if (fp)
+ {
+ char line[256];
+
+ if (fgets (line, sizeof line, fp) && atoi (line))
+ {
+ /* System is in fips mode. */
+ rv = 0;
+ force_fips_mode = 1;
+ }
+ fclose (fp);
+ }
+ else if ((saved_errno = errno) != ENOENT
+ && saved_errno != EACCES
+ && !access ("/proc/version", F_OK) )
+ {
+ /* Problem reading the fips file despite that we have the proc
+ file system. We better stop right away. */
+ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n",
+ procfname, strerror (saved_errno));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "reading `%s' failed: %s - abort",
+ procfname, strerror (saved_errno));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+ }
if (!rv)
{

View File

@ -0,0 +1,285 @@
diff -up libgcrypt-1.8.5/random/rand-internal.h.getrandom libgcrypt-1.8.5/random/rand-internal.h
--- libgcrypt-1.8.5/random/rand-internal.h.getrandom 2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.5/random/rand-internal.h 2020-04-20 14:55:34.875949624 +0200
@@ -47,6 +47,7 @@ void _gcry_random_progress (const char *
/*-- random-csprng.c --*/
void _gcry_rngcsprng_initialize (int full);
+void _gcry_rngcsprng_deinit (void);
void _gcry_rngcsprng_close_fds (void);
void _gcry_rngcsprng_dump_stats (void);
void _gcry_rngcsprng_secure_alloc (void);
@@ -68,6 +69,7 @@ void _gcry_rngcsprng_fast_poll (void);
/*-- random-drbg.c --*/
void _gcry_rngdrbg_inititialize (int full);
+void _gcry_rngdrbg_deinit (void);
void _gcry_rngdrbg_close_fds (void);
void _gcry_rngdrbg_dump_stats (void);
int _gcry_rngdrbg_is_faked (void);
diff -up libgcrypt-1.8.5/random/random.c.getrandom libgcrypt-1.8.5/random/random.c
--- libgcrypt-1.8.5/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.5/random/random.c 2020-04-20 14:55:34.876949605 +0200
@@ -110,8 +110,8 @@ _gcry_random_read_conf (void)
unsigned int result = 0;
fp = fopen (fname, "r");
- if (!fp)
- return result;
+ if (!fp) /* We make only_urandom the default. */
+ return RANDOM_CONF_ONLY_URANDOM;
for (;;)
{
@@ -228,6 +228,22 @@ _gcry_random_initialize (int full)
}
+/* Deinitialize this random subsystem. */
+void
+_gcry_random_deinit (void)
+{
+ if (fips_mode ())
+ _gcry_rngdrbg_deinit ();
+ else if (rng_types.standard)
+ _gcry_rngcsprng_deinit ();
+ else if (rng_types.fips)
+ _gcry_rngdrbg_deinit ();
+ else
+ _gcry_rngcsprng_deinit ();
+ /* not needed for system */
+}
+
+
/* If possible close file descriptors used by the RNG. */
void
_gcry_random_close_fds (void)
diff -up libgcrypt-1.8.5/random/random-csprng.c.getrandom libgcrypt-1.8.5/random/random-csprng.c
--- libgcrypt-1.8.5/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.5/random/random-csprng.c 2020-04-20 15:04:27.182877975 +0200
@@ -55,6 +55,10 @@
#ifdef __MINGW32__
#include <process.h>
#endif
+#if defined(__linux__) && defined(HAVE_SYSCALL)
+# include <sys/syscall.h>
+# include <linux/random.h>
+#endif
#include "g10lib.h"
#include "random.h"
#include "rand-internal.h"
@@ -343,6 +347,21 @@ _gcry_rngcsprng_initialize (int full)
}
+void
+_gcry_rngcsprng_deinit (void)
+{
+ lock_pool();
+ pool_writepos = 0;
+ pool_readpos = 0;
+ pool_filled = 0;
+ pool_filled_counter = 0;
+ did_initial_extra_seeding = 0;
+ pool_balance = 0;
+ just_mixed = 0;
+ unlock_pool();
+}
+
+
/* Try to close the FDs of the random gather module. This is
currently only implemented for rndlinux. */
void
@@ -1116,6 +1135,22 @@ getfnc_gather_random (void))(void (*)(co
enum random_origins, size_t, int);
#if USE_RNDLINUX
+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
+ long ret;
+ char buffer[1];
+
+ _gcry_pre_syscall ();
+ ret = syscall (__NR_getrandom,
+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK);
+ _gcry_post_syscall ();
+ if (ret != -1 || errno != ENOSYS)
+ {
+ fnc = _gcry_rndlinux_gather_random;
+ return fnc;
+ }
+ else
+ /* The syscall is not supported - fallback to /dev/urandom. */
+#endif
if ( !access (NAME_OF_DEV_RANDOM, R_OK)
&& !access (NAME_OF_DEV_URANDOM, R_OK))
{
diff -up libgcrypt-1.8.5/random/random-drbg.c.getrandom libgcrypt-1.8.5/random/random-drbg.c
--- libgcrypt-1.8.5/random/random-drbg.c.getrandom 2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.5/random/random-drbg.c 2020-04-20 15:02:37.782947902 +0200
@@ -1811,6 +1811,22 @@ _gcry_rngdrbg_inititialize (int full)
}
/*
+ * Deinitialize the DRBG invoked by the libgcrypt API
+ * It will be automatically re-initialized on next call
+ */
+void
+_gcry_rngdrbg_deinit (void)
+{
+ drbg_lock ();
+ if (drbg_state)
+ {
+ drbg_uninstantiate (drbg_state);
+ drbg_state = NULL;
+ }
+ drbg_unlock ();
+}
+
+/*
* Backend handler function for GCRYCTL_DRBG_REINIT
*
* Select a different DRBG type and initialize it.
diff -up libgcrypt-1.8.5/random/random.h.getrandom libgcrypt-1.8.5/random/random.h
--- libgcrypt-1.8.5/random/random.h.getrandom 2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.5/random/random.h 2020-04-20 14:55:34.877949586 +0200
@@ -29,6 +29,7 @@ void _gcry_register_random_progress (voi
void _gcry_set_preferred_rng_type (int type);
void _gcry_random_initialize (int full);
+void _gcry_random_deinit (void);
void _gcry_random_close_fds (void);
int _gcry_get_rng_type (int ignore_fips_mode);
void _gcry_random_dump_stats(void);
diff -up libgcrypt-1.8.5/random/rndlinux.c.getrandom libgcrypt-1.8.5/random/rndlinux.c
--- libgcrypt-1.8.5/random/rndlinux.c.getrandom 2020-04-20 15:01:50.159848963 +0200
+++ libgcrypt-1.8.5/random/rndlinux.c 2020-04-20 16:14:21.901610921 +0200
@@ -35,6 +35,7 @@
#include <poll.h>
#if defined(__linux__) && defined(HAVE_SYSCALL)
# include <sys/syscall.h>
+# include <linux/random.h>
#endif
#include "types.h"
@@ -147,12 +148,12 @@ _gcry_rndlinux_gather_random (void (*add
if (!add)
{
/* Special mode to close the descriptors. */
- if (fd_random != -1)
+ if (fd_random >= 0)
{
close (fd_random);
fd_random = -1;
}
- if (fd_urandom != -1)
+ if (fd_urandom >= 0)
{
close (fd_urandom);
fd_urandom = -1;
@@ -166,12 +167,12 @@ _gcry_rndlinux_gather_random (void (*add
apid = getpid ();
if (my_pid != apid)
{
- if (fd_random != -1)
+ if (fd_random >= 0)
{
close (fd_random);
fd_random = -1;
}
- if (fd_urandom != -1)
+ if (fd_urandom >= 0)
{
close (fd_urandom);
fd_urandom = -1;
@@ -216,7 +217,23 @@ _gcry_rndlinux_gather_random (void (*add
that we always require the device to be existent but want a more
graceful behaviour if the rarely needed close operation has been
used and the device needs to be re-opened later. */
- if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom)
+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
+ if (fd_urandom != -2 && !_gcry_in_constructor ())
+ {
+ long ret;
+
+ _gcry_pre_syscall ();
+ ret = syscall (__NR_getrandom,
+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK);
+ _gcry_post_syscall ();
+ if (ret > -1 || errno == EAGAIN || errno == EINTR)
+ {
+ fd_urandom = -2;
+ fd_random = -2;
+ }
+ }
+#endif
+ if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom && !_gcry_in_constructor ())
{
if (fd_random == -1)
{
@@ -255,6 +272,7 @@ _gcry_rndlinux_gather_random (void (*add
* syscall and not a new device and thus we are not able to use
* select(2) to have a timeout. */
#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
+ if (fd == -2)
{
long ret;
size_t nbytes;
@@ -270,9 +288,7 @@ _gcry_rndlinux_gather_random (void (*add
_gcry_post_syscall ();
}
while (ret == -1 && errno == EINTR);
- if (ret == -1 && errno == ENOSYS)
- ; /* The syscall is not supported - fallback to pulling from fd. */
- else
+ if (1)
{ /* The syscall is supported. Some sanity checks. */
if (ret == -1)
log_fatal ("unexpected error from getrandom: %s\n",
diff -up libgcrypt-1.8.5/src/g10lib.h.getrandom libgcrypt-1.8.5/src/g10lib.h
--- libgcrypt-1.8.5/src/g10lib.h.getrandom 2020-04-20 15:08:16.528538580 +0200
+++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 15:08:28.641309399 +0200
@@ -464,6 +464,6 @@ gpg_err_code_t _gcry_fips_run_selftests
void _gcry_fips_noreturn (void);
#define fips_noreturn() (_gcry_fips_noreturn ())
-
+int _gcry_in_constructor (void);
#endif /* G10LIB_H */
diff -up libgcrypt-1.8.5/src/global.c.getrandom libgcrypt-1.8.5/src/global.c
--- libgcrypt-1.8.5/src/global.c.getrandom 2020-04-20 15:06:21.891707597 +0200
+++ libgcrypt-1.8.5/src/global.c 2020-04-20 15:07:29.018437509 +0200
@@ -145,10 +145,18 @@ global_init (void)
#define FIPS_MODULE_PATH "/etc/system-fips"
#endif
+static int in_constructor = 0;
+
+int _gcry_in_constructor(void)
+{
+ return in_constructor;
+}
+
void __attribute__ ((constructor)) _gcry_global_constructor (void)
{
int rv;
+ in_constructor = 1;
rv = access (FIPS_MODULE_PATH, F_OK);
if (rv < 0 && errno != ENOENT)
rv = 0;
@@ -163,10 +171,12 @@ void __attribute__ ((constructor)) _gcry
/* force selftests */
global_init();
_gcry_fips_run_selftests (0);
- if (!fips_mode())
- _gcry_random_close_fds ();
+ _gcry_random_close_fds ();
+ _gcry_random_deinit ();
no_secure_memory = no_secmem_save;
}
+
+ in_constructor = 0;
}
/* This function is called by the macro fips_is_operational and makes

View File

@ -0,0 +1,89 @@
diff -up libgcrypt-1.8.5/src/fips.c.use-fipscheck libgcrypt-1.8.5/src/fips.c
--- libgcrypt-1.8.5/src/fips.c.use-fipscheck 2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.5/src/fips.c 2020-04-23 10:18:36.235764741 +0200
@@ -581,23 +581,50 @@ run_random_selftests (void)
return !!err;
}
+#ifdef ENABLE_HMAC_BINARY_CHECK
+static int
+get_library_path(const char *libname, const char *symbolname, char *path, size_t pathlen)
+{
+ Dl_info info;
+ void *dl, *sym;
+ int rv = -1;
+
+ dl = dlopen(libname, RTLD_LAZY);
+ if (dl == NULL) {
+ return -1;
+ }
+
+ sym = dlsym(dl, symbolname);
+
+ if (sym != NULL && dladdr(sym, &info)) {
+ strncpy(path, info.dli_fname, pathlen-1);
+ path[pathlen-1] = '\0';
+ rv = 0;
+ }
+
+ dlclose(dl);
+
+ return rv;
+}
+#endif
+
/* Run an integrity check on the binary. Returns 0 on success. */
static int
check_binary_integrity (void)
{
#ifdef ENABLE_HMAC_BINARY_CHECK
gpg_error_t err;
- Dl_info info;
+ char libpath[4096];
unsigned char digest[32];
int dlen;
char *fname = NULL;
- const char key[] = "What am I, a doctor or a moonshuttle conductor?";
-
- if (!dladdr ("gcry_check_version", &info))
+ const char key[] = "orboDeJITITejsirpADONivirpUkvarP";
+
+ if (get_library_path ("libgcrypt.so.20", "gcry_check_version", libpath, sizeof(libpath)))
err = gpg_error_from_syserror ();
else
{
- dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname,
+ dlen = _gcry_hmac256_file (digest, sizeof digest, libpath,
key, strlen (key));
if (dlen < 0)
err = gpg_error_from_syserror ();
@@ -605,7 +632,7 @@ check_binary_integrity (void)
err = gpg_error (GPG_ERR_INTERNAL);
else
{
- fname = xtrymalloc (strlen (info.dli_fname) + 1 + 5 + 1 );
+ fname = xtrymalloc (strlen (libpath) + 1 + 5 + 1 );
if (!fname)
err = gpg_error_from_syserror ();
else
@@ -614,7 +641,7 @@ check_binary_integrity (void)
char *p;
/* Prefix the basename with a dot. */
- strcpy (fname, info.dli_fname);
+ strcpy (fname, libpath);
p = strrchr (fname, '/');
if (p)
p++;
diff -up libgcrypt-1.8.5/src/Makefile.am.use-fipscheck libgcrypt-1.8.5/src/Makefile.am
--- libgcrypt-1.8.5/src/Makefile.am.use-fipscheck 2020-04-23 10:18:36.237764702 +0200
+++ libgcrypt-1.8.5/src/Makefile.am 2020-04-23 10:19:03.186247455 +0200
@@ -125,7 +125,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \
../cipher/libcipher.la \
../random/librandom.la \
../mpi/libmpi.la \
- ../compat/libcompat.la $(GPG_ERROR_LIBS)
+ ../compat/libcompat.la $(GPG_ERROR_LIBS) -ldl
dumpsexp_SOURCES = dumpsexp.c

BIN
libgcrypt-1.8.6.tar.bz2 Normal file

Binary file not shown.

View File

@ -1,14 +1,17 @@
%define gcrylibdir %{_libdir} %global gcrylibdir %{_libdir}
%global gcrysoname libgcrypt.so.20
%global hmackey orboDeJITITejsirpADONivirpUkvarP
Name: libgcrypt Name: libgcrypt
Version: 1.8.5 Version: 1.8.6
Release: 1 Release: 1
Summary: A general-purpose cryptography library Summary: A general-purpose cryptography library
License: LGPLv2+ License: LGPLv2+
URL: https://www.gnupg.org/ URL: https://www.gnupg.org/
Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.gz Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2
Source7: random.conf Source7: random.conf
Patch2: libgcrypt-1.6.2-use-fipscheck.patch Patch2: libgcrypt-1.8.5-use-fipscheck.patch
Patch5: libgcrypt-1.8.4-fips-keygen.patch Patch5: libgcrypt-1.8.4-fips-keygen.patch
Patch6: libgcrypt-1.8.4-tests-fipsmode.patch Patch6: libgcrypt-1.8.4-tests-fipsmode.patch
Patch7: libgcrypt-1.7.3-fips-cavs.patch Patch7: libgcrypt-1.7.3-fips-cavs.patch
@ -17,18 +20,19 @@ Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch
Patch14: libgcrypt-1.7.3-ecc-test-fix.patch Patch14: libgcrypt-1.7.3-ecc-test-fix.patch
Patch18: libgcrypt-1.8.3-fips-ctor.patch Patch18: libgcrypt-1.8.3-fips-ctor.patch
Patch22: libgcrypt-1.7.3-fips-reqs.patch Patch22: libgcrypt-1.7.3-fips-reqs.patch
Patch24: libgcrypt-1.8.4-getrandom.patch #Patch24: libgcrypt-1.8.5-getrandom.patch
Patch25: libgcrypt-1.8.3-cmac-selftest.patch #Patch25: libgcrypt-1.8.3-cmac-selftest.patch
Patch26: libgcrypt-1.8.3-fips-enttest.patch #Patch26: libgcrypt-1.8.3-fips-enttest.patch
Patch27: libgcrypt-1.8.3-md-fips-enforce.patch #Patch27: libgcrypt-1.8.3-md-fips-enforce.patch
Patch28: libgcrypt-1.8.5-intel-cet.patch #Patch28: libgcrypt-1.8.5-intel-cet.patch
Patch29: libgcrypt-1.8.5-build.patch #Patch29: libgcrypt-1.8.5-fips-module.patch
#Patch30: libgcrypt-1.8.5-aes-perf.patch
Patch6004: CVE-2019-12904-1.patch Patch6004: CVE-2019-12904-1.patch
Patch6005: CVE-2019-12904-2.patch Patch6005: CVE-2019-12904-2.patch
Patch6006: CVE-2019-12904-3.patch Patch6006: CVE-2019-12904-3.patch
BuildRequires: gcc fipscheck texinfo git BuildRequires: gcc texinfo git autoconf automake libtool
BuildRequires: gawk libgpg-error-devel >= 1.11 pkgconfig BuildRequires: gawk libgpg-error-devel >= 1.11 pkgconfig
%description %description
@ -50,21 +54,25 @@ applications using libgcrypt.
%autosetup -n %{name}-%{version} -p1 -S git %autosetup -n %{name}-%{version} -p1 -S git
%build %build
%configure --enable-noexecstack --enable-hmac-binary-check \ %define _lto_cflags %{nil}
autoreconf -f
%configure --disable-static --enable-noexecstack --enable-hmac-binary-check \
--enable-pubkey-ciphers='dsa elgamal rsa ecc' --disable-O-flag-munging --enable-pubkey-ciphers='dsa elgamal rsa ecc' --disable-O-flag-munging
sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool
%make_build %make_build
%check %check
fipshmac src/.libs/libgcrypt.so.?? src/hmac256 %{hmackey} src/.libs/%{gcrysoname} | cut -f1 -d ' ' >src/.libs/.%{gcrysoname}.hmac
make check make check
%define __spec_install_post \ %define __spec_install_post \
%{?__debug_package:%{__debug_install_post}} \ %{?__debug_package:%{__debug_install_post}} \
%{__arch_install_post} \ %{__arch_install_post} \
%{__os_install_post} \ %{__os_install_post} \
fipshmac $RPM_BUILD_ROOT%{gcrylibdir}/*.so.?? \ src/hmac256 %{hmackey} $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname} | cut -f1 -d ' ' >$RPM_BUILD_ROOT%{gcrylibdir}/.%{gcrysoname}.hmac \
%{nil} %{nil}
%install %install
@ -128,6 +136,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf
%{_infodir}/gcrypt.info* %{_infodir}/gcrypt.info*
%changelog %changelog
* Sun Jul 26 2020 openEuler Buildteam <buildteam@openeuler.org> - 1.8.6-1
- update to 1.8.6 from upstream
* Sat Dec 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.8.5-1 * Sat Dec 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.8.5-1
- update to 1.8.5 from upstream - update to 1.8.5 from upstream