Skip to content

Commit

Permalink
Add evutil_secure_rng_set_urandom_device_file
Browse files Browse the repository at this point in the history
This experimental function is needed for some seccomp2 hackery to
work, and should have no effect for systems that don't use it.
  • Loading branch information
nmathewson committed Aug 6, 2013
1 parent b8f5980 commit 2bbb5d7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
40 changes: 26 additions & 14 deletions arc4random.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,29 +293,41 @@ arc4_seed_proc_sys_kernel_random_uuid(void)

#ifndef WIN32
#define TRY_SEED_URANDOM
static char *arc4random_urandom_filename = NULL;

static int arc4_seed_urandom_helper_(const char *fname)
{
unsigned char buf[ADD_ENTROPY];
int fd;
size_t n;

fd = evutil_open_closeonexec(fname, O_RDONLY, 0);
if (fd<0)
return -1;
n = read_all(fd, buf, sizeof(buf));
close(fd);
if (n != sizeof(buf))
return -1;
arc4_addrandom(buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
arc4_seeded_ok = 1;
return 0;
}

static int
arc4_seed_urandom(void)
{
/* This is adapted from Tor's crypto_seed_rng() */
static const char *filenames[] = {
"/dev/srandom", "/dev/urandom", "/dev/random", NULL
};
unsigned char buf[ADD_ENTROPY];
int fd, i;
size_t n;
int i;
if (arc4random_urandom_filename)
return arc4_seed_urandom_helper_(arc4random_urandom_filename);

for (i = 0; filenames[i]; ++i) {
fd = evutil_open_closeonexec(filenames[i], O_RDONLY, 0);
if (fd<0)
continue;
n = read_all(fd, buf, sizeof(buf));
close(fd);
if (n != sizeof(buf))
return -1;
arc4_addrandom(buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
arc4_seeded_ok = 1;
return 0;
if (arc4_seed_urandom_helper_(filenames[i]) == 0)
return 0;
}

return -1;
Expand Down
17 changes: 17 additions & 0 deletions evutil_rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
#include <stdlib.h>
#include <string.h>
int
evutil_secure_rng_set_urandom_device_file(char *fname)
{
(void) fname;
return -1;
}
int
evutil_secure_rng_init(void)
{
/* call arc4random() now to force it to self-initialize */
Expand Down Expand Up @@ -123,6 +129,17 @@ evutil_secure_rng_global_setup_locks_(const int enable_locks)
}
#endif

int
evutil_secure_rng_set_urandom_device_file(char *fname)
{
#ifdef TRY_SEED_URANDOM
_ARC4_LOCK();
arc4random_urandom_filename = fname;
_ARC4_UNLOCK();
#endif
return 0;
}

int
evutil_secure_rng_init(void)
{
Expand Down
14 changes: 14 additions & 0 deletions include/event2/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,20 @@ void evutil_secure_rng_get_bytes(void *buf, size_t n);
*/
int evutil_secure_rng_init(void);

/**
* Set a filename to use in place of /dev/urandom for seeding the secure
* PRNG. Return 0 on success, -1 on failure.
*
* Call this function BEFORE calling any other initialization or .
*
* (This string will _NOT_ be copied internally. Do not free it while any
* user of the secure RNG might be running. Don't pass anything other than a
* real /dev/...random device file here, or you might lose security.)
*
* This API is unstable, and might change in a future libevent version.
*/
int evutil_secure_rng_set_urandom_device_file(char *fname);

/** Seed the random number generator with extra random bytes.
You should almost never need to call this function; it should be
Expand Down

0 comments on commit 2bbb5d7

Please sign in to comment.