/src/tor/src/lib/intmath/weakrng.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2003, Roger Dingledine |
2 | | * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. |
3 | | * Copyright (c) 2007-2021, The Tor Project, Inc. */ |
4 | | /* See LICENSE for licensing information */ |
5 | | |
6 | | /** |
7 | | * \file weakrng.c |
8 | | * |
9 | | * \brief A weak but fast PRNG based on a linear congruential generator. |
10 | | * |
11 | | * We don't want to use the platform random(), since some of them are even |
12 | | * worse than this. |
13 | | **/ |
14 | | |
15 | | #include "lib/intmath/weakrng.h" |
16 | | #include "lib/err/torerr.h" |
17 | | |
18 | | #include <stdlib.h> |
19 | | |
20 | | /** Initialize the insecure RNG <b>rng</b> from a seed value <b>seed</b>. */ |
21 | | void |
22 | | tor_init_weak_random(tor_weak_rng_t *rng, unsigned seed) |
23 | 0 | { |
24 | 0 | rng->state = (uint32_t)(seed & 0x7fffffff); |
25 | 0 | } |
26 | | |
27 | | /** Return a randomly chosen value in the range 0..TOR_WEAK_RANDOM_MAX based |
28 | | * on the RNG state of <b>rng</b>. This entropy will not be cryptographically |
29 | | * strong; do not rely on it for anything an adversary should not be able to |
30 | | * predict. */ |
31 | | int32_t |
32 | | tor_weak_random(tor_weak_rng_t *rng) |
33 | 0 | { |
34 | | /* Here's a linear congruential generator. OpenBSD and glibc use these |
35 | | * parameters; they aren't too bad, and should have maximal period over the |
36 | | * range 0..INT32_MAX. We don't want to use the platform rand() or random(), |
37 | | * since some platforms have bad weak RNGs that only return values in the |
38 | | * range 0..INT16_MAX, which just isn't enough. */ |
39 | 0 | rng->state = (rng->state * 1103515245 + 12345) & 0x7fffffff; |
40 | 0 | return (int32_t) rng->state; |
41 | 0 | } |
42 | | |
43 | | /** Return a random number in the range [0 , <b>top</b>). {That is, the range |
44 | | * of integers i such that 0 <= i < top.} Chooses uniformly. Requires that |
45 | | * top is greater than 0. This randomness is not cryptographically strong; do |
46 | | * not rely on it for anything an adversary should not be able to predict. */ |
47 | | int32_t |
48 | | tor_weak_random_range(tor_weak_rng_t *rng, int32_t top) |
49 | 0 | { |
50 | | /* We don't want to just do tor_weak_random() % top, since random() is often |
51 | | * implemented with an LCG whose modulus is a power of 2, and those are |
52 | | * cyclic in their low-order bits. */ |
53 | 0 | int divisor, result; |
54 | 0 | raw_assert(top > 0); |
55 | 0 | divisor = TOR_WEAK_RANDOM_MAX / top; |
56 | 0 | do { |
57 | 0 | result = (int32_t)(tor_weak_random(rng) / divisor); |
58 | 0 | } while (result >= top); |
59 | 0 | return result; |
60 | 0 | } |