Arc4random is intended to stir every 1.6 million bytes of output and 
the _rs_stir_if_needed() function checks to see if a stir is 
required to complete the request.  However, in the (insane?) case that 
someone requests more than 1.6 million random bytes in a single 
request, it does not stir again part way through.  This could in theory 
aid an attacker in determining the state of the generator by outputting 
a longer than desired sequence without introducing entropy.

for example:
u_char buf[10000000]; /* 10 million */
arc4random_buf(buf, sizeof(buf));
will stir before outputting data, but will fill the buffer with 10 
millions bytes with stirring gain.  If the intention is to stir every 
1.6 million bytes, it should stir about 6 times.

This can be fixed with a simple patch:
--- crypto/compat/arc4random.c.orig     2014-08-09 00:09:04.193913805

-0400
+++ crypto/compat/arc4random.c  2014-08-09 00:10:18.160615204
-0400
@@ -156,8 +156,10 @@
                        n -= m;
                        rs->rs_have -= m;
                }
-               if (rs->rs_have == 0)
-                       _rs_rekey(NULL, 0);
+               if (rs->rs_have == 0) {
+                       _rs_rekey(NULL, 0);
+                       _rs_stir_if_needed(min(n, rs->rs_have));
+               }
        }
 }

(Found when doing throughput testing.  arc4random is *very* fast: I got 
>200MB/s for a single large buffer.  The additional restir does not 
affect throughput because it happens so rarely).

-- 
Paul Maurer
[email protected]

Reply via email to