Blame SOURCES/libgcrypt-1.8.3-fips-enttest.patch

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