]> granicus.if.org Git - libevent/commitdiff
Add evutil_secure_rng_set_urandom_device_file
authorNick Mathewson <nickm@torproject.org>
Tue, 6 Aug 2013 21:06:23 +0000 (17:06 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 6 Aug 2013 21:06:23 +0000 (17:06 -0400)
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
evutil_rand.c
include/event2/util.h

index 33ddc2c7efcbeda06b5bf3d78a27f75d06a655b5..048057031408d9e2f7f68af50ad55c1087ce1bd2 100644 (file)
@@ -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;
index 284e230e9e8672098cd6124fd98e002208c3e41d..3c2c81de4250f1bb610abeaf4e9a679be777d29c 100644 (file)
 #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 */
@@ -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)
 {
index 52d58ddc771f4a21add162705ae660eceeb8f491..18cbd80699b69362b3d1463beed864ed3db80a9b 100644 (file)
@@ -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