Commit bf4eeb29f049e374b33b788a8df02357d659183c

Guillem Jover 2008-06-18T08:44:18

Add arc4random_stir and arc4random_addrandom functions

diff --git a/Makefile b/Makefile
index ca51123..48a2c4e 100644
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@ LIB_SHARED_SO = $(LIB_NAME).so
 LIB_SONAME = $(LIB_SHARED_SO).$(LIB_VERSION_MAJOR)
 LIB_SHARED = $(LIB_SONAME).$(LIB_VERSION_MINOR)
 
-MK_CFLAGS = -Iinclude/ -include bsd/bsd.h -D_GNU_SOURCE
+MK_CFLAGS = -Iinclude/ -include bsd/bsd.h -D_GNU_SOURCE -D__REENTRANT
 
 libs: $(LIB_STATIC) $(LIB_SHARED_SO)
 
diff --git a/Versions b/Versions
index 2bec4c5..b4e8392 100644
--- a/Versions
+++ b/Versions
@@ -1,6 +1,8 @@
 LIBBSD_0.0 {
   global:
     arc4random;
+    arc4random_stir;
+    arc4random_addrandom;
     bsd_getopt; optreset;
     errc; warnc; verrc; vwarnc;
     fgetln;
diff --git a/include/bsd/random.h b/include/bsd/random.h
index f3ab000..9999a8d 100644
--- a/include/bsd/random.h
+++ b/include/bsd/random.h
@@ -30,6 +30,8 @@
 #include <sys/types.h>
 
 u_int32_t arc4random();
+void arc4random_stir();
+void arc4random_addrandom(u_char *dat, int datlen);
 
 #endif
 
diff --git a/src/arc4random.c b/src/arc4random.c
index 22dae59..5c1837e 100644
--- a/src/arc4random.c
+++ b/src/arc4random.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.10 2004/03/24 14:44:57 gre
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <pthread.h>
 
 struct arc4_stream {
 	u_int8_t i;
@@ -39,8 +40,14 @@ struct arc4_stream {
 };
 
 #define	RANDOMDEV	"/dev/urandom"
+#ifdef __REENTRANT
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define	THREAD_LOCK()	pthread_mutex_lock(&arc4random_mtx)
+#define	THREAD_UNLOCK()	pthread_mutex_unlock(&arc4random_mtx)
+#else
 #define	THREAD_LOCK()
 #define	THREAD_UNLOCK()
+#endif
 
 static struct arc4_stream rs;
 static int rs_initialized;
@@ -155,6 +162,27 @@ arc4_check_stir(void)
 	}
 }
 
+void
+arc4random_stir()
+{
+	THREAD_LOCK();
+	arc4_check_init();
+	arc4_stir(&rs);
+	THREAD_UNLOCK();
+}
+
+void
+arc4random_addrandom(dat, datlen)
+	u_char *dat;
+	int     datlen;
+{
+	THREAD_LOCK();
+	arc4_check_init();
+	arc4_check_stir();
+	arc4_addrandom(&rs, dat, datlen);
+	THREAD_UNLOCK();
+}
+
 u_int32_t
 arc4random()
 {