mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Merge branch 'tor-github/pr/909'
Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
commit
e543c4e20c
5
changes/ticket29732
Normal file
5
changes/ticket29732
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
o Minor features (testing):
|
||||||
|
- Tor's unit test code now contains a standard set of functions to
|
||||||
|
replace the PRNG with a deterministic or reproducible version for
|
||||||
|
testing. Previously, various tests implemented this in various ways.
|
||||||
|
Implements ticket 29732.
|
@ -92,6 +92,10 @@ void crypto_rand_fast_shutdown(void);
|
|||||||
#if defined(TOR_UNIT_TESTS)
|
#if defined(TOR_UNIT_TESTS)
|
||||||
/* Used for white-box testing */
|
/* Used for white-box testing */
|
||||||
size_t crypto_fast_rng_get_bytes_used_per_stream(void);
|
size_t crypto_fast_rng_get_bytes_used_per_stream(void);
|
||||||
|
/* For deterministic prng implementations */
|
||||||
|
void crypto_fast_rng_disable_reseed(crypto_fast_rng_t *rng);
|
||||||
|
/* To override the prng for testing. */
|
||||||
|
crypto_fast_rng_t *crypto_replace_thread_fast_rng(crypto_fast_rng_t *rng);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CRYPTO_RAND_PRIVATE
|
#ifdef CRYPTO_RAND_PRIVATE
|
||||||
|
@ -95,8 +95,13 @@ CTASSERT(KEY_BITS == 128 || KEY_BITS == 192 || KEY_BITS == 256);
|
|||||||
|
|
||||||
struct crypto_fast_rng_t {
|
struct crypto_fast_rng_t {
|
||||||
/** How many more fills does this buffer have before we should mix
|
/** How many more fills does this buffer have before we should mix
|
||||||
* in the output of crypto_rand()? */
|
* in the output of crypto_strongest_rand()?
|
||||||
uint16_t n_till_reseed;
|
*
|
||||||
|
* This value may be negative if unit tests are enabled. If so, it
|
||||||
|
* indicates that we should never mix in extra data from
|
||||||
|
* crypto_strongest_rand().
|
||||||
|
*/
|
||||||
|
int16_t n_till_reseed;
|
||||||
/** How many bytes are remaining in cbuf.bytes? */
|
/** How many bytes are remaining in cbuf.bytes? */
|
||||||
uint16_t bytes_left;
|
uint16_t bytes_left;
|
||||||
#ifdef CHECK_PID
|
#ifdef CHECK_PID
|
||||||
@ -181,6 +186,18 @@ crypto_fast_rng_new_from_seed(const uint8_t *seed)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
/**
|
||||||
|
* Unit tests only: prevent a crypto_fast_rng_t from ever mixing in more
|
||||||
|
* entropy.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
crypto_fast_rng_disable_reseed(crypto_fast_rng_t *rng)
|
||||||
|
{
|
||||||
|
rng->n_till_reseed = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: create a crypto_cipher_t object from SEED_LEN bytes of
|
* Helper: create a crypto_cipher_t object from SEED_LEN bytes of
|
||||||
* input. The first KEY_LEN bytes are used as the stream cipher's key,
|
* input. The first KEY_LEN bytes are used as the stream cipher's key,
|
||||||
@ -193,19 +210,13 @@ cipher_from_seed(const uint8_t *seed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: refill the seed bytes and output buffer of <b>rng</b>, using
|
* Helper: mix additional entropy into <b>rng</b> by using our XOF to mix the
|
||||||
* the input seed bytes as input (key and IV) for the stream cipher.
|
* old value for the seed with some additional bytes from
|
||||||
*
|
* crypto_strongest_rand().
|
||||||
* If the n_till_reseed counter has reached zero, mix more random bytes into
|
|
||||||
* the seed before refilling the buffer.
|
|
||||||
**/
|
**/
|
||||||
static void
|
static void
|
||||||
crypto_fast_rng_refill(crypto_fast_rng_t *rng)
|
crypto_fast_rng_add_entopy(crypto_fast_rng_t *rng)
|
||||||
{
|
{
|
||||||
if (rng->n_till_reseed-- == 0) {
|
|
||||||
/* It's time to reseed the RNG. We'll do this by using our XOF to mix the
|
|
||||||
* old value for the seed with some additional bytes from
|
|
||||||
* crypto_strongest_rand(). */
|
|
||||||
crypto_xof_t *xof = crypto_xof_new();
|
crypto_xof_t *xof = crypto_xof_new();
|
||||||
crypto_xof_add_bytes(xof, rng->buf.seed, SEED_LEN);
|
crypto_xof_add_bytes(xof, rng->buf.seed, SEED_LEN);
|
||||||
{
|
{
|
||||||
@ -216,8 +227,31 @@ crypto_fast_rng_refill(crypto_fast_rng_t *rng)
|
|||||||
}
|
}
|
||||||
crypto_xof_squeeze_bytes(xof, rng->buf.seed, SEED_LEN);
|
crypto_xof_squeeze_bytes(xof, rng->buf.seed, SEED_LEN);
|
||||||
crypto_xof_free(xof);
|
crypto_xof_free(xof);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper: refill the seed bytes and output buffer of <b>rng</b>, using
|
||||||
|
* the input seed bytes as input (key and IV) for the stream cipher.
|
||||||
|
*
|
||||||
|
* If the n_till_reseed counter has reached zero, mix more random bytes into
|
||||||
|
* the seed before refilling the buffer.
|
||||||
|
**/
|
||||||
|
static void
|
||||||
|
crypto_fast_rng_refill(crypto_fast_rng_t *rng)
|
||||||
|
{
|
||||||
|
rng->n_till_reseed--;
|
||||||
|
if (rng->n_till_reseed == 0) {
|
||||||
|
/* It's time to reseed the RNG. */
|
||||||
|
crypto_fast_rng_add_entopy(rng);
|
||||||
rng->n_till_reseed = RESEED_AFTER;
|
rng->n_till_reseed = RESEED_AFTER;
|
||||||
|
} else if (rng->n_till_reseed < 0) {
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
/* Reseeding is disabled for testing; never do it on this prng. */
|
||||||
|
rng->n_till_reseed = -1;
|
||||||
|
#else
|
||||||
|
/* If testing is disabled, this shouldn't be able to become negative. */
|
||||||
|
tor_assert_unreached();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* Now fill rng->buf with output from our stream cipher, initialized from
|
/* Now fill rng->buf with output from our stream cipher, initialized from
|
||||||
* that seed value. */
|
* that seed value. */
|
||||||
@ -363,6 +397,20 @@ destroy_thread_fast_rng(void)
|
|||||||
tor_threadlocal_set(&thread_rng, NULL);
|
tor_threadlocal_set(&thread_rng, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
/**
|
||||||
|
* Replace the current thread's rng with <b>rng</b>. For use by the
|
||||||
|
* unit tests only. Returns the previous thread rng.
|
||||||
|
**/
|
||||||
|
crypto_fast_rng_t *
|
||||||
|
crypto_replace_thread_fast_rng(crypto_fast_rng_t *rng)
|
||||||
|
{
|
||||||
|
crypto_fast_rng_t *old_rng = tor_threadlocal_get(&thread_rng);
|
||||||
|
tor_threadlocal_set(&thread_rng, rng);
|
||||||
|
return old_rng;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the global thread-local key that will be used to keep track
|
* Initialize the global thread-local key that will be used to keep track
|
||||||
* of per-thread fast RNG instances. Called from the crypto subsystem's
|
* of per-thread fast RNG instances. Called from the crypto subsystem's
|
||||||
|
@ -89,6 +89,7 @@ src_test_test_SOURCES += \
|
|||||||
src/test/log_test_helpers.c \
|
src/test/log_test_helpers.c \
|
||||||
src/test/hs_test_helpers.c \
|
src/test/hs_test_helpers.c \
|
||||||
src/test/rend_test_helpers.c \
|
src/test/rend_test_helpers.c \
|
||||||
|
src/test/rng_test_helpers.c \
|
||||||
src/test/test.c \
|
src/test/test.c \
|
||||||
src/test/test_accounting.c \
|
src/test/test_accounting.c \
|
||||||
src/test/test_addr.c \
|
src/test/test_addr.c \
|
||||||
@ -211,6 +212,7 @@ endif
|
|||||||
src_test_test_slow_SOURCES =
|
src_test_test_slow_SOURCES =
|
||||||
if UNITTESTS_ENABLED
|
if UNITTESTS_ENABLED
|
||||||
src_test_test_slow_SOURCES += \
|
src_test_test_slow_SOURCES += \
|
||||||
|
src/test/rng_test_helpers.c \
|
||||||
src/test/test_slow.c \
|
src/test/test_slow.c \
|
||||||
src/test/test_crypto_slow.c \
|
src/test/test_crypto_slow.c \
|
||||||
src/test/test_process_slow.c \
|
src/test/test_process_slow.c \
|
||||||
@ -319,6 +321,7 @@ noinst_HEADERS+= \
|
|||||||
src/test/hs_test_helpers.h \
|
src/test/hs_test_helpers.h \
|
||||||
src/test/log_test_helpers.h \
|
src/test/log_test_helpers.h \
|
||||||
src/test/rend_test_helpers.h \
|
src/test/rend_test_helpers.h \
|
||||||
|
src/test/rng_test_helpers.h \
|
||||||
src/test/test.h \
|
src/test/test.h \
|
||||||
src/test/ptr_helpers.h \
|
src/test/ptr_helpers.h \
|
||||||
src/test/test_helpers.h \
|
src/test/test_helpers.h \
|
||||||
|
226
src/test/rng_test_helpers.c
Normal file
226
src/test/rng_test_helpers.c
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/* Copyright (c) 2018-2019, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file rng_test_helpers.c
|
||||||
|
* \brief Helpers for overriding PRNGs during unit tests.
|
||||||
|
*
|
||||||
|
* We define two PRNG overrides: a "reproducible PRNG" where the seed is
|
||||||
|
* chosen randomly but the stream can be replayed later on in case a bug is
|
||||||
|
* found, and a "deterministic PRNG" where the seed is fixed in the unit
|
||||||
|
* tests.
|
||||||
|
*
|
||||||
|
* Obviously, this code is testing-only.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "orconfig.h"
|
||||||
|
#include "core/or/or.h"
|
||||||
|
|
||||||
|
#include "lib/crypt_ops/crypto_rand.h"
|
||||||
|
|
||||||
|
#include "test/rng_test_helpers.h"
|
||||||
|
|
||||||
|
#ifndef TOR_UNIT_TESTS
|
||||||
|
#error "No. Never link this code into Tor proper."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True iff the RNG is currently replaced. Prevents double-replacement.
|
||||||
|
**/
|
||||||
|
static bool rng_is_replaced = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex to protect deterministic prng.
|
||||||
|
*
|
||||||
|
* Note that if you actually _use_ the prng from two threads at the same time,
|
||||||
|
* the results will probably be nondeterministic anyway.
|
||||||
|
*/
|
||||||
|
static tor_mutex_t *rng_mutex = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached old value for the thread prng.
|
||||||
|
**/
|
||||||
|
static crypto_fast_rng_t *stored_fast_rng = NULL;
|
||||||
|
|
||||||
|
/** replacement for crypto_strongest_rand that delegates to crypto_rand. */
|
||||||
|
static void
|
||||||
|
mock_crypto_strongest_rand(uint8_t *out, size_t len)
|
||||||
|
{
|
||||||
|
crypto_rand((char *)out, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the seed of the deterministic randomness. */
|
||||||
|
static uint8_t rng_seed[16];
|
||||||
|
static crypto_xof_t *rng_xof = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the seed for our PRNG to stdout. We use this when we're
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
testing_dump_reproducible_rng_seed(void)
|
||||||
|
{
|
||||||
|
printf("\n"
|
||||||
|
"Seed: %s\n",
|
||||||
|
hex_str((const char*)rng_seed, sizeof(rng_seed)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Produce deterministic randomness for the stochastic tests using the global
|
||||||
|
* rng_xof output.
|
||||||
|
*
|
||||||
|
* This function produces deterministic data over multiple calls iff it's
|
||||||
|
* called in the same call order with the same 'n' parameter.
|
||||||
|
* If not, outputs will deviate. */
|
||||||
|
static void
|
||||||
|
crypto_rand_deterministic(char *out, size_t n)
|
||||||
|
{
|
||||||
|
tor_assert(rng_xof);
|
||||||
|
tor_mutex_acquire(rng_mutex);
|
||||||
|
crypto_xof_squeeze_bytes(rng_xof, (uint8_t*)out, n);
|
||||||
|
tor_mutex_release(rng_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation helper: override our crypto_rand() PRNG with a given seed of
|
||||||
|
* length <b>seed_len</b>. Overlong seeds are truncated; short ones are
|
||||||
|
* padded.
|
||||||
|
**/
|
||||||
|
static void
|
||||||
|
enable_deterministic_rng_impl(const uint8_t *seed, size_t seed_len)
|
||||||
|
{
|
||||||
|
tor_assert(!rng_is_replaced);
|
||||||
|
tor_assert(crypto_rand == crypto_rand__real);
|
||||||
|
|
||||||
|
memset(rng_seed, 0, sizeof(rng_seed));
|
||||||
|
memcpy(rng_seed, seed, MIN(seed_len, sizeof(rng_seed)));
|
||||||
|
|
||||||
|
rng_mutex = tor_mutex_new();
|
||||||
|
|
||||||
|
crypto_xof_free(rng_xof);
|
||||||
|
rng_xof = crypto_xof_new();
|
||||||
|
crypto_xof_add_bytes(rng_xof, rng_seed, sizeof(rng_seed));
|
||||||
|
MOCK(crypto_rand, crypto_rand_deterministic);
|
||||||
|
MOCK(crypto_strongest_rand_, mock_crypto_strongest_rand);
|
||||||
|
|
||||||
|
uint8_t fast_rng_seed[CRYPTO_FAST_RNG_SEED_LEN];
|
||||||
|
memset(fast_rng_seed, 0xff, sizeof(fast_rng_seed));
|
||||||
|
memcpy(fast_rng_seed, rng_seed, MIN(sizeof(rng_seed),
|
||||||
|
sizeof(fast_rng_seed)));
|
||||||
|
crypto_fast_rng_t *fast_rng = crypto_fast_rng_new_from_seed(fast_rng_seed);
|
||||||
|
crypto_fast_rng_disable_reseed(fast_rng);
|
||||||
|
stored_fast_rng = crypto_replace_thread_fast_rng(fast_rng);
|
||||||
|
|
||||||
|
rng_is_replaced = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace our get_thread_fast_rng(), crypto_rand() and
|
||||||
|
* crypto_strongest_rand() prngs with a variant that generates all of its
|
||||||
|
* output deterministically from a randomly chosen seed. In the event of an
|
||||||
|
* error, you can log the seed later on with
|
||||||
|
* testing_dump_reproducible_rng_seed.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
testing_enable_reproducible_rng(void)
|
||||||
|
{
|
||||||
|
uint8_t seed[16];
|
||||||
|
crypto_rand((char*)seed, sizeof(seed));
|
||||||
|
enable_deterministic_rng_impl(seed, sizeof(seed));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace our get_thread_fast_rng(), crypto_rand() and
|
||||||
|
* crypto_strongest_rand() prngs 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)
|
||||||
|
{
|
||||||
|
static const uint8_t quotation[] =
|
||||||
|
"What will it be? A tree? A weed? "
|
||||||
|
"Each one is started from a seed."; // -- Mary Ann Hoberman
|
||||||
|
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() and crypto_strongest_rand() prngs with a variant
|
||||||
|
* that yields output from a buffer. If it reaches the end of the buffer, it
|
||||||
|
* starts over.
|
||||||
|
*
|
||||||
|
* Note: the get_thread_fast_rng() prng is not replaced by this; we'll need
|
||||||
|
* more code to support that.
|
||||||
|
**/
|
||||||
|
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);
|
||||||
|
MOCK(crypto_strongest_rand_, mock_crypto_strongest_rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Note that this function should be safe to call even if the rng has not
|
||||||
|
* yet been replaced.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
testing_disable_rng_override(void)
|
||||||
|
{
|
||||||
|
crypto_xof_free(rng_xof);
|
||||||
|
tor_free(prefilled_rng_buffer);
|
||||||
|
UNMOCK(crypto_rand);
|
||||||
|
UNMOCK(crypto_strongest_rand_);
|
||||||
|
tor_mutex_free(rng_mutex);
|
||||||
|
|
||||||
|
crypto_fast_rng_t *rng = crypto_replace_thread_fast_rng(stored_fast_rng);
|
||||||
|
crypto_fast_rng_free(rng);
|
||||||
|
|
||||||
|
rng_is_replaced = false;
|
||||||
|
}
|
26
src/test/rng_test_helpers.h
Normal file
26
src/test/rng_test_helpers.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* Copyright (c) 2017-2019, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#ifndef TOR_RNG_TEST_HELPERS_H
|
||||||
|
#define TOR_RNG_TEST_HELPERS_H
|
||||||
|
|
||||||
|
#include "core/or/or.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#define testing_disable_reproducible_rng() \
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif /* !defined(TOR_RNG_TEST_HELPERS_H) */
|
@ -12,6 +12,7 @@
|
|||||||
#include "lib/crypt_ops/crypto_dh.h"
|
#include "lib/crypt_ops/crypto_dh.h"
|
||||||
#include "lib/crypt_ops/crypto_rand.h"
|
#include "lib/crypt_ops/crypto_rand.h"
|
||||||
#include "app/config/or_state_st.h"
|
#include "app/config/or_state_st.h"
|
||||||
|
#include "test/rng_test_helpers.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
@ -354,18 +355,6 @@ test_onion_queues(void *arg)
|
|||||||
tor_free(onionskin);
|
tor_free(onionskin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static crypto_cipher_t *crypto_rand_aes_cipher = NULL;
|
|
||||||
|
|
||||||
// Mock replacement for crypto_rand: Generates bytes from a provided AES_CTR
|
|
||||||
// cipher in <b>crypto_rand_aes_cipher</b>.
|
|
||||||
static void
|
|
||||||
crypto_rand_deterministic_aes(char *out, size_t n)
|
|
||||||
{
|
|
||||||
tor_assert(crypto_rand_aes_cipher);
|
|
||||||
memset(out, 0, n);
|
|
||||||
crypto_cipher_crypt_inplace(crypto_rand_aes_cipher, out, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_circuit_timeout(void *arg)
|
test_circuit_timeout(void *arg)
|
||||||
{
|
{
|
||||||
@ -397,8 +386,7 @@ test_circuit_timeout(void *arg)
|
|||||||
|
|
||||||
// Use a deterministic RNG here, or else we'll get nondeterministic
|
// Use a deterministic RNG here, or else we'll get nondeterministic
|
||||||
// coverage in some of the circuitstats functions.
|
// coverage in some of the circuitstats functions.
|
||||||
MOCK(crypto_rand, crypto_rand_deterministic_aes);
|
testing_enable_deterministic_rng();
|
||||||
crypto_rand_aes_cipher = crypto_cipher_new("xyzzyplughplover");
|
|
||||||
|
|
||||||
circuitbuild_running_unit_tests();
|
circuitbuild_running_unit_tests();
|
||||||
#define timeout0 (build_time_t)(30*1000.0)
|
#define timeout0 (build_time_t)(30*1000.0)
|
||||||
@ -534,8 +522,8 @@ test_circuit_timeout(void *arg)
|
|||||||
circuit_build_times_free_timeouts(&final);
|
circuit_build_times_free_timeouts(&final);
|
||||||
or_state_free(state);
|
or_state_free(state);
|
||||||
teardown_periodic_events();
|
teardown_periodic_events();
|
||||||
UNMOCK(crypto_rand);
|
|
||||||
crypto_cipher_free(crypto_rand_aes_cipher);
|
testing_disable_deterministic_rng();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test encoding and parsing of rendezvous service descriptors. */
|
/** Test encoding and parsing of rendezvous service descriptors. */
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "feature/client/addressmap.h"
|
#include "feature/client/addressmap.h"
|
||||||
#include "test/log_test_helpers.h"
|
#include "test/log_test_helpers.h"
|
||||||
#include "lib/net/resolve.h"
|
#include "lib/net/resolve.h"
|
||||||
|
#include "test/rng_test_helpers.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_UN_H
|
#ifdef HAVE_SYS_UN_H
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
@ -945,27 +946,6 @@ test_virtaddrmap(void *data)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *canned_data = NULL;
|
|
||||||
static size_t canned_data_len = 0;
|
|
||||||
|
|
||||||
/* Mock replacement for crypto_rand() that returns canned data from
|
|
||||||
* canned_data above. */
|
|
||||||
static void
|
|
||||||
crypto_canned(char *ptr, size_t n)
|
|
||||||
{
|
|
||||||
if (canned_data_len) {
|
|
||||||
size_t to_copy = MIN(n, canned_data_len);
|
|
||||||
memcpy(ptr, canned_data, to_copy);
|
|
||||||
canned_data += to_copy;
|
|
||||||
canned_data_len -= to_copy;
|
|
||||||
n -= to_copy;
|
|
||||||
ptr += to_copy;
|
|
||||||
}
|
|
||||||
if (n) {
|
|
||||||
crypto_rand_unmocked(ptr, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_virtaddrmap_persist(void *data)
|
test_virtaddrmap_persist(void *data)
|
||||||
{
|
{
|
||||||
@ -973,6 +953,8 @@ test_virtaddrmap_persist(void *data)
|
|||||||
const char *a, *b, *c;
|
const char *a, *b, *c;
|
||||||
tor_addr_t addr;
|
tor_addr_t addr;
|
||||||
char *ones = NULL;
|
char *ones = NULL;
|
||||||
|
const char *canned_data;
|
||||||
|
size_t canned_data_len;
|
||||||
|
|
||||||
addressmap_init();
|
addressmap_init();
|
||||||
|
|
||||||
@ -991,7 +973,7 @@ test_virtaddrmap_persist(void *data)
|
|||||||
"1234567890" // the second call returns this.
|
"1234567890" // the second call returns this.
|
||||||
"abcdefghij"; // the third call returns this.
|
"abcdefghij"; // the third call returns this.
|
||||||
canned_data_len = 30;
|
canned_data_len = 30;
|
||||||
MOCK(crypto_rand, crypto_canned);
|
testing_enable_prefilled_rng(canned_data, canned_data_len);
|
||||||
|
|
||||||
a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
|
a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
|
||||||
tor_strdup("quuxit.baz"));
|
tor_strdup("quuxit.baz"));
|
||||||
@ -1001,9 +983,9 @@ test_virtaddrmap_persist(void *data)
|
|||||||
tt_assert(b);
|
tt_assert(b);
|
||||||
tt_str_op(a, OP_EQ, "gezdgnbvgy3tqojq.virtual");
|
tt_str_op(a, OP_EQ, "gezdgnbvgy3tqojq.virtual");
|
||||||
tt_str_op(b, OP_EQ, "mfrggzdfmztwq2lk.virtual");
|
tt_str_op(b, OP_EQ, "mfrggzdfmztwq2lk.virtual");
|
||||||
|
testing_disable_prefilled_rng();
|
||||||
|
|
||||||
// Now try something to get us an ipv4 address
|
// Now try something to get us an ipv4 address
|
||||||
UNMOCK(crypto_rand);
|
|
||||||
tt_int_op(0,OP_EQ, parse_virtual_addr_network("192.168.0.0/16",
|
tt_int_op(0,OP_EQ, parse_virtual_addr_network("192.168.0.0/16",
|
||||||
AF_INET, 0, NULL));
|
AF_INET, 0, NULL));
|
||||||
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
|
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
|
||||||
@ -1020,22 +1002,23 @@ test_virtaddrmap_persist(void *data)
|
|||||||
|
|
||||||
// Try some canned entropy and verify all the we discard duplicates,
|
// Try some canned entropy and verify all the we discard duplicates,
|
||||||
// addresses that end with 0, and addresses that end with 255.
|
// addresses that end with 0, and addresses that end with 255.
|
||||||
MOCK(crypto_rand, crypto_canned);
|
|
||||||
canned_data = "\x01\x02\x03\x04" // okay
|
canned_data = "\x01\x02\x03\x04" // okay
|
||||||
"\x01\x02\x03\x04" // duplicate
|
"\x01\x02\x03\x04" // duplicate
|
||||||
"\x03\x04\x00\x00" // bad ending 1
|
"\x03\x04\x00\x00" // bad ending 1
|
||||||
"\x05\x05\x00\xff" // bad ending 2
|
"\x05\x05\x00\xff" // bad ending 2
|
||||||
"\x05\x06\x07\xf0"; // okay
|
"\x05\x06\x07\xf0"; // okay
|
||||||
canned_data_len = 20;
|
canned_data_len = 20;
|
||||||
|
testing_enable_prefilled_rng(canned_data, canned_data_len);
|
||||||
|
|
||||||
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
|
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
|
||||||
tor_strdup("wumble.onion"));
|
tor_strdup("wumble.onion"));
|
||||||
b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
|
b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
|
||||||
tor_strdup("wumpus.onion"));
|
tor_strdup("wumpus.onion"));
|
||||||
tt_str_op(a, OP_EQ, "192.168.3.4");
|
tt_str_op(a, OP_EQ, "192.168.3.4");
|
||||||
tt_str_op(b, OP_EQ, "192.168.7.240");
|
tt_str_op(b, OP_EQ, "192.168.7.240");
|
||||||
|
testing_disable_prefilled_rng();
|
||||||
|
|
||||||
// Now try IPv6!
|
// Now try IPv6!
|
||||||
UNMOCK(crypto_rand);
|
|
||||||
tt_int_op(0,OP_EQ, parse_virtual_addr_network("1010:F000::/20",
|
tt_int_op(0,OP_EQ, parse_virtual_addr_network("1010:F000::/20",
|
||||||
AF_INET6, 0, NULL));
|
AF_INET6, 0, NULL));
|
||||||
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
|
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
|
||||||
@ -1051,7 +1034,7 @@ test_virtaddrmap_persist(void *data)
|
|||||||
tt_assert(!strcmpstart(b, "[1010:f"));
|
tt_assert(!strcmpstart(b, "[1010:f"));
|
||||||
|
|
||||||
// Try IPv6 with canned entropy, to make sure we detect duplicates.
|
// Try IPv6 with canned entropy, to make sure we detect duplicates.
|
||||||
MOCK(crypto_rand, crypto_canned);
|
|
||||||
canned_data = "acanthopterygian" // okay
|
canned_data = "acanthopterygian" // okay
|
||||||
"cinematographist" // okay
|
"cinematographist" // okay
|
||||||
"acanthopterygian" // duplicate
|
"acanthopterygian" // duplicate
|
||||||
@ -1060,6 +1043,8 @@ test_virtaddrmap_persist(void *data)
|
|||||||
"cinematographist" // duplicate
|
"cinematographist" // duplicate
|
||||||
"coadministration"; // okay
|
"coadministration"; // okay
|
||||||
canned_data_len = 16 * 7;
|
canned_data_len = 16 * 7;
|
||||||
|
testing_enable_prefilled_rng(canned_data, canned_data_len);
|
||||||
|
|
||||||
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
|
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
|
||||||
tor_strdup("wuffle.baz"));
|
tor_strdup("wuffle.baz"));
|
||||||
b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
|
b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
|
||||||
@ -1072,9 +1057,11 @@ test_virtaddrmap_persist(void *data)
|
|||||||
|
|
||||||
// Try address exhaustion: make sure we can actually fail if we
|
// Try address exhaustion: make sure we can actually fail if we
|
||||||
// get too many already-existing addresses.
|
// get too many already-existing addresses.
|
||||||
|
testing_disable_prefilled_rng();
|
||||||
canned_data_len = 128*1024;
|
canned_data_len = 128*1024;
|
||||||
canned_data = ones = tor_malloc(canned_data_len);
|
canned_data = ones = tor_malloc(canned_data_len);
|
||||||
memset(ones, 1, canned_data_len);
|
memset(ones, 1, canned_data_len);
|
||||||
|
testing_enable_prefilled_rng(canned_data, canned_data_len);
|
||||||
// There is some chance this one will fail if a previous random
|
// There is some chance this one will fail if a previous random
|
||||||
// allocation gave out the address already.
|
// allocation gave out the address already.
|
||||||
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
|
a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
|
||||||
@ -1091,7 +1078,7 @@ test_virtaddrmap_persist(void *data)
|
|||||||
expect_single_log_msg_containing("Ran out of virtual addresses!");
|
expect_single_log_msg_containing("Ran out of virtual addresses!");
|
||||||
|
|
||||||
done:
|
done:
|
||||||
UNMOCK(crypto_rand);
|
testing_disable_prefilled_rng();
|
||||||
tor_free(ones);
|
tor_free(ones);
|
||||||
addressmap_free_all();
|
addressmap_free_all();
|
||||||
teardown_capture_of_logs();
|
teardown_capture_of_logs();
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "test/test.h"
|
#include "test/test.h"
|
||||||
#include "test/test_helpers.h"
|
#include "test/test_helpers.h"
|
||||||
|
#include "test/rng_test_helpers.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
#ifdef HAVE_SYS_STAT_H
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -302,16 +303,6 @@ test_ext_or_cookie_auth(void *arg)
|
|||||||
tor_free(client_hash2);
|
tor_free(client_hash2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
crypto_rand_return_tse_str(char *to, size_t n)
|
|
||||||
{
|
|
||||||
if (n != 32) {
|
|
||||||
TT_FAIL(("Asked for %d bytes, not 32", (int)n));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(to, "te road There is always another ", 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_ext_or_cookie_auth_testvec(void *arg)
|
test_ext_or_cookie_auth_testvec(void *arg)
|
||||||
{
|
{
|
||||||
@ -326,7 +317,7 @@ test_ext_or_cookie_auth_testvec(void *arg)
|
|||||||
memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32);
|
memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32);
|
||||||
ext_or_auth_cookie_is_set = 1;
|
ext_or_auth_cookie_is_set = 1;
|
||||||
|
|
||||||
MOCK(crypto_rand, crypto_rand_return_tse_str);
|
testing_enable_prefilled_rng("te road There is always another ", 32);
|
||||||
|
|
||||||
tt_int_op(0, OP_EQ,
|
tt_int_op(0, OP_EQ,
|
||||||
handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
|
handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
|
||||||
@ -351,7 +342,7 @@ test_ext_or_cookie_auth_testvec(void *arg)
|
|||||||
"33b3cd77ff79bd80c2074bbf438119a2");
|
"33b3cd77ff79bd80c2074bbf438119a2");
|
||||||
|
|
||||||
done:
|
done:
|
||||||
UNMOCK(crypto_rand);
|
testing_disable_prefilled_rng();
|
||||||
tor_free(reply);
|
tor_free(reply);
|
||||||
tor_free(client_hash);
|
tor_free(client_hash);
|
||||||
tor_free(mem_op_hex_tmp);
|
tor_free(mem_op_hex_tmp);
|
||||||
@ -414,9 +405,9 @@ do_ext_or_handshake(or_connection_t *conn)
|
|||||||
CONTAINS("\x01\x00", 2);
|
CONTAINS("\x01\x00", 2);
|
||||||
WRITE("\x01", 1);
|
WRITE("\x01", 1);
|
||||||
WRITE("But when I look ahead up the whi", 32);
|
WRITE("But when I look ahead up the whi", 32);
|
||||||
MOCK(crypto_rand, crypto_rand_return_tse_str);
|
testing_enable_prefilled_rng("te road There is always another ", 32);
|
||||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||||
UNMOCK(crypto_rand);
|
testing_disable_prefilled_rng();
|
||||||
tt_int_op(TO_CONN(conn)->state, OP_EQ,
|
tt_int_op(TO_CONN(conn)->state, OP_EQ,
|
||||||
EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH);
|
EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH);
|
||||||
CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
|
CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
|
||||||
@ -481,9 +472,9 @@ test_ext_or_handshake(void *arg)
|
|||||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||||
/* send the rest of the nonce. */
|
/* send the rest of the nonce. */
|
||||||
WRITE("ahead up the whi", 16);
|
WRITE("ahead up the whi", 16);
|
||||||
MOCK(crypto_rand, crypto_rand_return_tse_str);
|
testing_enable_prefilled_rng("te road There is always another ", 32);
|
||||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||||
UNMOCK(crypto_rand);
|
testing_disable_prefilled_rng();
|
||||||
/* We should get the right reply from the server. */
|
/* We should get the right reply from the server. */
|
||||||
CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
|
CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
|
||||||
"\x02\x9f\x1a\xde\x76\x10\xd9\x10\x87\x8b\x62\xee\xb7\x40\x38\x21"
|
"\x02\x9f\x1a\xde\x76\x10\xd9\x10\x87\x8b\x62\xee\xb7\x40\x38\x21"
|
||||||
@ -582,7 +573,7 @@ test_ext_or_handshake(void *arg)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
UNMOCK(connection_write_to_buf_impl_);
|
UNMOCK(connection_write_to_buf_impl_);
|
||||||
UNMOCK(crypto_rand);
|
testing_disable_prefilled_rng();
|
||||||
if (conn)
|
if (conn)
|
||||||
connection_free_minimal(TO_CONN(conn));
|
connection_free_minimal(TO_CONN(conn));
|
||||||
#undef CONTAINS
|
#undef CONTAINS
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "test/hs_test_helpers.h"
|
#include "test/hs_test_helpers.h"
|
||||||
#include "test/test_helpers.h"
|
#include "test/test_helpers.h"
|
||||||
#include "test/log_test_helpers.h"
|
#include "test/log_test_helpers.h"
|
||||||
|
#include "test/rng_test_helpers.h"
|
||||||
|
|
||||||
#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
|
#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
|
||||||
DISABLE_GCC_WARNING(overlength-strings)
|
DISABLE_GCC_WARNING(overlength-strings)
|
||||||
@ -30,13 +31,6 @@ DISABLE_GCC_WARNING(overlength-strings)
|
|||||||
#include "test_hs_descriptor.inc"
|
#include "test_hs_descriptor.inc"
|
||||||
ENABLE_GCC_WARNING(overlength-strings)
|
ENABLE_GCC_WARNING(overlength-strings)
|
||||||
|
|
||||||
/* Mock function to fill all bytes with 1 */
|
|
||||||
static void
|
|
||||||
mock_crypto_strongest_rand(uint8_t *out, size_t out_len)
|
|
||||||
{
|
|
||||||
memset(out, 1, out_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test certificate encoding put in a descriptor. */
|
/* Test certificate encoding put in a descriptor. */
|
||||||
static void
|
static void
|
||||||
test_cert_encoding(void *arg)
|
test_cert_encoding(void *arg)
|
||||||
@ -799,7 +793,7 @@ test_build_authorized_client(void *arg)
|
|||||||
client_pubkey_b16,
|
client_pubkey_b16,
|
||||||
strlen(client_pubkey_b16));
|
strlen(client_pubkey_b16));
|
||||||
|
|
||||||
MOCK(crypto_strongest_rand_, mock_crypto_strongest_rand);
|
testing_enable_prefilled_rng("\x01", 1);
|
||||||
|
|
||||||
hs_desc_build_authorized_client(subcredential,
|
hs_desc_build_authorized_client(subcredential,
|
||||||
&client_auth_pk, &auth_ephemeral_sk,
|
&client_auth_pk, &auth_ephemeral_sk,
|
||||||
@ -815,7 +809,7 @@ test_build_authorized_client(void *arg)
|
|||||||
done:
|
done:
|
||||||
tor_free(desc_client);
|
tor_free(desc_client);
|
||||||
tor_free(mem_op_hex_tmp);
|
tor_free(mem_op_hex_tmp);
|
||||||
UNMOCK(crypto_strongest_rand_);
|
testing_disable_prefilled_rng();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct testcase_t hs_descriptor[] = {
|
struct testcase_t hs_descriptor[] = {
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "lib/math/prob_distr.h"
|
#include "lib/math/prob_distr.h"
|
||||||
#include "lib/math/fp.h"
|
#include "lib/math/fp.h"
|
||||||
#include "lib/crypt_ops/crypto_rand.h"
|
#include "lib/crypt_ops/crypto_rand.h"
|
||||||
|
#include "test/rng_test_helpers.h"
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -1117,49 +1118,14 @@ test_psi_dist_sample(const struct dist *dist)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the seed of the deterministic randomness */
|
|
||||||
static uint8_t rng_seed[16];
|
|
||||||
static crypto_xof_t *rng_xof = NULL;
|
|
||||||
|
|
||||||
/** Initialize the seed of the deterministic randomness. */
|
|
||||||
static void
|
|
||||||
init_deterministic_rand(void)
|
|
||||||
{
|
|
||||||
crypto_rand((char*)rng_seed, sizeof(rng_seed));
|
|
||||||
crypto_xof_free(rng_xof);
|
|
||||||
rng_xof = crypto_xof_new();
|
|
||||||
crypto_xof_add_bytes(rng_xof, rng_seed, sizeof(rng_seed));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
teardown_deterministic_rand(void)
|
|
||||||
{
|
|
||||||
crypto_xof_free(rng_xof);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_seed(void)
|
dump_seed(void)
|
||||||
{
|
{
|
||||||
printf("\n"
|
printf("\n"
|
||||||
"NOTE: This is a stochastic test, and we expect it to fail from\n"
|
"NOTE: This is a stochastic test, and we expect it to fail from\n"
|
||||||
"time to time, with some low probability. If you see it fail more\n"
|
"time to time, with some low probability. If you see it fail more\n"
|
||||||
"than one trial in 100, though, please tell us.\n\n"
|
"than one trial in 100, though, please tell us.\n\n");
|
||||||
"Seed: %s\n",
|
testing_dump_reproducible_rng_seed();
|
||||||
hex_str((const char*)rng_seed, sizeof(rng_seed)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Produce deterministic randomness for the stochastic tests using the global
|
|
||||||
* deterministic_rand_counter seed
|
|
||||||
*
|
|
||||||
* This function produces deterministic data over multiple calls iff it's
|
|
||||||
* called in the same call order with the same 'n' parameter (which is the
|
|
||||||
* case for the psi test). If not, outputs will deviate. */
|
|
||||||
static void
|
|
||||||
crypto_rand_deterministic(char *out, size_t n)
|
|
||||||
{
|
|
||||||
/* Use a XOF to squeeze bytes out of that silly counter */
|
|
||||||
tor_assert(rng_xof);
|
|
||||||
crypto_xof_squeeze_bytes(rng_xof, (uint8_t*)out, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1199,8 +1165,7 @@ test_stochastic_uniform(void *arg)
|
|||||||
};
|
};
|
||||||
bool ok = true, tests_failed = true;
|
bool ok = true, tests_failed = true;
|
||||||
|
|
||||||
init_deterministic_rand();
|
testing_enable_reproducible_rng();
|
||||||
MOCK(crypto_rand, crypto_rand_deterministic);
|
|
||||||
|
|
||||||
ok &= test_psi_dist_sample(&uniform01.base);
|
ok &= test_psi_dist_sample(&uniform01.base);
|
||||||
ok &= test_psi_dist_sample(&uniform_pos.base);
|
ok &= test_psi_dist_sample(&uniform_pos.base);
|
||||||
@ -1217,8 +1182,7 @@ test_stochastic_uniform(void *arg)
|
|||||||
if (tests_failed) {
|
if (tests_failed) {
|
||||||
dump_seed();
|
dump_seed();
|
||||||
}
|
}
|
||||||
teardown_deterministic_rand();
|
testing_disable_reproducible_rng();
|
||||||
UNMOCK(crypto_rand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -1288,8 +1252,7 @@ test_stochastic_genpareto(void *arg)
|
|||||||
bool tests_failed = true;
|
bool tests_failed = true;
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
init_deterministic_rand();
|
testing_enable_reproducible_rng();
|
||||||
MOCK(crypto_rand, crypto_rand_deterministic);
|
|
||||||
|
|
||||||
ok = test_stochastic_genpareto_impl(0, 1, -0.25);
|
ok = test_stochastic_genpareto_impl(0, 1, -0.25);
|
||||||
tt_assert(ok);
|
tt_assert(ok);
|
||||||
@ -1312,8 +1275,7 @@ test_stochastic_genpareto(void *arg)
|
|||||||
if (tests_failed) {
|
if (tests_failed) {
|
||||||
dump_seed();
|
dump_seed();
|
||||||
}
|
}
|
||||||
teardown_deterministic_rand();
|
testing_disable_reproducible_rng();
|
||||||
UNMOCK(crypto_rand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1324,8 +1286,7 @@ test_stochastic_geometric(void *arg)
|
|||||||
|
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
init_deterministic_rand();
|
testing_enable_reproducible_rng();
|
||||||
MOCK(crypto_rand, crypto_rand_deterministic);
|
|
||||||
|
|
||||||
ok = test_stochastic_geometric_impl(0.1);
|
ok = test_stochastic_geometric_impl(0.1);
|
||||||
tt_assert(ok);
|
tt_assert(ok);
|
||||||
@ -1342,8 +1303,7 @@ test_stochastic_geometric(void *arg)
|
|||||||
if (tests_failed) {
|
if (tests_failed) {
|
||||||
dump_seed();
|
dump_seed();
|
||||||
}
|
}
|
||||||
teardown_deterministic_rand();
|
testing_disable_reproducible_rng();
|
||||||
UNMOCK(crypto_rand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1353,8 +1313,7 @@ test_stochastic_logistic(void *arg)
|
|||||||
bool tests_failed = true;
|
bool tests_failed = true;
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
init_deterministic_rand();
|
testing_enable_reproducible_rng();
|
||||||
MOCK(crypto_rand, crypto_rand_deterministic);
|
|
||||||
|
|
||||||
ok = test_stochastic_logistic_impl(0, 1);
|
ok = test_stochastic_logistic_impl(0, 1);
|
||||||
tt_assert(ok);
|
tt_assert(ok);
|
||||||
@ -1371,8 +1330,7 @@ test_stochastic_logistic(void *arg)
|
|||||||
if (tests_failed) {
|
if (tests_failed) {
|
||||||
dump_seed();
|
dump_seed();
|
||||||
}
|
}
|
||||||
teardown_deterministic_rand();
|
testing_disable_reproducible_rng();
|
||||||
UNMOCK(crypto_rand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1382,8 +1340,7 @@ test_stochastic_log_logistic(void *arg)
|
|||||||
bool tests_failed = true;
|
bool tests_failed = true;
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
init_deterministic_rand();
|
testing_enable_reproducible_rng();
|
||||||
MOCK(crypto_rand, crypto_rand_deterministic);
|
|
||||||
|
|
||||||
ok = test_stochastic_log_logistic_impl(1, 1);
|
ok = test_stochastic_log_logistic_impl(1, 1);
|
||||||
tt_assert(ok);
|
tt_assert(ok);
|
||||||
@ -1400,8 +1357,7 @@ test_stochastic_log_logistic(void *arg)
|
|||||||
if (tests_failed) {
|
if (tests_failed) {
|
||||||
dump_seed();
|
dump_seed();
|
||||||
}
|
}
|
||||||
teardown_deterministic_rand();
|
testing_disable_reproducible_rng();
|
||||||
UNMOCK(crypto_rand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1411,8 +1367,7 @@ test_stochastic_weibull(void *arg)
|
|||||||
bool tests_failed = true;
|
bool tests_failed = true;
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
init_deterministic_rand();
|
testing_enable_reproducible_rng();
|
||||||
MOCK(crypto_rand, crypto_rand_deterministic);
|
|
||||||
|
|
||||||
ok = test_stochastic_weibull_impl(1, 0.5);
|
ok = test_stochastic_weibull_impl(1, 0.5);
|
||||||
tt_assert(ok);
|
tt_assert(ok);
|
||||||
@ -1431,7 +1386,7 @@ test_stochastic_weibull(void *arg)
|
|||||||
if (tests_failed) {
|
if (tests_failed) {
|
||||||
dump_seed();
|
dump_seed();
|
||||||
}
|
}
|
||||||
teardown_deterministic_rand();
|
testing_disable_reproducible_rng();
|
||||||
UNMOCK(crypto_rand);
|
UNMOCK(crypto_rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user