Bug in jitterentropy handling

Eric Berry via Gcrypt-devel <[email protected]> Wed, 15 Oct 2025 14:54:06 -0700
Newsgroups gmane.comp.encryption.gpg.libgcrypt.devel
Message-ID <CAGP7n5Hfi-u+jyA=DO3Pq_xSubqir6CqvY2UjHHFwAMZNoS=fw@mail.gmail.com>
Please see the attached patch.

The flag jent_rng_is_initialized is not being handled correctly.
- It is set to true before the corresponding jent_rng_collector structure
is fully initialized.
- It is not cleared when the jent_rng_collector is freed.

Subsequently, when trying to generate entropy in the function
_gcry_rndjent_poll after the jent_rng_collector has been freed,
jent_rng_is_initialized is true so jent_rng_collector is not
re-initialized, but then when trying to generate entropy jent_rng_collector
is null so entropy generation is skipped.

In Ubuntu, we want to create a userspace FIPS mode that generates entropy
solely through the jitter entropy library. Because of this bug, the
modifications we made to rndgetentropy.c to get all of the entropy from
_gcry_rndjent_poll goes into an infinite loop because _gcry_rndjent_poll
generates 0 random entropy. Consequently I think the existing code that
tries to generate 50% of the bytes from jitterentropy is actually getting
none.

This patch was generated against the master branch.

_______________________________________________
Gcrypt-devel mailing list
[email protected]
https://lists.gnupg.org/mailman/listinfo/gcrypt-devel
rndjent.fix.patch (application/octet-stream, 1.1 KB)
diff --git a/random/rndjent.c b/random/rndjent.c
index 0468c7cb..3fefb539 100644
--- a/random/rndjent.c
+++ b/random/rndjent.c
@@ -290,13 +290,16 @@ _gcry_rndjent_poll (void (*add)(const void*, size_t, enum random_origins),
       if (!jent_rng_is_initialized)
         {
           /* Auto-initialize.  */
-          jent_rng_is_initialized = 1;
           jent_entropy_collector_free (jent_rng_collector);
           jent_rng_collector = NULL;
           if ( !(_gcry_random_read_conf () & RANDOM_CONF_DISABLE_JENT))
             {
               if (!jent_entropy_init ())
-                jent_rng_collector = jent_entropy_collector_alloc (1, 0);
+                {
+                  jent_rng_collector = jent_entropy_collector_alloc (1, 0);
+                  if (jent_rng_collector != NULL)
+                    jent_rng_is_initialized = 1;
+                }
             }
         }
 
@@ -402,6 +405,7 @@ _gcry_rndjent_fini (void)
     {
       jent_entropy_collector_free (jent_rng_collector);
       jent_rng_collector = NULL;
+      jent_rng_is_initialized = 0;
     }
 
   unlock_rng ();