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]