summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-11-25 10:30:58 -0500
committerNick Mathewson <nickm@torproject.org>2015-11-25 22:29:59 -0500
commitdedea28c2ef59eb86f5d9704e5609ae13fa8b3c2 (patch)
tree92ddba2410a8a80aad28734be47c78c460bbd6e6 /src
parent232ccc18c40f0d0302b2e21b0f67885c548f8e63 (diff)
downloadtor-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.
Diffstat (limited to 'src')
-rw-r--r--src/common/compat.h2
-rw-r--r--src/common/crypto.c10
-rw-r--r--src/common/crypto.h3
-rw-r--r--src/or/main.c5
-rw-r--r--src/test/bench.c5
-rw-r--r--src/test/test_workqueue.c5
-rw-r--r--src/test/testing_common.c5
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();