[tor-commits] [tor/master] Add crypto_rand_int_range() and use it

nickm at torproject.org nickm at torproject.org
Thu Apr 23 13:21:49 UTC 2015


commit 3f413184728c1d7b441b8e54585c43220665218c
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Tue Apr 21 10:17:12 2015 -0400

    Add crypto_rand_int_range() and use it
    
    Incidently, this fixes a bug where the maximum value was never used when
    only using crypto_rand_int(). For instance this example below in
    rendservice.c never gets to INTRO_POINT_LIFETIME_MAX_SECONDS.
    
      int intro_point_lifetime_seconds =
        INTRO_POINT_LIFETIME_MIN_SECONDS +
        crypto_rand_int(INTRO_POINT_LIFETIME_MAX_SECONDS -
                        INTRO_POINT_LIFETIME_MIN_SECONDS);
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/common/crypto.c  |   21 ++++++++++++++++++++-
 src/common/crypto.h  |    1 +
 src/common/tortls.c  |    3 ++-
 src/or/entrynodes.c  |    6 ++++--
 src/or/main.c        |    2 +-
 src/or/rendservice.c |   10 ++++------
 src/or/router.c      |    4 +++-
 7 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/common/crypto.c b/src/common/crypto.c
index f05be2e..1c4eda9 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -2317,6 +2317,25 @@ crypto_rand_int(unsigned int max)
   }
 }
 
+/** Return a pseudorandom integer, chosen uniformly from the values between
+ * <b>min</b> and <b>max</b> inclusive.
+ *
+ * <b>min</b> MUST be between 0 and <b>max</b> - 1.
+ * <b>max</b> MUST be bigger than <b>min</b> and <= to INT_MAX.
+ */
+int
+crypto_rand_int_range(unsigned int min, unsigned int max)
+{
+  tor_assert(min <= max);
+  tor_assert(max <= INT_MAX);
+
+  /* The overflow is avoided here because crypto_rand_int() returns a value
+   * between 0 and (max - min - 1) with max being <= INT_MAX and min <= max.
+   * This is why we add 1 to the maximum value so we can actually get max as
+   * a return value. */
+  return min + crypto_rand_int(max - min + 1);
+}
+
 /** Return a pseudorandom 64-bit integer, chosen uniformly from the values
  * between 0 and <b>max</b>-1. */
 uint64_t
@@ -2379,7 +2398,7 @@ crypto_random_hostname(int min_rand_len, int max_rand_len, const char *prefix,
   if (min_rand_len > max_rand_len)
     min_rand_len = max_rand_len;
 
-  randlen = min_rand_len + crypto_rand_int(max_rand_len - min_rand_len + 1);
+  randlen = crypto_rand_int_range(min_rand_len, max_rand_len);
 
   prefixlen = strlen(prefix);
   resultlen = prefixlen + strlen(suffix) + randlen + 16;
diff --git a/src/common/crypto.h b/src/common/crypto.h
index b9c26a4..3de3c7e 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -254,6 +254,7 @@ int crypto_seed_rng(int startup);
 MOCK_DECL(int,crypto_rand,(char *to, size_t n));
 int crypto_strongest_rand(uint8_t *out, size_t out_len);
 int crypto_rand_int(unsigned int max);
+int crypto_rand_int_range(unsigned int min, unsigned int max);
 uint64_t crypto_rand_uint64(uint64_t max);
 double crypto_rand_double(void);
 struct tor_weak_rng_t;
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 32106eb..7809c1a 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -659,7 +659,8 @@ tor_tls_create_certificate(crypto_pk_t *rsa,
    * than having it start right now. Don't choose quite uniformly, since
    * then we might pick a time where we're about to expire. Lastly, be
    * sure to start on a day boundary. */
-  start_time = time(NULL) - crypto_rand_int(cert_lifetime) + 2*24*3600;
+  time_t now = time(NULL);
+  start_time = crypto_rand_int_range(now - cert_lifetime, now) + 2*24*3600;
   start_time -= start_time % (24*3600);
 
   tor_assert(rsa);
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 9663f34..9f07d5a 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -440,7 +440,8 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend,
    * don't all select them on the same day, and b) avoid leaving a
    * precise timestamp in the state file about when we first picked
    * this guard. For details, see the Jan 2010 or-dev thread. */
-  entry->chosen_on_date = time(NULL) - crypto_rand_int(3600*24*30);
+  time_t now = time(NULL);
+  entry->chosen_on_date = crypto_rand_int_range(now - 3600*24*30, now);
   entry->chosen_by_version = tor_strdup(VERSION);
 
   /* Are we picking this guard because all of our current guards are
@@ -1439,8 +1440,9 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg)
        }
      } else {
        if (state_version) {
+         time_t now = time(NULL);
+         e->chosen_on_date = crypto_rand_int_range(now - 3600*24*30, now);
          e->chosen_by_version = tor_strdup(state_version);
-         e->chosen_on_date = time(NULL) - crypto_rand_int(3600*24*30);
        }
      }
      if (e->path_bias_disabled && !e->bad_since)
diff --git a/src/or/main.c b/src/or/main.c
index 39c0f5c..b9009db 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1623,7 +1623,7 @@ run_scheduled_events(time_t now)
       time_to.check_for_correct_dns < now &&
       ! router_my_exit_policy_is_reject_star()) {
     if (!time_to.check_for_correct_dns) {
-      time_to.check_for_correct_dns = now + 60 + crypto_rand_int(120);
+      time_to.check_for_correct_dns = crypto_rand_int_range(now, now + 120) + 60;
     } else {
       dns_launch_correctness_checks();
       time_to.check_for_correct_dns = now + 12*3600 +
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index cf0352c..4b2331f 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -3133,9 +3133,8 @@ intro_point_should_expire_now(rend_intro_point_t *intro,
     /* This intro point has been published, but we haven't picked an
      * expiration time for it.  Pick one now. */
     int intro_point_lifetime_seconds =
-      INTRO_POINT_LIFETIME_MIN_SECONDS +
-      crypto_rand_int(INTRO_POINT_LIFETIME_MAX_SECONDS -
-                      INTRO_POINT_LIFETIME_MIN_SECONDS);
+      crypto_rand_int_range(INTRO_POINT_LIFETIME_MIN_SECONDS,
+                            INTRO_POINT_LIFETIME_MAX_SECONDS);
 
     /* Start the expiration timer now, rather than when the intro
      * point was first published.  There shouldn't be much of a time
@@ -3337,9 +3336,8 @@ rend_services_introduce(void)
       intro->time_to_expire = -1;
       intro->time_expiring = -1;
       intro->max_introductions =
-        INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS +
-        crypto_rand_int(INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS -
-                        INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS);
+        crypto_rand_int_range(INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS,
+                              INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS);
       smartlist_add(service->intro_nodes, intro);
       log_info(LD_REND, "Picked router %s as an intro point for %s.",
                safe_str_client(node_describe(node)),
diff --git a/src/or/router.c b/src/or/router.c
index b8bfd3c..afe533f 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -683,7 +683,9 @@ router_initialize_tls_context(void)
   if (!lifetime) { /* we should guess a good ssl cert lifetime */
 
     /* choose between 5 and 365 days, and round to the day */
-    lifetime = 5*24*3600 + crypto_rand_int(361*24*3600);
+    unsigned int five_days = 5*24*3600;
+    unsigned int one_year = 365*24*3600;
+    lifetime = crypto_rand_int_range(five_days, one_year);
     lifetime -= lifetime % (24*3600);
 
     if (crypto_rand_int(2)) {





More information about the tor-commits mailing list