diff --git a/arc4random.c b/arc4random.c index 2353626e..b14b723d 100644 --- a/arc4random.c +++ b/arc4random.c @@ -43,6 +43,10 @@ #define ARC4RANDOM_EXPORT #endif +#ifndef ARC4RANDOM_UINT32 +#define ARC4RANDOM_UINT32 uint32_t +#endif + #ifndef ARC4RANDOM_NO_INCLUDES #ifdef WIN32 #include @@ -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; diff --git a/configure.in b/configure.in index 7f911e5a..84976170 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/evutil_rand.c b/evutil_rand.c index 8639f092..b86ecd81 100644 --- a/evutil_rand.c +++ b/evutil_rand.c @@ -39,11 +39,39 @@ #ifdef _EVENT_HAVE_ARC4RANDOM #include +#include 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); }