commit c3b72583709332f051fb61e17f5102d0ada05917 Merge: 94c6eb7d7 94dcd38a1 Author: Nick Mathewson nickm@torproject.org Date: Thu May 3 13:50:18 2018 -0400
Merge remote-tracking branch 'isis/bug24660_r1'
src/common/address_set.c | 2 +- src/common/aes.c | 1 - src/common/compat_libevent.c | 2 +- src/common/crypto.c | 608 +------------------- src/common/crypto.h | 40 +- src/common/crypto_curve25519.c | 5 +- src/common/crypto_digest.c | 9 +- src/common/crypto_ed25519.c | 6 +- src/common/crypto_format.c | 4 +- src/common/crypto_pwbox.c | 6 +- src/common/crypto_rand.c | 609 +++++++++++++++++++++ src/common/crypto_rand.h | 52 ++ src/common/crypto_rsa.c | 8 +- src/common/crypto_s2k.c | 8 +- src/common/crypto_util.c | 105 ++++ src/common/crypto_util.h | 27 + src/common/include.am | 10 +- src/common/tortls.c | 2 + src/common/workqueue.c | 2 +- src/ext/ed25519/donna/ed25519-randombytes-custom.h | 2 +- src/ext/ed25519/donna/ed25519_tor.c | 2 + src/ext/ed25519/ref10/blinding.c | 2 +- src/ext/ed25519/ref10/keypair.c | 3 + src/ext/ed25519/ref10/randombytes.h | 2 +- src/ext/keccak-tiny/keccak-tiny-unrolled.c | 2 +- src/or/addressmap.c | 3 +- src/or/channelpadding.c | 1 + src/or/circpathbias.c | 1 + src/or/circuitbuild.c | 2 +- src/or/circuitlist.c | 2 + src/or/circuitmux_ewma.c | 1 + src/or/circuitstats.c | 1 + src/or/command.c | 1 + src/or/config.c | 2 + src/or/connection.c | 1 + src/or/connection_edge.c | 1 + src/or/connection_or.c | 2 + src/or/conscache.c | 1 + src/or/control.c | 2 + src/or/cpuworker.c | 2 + src/or/dirauth/shared_random.c | 6 +- src/or/dirauth/shared_random_state.c | 10 +- src/or/directory.c | 2 + src/or/dns.c | 1 + src/or/dos.c | 1 + src/or/entrynodes.c | 1 + src/or/ext_orport.c | 4 +- src/or/hibernate.c | 1 + src/or/hs_cache.c | 1 + src/or/hs_cache.h | 1 - src/or/hs_cell.c | 1 + src/or/hs_circuit.c | 2 + src/or/hs_circuit.h | 1 - src/or/hs_client.c | 30 +- src/or/hs_common.c | 2 + src/or/hs_control.c | 1 + src/or/hs_descriptor.c | 2 + src/or/hs_descriptor.h | 1 + src/or/hs_ident.c | 1 + src/or/hs_ident.h | 1 - src/or/hs_ntor.c | 1 + src/or/hs_service.c | 2 + src/or/main.c | 1 + src/or/networkstatus.c | 2 + src/or/onion.c | 1 + src/or/onion_fast.c | 2 + src/or/onion_ntor.c | 1 + src/or/onion_tap.c | 2 + src/or/proto_socks.c | 1 + src/or/relay.c | 2 + src/or/relay_crypto.c | 3 +- src/or/rendclient.c | 6 +- src/or/rendcommon.c | 8 +- src/or/rendservice.c | 2 + src/or/rephist.c | 1 + src/or/router.c | 2 + src/or/routerkeys.c | 1 + src/or/routerlist.c | 1 + src/or/routerparse.c | 19 +- src/or/torcert.c | 2 +- src/rust/Cargo.lock | 30 + src/rust/Cargo.toml | 4 +- src/rust/external/crypto_rand.rs | 87 +++ src/rust/external/lib.rs | 4 +- src/rust/rand/Cargo.toml | 27 + src/rust/rand/lib.rs | 16 + src/rust/rand/rng.rs | 140 +++++ src/test/bench.c | 1 + src/test/rend_test_helpers.c | 1 + src/test/test-memwipe.c | 2 +- src/test/test-timers.c | 2 +- src/test/test.c | 1 + src/test/test_address_set.c | 1 + src/test/test_buffers.c | 1 + src/test/test_cell_formats.c | 1 + src/test/test_channel.c | 1 + src/test/test_consdiffmgr.c | 1 + src/test/test_containers.c | 1 + src/test/test_crypto.c | 3 +- src/test/test_crypto_openssl.c | 4 +- src/test/test_crypto_slow.c | 1 + src/test/test_dir.c | 1 + src/test/test_dir_common.c | 1 - src/test/test_dos.c | 1 + src/test/test_entrynodes.c | 1 + src/test/test_extorport.c | 1 + src/test/test_helpers.c | 1 + src/test/test_hs_cell.c | 1 + src/test/test_hs_common.c | 1 + src/test/test_hs_descriptor.c | 1 + src/test/test_hs_intropoint.c | 2 +- src/test/test_hs_service.c | 3 +- src/test/test_nodelist.c | 1 + src/test/test_oom.c | 1 + src/test/test_relaycrypt.c | 1 + src/test/test_routerlist.c | 1 + src/test/test_shared_random.c | 7 +- src/test/test_storagedir.c | 1 + src/test/test_util.c | 1 + src/test/test_util_format.c | 1 + src/test/test_workqueue.c | 2 +- src/test/testing_common.c | 1 + src/test/testing_rsakeys.c | 1 + src/tools/tor-gencert.c | 2 + src/trunnel/trunnel-local.h | 2 +- 125 files changed, 1305 insertions(+), 732 deletions(-)
diff --cc src/common/workqueue.c index 12e31414e,de0079b75..563a98af9 --- a/src/common/workqueue.c +++ b/src/common/workqueue.c @@@ -25,9 -24,8 +25,9 @@@
#include "orconfig.h" #include "compat.h" +#include "compat_libevent.h" #include "compat_threads.h" - #include "crypto.h" + #include "crypto_rand.h" #include "util.h" #include "workqueue.h" #include "tor_queue.h" diff --cc src/or/circuitmux_ewma.c index e85301b26,b2ace8a9f..e5d5a1458 --- a/src/or/circuitmux_ewma.c +++ b/src/or/circuitmux_ewma.c @@@ -37,6 -37,6 +37,7 @@@ #include "or.h" #include "circuitmux.h" #include "circuitmux_ewma.h" ++#include "crypto_rand.h" #include "networkstatus.h"
/*** EWMA parameter #defines ***/ diff --cc src/or/config.c index 23f1d4f5a,18298937e..9af613e93 --- a/src/or/config.c +++ b/src/or/config.c @@@ -79,7 -78,10 +79,9 @@@ #include "control.h" #include "confparse.h" #include "cpuworker.h" + #include "crypto_rand.h" + #include "crypto_util.h" #include "dirserv.h" -#include "dirvote.h" #include "dns.h" #include "dos.h" #include "entrynodes.h" diff --cc src/or/dirauth/shared_random.c index 0a89fa8d2,745566877..6dd1f330e --- a/src/or/dirauth/shared_random.c +++ b/src/or/dirauth/shared_random.c @@@ -91,17 -91,15 +91,19 @@@ #include "shared_random.h" #include "config.h" #include "confparse.h" + #include "crypto_rand.h" + #include "crypto_util.h" -#include "dirvote.h" #include "networkstatus.h" --#include "routerkeys.h" #include "router.h" ++#include "routerkeys.h" #include "routerlist.h" - #include "shared_random_state.h" +#include "shared_random_client.h" + #include "shared_random_state.h" #include "util.h" +#include "voting_schedule.h" + +#include "dirauth/dirvote.h" +#include "dirauth/mode.h"
/* String prefix of shared random values in votes/consensuses. */ static const char previous_srv_str[] = "shared-rand-previous-value"; diff --cc src/or/dirauth/shared_random_state.c index 56c12c8c7,80470e4e9..245fb99ce --- a/src/or/dirauth/shared_random_state.c +++ b/src/or/dirauth/shared_random_state.c @@@ -11,16 -11,14 +11,16 @@@ #define SHARED_RANDOM_STATE_PRIVATE
#include "or.h" --#include "shared_random.h" #include "config.h" #include "confparse.h" - #include "voting_schedule.h" + #include "crypto_util.h" -#include "dirvote.h" ++#include "dirauth/dirvote.h" #include "networkstatus.h" #include "router.h" - #include "shared_random_state.h" ++#include "shared_random.h" +#include "shared_random_client.h" - - #include "dirauth/dirvote.h" + #include "shared_random_state.h" ++#include "voting_schedule.h"
/* Default filename of the shared random state on disk. */ static const char default_fname[] = "sr-state"; diff --cc src/or/directory.c index 76caab6a3,44e3d2f2a..3e8d5ae9c --- a/src/or/directory.c +++ b/src/or/directory.c @@@ -18,8 -18,11 +18,10 @@@ #include "consdiffmgr.h" #include "control.h" #include "compat.h" + #include "crypto_rand.h" + #include "crypto_util.h" #include "directory.h" #include "dirserv.h" -#include "dirvote.h" #include "entrynodes.h" #include "geoip.h" #include "hs_cache.h" diff --cc src/or/main.c index 08dfeb80f,b3f0a85cd..c3505a2d9 --- a/src/or/main.c +++ b/src/or/main.c @@@ -71,8 -70,10 +71,9 @@@ #include "control.h" #include "cpuworker.h" #include "crypto_s2k.h" + #include "crypto_rand.h" #include "directory.h" #include "dirserv.h" -#include "dirvote.h" #include "dns.h" #include "dnsserv.h" #include "dos.h" diff --cc src/or/networkstatus.c index a7a76b236,e223b6f1b..757989342 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@@ -48,8 -48,11 +48,10 @@@ #include "connection_or.h" #include "consdiffmgr.h" #include "control.h" + #include "crypto_rand.h" + #include "crypto_util.h" #include "directory.h" #include "dirserv.h" -#include "dirvote.h" #include "dos.h" #include "entrynodes.h" #include "hibernate.h" diff --cc src/or/relay_crypto.c index c42a4f9cc,000000000..530c8e582 mode 100644,000000..100644 --- a/src/or/relay_crypto.c +++ b/src/or/relay_crypto.c @@@ -1,326 -1,0 +1,327 @@@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "or.h" +#include "config.h" ++#include "crypto_util.h" +#include "hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN - #include "relay_crypto.h" +#include "relay.h" ++#include "relay_crypto.h" + +/** Update digest from the payload of cell. Assign integrity part to + * cell. + */ +static void +relay_set_digest(crypto_digest_t *digest, cell_t *cell) +{ + char integrity[4]; + relay_header_t rh; + + crypto_digest_add_bytes(digest, (char*)cell->payload, CELL_PAYLOAD_SIZE); + crypto_digest_get_digest(digest, integrity, 4); +// log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.", +// integrity[0], integrity[1], integrity[2], integrity[3]); + relay_header_unpack(&rh, cell->payload); + memcpy(rh.integrity, integrity, 4); + relay_header_pack(cell->payload, &rh); +} + +/** Does the digest for this circuit indicate that this cell is for us? + * + * Update digest from the payload of cell (with the integrity part set + * to 0). If the integrity part is valid, return 1, else restore digest + * and cell to their original state and return 0. + */ +static int +relay_digest_matches(crypto_digest_t *digest, cell_t *cell) +{ + uint32_t received_integrity, calculated_integrity; + relay_header_t rh; + crypto_digest_checkpoint_t backup_digest; + + crypto_digest_checkpoint(&backup_digest, digest); + + relay_header_unpack(&rh, cell->payload); + memcpy(&received_integrity, rh.integrity, 4); + memset(rh.integrity, 0, 4); + relay_header_pack(cell->payload, &rh); + +// log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.", +// received_integrity[0], received_integrity[1], +// received_integrity[2], received_integrity[3]); + + crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE); + crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4); + + int rv = 1; + + if (calculated_integrity != received_integrity) { +// log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing."); +// (%d vs %d).", received_integrity, calculated_integrity); + /* restore digest to its old form */ + crypto_digest_restore(digest, &backup_digest); + /* restore the relay header */ + memcpy(rh.integrity, &received_integrity, 4); + relay_header_pack(cell->payload, &rh); + rv = 0; + } + + memwipe(&backup_digest, 0, sizeof(backup_digest)); + return rv; +} + +/** Apply <b>cipher</b> to CELL_PAYLOAD_SIZE bytes of <b>in</b> + * (in place). + * + * Note that we use the same operation for encrypting and for decrypting. + */ +static void +relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in) +{ + crypto_cipher_crypt_inplace(cipher, (char*) in, CELL_PAYLOAD_SIZE); +} + +/** Do the appropriate en/decryptions for <b>cell</b> arriving on + * <b>circ</b> in direction <b>cell_direction</b>. + * + * If cell_direction == CELL_DIRECTION_IN: + * - If we're at the origin (we're the OP), for hops 1..N, + * decrypt cell. If recognized, stop. + * - Else (we're not the OP), encrypt one hop. Cell is not recognized. + * + * If cell_direction == CELL_DIRECTION_OUT: + * - decrypt one hop. Check if recognized. + * + * If cell is recognized, set *recognized to 1, and set + * *layer_hint to the hop that recognized it. + * + * Return -1 to indicate that we should mark the circuit for close, + * else return 0. + */ +int +relay_decrypt_cell(circuit_t *circ, cell_t *cell, + cell_direction_t cell_direction, + crypt_path_t **layer_hint, char *recognized) +{ + relay_header_t rh; + + tor_assert(circ); + tor_assert(cell); + tor_assert(recognized); + tor_assert(cell_direction == CELL_DIRECTION_IN || + cell_direction == CELL_DIRECTION_OUT); + + if (cell_direction == CELL_DIRECTION_IN) { + if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit. + * We'll want to do layered decrypts. */ + crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath; + thishop = cpath; + if (thishop->state != CPATH_STATE_OPEN) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Relay cell before first created cell? Closing."); + return -1; + } + do { /* Remember: cpath is in forward order, that is, first hop first. */ + tor_assert(thishop); + + /* decrypt one layer */ + relay_crypt_one_payload(thishop->crypto.b_crypto, cell->payload); + + relay_header_unpack(&rh, cell->payload); + if (rh.recognized == 0) { + /* it's possibly recognized. have to check digest to be sure. */ + if (relay_digest_matches(thishop->crypto.b_digest, cell)) { + *recognized = 1; + *layer_hint = thishop; + return 0; + } + } + + thishop = thishop->next; + } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN); + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Incoming cell at client not recognized. Closing."); + return -1; + } else { + relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto; + /* We're in the middle. Encrypt one layer. */ + relay_crypt_one_payload(crypto->b_crypto, cell->payload); + } + } else /* cell_direction == CELL_DIRECTION_OUT */ { + /* We're in the middle. Decrypt one layer. */ + relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto; + + relay_crypt_one_payload(crypto->f_crypto, cell->payload); + + relay_header_unpack(&rh, cell->payload); + if (rh.recognized == 0) { + /* it's possibly recognized. have to check digest to be sure. */ + if (relay_digest_matches(crypto->f_digest, cell)) { + *recognized = 1; + return 0; + } + } + } + return 0; +} + +/** + * Encrypt a cell <b>cell</b> that we are creating, and sending outbound on + * <b>circ</b> until the hop corresponding to <b>layer_hint</b>. + * + * The integrity field and recognized field of <b>cell</b>'s relay headers + * must be set to zero. + */ +void +relay_encrypt_cell_outbound(cell_t *cell, + origin_circuit_t *circ, + crypt_path_t *layer_hint) +{ + crypt_path_t *thishop; /* counter for repeated crypts */ + relay_set_digest(layer_hint->crypto.f_digest, cell); + + thishop = layer_hint; + /* moving from farthest to nearest hop */ + do { + tor_assert(thishop); + log_debug(LD_OR,"encrypting a layer of the relay cell."); + relay_crypt_one_payload(thishop->crypto.f_crypto, cell->payload); + + thishop = thishop->prev; + } while (thishop != circ->cpath->prev); +} + +/** + * Encrypt a cell <b>cell</b> that we are creating, and sending on + * <b>circuit</b> to the origin. + * + * The integrity field and recognized field of <b>cell</b>'s relay headers + * must be set to zero. + */ +void +relay_encrypt_cell_inbound(cell_t *cell, + or_circuit_t *or_circ) +{ + relay_set_digest(or_circ->crypto.b_digest, cell); + /* encrypt one layer */ + relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload); +} + +/** + * Release all storage held inside <b>crypto</b>, but do not free + * <b>crypto</b> itself: it lives inside another object. + */ +void +relay_crypto_clear(relay_crypto_t *crypto) +{ + if (BUG(!crypto)) + return; + crypto_cipher_free(crypto->f_crypto); + crypto_cipher_free(crypto->b_crypto); + crypto_digest_free(crypto->f_digest); + crypto_digest_free(crypto->b_digest); +} + +/** Initialize <b>crypto</b> from the key material in key_data. + * + * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden + * service circuits and <b>key_data</b> must be at least + * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length. + * + * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN + * bytes, which are used as follows: + * - 20 to initialize f_digest + * - 20 to initialize b_digest + * - 16 to key f_crypto + * - 16 to key b_crypto + * + * (If 'reverse' is true, then f_XX and b_XX are swapped.) + * + * Return 0 if init was successful, else -1 if it failed. + */ +int +relay_crypto_init(relay_crypto_t *crypto, + const char *key_data, size_t key_data_len, + int reverse, int is_hs_v3) +{ + crypto_digest_t *tmp_digest; + crypto_cipher_t *tmp_crypto; + size_t digest_len = 0; + size_t cipher_key_len = 0; + + tor_assert(crypto); + tor_assert(key_data); + tor_assert(!(crypto->f_crypto || crypto->b_crypto || + crypto->f_digest || crypto->b_digest)); + + /* Basic key size validation */ + if (is_hs_v3 && BUG(key_data_len != HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN)) { + goto err; + } else if (!is_hs_v3 && BUG(key_data_len != CPATH_KEY_MATERIAL_LEN)) { + goto err; + } + + /* If we are using this crypto for next gen onion services use SHA3-256, + otherwise use good ol' SHA1 */ + if (is_hs_v3) { + digest_len = DIGEST256_LEN; + cipher_key_len = CIPHER256_KEY_LEN; + crypto->f_digest = crypto_digest256_new(DIGEST_SHA3_256); + crypto->b_digest = crypto_digest256_new(DIGEST_SHA3_256); + } else { + digest_len = DIGEST_LEN; + cipher_key_len = CIPHER_KEY_LEN; + crypto->f_digest = crypto_digest_new(); + crypto->b_digest = crypto_digest_new(); + } + + tor_assert(digest_len != 0); + tor_assert(cipher_key_len != 0); + const int cipher_key_bits = (int) cipher_key_len * 8; + + crypto_digest_add_bytes(crypto->f_digest, key_data, digest_len); + crypto_digest_add_bytes(crypto->b_digest, key_data+digest_len, digest_len); + + crypto->f_crypto = crypto_cipher_new_with_bits(key_data+(2*digest_len), + cipher_key_bits); + if (!crypto->f_crypto) { + log_warn(LD_BUG,"Forward cipher initialization failed."); + goto err; + } + + crypto->b_crypto = crypto_cipher_new_with_bits( + key_data+(2*digest_len)+cipher_key_len, + cipher_key_bits); + if (!crypto->b_crypto) { + log_warn(LD_BUG,"Backward cipher initialization failed."); + goto err; + } + + if (reverse) { + tmp_digest = crypto->f_digest; + crypto->f_digest = crypto->b_digest; + crypto->b_digest = tmp_digest; + tmp_crypto = crypto->f_crypto; + crypto->f_crypto = crypto->b_crypto; + crypto->b_crypto = tmp_crypto; + } + + return 0; + err: + relay_crypto_clear(crypto); + return -1; +} + +/** Assert that <b>crypto</b> is valid and set. */ +void +relay_crypto_assert_ok(const relay_crypto_t *crypto) +{ + tor_assert(crypto->f_crypto); + tor_assert(crypto->b_crypto); + tor_assert(crypto->f_digest); + tor_assert(crypto->b_digest); +} + diff --cc src/or/routerlist.c index 914cf4ef1,8793c64ed..7603eb3ec --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@@ -99,8 -99,10 +99,9 @@@ #include "config.h" #include "connection.h" #include "control.h" + #include "crypto_rand.h" #include "directory.h" #include "dirserv.h" -#include "dirvote.h" #include "entrynodes.h" #include "fp_pair.h" #include "geoip.h" diff --cc src/or/routerparse.c index a729aa4b1,b00b1c636..7af41c3ba --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@@ -56,27 -56,27 +56,28 @@@ #define ROUTERPARSE_PRIVATE
#include "or.h" - #include "config.h" #include "circuitstats.h" + #include "config.h" + #include "crypto_util.h" ++#include "dirauth/shared_random.h" #include "dirserv.h" -#include "dirvote.h" + #include "entrynodes.h" + #include "memarea.h" + #include "microdesc.h" + #include "networkstatus.h" #include "parsecommon.h" #include "policies.h" #include "protover.h" #include "rendcommon.h" - #include "router.h" - #include "routerlist.h" - #include "memarea.h" - #include "microdesc.h" - #include "networkstatus.h" #include "rephist.h" + #include "router.h" #include "routerkeys.h" + #include "routerlist.h" #include "routerparse.h" - #include "entrynodes.h" - #include "torcert.h" #include "sandbox.h" -#include "shared_random.h" +#include "shared_random_client.h" + #include "torcert.h" +#include "voting_schedule.h" - #include "dirauth/shared_random.h"
#undef log #include <math.h> diff --cc src/test/test-timers.c index 5efd99cac,a5c3a3b96..f20f29578 --- a/src/test/test-timers.c +++ b/src/test/test-timers.c @@@ -7,9 -7,11 +7,9 @@@ #include <stdio.h> #include <string.h>
-#include <event2/event.h> - #include "compat.h" #include "compat_libevent.h" - #include "crypto.h" + #include "crypto_rand.h" #include "timers.h" #include "util.h"
diff --cc src/test/test_dir.c index 492753029,7d3b5344b..25b4e4287 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@@ -23,9 -23,10 +23,10 @@@ #include "config.h" #include "control.h" #include "crypto_ed25519.h" + #include "crypto_rand.h" #include "directory.h" #include "dirserv.h" -#include "dirvote.h" +#include "dirauth/dirvote.h" #include "entrynodes.h" #include "hibernate.h" #include "memarea.h" diff --cc src/test/test_hs_service.c index d2198c621,cad12481c..33b5e9607 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@@ -33,13 -33,13 +33,12 @@@ #include "circuitbuild.h" #include "circuitlist.h" #include "circuituse.h" - #include "crypto.h" + #include "crypto_rand.h" -#include "dirvote.h" +#include "dirauth/dirvote.h" #include "networkstatus.h" #include "nodelist.h" #include "relay.h" #include "routerparse.h" -- #include "hs_common.h" #include "hs_config.h" #include "hs_ident.h" diff --cc src/test/test_relaycrypt.c index eba989718,000000000..60bd47971 mode 100644,000000..100644 --- a/src/test/test_relaycrypt.c +++ b/src/test/test_relaycrypt.c @@@ -1,184 -1,0 +1,185 @@@ +/* Copyright 2001-2004 Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "or.h" +#include "circuitbuild.h" +#define CIRCUITLIST_PRIVATE +#include "circuitlist.h" ++#include "crypto_rand.h" +#include "relay.h" +#include "relay_crypto.h" +#include "test.h" + +static const char KEY_MATERIAL[3][CPATH_KEY_MATERIAL_LEN] = { + " 'My public key is in this signed x509 object', said Tom assertively.", + "'Let's chart the pedal phlanges in the tomb', said Tom cryptographically", + " 'Segmentation fault bugs don't _just happen_', said Tom seethingly.", +}; + +typedef struct testing_circuitset_t { + or_circuit_t *or_circ[3]; + origin_circuit_t *origin_circ; +} testing_circuitset_t; + +static int testing_circuitset_teardown(const struct testcase_t *testcase, + void *ptr); + +static void * +testing_circuitset_setup(const struct testcase_t *testcase) +{ + testing_circuitset_t *cs = tor_malloc_zero(sizeof(testing_circuitset_t)); + int i; + + for (i=0; i<3; ++i) { + cs->or_circ[i] = or_circuit_new(0, NULL); + tt_int_op(0, OP_EQ, + relay_crypto_init(&cs->or_circ[i]->crypto, + KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]), + 0, 0)); + } + + cs->origin_circ = origin_circuit_new(); + cs->origin_circ->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL; + for (i=0; i<3; ++i) { + crypt_path_t *hop = tor_malloc_zero(sizeof(*hop)); + relay_crypto_init(&hop->crypto, KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]), + 0, 0); + hop->state = CPATH_STATE_OPEN; + onion_append_to_cpath(&cs->origin_circ->cpath, hop); + tt_ptr_op(hop, OP_EQ, cs->origin_circ->cpath->prev); + } + + return cs; + done: + testing_circuitset_teardown(testcase, cs); + return NULL; +} + +static int +testing_circuitset_teardown(const struct testcase_t *testcase, void *ptr) +{ + (void)testcase; + testing_circuitset_t *cs = ptr; + int i; + for (i=0; i<3; ++i) { + circuit_free_(TO_CIRCUIT(cs->or_circ[i])); + } + circuit_free_(TO_CIRCUIT(cs->origin_circ)); + tor_free(cs); + return 1; +} + +static const struct testcase_setup_t relaycrypt_setup = { + testing_circuitset_setup, testing_circuitset_teardown +}; + +/* Test encrypting a cell to the final hop on a circuit, decrypting it + * at each hop, and recognizing it at the other end. Then do it again + * and again as the state evolves. */ +static void +test_relaycrypt_outbound(void *arg) +{ + testing_circuitset_t *cs = arg; + tt_assert(cs); + + relay_header_t rh; + cell_t orig; + cell_t encrypted; + int i, j; + + for (i = 0; i < 50; ++i) { + crypto_rand((char *)&orig, sizeof(orig)); + + relay_header_unpack(&rh, orig.payload); + rh.recognized = 0; + memset(rh.integrity, 0, sizeof(rh.integrity)); + relay_header_pack(orig.payload, &rh); + + memcpy(&encrypted, &orig, sizeof(orig)); + + /* Encrypt the cell to the last hop */ + relay_encrypt_cell_outbound(&encrypted, cs->origin_circ, + cs->origin_circ->cpath->prev); + + for (j = 0; j < 3; ++j) { + crypt_path_t *layer_hint = NULL; + char recognized = 0; + int r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]), + &encrypted, + CELL_DIRECTION_OUT, + &layer_hint, &recognized); + tt_int_op(r, OP_EQ, 0); + tt_ptr_op(layer_hint, OP_EQ, NULL); + tt_int_op(recognized != 0, OP_EQ, j == 2); + } + + tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE); + } + + done: + ; +} + +/* As above, but simulate inbound cells from the last hop. */ +static void +test_relaycrypt_inbound(void *arg) +{ + testing_circuitset_t *cs = arg; + tt_assert(cs); + + relay_header_t rh; + cell_t orig; + cell_t encrypted; + int i, j; + + for (i = 0; i < 50; ++i) { + crypto_rand((char *)&orig, sizeof(orig)); + + relay_header_unpack(&rh, orig.payload); + rh.recognized = 0; + memset(rh.integrity, 0, sizeof(rh.integrity)); + relay_header_pack(orig.payload, &rh); + + memcpy(&encrypted, &orig, sizeof(orig)); + + /* Encrypt the cell to the last hop */ + relay_encrypt_cell_inbound(&encrypted, cs->or_circ[2]); + + crypt_path_t *layer_hint = NULL; + char recognized = 0; + int r; + for (j = 1; j >= 0; --j) { + r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]), + &encrypted, + CELL_DIRECTION_IN, + &layer_hint, &recognized); + tt_int_op(r, OP_EQ, 0); + tt_ptr_op(layer_hint, OP_EQ, NULL); + tt_int_op(recognized, OP_EQ, 0); + } + + relay_decrypt_cell(TO_CIRCUIT(cs->origin_circ), + &encrypted, + CELL_DIRECTION_IN, + &layer_hint, &recognized); + tt_int_op(r, OP_EQ, 0); + tt_int_op(recognized, OP_EQ, 1); + tt_ptr_op(layer_hint, OP_EQ, cs->origin_circ->cpath->prev); + + tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE); + } + done: + ; +} + +#define TEST(name) \ + { # name, test_relaycrypt_ ## name, 0, &relaycrypt_setup, NULL } + +struct testcase_t relaycrypt_tests[] = { + TEST(outbound), + TEST(inbound), + END_OF_TESTCASES +}; + diff --cc src/test/test_routerlist.c index 71b487f35,e56a868e0..7fed65628 --- a/src/test/test_routerlist.c +++ b/src/test/test_routerlist.c @@@ -18,8 -18,9 +18,9 @@@ #include "connection.h" #include "container.h" #include "control.h" + #include "crypto_rand.h" #include "directory.h" -#include "dirvote.h" +#include "dirauth/dirvote.h" #include "entrynodes.h" #include "hibernate.h" #include "microdesc.h" diff --cc src/test/test_shared_random.c index 775a1c1d2,7928518ef..f6ab0dfab --- a/src/test/test_shared_random.c +++ b/src/test/test_shared_random.c @@@ -9,17 -9,16 +9,18 @@@ #include "or.h" #include "test.h" #include "config.h" + #include "crypto_rand.h" -#include "dirvote.h" -#include "shared_random.h" -#include "shared_random_state.h" +#include "dirauth/dirvote.h" +#include "dirauth/shared_random.h" +#include "dirauth/shared_random_state.h" ++#include "log_test_helpers.h" ++#include "networkstatus.h" ++#include "router.h" #include "routerkeys.h" #include "routerlist.h" --#include "router.h" #include "routerparse.h" -#include "networkstatus.h" -#include "log_test_helpers.h" +#include "shared_random_client.h" - #include "networkstatus.h" - #include "log_test_helpers.h" +#include "voting_schedule.h"
static authority_cert_t *mock_cert;