From 2bbb5d7612d3f9f12acb02e15127e676ff35d669 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 6 Aug 2013 17:06:23 -0400 Subject: [PATCH] Add evutil_secure_rng_set_urandom_device_file This experimental function is needed for some seccomp2 hackery to work, and should have no effect for systems that don't use it. --- arc4random.c | 40 ++++++++++++++++++++++++++-------------- evutil_rand.c | 17 +++++++++++++++++ include/event2/util.h | 14 ++++++++++++++ 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/arc4random.c b/arc4random.c index 33ddc2c7..04805703 100644 --- a/arc4random.c +++ b/arc4random.c @@ -293,6 +293,27 @@ 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) { @@ -300,22 +321,13 @@ arc4_seed_urandom(void) 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; diff --git a/evutil_rand.c b/evutil_rand.c index 284e230e..3c2c81de 100644 --- a/evutil_rand.c +++ b/evutil_rand.c @@ -43,6 +43,12 @@ #include #include 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 */ @@ -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) { diff --git a/include/event2/util.h b/include/event2/util.h index 52d58ddc..18cbd806 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -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 -- 2.50.1