tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: [6.0_BETA] cprng xxx: WARNING insufficient entropy at creation.
On Sat, Feb 25, 2012 at 03:50:39PM -0500, Thor Lancelot Simon wrote:
> On Sat, Feb 25, 2012 at 02:08:49PM -0500, Thor Lancelot Simon wrote:
> > On Sat, Feb 25, 2012 at 07:54:41PM +0100, Martin Husemann wrote:
> > >
> > > What I am still wondering is: is this a local setup problem, unavoidable
> > > on this hardware, or a bug in the code?
> >
> > Well, one worthwhile question is why sshd would be opening
> > /dev/urandom over and over again rather than opening once and
> > reading many times. If it opened it once, it would not deplete
> > your system's entropy in this manner.
>
> It's arc4_stir() in libc, I believe. I'll fix.
Try the following patch. Warning -- untested. But it should do the job.
Index: gen/arc4random.c
===================================================================
RCS file: /cvsroot/src/lib/libc/gen/arc4random.c,v
retrieving revision 1.10
diff -u -r1.10 arc4random.c
--- gen/arc4random.c 4 Feb 2011 22:07:07 -0000 1.10
+++ gen/arc4random.c 26 Feb 2012 04:51:08 -0000
@@ -31,6 +31,7 @@
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
+#include "reentrant.h"
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
@@ -44,13 +45,15 @@
#endif
struct arc4_stream {
+ int rndfd;
+ mutex_t mtx;
uint8_t i;
uint8_t j;
uint8_t s[256];
};
static int rs_initialized;
-static struct arc4_stream rs;
+static struct arc4_stream rs = { .rndfd = -1, .mtx = MUTEX_INITIALIZER };
static inline void arc4_init(struct arc4_stream *);
static inline void arc4_addrandom(struct arc4_stream *, u_char *, int);
@@ -89,21 +92,16 @@
static void
arc4_stir(struct arc4_stream *as)
{
- int fd;
- struct {
- struct timeval tv;
- u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)];
- } rdat;
+ int rdat[128 / sizeof(int)];
int n;
- gettimeofday(&rdat.tv, NULL);
- fd = open("/dev/urandom", O_RDONLY);
- if (fd != -1) {
- read(fd, rdat.rnd, sizeof(rdat.rnd));
- close(fd);
+ if (as->rndfd == -1) {
+ as->rndfd = open("/dev/urandom", O_RDONLY);
}
-#ifdef KERN_URND
- else {
+
+ if (as->rndfd != -1) {
+ read(as->rndfd, rdat, sizeof(rdat));
+ } else {
int mib[2];
u_int i;
size_t len;
@@ -114,15 +112,12 @@
mib[0] = CTL_KERN;
mib[1] = KERN_URND;
- for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i++) {
- len = sizeof(u_int);
- if (sysctl(mib, 2, &rdat.rnd[i], &len, NULL, 0) == -1)
- break;
+ for (i = 0; i < sizeof(rdat) / sizeof(int); i++) {
+ len = sizeof(rdat[i]);
+ if (sysctl(mib, 2, &rdat[i], &len, NULL, 0) == -1)
+ abort();
}
}
-#endif
- /* fd < 0 or failed sysctl ? Ah, what the heck. We'll just take
- * whatever was on the stack... */
arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
@@ -160,8 +155,8 @@
return val;
}
-void
-arc4random_stir(void)
+static inline void
+_arc4random_stir_unlocked(void)
{
if (!rs_initialized) {
arc4_init(&rs);
@@ -171,23 +166,67 @@
}
void
-arc4random_addrandom(u_char *dat, int datlen)
+arc4random_stir(void)
+{
+#ifdef _REENTRANT
+ if (__isthreaded) {
+ mutex_lock(&rs.mtx);
+ _arc4random_stir_unlocked();
+ mutex_unlock(&rs.mtx);
+ return;
+ }
+#endif
+ _arc4random_stir_unlocked();
+}
+
+static inline void
+_arc4random_addrandom_unlocked(u_char *dat, int datlen)
{
if (!rs_initialized)
- arc4random_stir();
+ arc4_stir(&rs);
arc4_addrandom(&rs, dat, datlen);
}
-uint32_t
-arc4random(void)
+void
+arc4random_addrandom(u_char *dat, int datlen)
+{
+#ifdef _REENTRANT
+ if (__isthreaded) {
+ mutex_lock(&rs.mtx);
+ _arc4random_addrandom_unlocked(dat, datlen);
+ mutex_unlock(&rs.mtx);
+ return;
+ }
+#endif
+ _arc4random_addrandom_unlocked(dat, datlen);
+}
+
+static inline uint32_t
+_arc4random_unlocked(void)
{
if (!rs_initialized)
- arc4random_stir();
+ arc4_stir(&rs);
return arc4_getword(&rs);
}
-void
-arc4random_buf(void *buf, size_t len)
+uint32_t
+arc4random(void)
+{
+ uint32_t v;
+#ifdef _REENTRANT
+ if (__isthreaded) {
+ mutex_lock(&rs.mtx);
+ v = _arc4random_unlocked();
+ mutex_unlock(&rs.mtx);
+ return v;
+ }
+#endif
+ v = _arc4random_unlocked();
+ return v;
+}
+
+static void
+_arc4random_buf_unlocked(void *buf, size_t len)
{
uint8_t *bp = buf;
uint8_t *ep = bp + len;
@@ -200,6 +239,20 @@
*bp++ = arc4_getbyte(&rs);
}
+void
+arc4random_buf(void *buf, size_t len)
+{
+#ifdef _REENTRANT
+ if (__isthreaded) {
+ mutex_lock(&rs.mtx);
+ _arc4random_buf_unlocked(buf, len);
+ mutex_unlock(&rs.mtx);
+ return;
+ } else
+#endif
+ _arc4random_buf_unlocked(buf, len);
+}
+
/*-
* Written by Damien Miller.
* With simplifications by Jinmei Tatuya.
@@ -216,8 +269,8 @@
* [2^32 % upper_bound, 2^32[ which maps back to
* [0, upper_bound[ after reduction modulo upper_bound.
*/
-uint32_t
-arc4random_uniform(uint32_t upper_bound)
+static uint32_t
+_arc4random_uniform_unlocked(uint32_t upper_bound)
{
uint32_t r, min;
@@ -243,7 +296,7 @@
* to re-roll (at all).
*/
if (!rs_initialized)
- arc4random_stir();
+ arc4_stir(&rs);
if (arc4_getbyte(&rs) & 1)
(void)arc4_getbyte(&rs);
do
@@ -253,24 +306,18 @@
return r % upper_bound;
}
-
-#if 0
-/*-------- Test code for i386 --------*/
-#include <stdio.h>
-#include <machine/pctr.h>
-int
-main(int argc, char **argv)
-{
- const int iter = 1000000;
- int i;
- pctrval v;
-
- v = rdtsc();
- for (i = 0; i < iter; i++)
- arc4random();
- v = rdtsc() - v;
- v /= iter;
-
- printf("%qd cycles\n", v);
-}
+uint32_t
+arc4random_uniform(uint32_t upper_bound)
+{
+ uint32_t v;
+#ifdef _REENTRANT
+ if (__isthreaded) {
+ mutex_lock(&rs.mtx);
+ v = _arc4random_uniform_unlocked(upper_bound);
+ mutex_unlock(&rs.mtx);
+ return v;
+ }
#endif
+ v = _arc4random_uniform_unlocked(upper_bound);
+ return v;
+}
Home |
Main Index |
Thread Index |
Old Index