From 73ec28ebcaef074f51293e9e6c7088008025773c Mon Sep 17 00:00:00 2001 From: Thomas Gschwantner Date: Sat, 28 Sep 2019 18:59:31 +0200 Subject: Fix random_bounded() to always be in [0, bound) Previously random_bounded(1) would return values in [0, 1], while values > 1 would return [0, bound). --- lease.c | 8 ++++---- random.c | 25 ++++++++++++++----------- random.h | 1 + 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lease.c b/lease.c index 8a48a27..a54298d 100644 --- a/lease.c +++ b/lease.c @@ -114,7 +114,7 @@ struct wg_dynamic_lease *new_lease(wg_key pubkey, uint32_t leasetime, if (wants_ipv4) { if (!ipv4) { - index = random_bounded(pool.total_ipv4 - 1); + index = random_bounded(pool.total_ipv4); debug("new_lease(v4): %u of %u\n", index, pool.total_ipv4); @@ -130,10 +130,10 @@ struct wg_dynamic_lease *new_lease(wg_key pubkey, uint32_t leasetime, if (wants_ipv6) { if (!ipv6) { if (pool.totalh_ipv6 > 0) { - index_l = random_bounded(UINT64_MAX); - index_h = random_bounded(pool.totalh_ipv6 - 1); + index_l = random_u64(); + index_h = random_bounded(pool.totalh_ipv6); } else { - index_l = random_bounded(pool.totall_ipv6 - 1); + index_l = random_bounded(pool.totall_ipv6); index_h = 0; } diff --git a/random.c b/random.c index eedb52f..ba8acfe 100644 --- a/random.c +++ b/random.c @@ -68,24 +68,27 @@ get_random_bytes(uint8_t *out, size_t len) return i == len; } -uint64_t random_bounded(uint64_t bound) +uint64_t random_u64() { uint64_t ret; + if (!get_random_bytes((uint8_t *)&ret, sizeof(ret))) + fatal("get_random_bytes()"); - if (bound == 0) - return 0; + return ret; +} - if (bound == 1) { - if (!get_random_bytes((uint8_t *)&ret, sizeof(ret))) - fatal("get_random_bytes()"); - return (ret > 0x7FFFFFFFFFFFFFFF) ? 1 : 0; - } +/* Returns a random number [0, bound) (exclusive) */ +uint64_t random_bounded(uint64_t bound) +{ + uint64_t ret, max_mod_bound; + + if (bound < 2) + return 0; - const uint64_t max_mod_bound = (1 + ~bound) % bound; + max_mod_bound = (1 + ~bound) % bound; do { - if (!get_random_bytes((uint8_t *)&ret, sizeof(ret))) - fatal("get_random_bytes()"); + ret = random_u64(); } while (ret < max_mod_bound); return ret % bound; diff --git a/random.h b/random.h index 04271a4..9654b2c 100644 --- a/random.h +++ b/random.h @@ -8,6 +8,7 @@ #include +uint64_t random_u64(); uint64_t random_bounded(uint64_t bound); #endif -- cgit v1.2.3-59-g8ed1b