diff options
author | Nick Mathewson <nickm@torproject.org> | 2015-11-25 10:30:58 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-11-25 22:29:59 -0500 |
commit | dedea28c2ef59eb86f5d9704e5609ae13fa8b3c2 (patch) | |
tree | 92ddba2410a8a80aad28734be47c78c460bbd6e6 | |
parent | 232ccc18c40f0d0302b2e21b0f67885c548f8e63 (diff) | |
download | tor-dedea28c2ef59eb86f5d9704e5609ae13fa8b3c2.tar.gz tor-dedea28c2ef59eb86f5d9704e5609ae13fa8b3c2.zip |
Make crypto_seed_rng() and crypto_rand() less scary.
These functions must really never fail; so have crypto_rand() assert
that it's working okay, and have crypto_seed_rng() demand that
callers check its return value. Also have crypto_seed_rng() check
RAND_status() before returning.
-rw-r--r-- | src/common/compat.h | 2 | ||||
-rw-r--r-- | src/common/crypto.c | 10 | ||||
-rw-r--r-- | src/common/crypto.h | 3 | ||||
-rw-r--r-- | src/or/main.c | 5 | ||||
-rw-r--r-- | src/test/bench.c | 5 | ||||
-rw-r--r-- | src/test/test_workqueue.c | 5 | ||||
-rw-r--r-- | src/test/testing_common.c | 5 |
7 files changed, 26 insertions, 9 deletions
diff --git a/src/common/compat.h b/src/common/compat.h index c7c468c754..c3d6abd07c 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -118,6 +118,7 @@ #define ATTR_CONST __attribute__((const)) #define ATTR_MALLOC __attribute__((malloc)) #define ATTR_NORETURN __attribute__((noreturn)) +#define ATTR_WUR __attribute__((warn_unused_result)) /* Alas, nonnull is not at present a good idea for us. We'd like to get * warnings when we pass NULL where we shouldn't (which nonnull does, albeit * spottily), but we don't want to tell the compiler to make optimizations @@ -153,6 +154,7 @@ #define ATTR_NORETURN #define ATTR_NONNULL(x) #define ATTR_UNUSED +#define ATTR_WUR #define PREDICT_LIKELY(exp) (exp) #define PREDICT_UNLIKELY(exp) (exp) #endif diff --git a/src/common/crypto.c b/src/common/crypto.c index 815c2ec0c5..b7dc4b86af 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -2358,7 +2358,7 @@ crypto_seed_rng(void) memwipe(buf, 0, sizeof(buf)); - if (rand_poll_ok || load_entropy_ok) + if ((rand_poll_ok || load_entropy_ok) && RAND_status() == 1) return 0; else return -1; @@ -2380,12 +2380,14 @@ int crypto_rand_unmocked(char *to, size_t n) { int r; + if (n == 0) + return 0; + tor_assert(n < INT_MAX); tor_assert(to); r = RAND_bytes((unsigned char*)to, (int)n); - if (r == 0) - crypto_log_errors(LOG_WARN, "generating random data"); - return (r == 1) ? 0 : -1; + tor_assert(r >= 0); + return 0; } /** Return a pseudorandom integer, chosen uniformly from the values diff --git a/src/common/crypto.h b/src/common/crypto.h index 6256f7346b..d2ced63bd5 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -16,6 +16,7 @@ #include <stdio.h> #include "torint.h" #include "testsupport.h" +#include "compat.h" /* Macro to create an arbitrary OpenSSL version number as used by @@ -258,7 +259,7 @@ int crypto_expand_key_material_rfc5869_sha256( uint8_t *key_out, size_t key_out_len); /* random numbers */ -int crypto_seed_rng(void); +int crypto_seed_rng(void) ATTR_WUR; MOCK_DECL(int,crypto_rand,(char *to, size_t n)); int crypto_rand_unmocked(char *to, size_t n); int crypto_strongest_rand(uint8_t *out, size_t out_len); diff --git a/src/or/main.c b/src/or/main.c index 9b3dbb5586..0f8d7ff3fa 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1389,7 +1389,10 @@ run_scheduled_events(time_t now) if (time_to.add_entropy < now) { if (time_to.add_entropy) { /* We already seeded once, so don't die on failure. */ - crypto_seed_rng(); + if (crypto_seed_rng() < 0) { + log_warn(LD_GENERAL, "Tried to re-seed RNG, but failed. We already " + "seeded once, though, so we won't exit here."); + } } /** How often do we add more entropy to OpenSSL's RNG pool? */ #define ENTROPY_INTERVAL (60*60) diff --git a/src/test/bench.c b/src/test/bench.c index 2a27377c80..70ec025b7b 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -643,7 +643,10 @@ main(int argc, const char **argv) reset_perftime(); - crypto_seed_rng(); + if (crypto_seed_rng() < 0) { + printf("Couldn't seed RNG; exiting.\n"); + return 1; + } crypto_init_siphash_key(); options = options_new(); init_logging(1); diff --git a/src/test/test_workqueue.c b/src/test/test_workqueue.c index 0d79733cf0..6edfd313cb 100644 --- a/src/test/test_workqueue.c +++ b/src/test/test_workqueue.c @@ -391,7 +391,10 @@ main(int argc, char **argv) init_logging(1); network_init(); crypto_global_init(1, NULL, NULL); - crypto_seed_rng(); + if (crypto_seed_rng() < 0) { + printf("Couldn't seed RNG; exiting.\n"); + return 1; + } rq = replyqueue_new(as_flags); tor_assert(rq); diff --git a/src/test/testing_common.c b/src/test/testing_common.c index 441024bd7d..2ea158fddd 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -272,7 +272,10 @@ main(int c, const char **v) return 1; } crypto_set_tls_dh_prime(); - crypto_seed_rng(); + if (crypto_seed_rng() < 0) { + printf("Couldn't seed RNG; exiting.\n"); + return 1; + } rep_hist_init(); network_init(); setup_directory(); |