commit fe173ce0bce9b54271d32e0b46a9f6d891b16970 Author: Nick Mathewson nickm@torproject.org Date: Mon Mar 18 09:59:18 2019 -0400
Add a testing PRNG replacement that returns canned data. --- src/test/rng_test_helpers.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ src/test/rng_test_helpers.h | 5 ++++ 2 files changed, 63 insertions(+)
diff --git a/src/test/rng_test_helpers.c b/src/test/rng_test_helpers.c index 4384d2bb3..424aedd19 100644 --- a/src/test/rng_test_helpers.c +++ b/src/test/rng_test_helpers.c @@ -99,6 +99,10 @@ testing_enable_reproducible_rng(void) * Replace our crypto_rand() prng with a variant that generates all of its * output deterministically from a fixed seed. This variant is mainly useful * for cases when we don't want coverage to change between runs. + * + * USAGE NOTE: Test correctness SHOULD NOT depend on the specific output of + * this "rng". If you need a specific output, use + * testing_enable_prefilled_rng() instead. **/ void testing_enable_deterministic_rng(void) @@ -109,6 +113,59 @@ testing_enable_deterministic_rng(void) enable_deterministic_rng_impl(quotation, sizeof(quotation)); }
+static uint8_t *prefilled_rng_buffer = NULL; +static size_t prefilled_rng_buflen; +static size_t prefilled_rng_idx; + +/** + * crypto_rand() replacement that returns canned data. + **/ +static void +crypto_rand_prefilled(char *out, size_t n) +{ + tor_mutex_acquire(rng_mutex); + while (n) { + size_t n_to_copy = MIN(prefilled_rng_buflen - prefilled_rng_idx, n); + memcpy(out, prefilled_rng_buffer + prefilled_rng_idx, n_to_copy); + out += n_to_copy; + n -= n_to_copy; + prefilled_rng_idx += n_to_copy; + + if (prefilled_rng_idx == prefilled_rng_buflen) { + prefilled_rng_idx = 0; + } + } + tor_mutex_release(rng_mutex); +} + +/** + * Replace our crypto_rand() prng with a variant that yields output + * from a buffer. If it reaches the end of the buffer, it starts over. + **/ +void +testing_enable_prefilled_rng(const void *buffer, size_t buflen) +{ + tor_assert(buflen > 0); + rng_mutex = tor_mutex_new(); + + prefilled_rng_buffer = tor_memdup(buffer, buflen); + prefilled_rng_buflen = buflen; + prefilled_rng_idx = 0; + + MOCK(crypto_rand, crypto_rand_prefilled); +} + +/** + * Reset the position in the prefilled RNG buffer to the start. + */ +void +testing_prefilled_rng_reset(void) +{ + tor_mutex_acquire(rng_mutex); + prefilled_rng_idx = 0; + tor_mutex_release(rng_mutex); +} + /** * Undo the overrides for our PRNG. To be used at the end of testing. **/ @@ -116,6 +173,7 @@ void testing_disable_rng_override(void) { crypto_xof_free(rng_xof); + tor_free(prefilled_rng_buffer); UNMOCK(crypto_rand); tor_mutex_free(rng_mutex); } diff --git a/src/test/rng_test_helpers.h b/src/test/rng_test_helpers.h index be95ec9d1..907099450 100644 --- a/src/test/rng_test_helpers.h +++ b/src/test/rng_test_helpers.h @@ -8,6 +8,9 @@
void testing_enable_deterministic_rng(void); void testing_enable_reproducible_rng(void); +void testing_enable_prefilled_rng(const void *buffer, size_t buflen); + +void testing_prefilled_rng_reset(void);
void testing_disable_rng_override(void);
@@ -15,6 +18,8 @@ void testing_disable_rng_override(void); testing_disable_rng_override() #define testing_disable_deterministic_rng() \ testing_disable_rng_override() +#define testing_disable_prefilled_rng() \ + testing_disable_rng_override()
void testing_dump_reproducible_rng_seed(void);
tor-commits@lists.torproject.org