aboutsummaryrefslogtreecommitdiff
path: root/src/or/cpuworker.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-02-08 16:28:05 -0500
committerNick Mathewson <nickm@torproject.org>2013-02-08 16:28:05 -0500
commit8cdd8b83539e57fb1891cce5b527dda335ab1452 (patch)
tree656a1bbdfe0c240a810333c803b3c2a718cf7a13 /src/or/cpuworker.c
parentfd1c2a13e7558086732288eb1a4f52aef2edeb2f (diff)
downloadtor-8cdd8b83539e57fb1891cce5b527dda335ab1452.tar
tor-8cdd8b83539e57fb1891cce5b527dda335ab1452.tar.gz
Fix numerous problems with Tor's weak RNG.
We need a weak RNG in a couple of places where the strong RNG is both needless and too slow. We had been using the weak RNG from our platform's libc implementation, but that was problematic (because many platforms have exceptionally horrible weak RNGs -- like, ones that only return values between 0 and SHORT_MAX) and because we were using it in a way that was wrong for LCG-based weak RNGs. (We were counting on the low bits of the LCG output to be as random as the high ones, which isn't true.) This patch adds a separate type for a weak RNG, adds an LCG implementation for it, and uses that exclusively where we had been using the platform weak RNG.
Diffstat (limited to 'src/or/cpuworker.c')
-rw-r--r--src/or/cpuworker.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index b5740f091..6b52f3b5d 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -196,8 +196,10 @@ static uint64_t onionskins_usec_roundtrip[MAX_ONION_HANDSHAKE_TYPE+1];
* time. (microseconds) */
#define MAX_BELIEVABLE_ONIONSKIN_DELAY (2*1000*1000)
+static tor_weak_rng_t request_sample_rng = TOR_WEAK_RNG_INIT;
+
/** Return true iff we'd like to measure a handshake of type
- * <b>onionskin_type</b>. */
+ * <b>onionskin_type</b>. Call only from the main thread. */
static int
should_time_request(uint16_t onionskin_type)
{
@@ -210,7 +212,7 @@ should_time_request(uint16_t onionskin_type)
return 1;
/** Otherwise, measure with P=1/128. We avoid doing this for every
* handshake, since the measurement itself can take a little time. */
- return tor_weak_random() < (TOR_RAND_MAX/128);
+ return tor_weak_random_one_in_n(&request_sample_rng, 128);
}
/** Return an estimate of how many microseconds we will need for a single
@@ -560,6 +562,7 @@ static void
spawn_enough_cpuworkers(void)
{
int num_cpuworkers_needed = get_num_cpus(get_options());
+ int reseed = 0;
if (num_cpuworkers_needed < MIN_CPUWORKERS)
num_cpuworkers_needed = MIN_CPUWORKERS;
@@ -572,7 +575,11 @@ spawn_enough_cpuworkers(void)
return;
}
num_cpuworkers++;
+ reseed++;
}
+
+ if (reseed)
+ crypto_seed_weak_rng(&request_sample_rng);
}
/** Take a pending task from the queue and assign it to 'cpuworker'. */