libgcrypt/libgcrypt-1.8.3-fips-enttest.patch
DistroBaker 570c9025e0 Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/libgcrypt.git#e12a03494690ed17d13ee81d78f4e1d8e7b0a083
2021-01-26 13:59:35 +00:00

114 lines
3.9 KiB
Diff

diff -up libgcrypt-1.8.3/random/random-drbg.c.fips-enttest libgcrypt-1.8.3/random/random-drbg.c
--- libgcrypt-1.8.3/random/random-drbg.c.fips-enttest 2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.3/random/random-drbg.c 2019-06-24 10:04:23.219547141 +0200
@@ -317,6 +317,7 @@ struct drbg_state_s
gcry_cipher_hd_t ctr_handle; /* CTR mode cipher handle */
int seeded:1; /* DRBG fully seeded? */
int pr:1; /* Prediction resistance enabled? */
+ int ent_primed:1; /* Previous entropy data primed? */
/* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the
* process which did the initialization so that we can detect a fork.
* The volatile modifier is required so that the compiler does not
@@ -324,6 +325,7 @@ struct drbg_state_s
pid_t seed_init_pid;
const struct drbg_state_ops_s *d_ops;
const struct drbg_core_s *core;
+ unsigned char ent_hash[64]; /* Hash of previous entropy data */
struct drbg_test_data_s *test_data;
};
@@ -610,11 +612,13 @@ drbg_get_entropy (drbg_state_t drbg, uns
size_t len)
{
int rc = 0;
+ unsigned char newhash[64];
/* Perform testing as defined in 11.3.2 */
if (drbg->test_data && drbg->test_data->fail_seed_source)
return -1;
+redo:
read_cb_buffer = buffer;
read_cb_size = len;
read_cb_len = 0;
@@ -634,6 +638,27 @@ drbg_get_entropy (drbg_state_t drbg, uns
#else
rc = -1;
#endif
+
+ /* to avoid storing the actual entropy obtained for indefinite
+ time, we just store the SHA-512 hash of the entropy gathered
+ */
+ _gcry_md_hash_buffer (GCRY_MD_SHA512, newhash, buffer, len);
+
+ if (!drbg->ent_primed)
+ {
+ memcpy (drbg->ent_hash, newhash, sizeof (drbg->ent_hash));
+ drbg->ent_primed = 1;
+ goto redo;
+ }
+
+ if (memcmp (newhash, drbg->ent_hash, sizeof (drbg->ent_hash)) == 0)
+ {
+ fips_signal_error ("Entropy source failed the continuous test");
+ return -1; /* continuous entropy test failed */
+ }
+
+ memcpy (drbg->ent_hash, newhash, sizeof (drbg->ent_hash));
+
return rc;
}
@@ -1341,26 +1366,38 @@ drbg_seed (drbg_state_t drbg, drbg_strin
}
else
{
+ int nonce = 0;
/* Gather entropy equal to the security strength of the DRBG.
* With a derivation function, a nonce is required in addition
* to the entropy. A nonce must be at least 1/2 of the security
* strength of the DRBG in size. Thus, entropy * nonce is 3/2
* of the strength. The consideration of a nonce is only
- * applicable during initial seeding. */
+ * applicable during initial seeding.
+ * To avoid pulling different length of data from entropy
+ * source, we use 2 * strength for initial seeding. */
entropylen = drbg_sec_strength (drbg->core->flags);
if (!entropylen)
return GPG_ERR_GENERAL;
if (0 == reseed)
- /* make sure we round up strength/2 in
- * case it is not divisible by 2 */
- entropylen = ((entropylen + 1) / 2) * 3;
+ {
+ nonce = 1;
+ }
dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen));
- entropy = xcalloc_secure (1, entropylen);
+ entropy = xcalloc_secure (nonce + 1, entropylen);
if (!entropy)
return GPG_ERR_ENOMEM;
ret = drbg_get_entropy (drbg, entropy, entropylen);
if (ret)
goto out;
+ if (nonce)
+ {
+ ret = drbg_get_entropy (drbg, entropy + entropylen, entropylen);
+ if (ret)
+ goto out;
+ /* make sure we round up strength/2 in
+ * case it is not divisible by 2 */
+ entropylen = 2 * entropylen;
+ }
drbg_string_fill (&data1, entropy, entropylen);
}
@@ -1597,6 +1634,7 @@ drbg_instantiate (drbg_state_t drbg,
drbg->core = &drbg_cores[coreref];
drbg->pr = pr;
drbg->seeded = 0;
+ drbg->ent_primed = 0;
if (drbg->core->flags & DRBG_HMAC)
drbg->d_ops = &drbg_hmac_ops;
else if (drbg->core->flags & DRBG_HASH_MASK)