Make RNG work when we have arc4random() but not arc4random_buf()

This commit is contained in:
Nick Mathewson 2010-02-13 00:11:44 -05:00
parent d4de062efc
commit 4ec8fea68e
3 changed files with 38 additions and 5 deletions

View File

@ -43,6 +43,10 @@
#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;

View 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

View File

@ -39,11 +39,39 @@
#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);
}