From 20fda296c5faada095c7122244ecd6beff1c0931 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 3 May 2010 13:00:00 -0400 Subject: [PATCH] Try /proc on Linux as entropy fallback; use sysctl as last resort It turns out that the happy fun Linux kernel is deprecating sysctl, and using sysctl to fetch entropy will spew messages in the kernel logs. Let's not do that. Instead, let's call sysctl for our entropy only when all other means fail. Additionally, let's add another means, and try /proc/sys/kernel/random/uuid if /dev/urandom fails. --- arc4random.c | 59 ++++++++++++++++++++++++++++++++++++++++++++----- evutil.c | 24 ++++++++++++++++++++ util-internal.h | 2 ++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/arc4random.c b/arc4random.c index 5e044643..c75b5d79 100644 --- a/arc4random.c +++ b/arc4random.c @@ -201,6 +201,49 @@ arc4_seed_sysctl_linux(void) } #endif +#ifdef __linux__ +#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID +static int +arc4_seed_proc_sys_kernel_random_uuid(void) +{ + /* Occasionally, somebody will make /proc/sys accessible in a chroot, + * but not /dev/urandom. Let's try /proc/sys/kernel/random/uuid. + * Its format is stupid, so we need to decode it from hex. + */ + int fd; + char buf[128]; + unsigned char entropy[64]; + int bytes, n, i, nybbles; + for (bytes = 0; bytestv_sec * 1000) + ((tv->tv_usec + 999) / 1000); } +int +evutil_hex_char_to_int(char c) +{ + switch(c) + { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'A': case 'a': return 10; + case 'B': case 'b': return 11; + case 'C': case 'c': return 12; + case 'D': case 'd': return 13; + case 'E': case 'e': return 14; + case 'F': case 'f': return 15; + } + return -1; +} diff --git a/util-internal.h b/util-internal.h index 60d4dfee..32cd88cb 100644 --- a/util-internal.h +++ b/util-internal.h @@ -223,6 +223,8 @@ const char *evutil_format_sockaddr_port(const struct sockaddr *sa, char *out, si long evutil_tv_to_msec(const struct timeval *tv); +int evutil_hex_char_to_int(char c); + #ifdef __cplusplus } #endif