summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/arc4random.c63
1 files changed, 30 insertions, 33 deletions
diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c
index 02f7814..a2b235f 100644
--- a/lib/libc/gen/arc4random.c
+++ b/lib/libc/gen/arc4random.c
@@ -33,11 +33,13 @@
__FBSDID("$FreeBSD$");
#include "namespace.h"
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdlib.h>
#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
#include <pthread.h>
#include "libc_private.h"
@@ -71,9 +73,9 @@ static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
_pthread_mutex_unlock(&arc4random_mtx); \
} while (0)
-static struct arc4_stream rs;
static int rs_initialized;
-static int rs_stired;
+static struct arc4_stream rs;
+static pid_t arc4_stir_pid;
static int arc4_count;
static inline u_int8_t arc4_getbyte(void);
@@ -117,6 +119,10 @@ arc4_stir(void)
u_char rnd[KEYSIZE];
} rdat;
+ if (!rs_initialized) {
+ arc4_init();
+ rs_initialized = 1;
+ }
fd = _open(RANDOMDEV, O_RDONLY, 0);
done = 0;
if (fd >= 0) {
@@ -141,6 +147,18 @@ arc4_stir(void)
arc4_count = 1600000;
}
+static void
+arc4_stir_if_needed(void)
+{
+ pid_t pid = getpid();
+
+ if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid)
+ {
+ arc4_stir_pid = pid;
+ arc4_stir();
+ }
+}
+
static inline u_int8_t
arc4_getbyte(void)
{
@@ -166,31 +184,11 @@ arc4_getword(void)
return val;
}
-static void
-arc4_check_init(void)
-{
- if (!rs_initialized) {
- arc4_init();
- rs_initialized = 1;
- }
-}
-
-static inline void
-arc4_check_stir(void)
-{
- if (!rs_stired || arc4_count <= 0) {
- arc4_stir();
- rs_stired = 1;
- }
-}
-
void
arc4random_stir(void)
{
_ARC4_LOCK();
- arc4_check_init();
arc4_stir();
- rs_stired = 1;
_ARC4_UNLOCK();
}
@@ -198,8 +196,8 @@ void
arc4random_addrandom(u_char *dat, int datlen)
{
_ARC4_LOCK();
- arc4_check_init();
- arc4_check_stir();
+ if (!rs_initialized)
+ arc4_stir();
arc4_addrandom(dat, datlen);
_ARC4_UNLOCK();
}
@@ -209,10 +207,9 @@ arc4random(void)
{
u_int32_t val;
_ARC4_LOCK();
- arc4_check_init();
- arc4_check_stir();
- val = arc4_getword();
arc4_count -= 4;
+ arc4_stir_if_needed();
+ val = arc4_getword();
_ARC4_UNLOCK();
return val;
}
@@ -222,11 +219,11 @@ arc4random_buf(void *_buf, size_t n)
{
u_char *buf = (u_char *)_buf;
_ARC4_LOCK();
- arc4_check_init();
+ arc4_stir_if_needed();
while (n--) {
- arc4_check_stir();
+ if (--arc4_count <= 0)
+ arc4_stir();
buf[n] = arc4_getbyte();
- arc4_count--;
}
_ARC4_UNLOCK();
}
OpenPOWER on IntegriCloud