forked from pool/libgcrypt
Pedro Monreal Gonzalez
dea0435690
- Update to 1.9.1 * *Fix exploitable bug* in hash functions introduced with 1.9.0. [bsc#1181632, CVE-2021-3345] * Return an error if a negative MPI is used with sexp scan functions. * Check for operational FIPS in the random and KDF functions. * Fix compile error on ARMv7 with NEON disabled. * Fix self-test in KDF module. * Improve assembler checks for better LTO support. * Fix 32-bit cross build on x86. * Fix non-NEON ARM assembly implementation for SHA512. * Fix build problems with the cipher_bulk_ops_t typedef. * Fix Ed25519 private key handling for preceding ZEROs. * Fix overflow in modular inverse implementation. * Fix register access for AVX/AVX2 implementations of Blake2. * Add optimized cipher and hash functions for s390x/zSeries. * Use hardware bit counting functionx when available. * Update DSA functions to match FIPS 186-3. * New self-tests for CMACs and KDFs. * Add bulk cipher functions for OFB and GCM modes. - Update libgpg-error required version - Use the suffix variable correctly in get_hmac_path() - Rebase libgcrypt-fips_selftest_trigger_file.patch - Add the global config file /etc/gcrypt/random.conf * This file can be used to globally change parameters of the random generator with the options: only-urandom and disable-jent. - Update to 1.9.0: OBS-URL: https://build.opensuse.org/request/show/868925 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libgcrypt?expand=0&rev=142
267 lines
8.5 KiB
Diff
267 lines
8.5 KiB
Diff
Index: libgcrypt-1.9.0/cipher/md.c
|
||
===================================================================
|
||
--- libgcrypt-1.9.0.orig/cipher/md.c
|
||
+++ libgcrypt-1.9.0/cipher/md.c
|
||
@@ -564,11 +564,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;
|
||
}
|
||
}
|
||
Index: libgcrypt-1.9.0/src/fips.c
|
||
===================================================================
|
||
--- libgcrypt-1.9.0.orig/src/fips.c
|
||
+++ libgcrypt-1.9.0/src/fips.c
|
||
@@ -90,7 +90,31 @@ static void fips_new_state (enum module_
|
||
#define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p))
|
||
|
||
|
||
-
|
||
+/* 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 +124,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)
|
||
@@ -190,24 +213,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");
|
||
@@ -356,16 +361,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
|
||
@@ -381,9 +390,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;
|
||
}
|
||
|
||
@@ -729,9 +740,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;
|
||
@@ -753,21 +780,12 @@ _gcry_fips_run_selftests (int extended)
|
||
if (run_pubkey_selftests (extended))
|
||
goto leave;
|
||
|
||
- if (fips_mode ())
|
||
- {
|
||
- /* 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;
|
||
}
|
||
@@ -823,6 +841,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;
|
||
@@ -837,6 +856,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;
|
||
Index: libgcrypt-1.9.0/src/global.c
|
||
===================================================================
|
||
--- libgcrypt-1.9.0.orig/src/global.c
|
||
+++ libgcrypt-1.9.0/src/global.c
|
||
@@ -141,6 +141,29 @@ global_init (void)
|
||
}
|
||
|
||
|
||
+#ifndef FIPS_MODULE_PATH
|
||
+#define FIPS_MODULE_PATH "/etc/system-fips"
|
||
+#endif
|
||
+
|
||
+void __attribute__ ((constructor)) _gcry_global_constructor (void)
|
||
+{
|
||
+ int rv;
|
||
+
|
||
+ /* We always need the FSM lock to be functional. */
|
||
+ _gcry_initialize_fsm_lock ();
|
||
+
|
||
+ rv = access (FIPS_MODULE_PATH, F_OK);
|
||
+ if (rv < 0 && errno != ENOENT)
|
||
+ rv = 0;
|
||
+
|
||
+ if (!rv)
|
||
+ {
|
||
+ /* We run the integrity check at this point. The remaining
|
||
+ selftests are run before use of the library by application. */
|
||
+ _gcry_fips_run_selftests (0);
|
||
+ }
|
||
+}
|
||
+
|
||
/* This function is called by the macro fips_is_operational and makes
|
||
sure that the minimal initialization has been done. This is far
|
||
from a perfect solution and hides problems with an improper
|
||
@@ -672,9 +695,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
|
||
|
||
case GCRYCTL_FIPS_MODE_P:
|
||
if (fips_mode ()
|
||
- && !_gcry_is_fips_mode_inactive ()
|
||
- && !no_secure_memory)
|
||
- rc = GPG_ERR_GENERAL; /* Used as TRUE value */
|
||
+ && !_gcry_is_fips_mode_inactive ())
|
||
+ rc = GPG_ERR_GENERAL; /* Used as TRUE value */
|
||
break;
|
||
|
||
case GCRYCTL_FORCE_FIPS_MODE:
|
||
@@ -750,9 +772,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
|
||
break;
|
||
|
||
case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
|
||
- if (!_gcry_global_any_init_done)
|
||
+ if (fips_mode())
|
||
{
|
||
- /* 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_enforced_fips_mode ();
|
||
}
|
||
Index: libgcrypt-1.9.0/src/g10lib.h
|
||
===================================================================
|
||
--- libgcrypt-1.9.0.orig/src/g10lib.h
|
||
+++ libgcrypt-1.9.0/src/g10lib.h
|
||
@@ -429,6 +429,8 @@ gpg_err_code_t _gcry_sexp_vextract_param
|
||
|
||
extern int _gcry_no_fips_mode_required;
|
||
|
||
+void _gcry_initialize_fsm_lock (void);
|
||
+
|
||
void _gcry_initialize_fips_mode (int force);
|
||
|
||
/* This macro returns true if fips mode is enabled. This is
|