diff --git a/src/common/crypto.c b/src/common/crypto.c index 13095ad79d..49dc55a3e3 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -260,8 +260,23 @@ crypto_force_rand_ssleay(void) return 0; } -/** Initialize the parts of the crypto library that don't depend on - * settings or options. Return 0 on success, -1 on failure. +/** Set up the siphash key if we haven't already done so. */ +int +crypto_init_siphash_key(void) +{ + static int have_seeded_siphash = 0; + struct sipkey key; + if (have_seeded_siphash) + return 0; + + if (crypto_rand((char*) &key, sizeof(key)) < 0) + return -1; + siphash_set_global_key(&key); + have_seeded_siphash = 1; + return 0; +} + +/** Initialize the crypto library. Return 0 on success, -1 on failure. */ int crypto_early_init(void) @@ -295,6 +310,8 @@ crypto_early_init(void) if (crypto_seed_rng(1) < 0) return -1; + if (crypto_init_siphash_key() < 0) + return -1; } return 0; } @@ -379,7 +396,6 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir) evaluate_evp_for_aes(-1); evaluate_ctr_for_aes(); - } return 0; } diff --git a/src/common/crypto.h b/src/common/crypto.h index 79a8a1bda4..3666d5f9a3 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -257,6 +257,7 @@ uint64_t crypto_rand_uint64(uint64_t max); double crypto_rand_double(void); struct tor_weak_rng_t; void crypto_seed_weak_rng(struct tor_weak_rng_t *rng); +int crypto_init_siphash_key(void); char *crypto_random_hostname(int min_rand_len, int max_rand_len, const char *prefix, const char *suffix); diff --git a/src/ext/csiphash.c b/src/ext/csiphash.c index 9a8833d104..30be40b518 100644 --- a/src/ext/csiphash.c +++ b/src/ext/csiphash.c @@ -31,6 +31,9 @@ #include "torint.h" #include "siphash.h" +/* for tor_assert */ +#include "util.h" +/* for memcpy */ #include #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ @@ -137,11 +140,13 @@ static int the_siphash_key_is_set = 0; static struct sipkey the_siphash_key; uint64_t siphash24g(const void *src, unsigned long src_sz) { + tor_assert(the_siphash_key_is_set); return siphash24(src, src_sz, &the_siphash_key); } void siphash_set_global_key(const struct sipkey *key) { + tor_assert(! the_siphash_key_is_set); the_siphash_key.k0 = key->k0; the_siphash_key.k1 = key->k1; the_siphash_key_is_set = 1; diff --git a/src/test/bench.c b/src/test/bench.c index ae311b53cf..c9cc101b72 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -544,6 +544,7 @@ main(int argc, const char **argv) reset_perftime(); crypto_seed_rng(1); + crypto_init_siphash_key(); options = options_new(); init_logging(); options->command = CMD_RUN_UNITTESTS;