Blob Blame History Raw
diff -up libgcrypt-1.5.3/random/random-csprng.c.rng-predictable libgcrypt-1.5.3/random/random-csprng.c
--- libgcrypt-1.5.3/random/random-csprng.c.rng-predictable	2015-08-11 14:31:35.904275580 +0200
+++ libgcrypt-1.5.3/random/random-csprng.c	2016-08-17 23:35:15.691980751 +0200
@@ -561,41 +561,46 @@ _gcry_rngcsprng_randomize (void *buffer,
 
 
 /*
-   Mix the pool:
-
-   |........blocks*20byte........|20byte|..44byte..|
-   <..44byte..>           <20byte>
-        |                    |
-        |                    +------+
-        +---------------------------|----------+
-                                    v          v
-   |........blocks*20byte........|20byte|..44byte..|
-                                 <.....64bytes.....>
-                                         |
-      +----------------------------------+
-     Hash
-      v
-   |.............................|20byte|..44byte..|
-   <20byte><20byte><..44byte..>
-      |                |
-      |                +---------------------+
-      +-----------------------------+        |
-                                    v        v
-   |.............................|20byte|..44byte..|
-                                 <.....64byte......>
-                                        |
-              +-------------------------+
-             Hash
-              v
-   |.............................|20byte|..44byte..|
-   <20byte><20byte><..44byte..>
-
-   and so on until we did this for all blocks.
-
-   To better protect against implementation errors in this code, we
-   xor a digest of the entire pool into the pool before mixing.
-
-   Note: this function must only be called with a locked pool.
+ * Mix the 600 byte pool.  Note that the 64 byte scratch area directly
+ * follows the pool.  The numbers in the diagram give the number of
+ * bytes.
+ *         <................600...............>   <.64.>
+ * pool   |------------------------------------| |------|
+ *         <20><.24.>                      <20>
+ *          |     |                         +-----+
+ *          +-----|-------------------------------|-+
+ *                +-------------------------------|-|-+
+ *                                                v v v
+ *                                               |------|
+ *                                                <hash>
+ *          +---------------------------------------+
+ *          v
+ *         <20>
+ * pool'  |------------------------------------|
+ *         <20><20><.24.>
+ *          +---|-----|---------------------------+
+ *              +-----|---------------------------|-+
+ *                    +---------------------------|-|-+
+ *                                                v v v
+ *                                               |------|
+ *                                                <hash>
+ *                                                  |
+ *              +-----------------------------------+
+ *              v
+ *             <20>
+ * pool'' |------------------------------------|
+ *         <20><20><20><.24.>
+ *              +---|-----|-----------------------+
+ *                  +-----|-----------------------|-+
+ *                        +-----------------------|-|-+
+ *                                                v v v
+ *
+ * and so on until we did this for all 30 blocks.
+ *
+ * To better protect against implementation errors in this code, we
+ * xor a digest of the entire pool into the pool before mixing.
+ *
+ * Note: this function must only be called with a locked pool.
  */
 static void
 mix_pool(unsigned char *pool)
@@ -615,32 +620,30 @@ mix_pool(unsigned char *pool)
   gcry_assert (pool_is_locked);
   _gcry_rmd160_init( &md );
 
-  /* Loop over the pool.  */
+  /* pool_0 -> pool'.  */
   pend = pool + POOLSIZE;
-  memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
-  memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
-  _gcry_rmd160_mixblock( &md, hashbuf);
-  memcpy(pool, hashbuf, 20 );
+  memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN);
+  memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
+  _gcry_rmd160_mixblock (&md, hashbuf);
+  memcpy (pool, hashbuf, DIGESTLEN);
 
   if (failsafe_digest_valid && pool == rndpool)
     {
-      for (i=0; i < 20; i++)
+      for (i=0; i < DIGESTLEN; i++)
         pool[i] ^= failsafe_digest[i];
     }
 
+  /* Loop for the remaining iterations.  */
   p = pool;
   for (n=1; n < POOLBLOCKS; n++)
     {
-      memcpy (hashbuf, p, DIGESTLEN);
-
-      p += DIGESTLEN;
-      if (p+DIGESTLEN+BLOCKLEN < pend)
-        memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN);
+      if (p + BLOCKLEN < pend)
+        memcpy (hashbuf, p, BLOCKLEN);
       else
         {
-          unsigned char *pp = p + DIGESTLEN;
+          unsigned char *pp = p;
 
-          for (i=DIGESTLEN; i < BLOCKLEN; i++ )
+          for (i=0; i < BLOCKLEN; i++ )
             {
               if ( pp >= pend )
                 pp = pool;
@@ -648,8 +651,9 @@ mix_pool(unsigned char *pool)
 	    }
 	}
 
-      _gcry_rmd160_mixblock ( &md, hashbuf);
-      memcpy(p, hashbuf, 20 );
+      _gcry_rmd160_mixblock (&md, hashbuf);
+      p += DIGESTLEN;
+      memcpy (p, hashbuf, DIGESTLEN);
     }
 
     /* Our hash implementation does only leave small parts (64 bytes)