diff options
author | Thomas Gschwantner <tharre3@gmail.com> | 2019-09-28 18:59:31 +0200 |
---|---|---|
committer | Thomas Gschwantner <tharre3@gmail.com> | 2019-12-11 06:22:17 +0100 |
commit | 4a12b8eff80d369ab3b220aa9d533faf88dd4df9 (patch) | |
tree | 46767f57b47084507b9c41c8cf990f72922689b3 | |
parent | Fixup client, including a lot of refactoring (diff) | |
download | wg-dynamic-4a12b8eff80d369ab3b220aa9d533faf88dd4df9.tar.xz wg-dynamic-4a12b8eff80d369ab3b220aa9d533faf88dd4df9.zip |
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).
-rw-r--r-- | lease.c | 8 | ||||
-rw-r--r-- | random.c | 25 | ||||
-rw-r--r-- | random.h | 1 |
3 files changed, 19 insertions, 15 deletions
@@ -237,7 +237,7 @@ struct wg_dynamic_lease *set_lease(wg_key pubkey, uint32_t leasetime, debug("IPv4 pool empty\n"); memset(&lease->ipv4, 0, sizeof(lease->ipv4)); } else { - uint32_t index = random_bounded(pool.total_ipv4 - 1); + uint32_t index = random_bounded(pool.total_ipv4); debug("new_lease(v4): %u of %u\n", index, pool.total_ipv4); ipp_addnth_v4(&pool, &lease->ipv4, index); @@ -262,10 +262,10 @@ struct wg_dynamic_lease *set_lease(wg_key pubkey, uint32_t leasetime, uint64_t index_l; uint32_t index_h; 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; } @@ -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; @@ -8,6 +8,7 @@ #include <stdint.h> +uint64_t random_u64(); uint64_t random_bounded(uint64_t bound); #endif |