forked from pool/libgcrypt
Accepting request 1001247 from home:pmonrealgonzalez:branches:devel:libraries:c_c++
Sync the FIPS changes to be added in SLE-15-SP4 OBS-URL: https://build.opensuse.org/request/show/1001247 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libgcrypt?expand=0&rev=156
This commit is contained in:
parent
80f9a1053d
commit
82bc8eba9a
160
libgcrypt-FIPS-SLI-pk.patch
Normal file
160
libgcrypt-FIPS-SLI-pk.patch
Normal file
@ -0,0 +1,160 @@
|
||||
Index: libgcrypt-1.9.4/src/fips.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/src/fips.c
|
||||
+++ libgcrypt-1.9.4/src/fips.c
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "cipher-proto.h"
|
||||
+#include "cipher.h"
|
||||
#include "hmac256.h"
|
||||
|
||||
|
||||
@@ -482,6 +483,78 @@ _gcry_fips_indicator_kdf (va_list arg_pt
|
||||
default:
|
||||
return GPG_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* FIPS approved curves, extracted from:
|
||||
+ * cipher/ecc-curves.c:curve_aliases[] and domain_parms[]. */
|
||||
+static const struct
|
||||
+{
|
||||
+ const char *name; /* Our name. */
|
||||
+ const char *other; /* Other name. */
|
||||
+} fips_approved_curve[] =
|
||||
+ {
|
||||
+ /* "NIST P-192" is non-approved if FIPS 140-3 */
|
||||
+ /* { "NIST P-192", "1.2.840.10045.3.1.1" }, /\* X9.62 OID *\/ */
|
||||
+ /* { "NIST P-192", "prime192v1" }, /\* X9.62 name. *\/ */
|
||||
+ /* { "NIST P-192", "secp192r1" }, /\* SECP name. *\/ */
|
||||
+ /* { "NIST P-192", "nistp192" }, /\* rfc5656. *\/ */
|
||||
+
|
||||
+ { "NIST P-224", "secp224r1" },
|
||||
+ { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */
|
||||
+ { "NIST P-224", "nistp224" }, /* rfc5656. */
|
||||
+
|
||||
+ { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */
|
||||
+ { "NIST P-256", "prime256v1" },
|
||||
+ { "NIST P-256", "secp256r1" },
|
||||
+ { "NIST P-256", "nistp256" }, /* rfc5656. */
|
||||
+
|
||||
+ { "NIST P-384", "secp384r1" },
|
||||
+ { "NIST P-384", "1.3.132.0.34" },
|
||||
+ { "NIST P-384", "nistp384" }, /* rfc5656. */
|
||||
+
|
||||
+ { "NIST P-521", "secp521r1" },
|
||||
+ { "NIST P-521", "1.3.132.0.35" },
|
||||
+ { "NIST P-521", "nistp521" }, /* rfc5656. */
|
||||
+ { NULL, NULL}
|
||||
+ };
|
||||
+
|
||||
+int
|
||||
+_gcry_fips_indicator_pk (va_list arg_ptr)
|
||||
+{
|
||||
+ enum gcry_pk_algos alg = va_arg (arg_ptr, enum gcry_pk_algos);
|
||||
+ enum pk_operation oper;
|
||||
+ const char *curve_name;
|
||||
+
|
||||
+ switch (alg)
|
||||
+ {
|
||||
+ case GCRY_PK_RSA:
|
||||
+ case GCRY_PK_RSA_E:
|
||||
+ case GCRY_PK_RSA_S:
|
||||
+ oper = va_arg (arg_ptr, enum pk_operation);
|
||||
+ switch (oper)
|
||||
+ {
|
||||
+ case PUBKEY_OP_ENCRYPT:
|
||||
+ case PUBKEY_OP_DECRYPT:
|
||||
+ return GPG_ERR_NOT_SUPPORTED;
|
||||
+ default:
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
+ }
|
||||
+ case GCRY_PK_ECC:
|
||||
+ case GCRY_PK_ECDH:
|
||||
+ case GCRY_PK_ECDSA:
|
||||
+ curve_name = va_arg (arg_ptr, const char *);
|
||||
+ for (int idx = 0; fips_approved_curve[idx].name; ++idx)
|
||||
+ {
|
||||
+ /* Check for the usual name and an alias. */
|
||||
+ if (!strcmp (curve_name, fips_approved_curve[idx].name) ||
|
||||
+ !strcmp (curve_name, fips_approved_curve[idx].other))
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
+ }
|
||||
+ return GPG_ERR_NOT_SUPPORTED;
|
||||
+ default:
|
||||
+ return GPG_ERR_NOT_SUPPORTED;
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
Index: libgcrypt-1.9.4/src/gcrypt.h.in
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/src/gcrypt.h.in
|
||||
+++ libgcrypt-1.9.4/src/gcrypt.h.in
|
||||
@@ -336,7 +336,8 @@ enum gcry_ctl_cmds
|
||||
GCRYCTL_AUTO_EXPAND_SECMEM = 78,
|
||||
GCRYCTL_SET_ALLOW_WEAK_KEY = 79,
|
||||
GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER = 81,
|
||||
- GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82
|
||||
+ GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82,
|
||||
+ GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 83
|
||||
};
|
||||
|
||||
/* Perform various operations defined by CMD. */
|
||||
Index: libgcrypt-1.9.4/doc/gcrypt.texi
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/doc/gcrypt.texi
|
||||
+++ libgcrypt-1.9.4/doc/gcrypt.texi
|
||||
@@ -975,6 +975,18 @@ certification. If the KDF is approved, t
|
||||
@code{GPG_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED}
|
||||
is returned.
|
||||
|
||||
+@item GCRYCTL_FIPS_SERVICE_INDICATOR_PK; Arguments: enum gcry_pk_algos
|
||||
+[, enum pk_operation (only for GCRY_PK_RSA)] [, const char * (only for
|
||||
+GCRY_PK_ECC, GCRY_PK_ECDH or GCRY_PK_ECDSA)]
|
||||
+
|
||||
+Check if the given asymmetric cipher is approved under the current FIPS
|
||||
+140-3 certification. For GCRY_PK_RSA, an additional parameter for the
|
||||
+operation mode @code{enum pk_operation} is required. For GCRY_PK_ECC,
|
||||
+GCRY_PK_ECDH and GCRY_PK_ECDSA, the additional parameter is the curve
|
||||
+name or its alias as @code{const char *}. If the combination is
|
||||
+approved, this function returns @code{GPG_ERR_NO_ERROR}. Otherwise
|
||||
+@code{GPG_ERR_NOT_SUPPORTED} is returned.
|
||||
+
|
||||
@end table
|
||||
|
||||
@end deftypefun
|
||||
Index: libgcrypt-1.9.4/src/g10lib.h
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/src/g10lib.h
|
||||
+++ libgcrypt-1.9.4/src/g10lib.h
|
||||
@@ -489,6 +489,7 @@ void _gcry_fips_signal_error (const char
|
||||
|
||||
int _gcry_fips_indicator_cipher (va_list arg_ptr);
|
||||
int _gcry_fips_indicator_kdf (va_list arg_ptr);
|
||||
+int _gcry_fips_indicator_pk (va_list arg_ptr);
|
||||
|
||||
int _gcry_fips_is_operational (void);
|
||||
|
||||
Index: libgcrypt-1.9.4/src/global.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/src/global.c
|
||||
+++ libgcrypt-1.9.4/src/global.c
|
||||
@@ -768,6 +768,15 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
|
||||
rc = _gcry_fips_indicator_kdf (arg_ptr);
|
||||
break;
|
||||
|
||||
+ case GCRYCTL_FIPS_SERVICE_INDICATOR_PK:
|
||||
+ /* Get FIPS Service Indicator for a given asymmetric algorithm. For
|
||||
+ * GCRY_PK_RSA, an additional parameter for the operation mode is
|
||||
+ * required. For ECC, ECDH and ECDSA, the additional parameter is the
|
||||
+ * curve name or its alias. Returns GPG_ERR_NO_ERROR if the
|
||||
+ * algorithm is allowed or GPG_ERR_NOT_SUPPORTED otherwise. */
|
||||
+ rc = _gcry_fips_indicator_pk (arg_ptr);
|
||||
+ break;
|
||||
+
|
||||
case PRIV_CTL_INIT_EXTRNG_TEST: /* Init external random test. */
|
||||
rc = GPG_ERR_NOT_SUPPORTED;
|
||||
break;
|
@ -2,7 +2,7 @@ Index: libgcrypt-1.9.4/src/fips.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/src/fips.c
|
||||
+++ libgcrypt-1.9.4/src/fips.c
|
||||
@@ -437,6 +437,59 @@ _gcry_fips_test_operational (void)
|
||||
@@ -437,6 +437,54 @@ _gcry_fips_test_operational (void)
|
||||
}
|
||||
|
||||
|
||||
@ -14,11 +14,6 @@ Index: libgcrypt-1.9.4/src/fips.c
|
||||
+
|
||||
+ switch (alg)
|
||||
+ {
|
||||
+ case GCRY_CIPHER_AES:
|
||||
+ case GCRY_CIPHER_AES192:
|
||||
+ case GCRY_CIPHER_AES256:
|
||||
+ mode = va_arg (arg_ptr, enum gcry_cipher_modes);
|
||||
+ switch (mode)
|
||||
+ case GCRY_CIPHER_AES:
|
||||
+ case GCRY_CIPHER_AES192:
|
||||
+ case GCRY_CIPHER_AES256:
|
||||
|
@ -12,10 +12,46 @@ Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
tests/t-kdf.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/tests/t-kdf.c b/tests/t-kdf.c
|
||||
index 7a48e98a..48309b9a 100644
|
||||
--- a/tests/t-kdf.c
|
||||
+++ b/tests/t-kdf.c
|
||||
Index: libgcrypt-1.9.4/tests/t-kdf.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/tests/t-kdf.c
|
||||
+++ libgcrypt-1.9.4/tests/t-kdf.c
|
||||
@@ -998,7 +998,7 @@ check_pbkdf2 (void)
|
||||
"\xa5\x7a\xe5\xa6\x08\x83\x96\xd1\x20\x85\x0c\x5c\x09\xde\x0a\x52"
|
||||
"\x51\x00\x93\x8a\x59\xb1\xb5\xc3\xf7\x81\x09\x10\xd0\x5f\xcd\x97"
|
||||
}, */
|
||||
- {
|
||||
+ /* { -- not FIPS approved
|
||||
"passwordPASSWORDpassword", 24,
|
||||
"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
|
||||
GCRY_MD_GOSTR3411_CP,
|
||||
@@ -1007,7 +1007,7 @@ check_pbkdf2 (void)
|
||||
"\x78\x83\x58\xc6\x9c\xb2\xdb\xe2\x51\xa7\xbb\x17\xd5\xf4\x24\x1f"
|
||||
"\x26\x5a\x79\x2a\x35\xbe\xcd\xe8\xd5\x6f\x32\x6b\x49\xc8\x50\x47"
|
||||
"\xb7\x63\x8a\xcb\x47\x64\xb1\xfd"
|
||||
- },
|
||||
+ }, */
|
||||
{
|
||||
"pass\0word", 9,
|
||||
"sa\0lt", 5,
|
||||
@@ -1061,7 +1061,7 @@ check_pbkdf2 (void)
|
||||
"\x1a\xdb\x60\x1c\x7e\x2a\x31\x4e\x8c\xb7\xb1\xe9\xdf\x84\x0e\x36"
|
||||
"\xab\x56\x15\xbe\x5d\x74\x2b\x6c\xf2\x03\xfb\x55\xfd\xc4\x80\x71"
|
||||
}, */
|
||||
- {
|
||||
+ /* { -- not FIPS approved
|
||||
"passwordPASSWORDpassword", 24,
|
||||
"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
|
||||
GCRY_MD_STRIBOG512,
|
||||
@@ -1074,7 +1074,7 @@ check_pbkdf2 (void)
|
||||
"\xbd\x24\x21\xee\x9b\xb7\x11\x83\xba\x88\x2c\xee\xbf\xef\x25\x9f"
|
||||
"\x33\xf9\xe2\x7d\xc6\x17\x8c\xb8\x9d\xc3\x74\x28\xcf\x9c\xc5\x2a"
|
||||
"\x2b\xaa\x2d\x3a"
|
||||
- },
|
||||
+ }, */
|
||||
{
|
||||
"pass\0word", 9,
|
||||
"sa\0lt", 5,
|
||||
@@ -1104,6 +1104,13 @@ check_pbkdf2 (void)
|
||||
GCRY_KDF_PBKDF2, tv[tvidx].hashalgo,
|
||||
tv[tvidx].salt, tv[tvidx].saltlen,
|
||||
@ -30,6 +66,3 @@ index 7a48e98a..48309b9a 100644
|
||||
if (err)
|
||||
fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err));
|
||||
else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
|
||||
--
|
||||
2.34.1
|
||||
|
||||
|
13
libgcrypt-indicate-shake.patch
Normal file
13
libgcrypt-indicate-shake.patch
Normal file
@ -0,0 +1,13 @@
|
||||
Index: libgcrypt-1.9.4/src/fips.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/src/fips.c
|
||||
+++ libgcrypt-1.9.4/src/fips.c
|
||||
@@ -593,6 +593,8 @@ _gcry_fips_indicator_hash (va_list arg_p
|
||||
case GCRY_MD_SHA3_256:
|
||||
case GCRY_MD_SHA3_384:
|
||||
case GCRY_MD_SHA3_512:
|
||||
+ case GCRY_MD_SHAKE128:
|
||||
+ case GCRY_MD_SHAKE256:
|
||||
return GPG_ERR_NO_ERROR;
|
||||
default:
|
||||
return GPG_ERR_NOT_SUPPORTED;
|
4168
libgcrypt-jitterentropy-3.3.0.patch
Normal file
4168
libgcrypt-jitterentropy-3.3.0.patch
Normal file
File diff suppressed because it is too large
Load Diff
661
libgcrypt-jitterentropy-3.4.0.patch
Normal file
661
libgcrypt-jitterentropy-3.4.0.patch
Normal file
@ -0,0 +1,661 @@
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-base.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-base.c
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-base.c
|
||||
@@ -42,7 +42,7 @@
|
||||
* require consumer to be updated (as long as this number
|
||||
* is zero, the API is not considered stable and can
|
||||
* change without a bump of the major version) */
|
||||
-#define MINVERSION 3 /* API compatible, ABI may change, functional
|
||||
+#define MINVERSION 4 /* API compatible, ABI may change, functional
|
||||
* enhancements only, consumer can be left unchanged if
|
||||
* enhancements are not considered */
|
||||
#define PATCHLEVEL 0 /* API / ABI compatible, no functional changes, no
|
||||
@@ -200,29 +200,38 @@ ssize_t jent_read_entropy(struct rand_da
|
||||
tocopy = (DATA_SIZE_BITS / 8);
|
||||
else
|
||||
tocopy = len;
|
||||
- memcpy(p, &ec->data, tocopy);
|
||||
+
|
||||
+ jent_read_random_block(ec, p, tocopy);
|
||||
|
||||
len -= tocopy;
|
||||
p += tocopy;
|
||||
}
|
||||
|
||||
/*
|
||||
- * To be on the safe side, we generate one more round of entropy
|
||||
- * which we do not give out to the caller. That round shall ensure
|
||||
- * that in case the calling application crashes, memory dumps, pages
|
||||
- * out, or due to the CPU Jitter RNG lingering in memory for long
|
||||
- * time without being moved and an attacker cracks the application,
|
||||
- * all he reads in the entropy pool is a value that is NEVER EVER
|
||||
- * being used for anything. Thus, he does NOT see the previous value
|
||||
- * that was returned to the caller for cryptographic purposes.
|
||||
+ * Enhanced backtracking support: At this point, the hash state
|
||||
+ * contains the digest of the previous Jitter RNG collection round
|
||||
+ * which is inserted there by jent_read_random_block with the SHA
|
||||
+ * update operation. At the current code location we completed
|
||||
+ * one request for a caller and we do not know how long it will
|
||||
+ * take until a new request is sent to us. To guarantee enhanced
|
||||
+ * backtracking resistance at this point (i.e. ensure that an attacker
|
||||
+ * cannot obtain information about prior random numbers we generated),
|
||||
+ * but still stirring the hash state with old data the Jitter RNG
|
||||
+ * obtains a new message digest from its state and re-inserts it.
|
||||
+ * After this operation, the Jitter RNG state is still stirred with
|
||||
+ * the old data, but an attacker who gets access to the memory after
|
||||
+ * this point cannot deduce the random numbers produced by the
|
||||
+ * Jitter RNG prior to this point.
|
||||
*/
|
||||
/*
|
||||
- * If we use secured memory, do not use that precaution as the secure
|
||||
- * memory protects the entropy pool. Moreover, note that using this
|
||||
- * call reduces the speed of the RNG by up to half
|
||||
+ * If we use secured memory, where backtracking support may not be
|
||||
+ * needed because the state is protected in a different method,
|
||||
+ * it is permissible to drop this support. But strongly weigh the
|
||||
+ * pros and cons considering that the SHA3 operation is not that
|
||||
+ * expensive.
|
||||
*/
|
||||
-#ifndef JENT_CPU_JITTERENTROPY_SECURE_MEMORY
|
||||
- jent_random_data(ec);
|
||||
+#ifndef CONFIG_CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY
|
||||
+ jent_read_random_block(ec, NULL, 0);
|
||||
#endif
|
||||
|
||||
err:
|
||||
@@ -379,6 +388,7 @@ static struct rand_data
|
||||
*jent_entropy_collector_alloc_internal(unsigned int osr, unsigned int flags)
|
||||
{
|
||||
struct rand_data *entropy_collector;
|
||||
+ uint32_t memsize = 0;
|
||||
|
||||
/*
|
||||
* Requesting disabling and forcing of internal timer
|
||||
@@ -405,9 +415,8 @@ static struct rand_data
|
||||
return NULL;
|
||||
|
||||
if (!(flags & JENT_DISABLE_MEMORY_ACCESS)) {
|
||||
- uint32_t memsize = jent_memsize(flags);
|
||||
-
|
||||
- entropy_collector->mem = _gcry_calloc (1, memsize);
|
||||
+ memsize = jent_memsize(flags);
|
||||
+ entropy_collector->mem = (unsigned char *)jent_zalloc(memsize);
|
||||
|
||||
#ifdef JENT_RANDOM_MEMACCESS
|
||||
/*
|
||||
@@ -431,13 +440,19 @@ static struct rand_data
|
||||
entropy_collector->memaccessloops = JENT_MEMORY_ACCESSLOOPS;
|
||||
}
|
||||
|
||||
+ if (sha3_alloc(&entropy_collector->hash_state))
|
||||
+ goto err;
|
||||
+
|
||||
+ /* Initialize the hash state */
|
||||
+ sha3_256_init(entropy_collector->hash_state);
|
||||
+
|
||||
/* verify and set the oversampling rate */
|
||||
if (osr < JENT_MIN_OSR)
|
||||
osr = JENT_MIN_OSR;
|
||||
entropy_collector->osr = osr;
|
||||
entropy_collector->flags = flags;
|
||||
|
||||
- if (jent_fips_enabled() || (flags & JENT_FORCE_FIPS))
|
||||
+ if ((flags & JENT_FORCE_FIPS) || jent_fips_enabled())
|
||||
entropy_collector->fips_enabled = 1;
|
||||
|
||||
/* Initialize the APT */
|
||||
@@ -469,7 +484,7 @@ static struct rand_data
|
||||
|
||||
err:
|
||||
if (entropy_collector->mem != NULL)
|
||||
- jent_zfree(entropy_collector->mem, JENT_MEMORY_SIZE);
|
||||
+ jent_zfree(entropy_collector->mem, memsize);
|
||||
jent_zfree(entropy_collector, sizeof(struct rand_data));
|
||||
return NULL;
|
||||
}
|
||||
@@ -511,6 +526,7 @@ JENT_PRIVATE_STATIC
|
||||
void jent_entropy_collector_free(struct rand_data *entropy_collector)
|
||||
{
|
||||
if (entropy_collector != NULL) {
|
||||
+ sha3_dealloc(entropy_collector->hash_state);
|
||||
jent_notime_disable(entropy_collector);
|
||||
if (entropy_collector->mem != NULL) {
|
||||
jent_zfree(entropy_collector->mem,
|
||||
@@ -664,6 +680,7 @@ static inline int jent_entropy_init_comm
|
||||
int ret;
|
||||
|
||||
jent_notime_block_switch();
|
||||
+ jent_health_cb_block_switch();
|
||||
|
||||
if (sha3_tester())
|
||||
return EHASH;
|
||||
@@ -710,6 +727,8 @@ int jent_entropy_init_ex(unsigned int os
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ret = ENOTIME;
|
||||
+
|
||||
/* Test without internal timer unless caller does not want it */
|
||||
if (!(flags & JENT_FORCE_INTERNAL_TIMER))
|
||||
ret = jent_time_entropy_init(osr,
|
||||
@@ -725,10 +744,14 @@ int jent_entropy_init_ex(unsigned int os
|
||||
return jent_entropy_init_common_post(ret);
|
||||
}
|
||||
|
||||
-#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER
|
||||
JENT_PRIVATE_STATIC
|
||||
int jent_entropy_switch_notime_impl(struct jent_notime_thread *new_thread)
|
||||
{
|
||||
return jent_notime_switch(new_thread);
|
||||
}
|
||||
-#endif
|
||||
+
|
||||
+JENT_PRIVATE_STATIC
|
||||
+int jent_set_fips_failure_callback(jent_fips_failure_cb cb)
|
||||
+{
|
||||
+ return jent_set_fips_failure_callback_internal(cb);
|
||||
+}
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-gcd.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-gcd.c
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-gcd.c
|
||||
@@ -113,12 +113,8 @@ int jent_gcd_analyze(uint64_t *delta_his
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Ensure that we have variations in the time stamp below 100 for at
|
||||
- * least 10% of all checks -- on some platforms, the counter increments
|
||||
- * in multiples of 100, but not always
|
||||
- */
|
||||
- if (running_gcd >= 100) {
|
||||
+ /* Set a sensible maximum value. */
|
||||
+ if (running_gcd >= UINT32_MAX / 2) {
|
||||
ret = ECOARSETIME;
|
||||
goto out;
|
||||
}
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-health.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-health.c
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-health.c
|
||||
@@ -19,9 +19,24 @@
|
||||
* DAMAGE.
|
||||
*/
|
||||
|
||||
-#include "jitterentropy.h"
|
||||
#include "jitterentropy-health.h"
|
||||
|
||||
+static jent_fips_failure_cb fips_cb = NULL;
|
||||
+static int jent_health_cb_switch_blocked = 0;
|
||||
+
|
||||
+void jent_health_cb_block_switch(void)
|
||||
+{
|
||||
+ jent_health_cb_switch_blocked = 1;
|
||||
+}
|
||||
+
|
||||
+int jent_set_fips_failure_callback_internal(jent_fips_failure_cb cb)
|
||||
+{
|
||||
+ if (jent_health_cb_switch_blocked)
|
||||
+ return -EAGAIN;
|
||||
+ fips_cb = cb;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/***************************************************************************
|
||||
* Lag Predictor Test
|
||||
*
|
||||
@@ -434,5 +449,9 @@ unsigned int jent_health_failure(struct
|
||||
if (!ec->fips_enabled)
|
||||
return 0;
|
||||
|
||||
+ if (fips_cb && ec->health_failure) {
|
||||
+ fips_cb(ec, ec->health_failure);
|
||||
+ }
|
||||
+
|
||||
return ec->health_failure;
|
||||
}
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-health.h
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-health.h
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-health.h
|
||||
@@ -20,11 +20,16 @@
|
||||
#ifndef JITTERENTROPY_HEALTH_H
|
||||
#define JITTERENTROPY_HEALTH_H
|
||||
|
||||
+#include "jitterentropy.h"
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
+void jent_health_cb_block_switch(void);
|
||||
+int jent_set_fips_failure_callback_internal(jent_fips_failure_cb cb);
|
||||
+
|
||||
static inline uint64_t jent_delta(uint64_t prev, uint64_t next)
|
||||
{
|
||||
return (next - prev);
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-noise.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-noise.c
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-noise.c
|
||||
@@ -33,7 +33,7 @@
|
||||
* Update of the loop count used for the next round of
|
||||
* an entropy collection.
|
||||
*
|
||||
- * @ec [in] entropy collector struct -- may be NULL
|
||||
+ * @ec [in] entropy collector struct
|
||||
* @bits [in] is the number of low bits of the timer to consider
|
||||
* @min [in] is the number of bits we shift the timer value to the right at
|
||||
* the end to make sure we have a guaranteed minimum value
|
||||
@@ -61,16 +61,13 @@ static uint64_t jent_loop_shuffle(struct
|
||||
* Mix the current state of the random number into the shuffle
|
||||
* calculation to balance that shuffle a bit more.
|
||||
*/
|
||||
- if (ec) {
|
||||
- jent_get_nstime_internal(ec, &time);
|
||||
- time ^= ec->data[0];
|
||||
- }
|
||||
+ jent_get_nstime_internal(ec, &time);
|
||||
|
||||
/*
|
||||
* We fold the time value as much as possible to ensure that as many
|
||||
* bits of the time stamp are included as possible.
|
||||
*/
|
||||
- for (i = 0; ((DATA_SIZE_BITS + bits - 1) / bits) > i; i++) {
|
||||
+ for (i = 0; (((sizeof(time) << 3) + bits - 1) / bits) > i; i++) {
|
||||
shuffle ^= time & mask;
|
||||
time = time >> bits;
|
||||
}
|
||||
@@ -91,11 +88,11 @@ static uint64_t jent_loop_shuffle(struct
|
||||
* This function injects the individual bits of the time value into the
|
||||
* entropy pool using a hash.
|
||||
*
|
||||
- * @ec [in] entropy collector struct -- may be NULL
|
||||
- * @time [in] time stamp to be injected
|
||||
+ * @ec [in] entropy collector struct
|
||||
+ * @time [in] time delta to be injected
|
||||
* @loop_cnt [in] if a value not equal to 0 is set, use the given value as
|
||||
* number of loops to perform the hash operation
|
||||
- * @stuck [in] Is the time stamp identified as stuck?
|
||||
+ * @stuck [in] Is the time delta identified as stuck?
|
||||
*
|
||||
* Output:
|
||||
* updated hash context
|
||||
@@ -104,17 +101,19 @@ static void jent_hash_time(struct rand_d
|
||||
uint64_t loop_cnt, unsigned int stuck)
|
||||
{
|
||||
HASH_CTX_ON_STACK(ctx);
|
||||
- uint8_t itermediary[SHA3_256_SIZE_DIGEST];
|
||||
+ uint8_t intermediary[SHA3_256_SIZE_DIGEST];
|
||||
uint64_t j = 0;
|
||||
- uint64_t hash_loop_cnt;
|
||||
#define MAX_HASH_LOOP 3
|
||||
#define MIN_HASH_LOOP 0
|
||||
|
||||
/* Ensure that macros cannot overflow jent_loop_shuffle() */
|
||||
BUILD_BUG_ON((MAX_HASH_LOOP + MIN_HASH_LOOP) > 63);
|
||||
- hash_loop_cnt =
|
||||
+ uint64_t hash_loop_cnt =
|
||||
jent_loop_shuffle(ec, MAX_HASH_LOOP, MIN_HASH_LOOP);
|
||||
|
||||
+ /* Use the memset to shut up valgrind */
|
||||
+ memset(intermediary, 0, sizeof(intermediary));
|
||||
+
|
||||
sha3_256_init(&ctx);
|
||||
|
||||
/*
|
||||
@@ -125,35 +124,54 @@ static void jent_hash_time(struct rand_d
|
||||
hash_loop_cnt = loop_cnt;
|
||||
|
||||
/*
|
||||
- * This loop basically slows down the SHA-3 operation depending
|
||||
- * on the hash_loop_cnt. Each iteration of the loop generates the
|
||||
- * same result.
|
||||
+ * This loop fills a buffer which is injected into the entropy pool.
|
||||
+ * The main reason for this loop is to execute something over which we
|
||||
+ * can perform a timing measurement. The injection of the resulting
|
||||
+ * data into the pool is performed to ensure the result is used and
|
||||
+ * the compiler cannot optimize the loop away in case the result is not
|
||||
+ * used at all. Yet that data is considered "additional information"
|
||||
+ * considering the terminology from SP800-90A without any entropy.
|
||||
+ *
|
||||
+ * Note, it does not matter which or how much data you inject, we are
|
||||
+ * interested in one Keccack1600 compression operation performed with
|
||||
+ * the sha3_final.
|
||||
*/
|
||||
for (j = 0; j < hash_loop_cnt; j++) {
|
||||
- sha3_update(&ctx, ec->data, SHA3_256_SIZE_DIGEST);
|
||||
- sha3_update(&ctx, (uint8_t *)&time, sizeof(uint64_t));
|
||||
+ sha3_update(&ctx, intermediary, sizeof(intermediary));
|
||||
+ sha3_update(&ctx, (uint8_t *)&ec->rct_count,
|
||||
+ sizeof(ec->rct_count));
|
||||
+ sha3_update(&ctx, (uint8_t *)&ec->apt_cutoff,
|
||||
+ sizeof(ec->apt_cutoff));
|
||||
+ sha3_update(&ctx, (uint8_t *)&ec->apt_observations,
|
||||
+ sizeof(ec->apt_observations));
|
||||
+ sha3_update(&ctx, (uint8_t *)&ec->apt_count,
|
||||
+ sizeof(ec->apt_count));
|
||||
+ sha3_update(&ctx,(uint8_t *) &ec->apt_base,
|
||||
+ sizeof(ec->apt_base));
|
||||
sha3_update(&ctx, (uint8_t *)&j, sizeof(uint64_t));
|
||||
+ sha3_final(&ctx, intermediary);
|
||||
+ }
|
||||
|
||||
- /*
|
||||
- * If the time stamp is stuck, do not finally insert the value
|
||||
- * into the entropy pool. Although this operation should not do
|
||||
- * any harm even when the time stamp has no entropy, SP800-90B
|
||||
- * requires that any conditioning operation to have an identical
|
||||
- * amount of input data according to section 3.1.5.
|
||||
- */
|
||||
+ /*
|
||||
+ * Inject the data from the previous loop into the pool. This data is
|
||||
+ * not considered to contain any entropy, but it stirs the pool a bit.
|
||||
+ */
|
||||
+ sha3_update(ec->hash_state, intermediary, sizeof(intermediary));
|
||||
|
||||
- /*
|
||||
- * The sha3_final operations re-initialize the context for the
|
||||
- * next loop iteration.
|
||||
- */
|
||||
- if (stuck || (j < hash_loop_cnt - 1))
|
||||
- sha3_final(&ctx, itermediary);
|
||||
- else
|
||||
- sha3_final(&ctx, ec->data);
|
||||
- }
|
||||
+ /*
|
||||
+ * Insert the time stamp into the hash context representing the pool.
|
||||
+ *
|
||||
+ * If the time stamp is stuck, do not finally insert the value into the
|
||||
+ * entropy pool. Although this operation should not do any harm even
|
||||
+ * when the time stamp has no entropy, SP800-90B requires that any
|
||||
+ * conditioning operation to have an identical amount of input data
|
||||
+ * according to section 3.1.5.
|
||||
+ */
|
||||
+ if (!stuck)
|
||||
+ sha3_update(ec->hash_state, (uint8_t *)&time, sizeof(uint64_t));
|
||||
|
||||
jent_memset_secure(&ctx, SHA_MAX_CTX_SIZE);
|
||||
- jent_memset_secure(itermediary, sizeof(itermediary));
|
||||
+ jent_memset_secure(intermediary, sizeof(intermediary));
|
||||
}
|
||||
|
||||
#define MAX_ACC_LOOP_BIT 7
|
||||
@@ -184,37 +202,37 @@ static inline uint32_t xoshiro128starsta
|
||||
|
||||
static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt)
|
||||
{
|
||||
- uint64_t i = 0;
|
||||
+ uint64_t i = 0, time = 0;
|
||||
union {
|
||||
uint32_t u[4];
|
||||
uint8_t b[sizeof(uint32_t) * 4];
|
||||
} prngState = { .u = {0x8e93eec0, 0xce65608a, 0xa8d46b46, 0xe83cef69} };
|
||||
uint32_t addressMask;
|
||||
- uint64_t acc_loop_cnt;
|
||||
-
|
||||
- if (NULL == ec || NULL == ec->mem)
|
||||
- return;
|
||||
-
|
||||
- addressMask = ec->memmask;
|
||||
|
||||
/* Ensure that macros cannot overflow jent_loop_shuffle() */
|
||||
BUILD_BUG_ON((MAX_ACC_LOOP_BIT + MIN_ACC_LOOP_BIT) > 63);
|
||||
- acc_loop_cnt =
|
||||
+ uint64_t acc_loop_cnt =
|
||||
jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT);
|
||||
|
||||
+ if (NULL == ec || NULL == ec->mem)
|
||||
+ return;
|
||||
+ addressMask = ec->memmask;
|
||||
+
|
||||
/*
|
||||
* Mix the current data into prngState
|
||||
*
|
||||
* Any time you see a PRNG in a noise source, you should be concerned.
|
||||
*
|
||||
* The PRNG doesn't directly produce the raw noise, it just adjusts the
|
||||
* location being updated. The timing of the update is part of the raw
|
||||
* sample. The main thing this process gets you isn't better
|
||||
* "per-update: timing, it gets you mostly independent "per-update"
|
||||
* timing, so we can now benefit from the Central Limit Theorem!
|
||||
*/
|
||||
- for (i = 0; i < sizeof(prngState); i++)
|
||||
- prngState.b[i] ^= ec->data[i];
|
||||
+ for (i = 0; i < sizeof(prngState); i++) {
|
||||
+ jent_get_nstime_internal(ec, &time);
|
||||
+ prngState.b[i] ^= (uint8_t)(time & 0xff);
|
||||
+ }
|
||||
|
||||
/*
|
||||
* testing purposes -- allow test app to set the counter, not
|
||||
@@ -358,21 +376,21 @@ unsigned int jent_measure_jitter(struct
|
||||
|
||||
/**
|
||||
* Generator of one 256 bit random number
|
||||
- * Function fills rand_data->data
|
||||
+ * Function fills rand_data->hash_state
|
||||
*
|
||||
* @ec [in] Reference to entropy collector
|
||||
*/
|
||||
void jent_random_data(struct rand_data *ec)
|
||||
{
|
||||
- unsigned int k = 0, safety_factor = ENTROPY_SAFETY_FACTOR;
|
||||
+ unsigned int k = 0, safety_factor = 0;
|
||||
|
||||
- if (!ec->fips_enabled)
|
||||
- safety_factor = 0;
|
||||
+ if (ec->fips_enabled)
|
||||
+ safety_factor = ENTROPY_SAFETY_FACTOR;
|
||||
|
||||
/* priming of the ->prev_time value */
|
||||
jent_measure_jitter(ec, 0, NULL);
|
||||
|
||||
- while (1) {
|
||||
+ while (!jent_health_failure(ec)) {
|
||||
/* If a stuck measurement is received, repeat measurement */
|
||||
if (jent_measure_jitter(ec, 0, NULL))
|
||||
continue;
|
||||
@@ -385,3 +403,22 @@ void jent_random_data(struct rand_data *
|
||||
break;
|
||||
}
|
||||
}
|
||||
+
|
||||
+void jent_read_random_block(struct rand_data *ec, char *dst, size_t dst_len)
|
||||
+{
|
||||
+ uint8_t jent_block[SHA3_256_SIZE_DIGEST];
|
||||
+
|
||||
+ BUILD_BUG_ON(SHA3_256_SIZE_DIGEST != (DATA_SIZE_BITS / 8));
|
||||
+
|
||||
+ /* The final operation automatically re-initializes the ->hash_state */
|
||||
+ sha3_final(ec->hash_state, jent_block);
|
||||
+ if (dst_len)
|
||||
+ memcpy(dst, jent_block, dst_len);
|
||||
+
|
||||
+ /*
|
||||
+ * Stir the new state with the data from the old state - the digest
|
||||
+ * of the old data is not considered to have entropy.
|
||||
+ */
|
||||
+ sha3_update(ec->hash_state, jent_block, sizeof(jent_block));
|
||||
+ jent_memset_secure(jent_block, sizeof(jent_block));
|
||||
+}
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-noise.h
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-noise.h
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-noise.h
|
||||
@@ -31,6 +31,7 @@ unsigned int jent_measure_jitter(struct
|
||||
uint64_t loop_cnt,
|
||||
uint64_t *ret_current_delta);
|
||||
void jent_random_data(struct rand_data *ec);
|
||||
+void jent_read_random_block(struct rand_data *ec, char *dst, size_t dst_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-sha3.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-sha3.c
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-sha3.c
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "jitterentropy-sha3.h"
|
||||
+#include "jitterentropy.h"
|
||||
|
||||
/***************************************************************************
|
||||
* Message Digest Implementation
|
||||
@@ -380,3 +381,23 @@ int sha3_tester(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+int sha3_alloc(void **hash_state)
|
||||
+{
|
||||
+ struct sha_ctx *tmp;
|
||||
+
|
||||
+ tmp = jent_zalloc(SHA_MAX_CTX_SIZE);
|
||||
+ if (!tmp)
|
||||
+ return 1;
|
||||
+
|
||||
+ *hash_state = tmp;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void sha3_dealloc(void *hash_state)
|
||||
+{
|
||||
+ struct sha_ctx *ctx = (struct sha_ctx *)hash_state;
|
||||
+
|
||||
+ jent_zfree(ctx, SHA_MAX_CTX_SIZE);
|
||||
+}
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-sha3.h
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-sha3.h
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-sha3.h
|
||||
@@ -47,6 +47,8 @@ struct sha_ctx {
|
||||
void sha3_256_init(struct sha_ctx *ctx);
|
||||
void sha3_update(struct sha_ctx *ctx, const uint8_t *in, size_t inlen);
|
||||
void sha3_final(struct sha_ctx *ctx, uint8_t *digest);
|
||||
+int sha3_alloc(void **hash_state);
|
||||
+void sha3_dealloc(void *hash_state);
|
||||
int sha3_tester(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-timer.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-timer.c
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-timer.c
|
||||
@@ -202,8 +202,8 @@ int jent_notime_enable(struct rand_data
|
||||
if (jent_force_internal_timer || (flags & JENT_FORCE_INTERNAL_TIMER)) {
|
||||
/* Self test not run yet */
|
||||
if (!jent_force_internal_timer &&
|
||||
- jent_time_entropy_init(flags | JENT_FORCE_INTERNAL_TIMER,
|
||||
- ec->osr))
|
||||
+ jent_time_entropy_init(ec->osr,
|
||||
+ flags | JENT_FORCE_INTERNAL_TIMER))
|
||||
return EHEALTH;
|
||||
|
||||
ec->enable_notime = 1;
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy.h
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy.h
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy.h
|
||||
@@ -42,6 +42,10 @@
|
||||
#ifndef _JITTERENTROPY_H
|
||||
#define _JITTERENTROPY_H
|
||||
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
/***************************************************************************
|
||||
* Jitter RNG Configuration Section
|
||||
*
|
||||
@@ -49,7 +53,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
- * Enable timer-less timer support
|
||||
+ * Enable timer-less timer support with JENT_CONF_ENABLE_INTERNAL_TIMER
|
||||
*
|
||||
* In case the hardware is identified to not provide a high-resolution time
|
||||
* stamp, this option enables a built-in high-resolution time stamp mechanism.
|
||||
@@ -166,7 +173,7 @@ struct rand_data
|
||||
* of the RNG are marked as SENSITIVE. A user must not
|
||||
* access that information while the RNG executes its loops to
|
||||
* calculate the next random value. */
|
||||
- uint8_t data[SHA3_256_SIZE_DIGEST]; /* SENSITIVE Actual random number */
|
||||
+ void *hash_state; /* SENSITIVE hash state entropy pool */
|
||||
uint64_t prev_time; /* SENSITIVE Previous time stamp */
|
||||
#define DATA_SIZE_BITS (SHA3_256_SIZE_DIGEST_BITS)
|
||||
|
||||
@@ -378,29 +389,34 @@ int jent_entropy_init(void);
|
||||
JENT_PRIVATE_STATIC
|
||||
int jent_entropy_init_ex(unsigned int osr, unsigned int flags);
|
||||
|
||||
+/*
|
||||
+ * Set a callback to run on health failure in FIPS mode.
|
||||
+ * This function will take an action determined by the caller.
|
||||
+ */
|
||||
+typedef void (*jent_fips_failure_cb)(struct rand_data *ec,
|
||||
+ unsigned int health_failure);
|
||||
+JENT_PRIVATE_STATIC
|
||||
+int jent_set_fips_failure_callback(jent_fips_failure_cb cb);
|
||||
+
|
||||
/* return version number of core library */
|
||||
JENT_PRIVATE_STATIC
|
||||
unsigned int jent_version(void);
|
||||
|
||||
-#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER
|
||||
/* Set a different thread handling logic for the notimer support */
|
||||
JENT_PRIVATE_STATIC
|
||||
int jent_entropy_switch_notime_impl(struct jent_notime_thread *new_thread);
|
||||
-#endif
|
||||
|
||||
/* -- END of Main interface functions -- */
|
||||
|
||||
/* -- BEGIN timer-less threading support functions to prevent code dupes -- */
|
||||
|
||||
-struct jent_notime_ctx {
|
||||
#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER
|
||||
+
|
||||
+struct jent_notime_ctx {
|
||||
pthread_attr_t notime_pthread_attr; /* pthreads library */
|
||||
pthread_t notime_thread_id; /* pthreads thread ID */
|
||||
-#endif
|
||||
};
|
||||
|
||||
-#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER
|
||||
-
|
||||
JENT_PRIVATE_STATIC
|
||||
int jent_notime_init(void **ctx);
|
||||
|
||||
@@ -448,4 +464,8 @@ uint64_t jent_lfsr_var_stat(struct rand_
|
||||
|
||||
/* -- END of statistical test function -- */
|
||||
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#endif /* _JITTERENTROPY_H */
|
||||
Index: libgcrypt-1.9.4/random/jitterentropy-base-user.h
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/random/jitterentropy-base-user.h
|
||||
+++ libgcrypt-1.9.4/random/jitterentropy-base-user.h
|
||||
@@ -216,12 +216,12 @@ static inline void jent_get_cachesize(lo
|
||||
ext = strstr(buf, "K");
|
||||
if (ext) {
|
||||
shift = 10;
|
||||
- ext = '\0';
|
||||
+ *ext = '\0';
|
||||
} else {
|
||||
ext = strstr(buf, "M");
|
||||
if (ext) {
|
||||
shift = 20;
|
||||
- ext = '\0';
|
||||
+ *ext = '\0';
|
||||
}
|
||||
}
|
||||
|
12
libgcrypt-out-of-core-handler.patch
Normal file
12
libgcrypt-out-of-core-handler.patch
Normal file
@ -0,0 +1,12 @@
|
||||
Index: libgcrypt-1.9.4/src/global.c
|
||||
===================================================================
|
||||
--- libgcrypt-1.9.4.orig/src/global.c
|
||||
+++ libgcrypt-1.9.4/src/global.c
|
||||
@@ -951,7 +951,6 @@ _gcry_set_outofcore_handler (int (*f)(vo
|
||||
|
||||
if (fips_mode () )
|
||||
{
|
||||
- log_info ("out of core handler ignored in FIPS mode\n");
|
||||
return;
|
||||
}
|
||||
|
@ -1,3 +1,19 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Aug 23 09:19:00 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
|
||||
|
||||
- FIPS: gpg/gpg2 gets out of core handler in FIPS mode while
|
||||
typing Tab key to Auto-Completion. [bsc#1182983]
|
||||
* Add libgcrypt-out-of-core-handler.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Aug 8 11:33:03 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
|
||||
|
||||
- FIPS: Port libgcrypt to use jitterentropy [bsc#1202117, jsc#SLE-24941]
|
||||
* Enable the jitter based entropy generator by default in random.conf
|
||||
- Add libgcrypt-jitterentropy-3.3.0.patch
|
||||
* Update the internal jitterentropy to version 3.4.0
|
||||
- Add libgcrypt-jitterentropy-3.4.0.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Aug 1 07:27:35 UTC 2022 - Stephan Kulow <coolo@suse.com>
|
||||
|
||||
@ -5,6 +21,31 @@ Mon Aug 1 07:27:35 UTC 2022 - Stephan Kulow <coolo@suse.com>
|
||||
- Do not use %release in binaries (but use SOURCE_DATE_EPOCH)
|
||||
- Fix date call messed up by spec-cleaner
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Apr 14 12:30:36 UTC 2022 - Dennis Knorr <dennis.knorr@suse.com>
|
||||
|
||||
- FIPS: extend the service indicator [bsc#1190700]
|
||||
* introduced a pk indicator function
|
||||
* adapted the approved and non approved ciphersuites
|
||||
* Add libgcrypt_indicators_changes.patch
|
||||
* Add libgcrypt-indicate-shake.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Mar 22 12:32:09 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
|
||||
|
||||
- FIPS: Implement a service indicator for asymmetric ciphers [bsc#1190700]
|
||||
* Mark RSA public key encryption and private key decryption with
|
||||
padding (e.g. OAEP, PKCS) as non-approved since RSA-OAEP lacks
|
||||
peer key assurance validation requirements per SP800-56Brev2.
|
||||
* Mark ECC as approved only for NIST curves P-224, P-256, P-384
|
||||
and P-521 with check for common NIST names and aliases.
|
||||
* Mark DSA, ELG, EDDSA, ECDSA and ECDH as non-approved.
|
||||
* Add libgcrypt-FIPS-SLI-pk.patch
|
||||
* Rebase libgcrypt-FIPS-service-indicators.patch
|
||||
- Run the regression tests also in FIPS mode.
|
||||
* Disable tests for non-FIPS approved algos.
|
||||
* Rebase: libgcrypt-FIPS-verify-unsupported-KDF-test.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Feb 1 11:28:51 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
|
||||
|
||||
|
@ -96,6 +96,17 @@ Patch39: libgcrypt-FIPS-HMAC-short-keylen.patch
|
||||
Patch40: libgcrypt-FIPS-service-indicators.patch
|
||||
#PATCH-FIX-UPSTREAM bsc#1195385 FIPS: Disable DSA in FIPS mode
|
||||
Patch41: libgcrypt-FIPS-disable-DSA.patch
|
||||
#PATCH-FIX-UPSTREAM bsc#1190700 FIPS: Provide a service-level indicator for PK
|
||||
Patch42: libgcrypt-FIPS-SLI-pk.patch
|
||||
#PATCH-FIX-SUSE bsc#1190700 FIPS add indicators
|
||||
Patch43: libgcrypt_indicators_changes.patch
|
||||
#PATCH-FIX-SUSE bsc#1190700 FIPS allow shake
|
||||
Patch44: libgcrypt-indicate-shake.patch
|
||||
#PATCH-FIX-UPSTREAM bsc#1202117 jsc#SLE-24941 FIPS: Port libgcrypt to use jitterentropy
|
||||
Patch45: libgcrypt-jitterentropy-3.3.0.patch
|
||||
Patch46: libgcrypt-jitterentropy-3.4.0.patch
|
||||
#PATCH-FIX-SUSE bsc#1182983 gpg: out of core handler ignored in FIPS mode while typing Tab key to Auto-Completion
|
||||
Patch47: libgcrypt-out-of-core-handler.patch
|
||||
BuildRequires: automake >= 1.14
|
||||
BuildRequires: fipscheck
|
||||
BuildRequires: libgpg-error-devel >= 1.27
|
||||
@ -213,6 +224,9 @@ export CFLAGS="%{optflags} $(getconf LFS_CFLAGS)"
|
||||
fipshmac src/.libs/libgcrypt.so.??
|
||||
%make_build check
|
||||
|
||||
# run the regression tests also in FIPS mode
|
||||
LIBGCRYPT_FORCE_FIPS_MODE=1 make -k check VERBOSE=1 || true
|
||||
|
||||
%install
|
||||
%make_install
|
||||
rm %{buildroot}%{_libdir}/%{name}.la
|
||||
|
238
libgcrypt_indicators_changes.patch
Normal file
238
libgcrypt_indicators_changes.patch
Normal file
@ -0,0 +1,238 @@
|
||||
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
|
||||
index afb8a05..c613577 100644
|
||||
--- a/doc/gcrypt.texi
|
||||
+++ b/doc/gcrypt.texi
|
||||
@@ -968,23 +968,39 @@ is approved under the current FIPS 140-3 certification. If the
|
||||
combination is approved, this function returns @code{GPG_ERR_NO_ERROR}.
|
||||
Otherwise @code{GPG_ERR_NOT_SUPPORTED} is returned.
|
||||
|
||||
+@item GCRYCTL_FIPS_SERVICE_INDICATOR_HASH; Arguments: enum gcry_md_algos
|
||||
+
|
||||
+Check if the given HASH is approved under the current FIPS 140-3
|
||||
+certification. If the HASH is approved, this function returns
|
||||
+@code{GPS_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED}
|
||||
+is returned.
|
||||
+
|
||||
+@item GCRYCTL_FIPS_SERVICE_INDICATOR_MAC; Arguments: enum gcry_mac_algos [, unsigned int]
|
||||
+
|
||||
+Check if the given MAC is approved under the current FIPS 140-3
|
||||
+certification. The second parameter provides the keylen (if the
|
||||
+algorithm supports different key sizes). If the MAC is approved,
|
||||
+this function returns @code{GPS_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED}
|
||||
+is returned.
|
||||
+
|
||||
@item GCRYCTL_FIPS_SERVICE_INDICATOR_KDF; Arguments: enum gcry_kdf_algos
|
||||
|
||||
Check if the given KDF is approved under the current FIPS 140-3
|
||||
-certification. If the KDF is approved, this function returns
|
||||
-@code{GPG_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED}
|
||||
-is returned.
|
||||
+certification. If the KDF is approved, this function returns @code{GPG_ERR_NO_ERROR}.
|
||||
+Otherwise @code{GPG_ERR_NOT_SUPPORTED} is returned.
|
||||
|
||||
@item GCRYCTL_FIPS_SERVICE_INDICATOR_PK; Arguments: enum gcry_pk_algos
|
||||
-[, enum pk_operation (only for GCRY_PK_RSA)] [, const char * (only for
|
||||
-GCRY_PK_ECC, GCRY_PK_ECDH or GCRY_PK_ECDSA)]
|
||||
+[, constants GCRY_PK_USAGE_ENCR or GCRY_PK_USAGE_SIGN, unsigned int (only for GCRY_PK_RSA)]
|
||||
+[, const char * (only for GCRY_PK_ECC, GCRY_PK_ECDH or GCRY_PK_ECDSA)]
|
||||
|
||||
Check if the given asymmetric cipher is approved under the current FIPS
|
||||
-140-3 certification. For GCRY_PK_RSA, an additional parameter for the
|
||||
-operation mode @code{enum pk_operation} is required. For GCRY_PK_ECC,
|
||||
-GCRY_PK_ECDH and GCRY_PK_ECDSA, the additional parameter is the curve
|
||||
-name or its alias as @code{const char *}. If the combination is
|
||||
-approved, this function returns @code{GPG_ERR_NO_ERROR}. Otherwise
|
||||
+140-3 certification. For GCRY_PK_RSA, two additional parameter are required:
|
||||
+first describes the purpose of the algorithm through one of the constants
|
||||
+(GCRY_PK_USAGE_ENCR for encryption or decryption operations; GCRY_PK_USAGE_SIGN for
|
||||
+sign or verify operations).
|
||||
+Second one is the key length. For GCRY_PK_ECC, GCRY_PK_ECDH and GCRY_PK_ECDSA,
|
||||
+only a single parameter is needed: the curve name or its alias as @code{const char *}.
|
||||
+If the combination is approved, this function returns @code{GPG_ERR_NO_ERROR}. Otherwise
|
||||
@code{GPG_ERR_NOT_SUPPORTED} is returned.
|
||||
|
||||
@end table
|
||||
diff --git a/src/fips.c b/src/fips.c
|
||||
index f523e7d..d5ca482 100644
|
||||
--- a/src/fips.c
|
||||
+++ b/src/fips.c
|
||||
@@ -452,6 +452,7 @@ _gcry_fips_indicator_cipher (va_list arg_ptr)
|
||||
mode = va_arg (arg_ptr, enum gcry_cipher_modes);
|
||||
switch (mode)
|
||||
{
|
||||
+ case GCRY_CIPHER_MODE_AESWRAP:
|
||||
case GCRY_CIPHER_MODE_ECB:
|
||||
case GCRY_CIPHER_MODE_CBC:
|
||||
case GCRY_CIPHER_MODE_CFB:
|
||||
@@ -459,7 +460,6 @@ _gcry_fips_indicator_cipher (va_list arg_ptr)
|
||||
case GCRY_CIPHER_MODE_OFB:
|
||||
case GCRY_CIPHER_MODE_CTR:
|
||||
case GCRY_CIPHER_MODE_CCM:
|
||||
- case GCRY_CIPHER_MODE_GCM:
|
||||
case GCRY_CIPHER_MODE_XTS:
|
||||
return GPG_ERR_NO_ERROR;
|
||||
default:
|
||||
@@ -519,11 +519,25 @@ static const struct
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
+enum pk_operation convert_from_pk_usage(unsigned int pk_usage)
|
||||
+{
|
||||
+ switch (pk_usage)
|
||||
+ {
|
||||
+ case GCRY_PK_USAGE_SIGN:
|
||||
+ return PUBKEY_OP_SIGN;
|
||||
+ case GCRY_PK_USAGE_ENCR:
|
||||
+ return PUBKEY_OP_ENCRYPT;
|
||||
+ default:
|
||||
+ return PUBKEY_OP_DECRYPT;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int
|
||||
_gcry_fips_indicator_pk (va_list arg_ptr)
|
||||
{
|
||||
enum gcry_pk_algos alg = va_arg (arg_ptr, enum gcry_pk_algos);
|
||||
enum pk_operation oper;
|
||||
+ unsigned int keylen;
|
||||
const char *curve_name;
|
||||
|
||||
switch (alg)
|
||||
@@ -531,13 +545,17 @@ _gcry_fips_indicator_pk (va_list arg_ptr)
|
||||
case GCRY_PK_RSA:
|
||||
case GCRY_PK_RSA_E:
|
||||
case GCRY_PK_RSA_S:
|
||||
- oper = va_arg (arg_ptr, enum pk_operation);
|
||||
+ oper = convert_from_pk_usage(va_arg (arg_ptr, unsigned int));
|
||||
switch (oper)
|
||||
{
|
||||
case PUBKEY_OP_ENCRYPT:
|
||||
case PUBKEY_OP_DECRYPT:
|
||||
return GPG_ERR_NOT_SUPPORTED;
|
||||
default:
|
||||
+ keylen = va_arg (arg_ptr, unsigned int);
|
||||
+ if (keylen < 2048) {
|
||||
+ return GPG_ERR_NOT_SUPPORTED;
|
||||
+ }
|
||||
return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
case GCRY_PK_ECC:
|
||||
@@ -557,6 +575,60 @@ _gcry_fips_indicator_pk (va_list arg_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
+int
|
||||
+_gcry_fips_indicator_hash (va_list arg_ptr)
|
||||
+{
|
||||
+ enum gcry_md_algos alg = va_arg (arg_ptr, enum gcry_md_algos);
|
||||
+
|
||||
+ switch (alg)
|
||||
+ {
|
||||
+ case GCRY_MD_SHA1:
|
||||
+ case GCRY_MD_SHA224:
|
||||
+ case GCRY_MD_SHA256:
|
||||
+ case GCRY_MD_SHA384:
|
||||
+ case GCRY_MD_SHA512:
|
||||
+ case GCRY_MD_SHA512_224:
|
||||
+ case GCRY_MD_SHA512_256:
|
||||
+ case GCRY_MD_SHA3_224:
|
||||
+ case GCRY_MD_SHA3_256:
|
||||
+ case GCRY_MD_SHA3_384:
|
||||
+ case GCRY_MD_SHA3_512:
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
+ default:
|
||||
+ return GPG_ERR_NOT_SUPPORTED;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+_gcry_fips_indicator_mac (va_list arg_ptr)
|
||||
+{
|
||||
+ enum gcry_mac_algos alg = va_arg (arg_ptr, enum gcry_mac_algos);
|
||||
+ unsigned int keylen = va_arg (arg_ptr, unsigned int);
|
||||
+
|
||||
+ switch (alg)
|
||||
+ {
|
||||
+ case GCRY_MAC_HMAC_SHA1:
|
||||
+ case GCRY_MAC_HMAC_SHA224:
|
||||
+ case GCRY_MAC_HMAC_SHA256:
|
||||
+ case GCRY_MAC_HMAC_SHA384:
|
||||
+ case GCRY_MAC_HMAC_SHA512:
|
||||
+ case GCRY_MAC_HMAC_SHA512_224:
|
||||
+ case GCRY_MAC_HMAC_SHA512_256:
|
||||
+ case GCRY_MAC_HMAC_SHA3_224:
|
||||
+ case GCRY_MAC_HMAC_SHA3_256:
|
||||
+ case GCRY_MAC_HMAC_SHA3_384:
|
||||
+ case GCRY_MAC_HMAC_SHA3_512:
|
||||
+ if (keylen >= 112) {
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
+ }
|
||||
+ case GCRY_MAC_CMAC_AES:
|
||||
+ if (keylen == 128 || keylen == 192 || keylen == 256) {
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
+ }
|
||||
+ default:
|
||||
+ return GPG_ERR_NOT_SUPPORTED;
|
||||
+ }
|
||||
+}
|
||||
|
||||
/* This is a test on whether the library is in the error or
|
||||
operational state. */
|
||||
diff --git a/src/g10lib.h b/src/g10lib.h
|
||||
index 9fc868b..92c24a5 100644
|
||||
--- a/src/g10lib.h
|
||||
+++ b/src/g10lib.h
|
||||
@@ -488,7 +488,9 @@ void _gcry_fips_signal_error (const char *srcfile,
|
||||
#endif
|
||||
|
||||
int _gcry_fips_indicator_cipher (va_list arg_ptr);
|
||||
+int _gcry_fips_indicator_hash (va_list arg_ptr);
|
||||
int _gcry_fips_indicator_kdf (va_list arg_ptr);
|
||||
+int _gcry_fips_indicator_mac (va_list arg_ptr);
|
||||
int _gcry_fips_indicator_pk (va_list arg_ptr);
|
||||
|
||||
int _gcry_fips_is_operational (void);
|
||||
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
|
||||
index 7704d17..344f879 100644
|
||||
--- a/src/gcrypt.h.in
|
||||
+++ b/src/gcrypt.h.in
|
||||
@@ -337,7 +337,9 @@ enum gcry_ctl_cmds
|
||||
GCRYCTL_SET_ALLOW_WEAK_KEY = 79,
|
||||
GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER = 81,
|
||||
GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82,
|
||||
- GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 83
|
||||
+ GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 83,
|
||||
+ GCRYCTL_FIPS_SERVICE_INDICATOR_HASH = 84,
|
||||
+ GCRYCTL_FIPS_SERVICE_INDICATOR_MAC = 85
|
||||
};
|
||||
|
||||
/* Perform various operations defined by CMD. */
|
||||
diff --git a/src/global.c b/src/global.c
|
||||
index c01b424..03756ea 100644
|
||||
--- a/src/global.c
|
||||
+++ b/src/global.c
|
||||
@@ -762,12 +762,24 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
|
||||
rc = _gcry_fips_indicator_cipher (arg_ptr);
|
||||
break;
|
||||
|
||||
+ case GCRYCTL_FIPS_SERVICE_INDICATOR_HASH:
|
||||
+ /* Get FIPS Service Indicator for a given HASH. Returns GPG_ERR_NO_ERROR
|
||||
+ * if algorithm is allowed or GPG_ERR_NOT_SUPPORTED otherwise */
|
||||
+ rc = _gcry_fips_indicator_hash (arg_ptr);
|
||||
+ break;
|
||||
+
|
||||
case GCRYCTL_FIPS_SERVICE_INDICATOR_KDF:
|
||||
/* Get FIPS Service Indicator for a given KDF. Returns GPG_ERR_NO_ERROR
|
||||
* if algorithm is allowed or GPG_ERR_NOT_SUPPORTED otherwise */
|
||||
rc = _gcry_fips_indicator_kdf (arg_ptr);
|
||||
break;
|
||||
|
||||
+ case GCRYCTL_FIPS_SERVICE_INDICATOR_MAC:
|
||||
+ /* Get FIPS Service Indicator for a given HMAC. Returns GPG_ERR_NO_ERROR
|
||||
+ * if algorithm is allowed or GPG_ERR_NOT_SUPPORTED otherwise */
|
||||
+ rc = _gcry_fips_indicator_mac (arg_ptr);
|
||||
+ break;
|
||||
+
|
||||
case GCRYCTL_FIPS_SERVICE_INDICATOR_PK:
|
||||
/* Get FIPS Service Indicator for a given asymmetric algorithm. For
|
||||
* GCRY_PK_RSA, an additional parameter for the operation mode is
|
@ -6,4 +6,4 @@
|
||||
# only-urandom
|
||||
|
||||
# Disable the use of the jitter based entropy generator.
|
||||
disable-jent
|
||||
# disable-jent
|
||||
|
Loading…
Reference in New Issue
Block a user