Make RNG work when we have arc4random() but not arc4random_buf()
authorNick Mathewson <nickm@torproject.org>
Sat, 13 Feb 2010 05:11:44 +0000 (00:11 -0500)
committerNick Mathewson <nickm@torproject.org>
Sat, 13 Feb 2010 05:11:44 +0000 (00:11 -0500)
arc4random.c
configure.in
evutil_rand.c

index 2353626e182039f50ae977c3e6df2b3731a8b79f..b14b723d128b62df0dd6f14b844672d12b985f78 100644 (file)
 #define ARC4RANDOM_EXPORT
 #endif
 
+#ifndef ARC4RANDOM_UINT32
+#define ARC4RANDOM_UINT32 uint32_t
+#endif
+
 #ifndef ARC4RANDOM_NO_INCLUDES
 #ifdef WIN32
 #include <wincrypt.h>
@@ -283,10 +287,10 @@ arc4random_addrandom(const unsigned char *dat, int datlen)
 #endif
 
 #ifndef ARC4RANDOM_NORANDOM
-ARC4RANDOM_EXPORT unsigned int
+ARC4RANDOM_EXPORT ARC4RANDOM_UINT32
 arc4random(void)
 {
-       unsigned int val;
+       ARC4RANDOM_UINT32 val;
        _ARC4_LOCK();
        arc4_count -= 4;
        arc4_stir_if_needed();
@@ -324,7 +328,7 @@ arc4random_buf(void *_buf, size_t n)
 ARC4RANDOM_EXPORT unsigned int
 arc4random_uniform(unsigned int upper_bound)
 {
-       unsigned int r, min;
+       ARC4RANDOM_UINT32 r, min;
 
        if (upper_bound < 2)
                return 0;
index 7f911e5a7e4059496872ad73e06b121ac3fc148b..849761701d493cbc5559d6db779bef1850a8db7f 100644 (file)
@@ -183,7 +183,7 @@ AC_C_INLINE
 AC_HEADER_TIME
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop inet_pton signal sigaction strtoll inet_aton pipe eventfd sendfile mmap splice arc4random issetugid geteuid getegid getservbyname getprotobynumber setenv unsetenv putenv)
+AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop inet_pton signal sigaction strtoll inet_aton pipe eventfd sendfile mmap splice arc4random arc4random_buf issetugid geteuid getegid getservbyname getprotobynumber setenv unsetenv putenv)
 
 # Check for gethostbyname_r in all its glorious incompatible versions.
 #   (This is cut-and-pasted from Tor, which based its logic on
index 8639f092a256c7b92794b6704ed4ac2a5caea965..b86ecd8147c683c934e5ea3618511bee5487d7fe 100644 (file)
 
 #ifdef _EVENT_HAVE_ARC4RANDOM
 #include <stdlib.h>
+#include <string.h>
 int
 evutil_secure_rng_init(void)
 {
        return 0;
 }
+
+#ifndef _EVENT_HAVE_ARC4RANDOM_BUF
+static void
+arc4random_buf(void *buf, size_t n)
+{
+       unsigned char *b = buf;
+       /* Make sure that we start out with b at a 4-byte alignment; plenty
+        * of CPUs care about this for 32-bit access. */
+       if (n >= 4 && ((ev_uintptr_t)b) & 3) {
+               ev_uint32_t u = arc4random();
+               int n_bytes = 4 - (((ev_uintptr_t)b) & 3);
+               memcpy(b, &u, n_bytes);
+               b += n_bytes;
+               n -= n_bytes;
+       }
+       while (n >= 4) {
+               *(ev_uint32_t*)b = arc4random();
+               b += 4;
+               n -= 4;
+       }
+       if (n) {
+               ev_uint32_t u = arc4random();
+               memcpy(b, &u, n);
+       }
+}
+#endif
+
 #else /* !_EVENT_HAVE_ARC4RANDOM { */
 
 #ifdef _EVENT_ssize_t
@@ -54,6 +82,7 @@ evutil_secure_rng_init(void)
 #define _ARC4_UNLOCK() EVLOCK_UNLOCK(arc4rand_lock, 0)
 static void *arc4rand_lock;
 
+#define ARC4RANDOM_UINT32 ev_uint32_t
 #define ARC4RANDOM_NOSTIR
 #define ARC4RANDOM_NORANDOM
 #define ARC4RANDOM_NOUNIFORM
@@ -87,6 +116,6 @@ evutil_secure_rng_get_bytes(void *buf, size_t n)
 void
 evutil_secure_rng_add_bytes(const char *buf, size_t n)
 {
-       arc4random_addrandom((const unsigned char*)buf, n);
+       arc4random_addrandom((unsigned char*)buf, n);
 }