From 660e346fce00c2de4675bd8fc799f506d917f55c Mon Sep 17 00:00:00 2001 From: iphydf Date: Fri, 1 Apr 2022 13:51:32 +0000 Subject: [PATCH 1/2] cleanup: Disallow stack frames of over 9000 bytes. This only happens in tests, which are easy to fix. Inside toxcore we should actually be more stringent, but for now this helps already. --- .github/scripts/flags-gcc.sh | 2 +- auto_tests/TCP_test.c | 10 ++- auto_tests/crypto_test.c | 157 +++++++++++++++++++---------------- other/analysis/run-gcc | 2 +- 4 files changed, 94 insertions(+), 77 deletions(-) diff --git a/.github/scripts/flags-gcc.sh b/.github/scripts/flags-gcc.sh index 610a29570f..0cacdb4b17 100644 --- a/.github/scripts/flags-gcc.sh +++ b/.github/scripts/flags-gcc.sh @@ -18,7 +18,7 @@ add_flag -Wenum-compare add_flag -Wfloat-equal add_flag -Wformat=2 add_flag -Wframe-address -add_flag -Wframe-larger-than=12400 +add_flag -Wframe-larger-than=9000 add_flag -Wignored-attributes add_flag -Wignored-qualifiers add_flag -Winit-self diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index e643d36e61..2b1110e399 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c @@ -86,10 +86,12 @@ static void test_basic(void) // Generation of the initial handshake. uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE]; - uint8_t handshake_plain[TCP_HANDSHAKE_PLAIN_SIZE]; + uint8_t *handshake_plain = (uint8_t *)malloc(TCP_HANDSHAKE_PLAIN_SIZE); + ck_assert(handshake_plain != nullptr); crypto_new_keypair(handshake_plain, t_secret_key); memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, f_nonce, CRYPTO_NONCE_SIZE); - uint8_t handshake[TCP_CLIENT_HANDSHAKE_SIZE]; + uint8_t *handshake = (uint8_t *)malloc(TCP_CLIENT_HANDSHAKE_SIZE); + ck_assert(handshake != nullptr); memcpy(handshake, f_public_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(handshake + CRYPTO_PUBLIC_KEY_SIZE); @@ -99,6 +101,8 @@ static void test_basic(void) ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), "encrypt_data() call failed."); + free(handshake_plain); + // Sending the handshake ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1, &localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1, @@ -109,6 +113,8 @@ static void test_basic(void) ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1, "The attempt to send the last byte of handshake failed."); + free(handshake); + do_TCP_server_delay(tcp_s, mono_time, 50); // Receiving server response and decrypting it diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 9ab06363bc..0c7866f943 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -18,27 +18,27 @@ static void rand_bytes(uint8_t *b, size_t blen) // These test vectors are from libsodium's test suite -static const unsigned char alicesk[32] = { +static const uint8_t alicesk[32] = { 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a }; -static const unsigned char bobpk[32] = { +static const uint8_t bobpk[32] = { 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f }; -static const unsigned char test_nonce[24] = { +static const uint8_t test_nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; -static const unsigned char test_m[131] = { +static const uint8_t test_m[131] = { 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, @@ -58,7 +58,7 @@ static const unsigned char test_m[131] = { 0x5e, 0x07, 0x05 }; -static const unsigned char test_c[147] = { +static const uint8_t test_c[147] = { 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, @@ -82,76 +82,77 @@ static const unsigned char test_c[147] = { static void test_known(void) { - unsigned char c[147]; - unsigned char m[131]; + uint8_t c[147]; + uint8_t m[131]; uint16_t clen, mlen; - ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(unsigned char), + ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(unsigned char), c); + clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); - ck_assert_msg(clen == sizeof(c) / sizeof(unsigned char), "wrong ciphertext length"); + ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(unsigned char), m); + mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); - ck_assert_msg(mlen == sizeof(m) / sizeof(unsigned char), "wrong plaintext length"); + ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); } static void test_fast_known(void) { - unsigned char k[CRYPTO_SHARED_KEY_SIZE]; - unsigned char c[147]; - unsigned char m[131]; + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; + uint8_t c[147]; + uint8_t m[131]; uint16_t clen, mlen; encrypt_precompute(bobpk, alicesk, k); - ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(unsigned char), + ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(unsigned char), c); + clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); - ck_assert_msg(clen == sizeof(c) / sizeof(unsigned char), "wrong ciphertext length"); + ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(unsigned char), m); + mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); - ck_assert_msg(mlen == sizeof(m) / sizeof(unsigned char), "wrong plaintext length"); + ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); } static void test_endtoend(void) { // Test 100 random messages and keypairs for (uint8_t testno = 0; testno < 100; testno++) { - unsigned char pk1[CRYPTO_PUBLIC_KEY_SIZE]; - unsigned char sk1[CRYPTO_SECRET_KEY_SIZE]; - unsigned char pk2[CRYPTO_PUBLIC_KEY_SIZE]; - unsigned char sk2[CRYPTO_SECRET_KEY_SIZE]; - unsigned char k1[CRYPTO_SHARED_KEY_SIZE]; - unsigned char k2[CRYPTO_SHARED_KEY_SIZE]; - - unsigned char n[CRYPTO_NONCE_SIZE]; - - unsigned char m[500]; - unsigned char c1[sizeof(m) + CRYPTO_MAC_SIZE]; - unsigned char c2[sizeof(m) + CRYPTO_MAC_SIZE]; - unsigned char c3[sizeof(m) + CRYPTO_MAC_SIZE]; - unsigned char c4[sizeof(m) + CRYPTO_MAC_SIZE]; - unsigned char m1[sizeof(m)]; - unsigned char m2[sizeof(m)]; - unsigned char m3[sizeof(m)]; - unsigned char m4[sizeof(m)]; - - //Generate random message (random length from 100 to 500) - const uint16_t mlen = (random_u32() % 400) + 100; + uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; + uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; + uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; + uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; + + uint8_t n[CRYPTO_NONCE_SIZE]; + + enum { M_SIZE = 50 }; + uint8_t m[M_SIZE]; + uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t m1[sizeof(m)]; + uint8_t m2[sizeof(m)]; + uint8_t m3[sizeof(m)]; + uint8_t m4[sizeof(m)]; + + //Generate random message (random length from 10 to 50) + const uint16_t mlen = (random_u32() % (M_SIZE - 10)) + 10; rand_bytes(m, mlen); rand_bytes(n, CRYPTO_NONCE_SIZE); @@ -192,67 +193,77 @@ static void test_endtoend(void) static void test_large_data(void) { - unsigned char k[CRYPTO_SHARED_KEY_SIZE]; - - unsigned char n[CRYPTO_NONCE_SIZE]; + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; + uint8_t n[CRYPTO_NONCE_SIZE]; - unsigned char m1[MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE]; - unsigned char c1[sizeof(m1) + CRYPTO_MAC_SIZE]; - unsigned char m1prime[sizeof(m1)]; + const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; + uint8_t *m1 = (uint8_t *)malloc(m1_size); + uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); + uint8_t *m1prime = (uint8_t *)malloc(m1_size); - unsigned char m2[MAX_CRYPTO_PACKET_SIZE]; - unsigned char c2[sizeof(m2) + CRYPTO_MAC_SIZE]; + const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; + uint8_t *m2 = (uint8_t *)malloc(m2_size); + uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); - uint16_t c1len, c2len; - uint16_t m1plen; + ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); //Generate random messages - rand_bytes(m1, sizeof(m1)); - rand_bytes(m2, sizeof(m2)); + rand_bytes(m1, m1_size); + rand_bytes(m2, m2_size); rand_bytes(n, CRYPTO_NONCE_SIZE); //Generate key rand_bytes(k, CRYPTO_SHARED_KEY_SIZE); - c1len = encrypt_data_symmetric(k, n, m1, sizeof(m1), c1); - c2len = encrypt_data_symmetric(k, n, m2, sizeof(m2), c2); + const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); + const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2); + + ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); + ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); - ck_assert_msg(c1len == sizeof(m1) + CRYPTO_MAC_SIZE, "could not encrypt"); - ck_assert_msg(c2len == sizeof(m2) + CRYPTO_MAC_SIZE, "could not encrypt"); + const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); + ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - ck_assert_msg(m1plen == sizeof(m1), "decrypted text lengths differ"); - ck_assert_msg(memcmp(m1prime, m1, sizeof(m1)) == 0, "decrypted texts differ"); + free(c2); + free(m2); + free(m1prime); + free(c1); + free(m1); } static void test_large_data_symmetric(void) { - unsigned char k[CRYPTO_SYMMETRIC_KEY_SIZE]; + uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; - unsigned char n[CRYPTO_NONCE_SIZE]; + uint8_t n[CRYPTO_NONCE_SIZE]; - unsigned char m1[16 * 16 * 16]; - unsigned char c1[sizeof(m1) + CRYPTO_MAC_SIZE]; - unsigned char m1prime[sizeof(m1)]; + const size_t m1_size = 16 * 16 * 16; + uint8_t *m1 = (uint8_t *)malloc(m1_size); + uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); + uint8_t *m1prime = (uint8_t *)malloc(m1_size); - uint16_t c1len; - uint16_t m1plen; + ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); //Generate random messages - rand_bytes(m1, sizeof(m1)); + rand_bytes(m1, m1_size); rand_bytes(n, CRYPTO_NONCE_SIZE); //Generate key new_symmetric_key(k); - c1len = encrypt_data_symmetric(k, n, m1, sizeof(m1), c1); - ck_assert_msg(c1len == sizeof(m1) + CRYPTO_MAC_SIZE, "could not encrypt data"); + const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); + ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data"); + + const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); + ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - ck_assert_msg(m1plen == sizeof(m1), "decrypted text lengths differ"); - ck_assert_msg(memcmp(m1prime, m1, sizeof(m1)) == 0, "decrypted texts differ"); + free(m1prime); + free(c1); + free(m1); } static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) diff --git a/other/analysis/run-gcc b/other/analysis/run-gcc index 563b6da6cf..2466c88cec 100755 --- a/other/analysis/run-gcc +++ b/other/analysis/run-gcc @@ -43,7 +43,7 @@ run() { -Wfloat-equal \ -Wformat=2 \ -Wframe-address \ - -Wframe-larger-than=12400 \ + -Wframe-larger-than=9000 \ -Wignored-attributes \ -Wignored-qualifiers \ -Winit-self \ From cc31ff07fabda4dde59c201c0a5bd47b8af00498 Mon Sep 17 00:00:00 2001 From: iphydf Date: Sun, 27 Mar 2022 21:34:12 +0000 Subject: [PATCH 2/2] feat: Add support for custom random number generator. This can be used by fuzzers to make RNG-driven code deterministic (i.e. based on the fuzzer input). --- auto_tests/TCP_test.c | 100 ++++++++++-------- auto_tests/conference_av_test.c | 10 +- auto_tests/conference_test.c | 10 +- auto_tests/crypto_test.c | 42 +++++--- auto_tests/encryptsave_test.c | 4 +- auto_tests/network_test.c | 11 +- auto_tests/onion_test.c | 46 ++++---- auto_tests/reconnect_test.c | 4 +- auto_tests/save_friend_test.c | 14 +-- auto_tests/tox_many_tcp_test.c | 12 ++- auto_tests/tox_many_test.c | 6 +- other/DHT_bootstrap.c | 9 +- .../docker/tox-bootstrapd.sha256 | 2 +- other/bootstrap_daemon/src/tox-bootstrapd.c | 11 +- testing/Messenger_test.c | 2 +- toxav/BUILD.bazel | 1 + toxav/groupav.c | 3 +- toxav/rtp.c | 2 +- toxav/rtp_test.cc | 36 ++++--- toxav/toxav.c | 2 +- toxcore/DHT.c | 56 +++++----- toxcore/DHT.h | 8 +- toxcore/DHT_test.cc | 43 +++++--- toxcore/Messenger.c | 17 +-- toxcore/Messenger.h | 3 +- toxcore/TCP_client.c | 15 ++- toxcore/TCP_client.h | 5 +- toxcore/TCP_common.h | 1 + toxcore/TCP_connection.c | 17 +-- toxcore/TCP_connection.h | 5 +- toxcore/TCP_server.c | 21 ++-- toxcore/TCP_server.h | 7 +- toxcore/crypto_core.c | 76 +++++++++---- toxcore/crypto_core.h | 38 +++++-- toxcore/crypto_core_test.cc | 5 +- toxcore/group.c | 9 +- toxcore/group.h | 3 +- toxcore/group_moderation_test.cc | 5 +- toxcore/net_crypto.c | 34 +++--- toxcore/net_crypto.h | 2 +- toxcore/network.c | 76 ++++--------- toxcore/network.h | 8 +- toxcore/onion.c | 30 +++--- toxcore/onion.h | 11 +- toxcore/onion_announce.c | 33 +++--- toxcore/onion_announce.h | 18 ++-- toxcore/onion_client.c | 60 ++++++----- toxcore/onion_client.h | 2 +- toxcore/ping.c | 10 +- toxcore/ping.h | 2 +- toxcore/ping_array.c | 6 +- toxcore/ping_array.h | 9 +- toxcore/ping_array_test.cc | 24 +++-- toxcore/tox.c | 27 +++-- toxcore/tox_events_test.cc | 4 +- toxcore/tox_struct.h | 1 + toxcore/tox_test.cc | 13 ++- toxcore/util_test.cc | 10 +- toxencryptsave/toxencryptsave.c | 4 +- 59 files changed, 587 insertions(+), 458 deletions(-) diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index 2b1110e399..33205e8946 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c @@ -46,15 +46,17 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643}; static void test_basic(void) { Mono_Time *mono_time = mono_time_new(); + const Random *rng = system_random(); + ck_assert(rng != nullptr); Logger *logger = logger_new(); logger_callback_log(logger, (logger_cb *)print_debug_log, nullptr, nullptr); // Attempt to create a new TCP_Server instance. uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(self_public_key, self_secret_key); + crypto_new_keypair(rng, self_public_key, self_secret_key); const Network *ns = system_network(); - TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); + TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS); @@ -81,19 +83,19 @@ static void test_basic(void) uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t f_nonce[CRYPTO_NONCE_SIZE]; - crypto_new_keypair(f_public_key, f_secret_key); - random_nonce(f_nonce); + crypto_new_keypair(rng, f_public_key, f_secret_key); + random_nonce(rng, f_nonce); // Generation of the initial handshake. uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t *handshake_plain = (uint8_t *)malloc(TCP_HANDSHAKE_PLAIN_SIZE); ck_assert(handshake_plain != nullptr); - crypto_new_keypair(handshake_plain, t_secret_key); + crypto_new_keypair(rng, handshake_plain, t_secret_key); memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, f_nonce, CRYPTO_NONCE_SIZE); uint8_t *handshake = (uint8_t *)malloc(TCP_CLIENT_HANDSHAKE_SIZE); ck_assert(handshake != nullptr); memcpy(handshake, f_public_key, CRYPTO_PUBLIC_KEY_SIZE); - random_nonce(handshake + CRYPTO_PUBLIC_KEY_SIZE); + random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); // Encrypting handshake int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, @@ -194,7 +196,7 @@ struct sec_TCP_con { uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; }; -static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time) +static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time) { struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con)); ck_assert(sec_c != nullptr); @@ -203,22 +205,22 @@ static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Network *ns, IP_Port localhost; localhost.ip = get_loopback(); - localhost.port = net_htons(ports[random_u32() % NUM_PORTS]); + localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); bool ok = net_connect(logger, sock, &localhost); ck_assert_msg(ok, "Failed to connect to the test TCP relay server."); uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(sec_c->public_key, f_secret_key); - random_nonce(sec_c->sent_nonce); + crypto_new_keypair(rng, sec_c->public_key, f_secret_key); + random_nonce(rng, sec_c->sent_nonce); uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t handshake_plain[TCP_HANDSHAKE_PLAIN_SIZE]; - crypto_new_keypair(handshake_plain, t_secret_key); + crypto_new_keypair(rng, handshake_plain, t_secret_key); memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, sec_c->sent_nonce, CRYPTO_NONCE_SIZE); uint8_t handshake[TCP_CLIENT_HANDSHAKE_SIZE]; memcpy(handshake, sec_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); - random_nonce(handshake + CRYPTO_PUBLIC_KEY_SIZE); + random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); @@ -296,19 +298,21 @@ static int read_packet_sec_TCP(const Logger *logger, struct sec_TCP_con *con, ui static void test_some(void) { Mono_Time *mono_time = mono_time_new(); + const Random *rng = system_random(); + ck_assert(rng != nullptr); Logger *logger = logger_new(); const Network *ns = system_network(); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(self_public_key, self_secret_key); - TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); + crypto_new_keypair(rng, self_public_key, self_secret_key); + TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server"); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports."); - struct sec_TCP_con *con1 = new_TCP_con(logger, ns, tcp_s, mono_time); - struct sec_TCP_con *con2 = new_TCP_con(logger, ns, tcp_s, mono_time); - struct sec_TCP_con *con3 = new_TCP_con(logger, ns, tcp_s, mono_time); + struct sec_TCP_con *con1 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); + struct sec_TCP_con *con2 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); + struct sec_TCP_con *con3 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE]; requ_p[0] = TCP_PACKET_ROUTING_REQUEST; @@ -484,26 +488,28 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint static void test_client(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); Mono_Time *mono_time = mono_time_new(); Logger *logger = logger_new(); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(self_public_key, self_secret_key); + crypto_new_keypair(rng, self_public_key, self_secret_key); const Network *ns = system_network(); - TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); + TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports."); uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(f_public_key, f_secret_key); + crypto_new_keypair(rng, f_public_key, f_secret_key); IP_Port ip_port_tcp_s; - ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]); + ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); - TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s, self_public_key, f_public_key, + TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); do_TCP_connection(logger, mono_time, conn, nullptr); c_sleep(50); @@ -536,9 +542,9 @@ static void test_client(void) uint8_t f2_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(f2_public_key, f2_secret_key); - ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]); - TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s, self_public_key, f2_public_key, + crypto_new_keypair(rng, f2_public_key, f2_secret_key); + ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); + TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, f2_secret_key, nullptr); // The client should call this function (defined earlier) during the routing process. @@ -613,22 +619,24 @@ static void test_client(void) // Test how the client handles servers that don't respond. static void test_client_invalid(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); Mono_Time *mono_time = mono_time_new(); Logger *logger = logger_new(); const Network *ns = system_network(); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(self_public_key, self_secret_key); + crypto_new_keypair(rng, self_public_key, self_secret_key); uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(f_public_key, f_secret_key); + crypto_new_keypair(rng, f_public_key, f_secret_key); IP_Port ip_port_tcp_s; - ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]); + ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); - TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s, + TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); // Run the client's main loop but not the server. @@ -688,28 +696,30 @@ static void test_tcp_connection(void) { Mono_Time *mono_time = mono_time_new(); Logger *logger = logger_new(); + const Random *rng = system_random(); + ck_assert(rng != nullptr); const Network *ns = system_network(); tcp_data_callback_called = 0; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(self_public_key, self_secret_key); - TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); + crypto_new_keypair(rng, self_public_key, self_secret_key); + TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); TCP_Proxy_Info proxy_info; proxy_info.proxy_type = TCP_PROXY_NONE; - crypto_new_keypair(self_public_key, self_secret_key); - TCP_Connections *tc_1 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info); + crypto_new_keypair(rng, self_public_key, self_secret_key); + TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); - crypto_new_keypair(self_public_key, self_secret_key); - TCP_Connections *tc_2 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info); + crypto_new_keypair(rng, self_public_key, self_secret_key); + TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); IP_Port ip_port_tcp_s; - ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]); + ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123); @@ -717,7 +727,7 @@ static void test_tcp_connection(void) ck_assert_msg(add_tcp_relay_connection(tc_1, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, "Could not add tcp relay to connection\n"); - ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]); + ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); connection = new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123); ck_assert_msg(connection == 0, "Connection id wrong"); ck_assert_msg(add_tcp_relay_connection(tc_2, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, @@ -795,6 +805,8 @@ static void test_tcp_connection2(void) { Mono_Time *mono_time = mono_time_new(); Logger *logger = logger_new(); + const Random *rng = system_random(); + ck_assert(rng != nullptr); const Network *ns = system_network(); tcp_oobdata_callback_called = 0; @@ -802,23 +814,23 @@ static void test_tcp_connection2(void) uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(self_public_key, self_secret_key); - TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); + crypto_new_keypair(rng, self_public_key, self_secret_key); + TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); TCP_Proxy_Info proxy_info; proxy_info.proxy_type = TCP_PROXY_NONE; - crypto_new_keypair(self_public_key, self_secret_key); - TCP_Connections *tc_1 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info); + crypto_new_keypair(rng, self_public_key, self_secret_key); + TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); - crypto_new_keypair(self_public_key, self_secret_key); - TCP_Connections *tc_2 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info); + crypto_new_keypair(rng, self_public_key, self_secret_key); + TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); IP_Port ip_port_tcp_s; - ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]); + ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123); diff --git a/auto_tests/conference_av_test.c b/auto_tests/conference_av_test.c index b8c05574d3..f0557fd9e6 100644 --- a/auto_tests/conference_av_test.c +++ b/auto_tests/conference_av_test.c @@ -165,12 +165,12 @@ static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes) * returns a random index at which a list of booleans is false * (some such index is required to exist) */ -static uint32_t random_false_index(bool *list, const uint32_t length) +static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length) { uint32_t index; do { - index = random_u32() % length; + index = random_u32(rng) % length; } while (list[index]); return index; @@ -287,6 +287,8 @@ static void do_audio(AutoTox *autotoxes, uint32_t iterations) static void run_conference_tests(AutoTox *autotoxes) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); bool disabled[NUM_AV_GROUP_TOX] = {0}; test_audio(autotoxes, disabled, false); @@ -302,7 +304,7 @@ static void run_conference_tests(AutoTox *autotoxes) ck_assert(NUM_AV_DISCONNECT < NUM_AV_GROUP_TOX); for (uint32_t i = 0; i < NUM_AV_DISCONNECT; ++i) { - uint32_t disconnect = random_false_index(disconnected, NUM_AV_GROUP_TOX); + uint32_t disconnect = random_false_index(rng, disconnected, NUM_AV_GROUP_TOX); disconnected[disconnect] = true; if (i < NUM_AV_DISCONNECT / 2) { @@ -358,7 +360,7 @@ static void run_conference_tests(AutoTox *autotoxes) ck_assert(NUM_AV_DISABLE < NUM_AV_GROUP_TOX); for (uint32_t i = 0; i < NUM_AV_DISABLE; ++i) { - uint32_t disable = random_false_index(disabled, NUM_AV_GROUP_TOX); + uint32_t disable = random_false_index(rng, disabled, NUM_AV_GROUP_TOX); disabled[disable] = true; printf("Disabling #%u\n", autotoxes[disable].index); ck_assert_msg(toxav_groupchat_enable_av(autotoxes[disable].tox, 0, audio_callback, &autotoxes[disable]) != 0, diff --git a/auto_tests/conference_test.c b/auto_tests/conference_test.c index fd0ebdb69c..b5520200c1 100644 --- a/auto_tests/conference_test.c +++ b/auto_tests/conference_test.c @@ -179,12 +179,12 @@ static bool names_propagated(uint32_t tox_count, AutoTox *autotoxes) * returns a random index at which a list of booleans is false * (some such index is required to exist) */ -static uint32_t random_false_index(bool *list, const uint32_t length) +static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length) { uint32_t index; do { - index = random_u32() % length; + index = random_u32(rng) % length; } while (list[index]); return index; @@ -192,6 +192,8 @@ static uint32_t random_false_index(bool *list, const uint32_t length) static void run_conference_tests(AutoTox *autotoxes) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); /* disabling name change propagation check for now, as it occasionally * fails due to disconnections too short to trigger freezing */ const bool check_name_change_propagation = false; @@ -215,7 +217,7 @@ static void run_conference_tests(AutoTox *autotoxes) ck_assert(NUM_DISCONNECT < NUM_GROUP_TOX); for (uint32_t i = 0; i < NUM_DISCONNECT; ++i) { - uint32_t disconnect = random_false_index(disconnected, NUM_GROUP_TOX); + uint32_t disconnect = random_false_index(rng, disconnected, NUM_GROUP_TOX); disconnected[disconnect] = true; if (i < NUM_DISCONNECT / 2) { @@ -292,7 +294,7 @@ static void run_conference_tests(AutoTox *autotoxes) Tox_Err_Conference_Send_Message err; ck_assert_msg( tox_conference_send_message( - autotoxes[random_u32() % NUM_GROUP_TOX].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE, + autotoxes[random_u32(rng) % NUM_GROUP_TOX].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE, sizeof(GROUP_MESSAGE) - 1, &err) != 0, "failed to send group message"); ck_assert_msg( err == TOX_ERR_CONFERENCE_SEND_MESSAGE_OK, "failed to send group message"); diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 0c7866f943..f4fdf3e22d 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -7,12 +7,12 @@ #include "../toxcore/net_crypto.h" #include "check_compat.h" -static void rand_bytes(uint8_t *b, size_t blen) +static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) { size_t i; for (i = 0; i < blen; i++) { - b[i] = random_u08(); + b[i] = random_u08(rng); } } @@ -129,6 +129,9 @@ static void test_fast_known(void) static void test_endtoend(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); + // Test 100 random messages and keypairs for (uint8_t testno = 0; testno < 100; testno++) { uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; @@ -152,13 +155,13 @@ static void test_endtoend(void) uint8_t m4[sizeof(m)]; //Generate random message (random length from 10 to 50) - const uint16_t mlen = (random_u32() % (M_SIZE - 10)) + 10; - rand_bytes(m, mlen); - rand_bytes(n, CRYPTO_NONCE_SIZE); + const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; + rand_bytes(rng, m, mlen); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); //Generate keypairs - crypto_new_keypair(pk1, sk1); - crypto_new_keypair(pk2, sk2); + crypto_new_keypair(rng, pk1, sk1); + crypto_new_keypair(rng, pk2, sk2); //Precompute shared keys encrypt_precompute(pk2, sk1, k1); @@ -193,6 +196,8 @@ static void test_endtoend(void) static void test_large_data(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE]; @@ -208,12 +213,12 @@ static void test_large_data(void) ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); //Generate random messages - rand_bytes(m1, m1_size); - rand_bytes(m2, m2_size); - rand_bytes(n, CRYPTO_NONCE_SIZE); + rand_bytes(rng, m1, m1_size); + rand_bytes(rng, m2, m2_size); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); //Generate key - rand_bytes(k, CRYPTO_SHARED_KEY_SIZE); + rand_bytes(rng, k, CRYPTO_SHARED_KEY_SIZE); const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2); @@ -235,6 +240,8 @@ static void test_large_data(void) static void test_large_data_symmetric(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE]; @@ -247,11 +254,11 @@ static void test_large_data_symmetric(void) ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); //Generate random messages - rand_bytes(m1, m1_size); - rand_bytes(n, CRYPTO_NONCE_SIZE); + rand_bytes(rng, m1, m1_size); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); //Generate key - new_symmetric_key(k); + new_symmetric_key(rng, k); const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data"); @@ -289,12 +296,15 @@ static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) static void test_increment_nonce(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); + uint32_t i; uint8_t n[CRYPTO_NONCE_SIZE]; for (i = 0; i < CRYPTO_NONCE_SIZE; ++i) { - n[i] = random_u08(); + n[i] = random_u08(rng); } uint8_t n1[CRYPTO_NONCE_SIZE]; @@ -308,7 +318,7 @@ static void test_increment_nonce(void) } for (i = 0; i < (1 << 18); ++i) { - const uint32_t r = random_u32(); + const uint32_t r = random_u32(rng); increment_nonce_number_cmp(n, r); increment_nonce_number(n1, r); ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce_number function"); diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c index 1388170535..fb49c4e2af 100644 --- a/auto_tests/encryptsave_test.c +++ b/auto_tests/encryptsave_test.c @@ -169,7 +169,9 @@ static void test_keys(void) ck_assert(encrypted2a != nullptr); uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a); ck_assert(in_plaintext2a != nullptr); - random_bytes(in_plaintext2a, plaintext_length2a); + const Random *rng = system_random(); + ck_assert(rng != nullptr); + random_bytes(rng, in_plaintext2a, plaintext_length2a); ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr); ck_assert_msg(ret, "tox_pass_encrypt failure 2a: %d", encerr); diff --git a/auto_tests/network_test.c b/auto_tests/network_test.c index f79d86e365..6d105262ad 100644 --- a/auto_tests/network_test.c +++ b/auto_tests/network_test.c @@ -162,19 +162,12 @@ static void test_ip_equal(void) ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET6, ::1}, {TOX_AF_INET6, ::2} ): expected result 0, got %d.", res); } -static void network_suite(void) -{ - networking_at_startup(); - - test_addr_resolv_localhost(); - test_ip_equal(); -} - int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); - network_suite(); + test_addr_resolv_localhost(); + test_ip_equal(); return 0; } diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index dbb8d344b0..0e7a5e2e40 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -169,10 +169,10 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac * Use Onion_Path path to send data of length to dest. * Maximum length of data is ONION_MAX_DATA_SIZE. */ -static void send_onion_packet(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) +static void send_onion_packet(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - const int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length); ck_assert_msg(len != -1, "failed to create onion packet"); ck_assert_msg(sendpacket(net, &path->ip_port1, packet, len) == len, "failed to send onion packet"); } @@ -195,12 +195,14 @@ static void test_basic(void) Logger *log2 = logger_new(); logger_callback_log(log2, (logger_cb *)print_debug_log, nullptr, &index[1]); + const Random *rng = system_random(); + ck_assert(rng != nullptr); Mono_Time *mono_time1 = mono_time_new(); Mono_Time *mono_time2 = mono_time_new(); IP ip = get_loopback(); - Onion *onion1 = new_onion(log1, mono_time1, new_dht(log1, ns, mono_time1, new_networking(log1, ns, &ip, 36567), true, false)); - Onion *onion2 = new_onion(log2, mono_time2, new_dht(log2, ns, mono_time2, new_networking(log2, ns, &ip, 36568), true, false)); + Onion *onion1 = new_onion(log1, mono_time1, rng, new_dht(log1, rng, ns, mono_time1, new_networking(log1, ns, &ip, 36567), true, false)); + Onion *onion2 = new_onion(log2, mono_time2, rng, new_dht(log2, rng, ns, mono_time2, new_networking(log2, ns, &ip, 36568), true, false)); ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing."); networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST_OLD, &handle_test_1, onion2); @@ -225,8 +227,8 @@ static void test_basic(void) nodes[2] = n1; nodes[3] = n2; Onion_Path path; - create_onion_path(onion1->dht, &path, nodes); - send_onion_packet(onion1->net, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet)); + create_onion_path(rng, onion1->dht, &path, nodes); + send_onion_packet(onion1->net, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet)); handled_test_1 = 0; @@ -243,16 +245,16 @@ static void test_basic(void) do_onion(mono_time2, onion2); } while (handled_test_2 == 0); - Onion_Announce *onion1_a = new_onion_announce(log1, mono_time1, onion1->dht); - Onion_Announce *onion2_a = new_onion_announce(log2, mono_time2, onion2->dht); + Onion_Announce *onion1_a = new_onion_announce(log1, rng, mono_time1, onion1->dht); + Onion_Announce *onion2_a = new_onion_announce(log2, rng, mono_time2, onion2->dht); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3, onion1); ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing."); uint8_t zeroes[64] = {0}; - random_bytes(sb_data, sizeof(sb_data)); + random_bytes(rng, sb_data, sizeof(sb_data)); uint64_t s; memcpy(&s, sb_data, sizeof(uint64_t)); memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE); - int ret = send_announce_request(onion1->net, &path, &nodes[3], + int ret = send_announce_request(onion1->net, rng, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), zeroes, @@ -267,12 +269,12 @@ static void test_basic(void) c_sleep(50); } while (handled_test_3 == 0); - random_bytes(sb_data, sizeof(sb_data)); + random_bytes(rng, sb_data, sizeof(sb_data)); memcpy(&s, sb_data, sizeof(uint64_t)); memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE); onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2)); networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); - send_announce_request(onion1->net, &path, &nodes[3], + send_announce_request(onion1->net, rng, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), test_3_ping_id, @@ -293,11 +295,11 @@ static void test_basic(void) Mono_Time *mono_time3 = mono_time_new(); - Onion *onion3 = new_onion(log3, mono_time3, new_dht(log3, ns, mono_time3, new_networking(log3, ns, &ip, 36569), true, false)); + Onion *onion3 = new_onion(log3, mono_time3, rng, new_dht(log3, rng, ns, mono_time3, new_networking(log3, ns, &ip, 36569), true, false)); ck_assert_msg((onion3 != nullptr), "Onion failed initializing."); - random_nonce(nonce); - ret = send_data_request(onion3->net, &path, &nodes[3].ip_port, + random_nonce(rng, nonce); + ret = send_data_request(onion3->net, rng, &path, &nodes[3].ip_port, dht_get_self_public_key(onion1->dht), dht_get_self_public_key(onion1->dht), nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo")); @@ -358,7 +360,7 @@ typedef struct { Onion_Client *onion_c; } Onions; -static Onions *new_onions(uint16_t port, uint32_t *index) +static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) { IP ip = get_loopback(); ip.ip.v6.uint8[15] = 1; @@ -395,7 +397,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index) return nullptr; } - DHT *dht = new_dht(on->log, ns, on->mono_time, net, true, false); + DHT *dht = new_dht(on->log, rng, ns, on->mono_time, net, true, false); if (!dht) { kill_networking(net); @@ -405,7 +407,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index) return nullptr; } - on->onion = new_onion(on->log, on->mono_time, dht); + on->onion = new_onion(on->log, on->mono_time, rng, dht); if (!on->onion) { kill_dht(dht); @@ -416,7 +418,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index) return nullptr; } - on->onion_a = new_onion_announce(on->log, on->mono_time, dht); + on->onion_a = new_onion_announce(on->log, rng, on->mono_time, dht); if (!on->onion_a) { kill_onion(on->onion); @@ -429,7 +431,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index) } TCP_Proxy_Info inf = {{{{0}}}}; - on->onion_c = new_onion_client(on->log, on->mono_time, new_net_crypto(on->log, on->mono_time, ns, dht, &inf)); + on->onion_c = new_onion_client(on->log, rng, on->mono_time, new_net_crypto(on->log, rng, ns, on->mono_time, dht, &inf)); if (!on->onion_c) { kill_onion_announce(on->onion_a); @@ -532,10 +534,12 @@ static void test_announce(void) uint32_t i, j; uint32_t index[NUM_ONIONS]; Onions *onions[NUM_ONIONS]; + const Random *rng = system_random(); + ck_assert(rng != nullptr); for (i = 0; i < NUM_ONIONS; ++i) { index[i] = i + 1; - onions[i] = new_onions(i + 36655, &index[i]); + onions[i] = new_onions(rng, i + 36655, &index[i]); ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i); } diff --git a/auto_tests/reconnect_test.c b/auto_tests/reconnect_test.c index 91c60cdada..bf01660808 100644 --- a/auto_tests/reconnect_test.c +++ b/auto_tests/reconnect_test.c @@ -51,6 +51,8 @@ static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32 static void test_reconnect(AutoTox *autotoxes) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); const time_t test_start_time = time(nullptr); printf("letting connections settle\n"); @@ -59,7 +61,7 @@ static void test_reconnect(AutoTox *autotoxes) iterate_all_wait(autotoxes, TOX_COUNT, ITERATION_INTERVAL); } while (time(nullptr) - test_start_time < 2); - uint16_t disconnect = random_u16() % TOX_COUNT; + const uint16_t disconnect = random_u16(rng) % TOX_COUNT; printf("disconnecting #%u\n", autotoxes[disconnect].index); do { diff --git a/auto_tests/save_friend_test.c b/auto_tests/save_friend_test.c index 5002c2fa33..80a6ed037e 100644 --- a/auto_tests/save_friend_test.c +++ b/auto_tests/save_friend_test.c @@ -19,13 +19,13 @@ struct test_data { bool received_status_message; }; -static void set_random(Tox *m, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length) +static void set_random(Tox *m, const Random *rng, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length) { VLA(uint8_t, text, length); uint32_t i; for (i = 0; i < length; ++i) { - text[i] = random_u08(); + text[i] = random_u08(rng); } setter(m, text, SIZEOF_VLA(text), nullptr); @@ -86,10 +86,12 @@ int main(void) ck_assert(reference_name != nullptr); ck_assert(reference_status != nullptr); - set_random(tox1, tox_self_set_name, tox_max_name_length()); - set_random(tox2, tox_self_set_name, tox_max_name_length()); - set_random(tox1, tox_self_set_status_message, tox_max_status_message_length()); - set_random(tox2, tox_self_set_status_message, tox_max_status_message_length()); + const Random *rng = system_random(); + ck_assert(rng != nullptr); + set_random(tox1, rng, tox_self_set_name, tox_max_name_length()); + set_random(tox2, rng, tox_self_set_name, tox_max_name_length()); + set_random(tox1, rng, tox_self_set_status_message, tox_max_status_message_length()); + set_random(tox2, rng, tox_self_set_status_message, tox_max_status_message_length()); tox_self_get_name(tox2, reference_name); tox_self_get_status_message(tox2, reference_status); diff --git a/auto_tests/tox_many_tcp_test.c b/auto_tests/tox_many_tcp_test.c index b406bc83e1..f466e3e171 100644 --- a/auto_tests/tox_many_tcp_test.c +++ b/auto_tests/tox_many_tcp_test.c @@ -41,6 +41,8 @@ static uint16_t tcp_relay_port = 33448; static void test_many_clients_tcp(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; uint32_t index[NUM_TOXES_TCP]; @@ -88,8 +90,8 @@ static void test_many_clients_tcp(void) for (i = 0; i < NUM_FRIENDS; ++i) { loop_top: - pairs[i].tox1 = random_u32() % NUM_TOXES_TCP; - pairs[i].tox2 = (pairs[i].tox1 + random_u32() % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP; + pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP; + pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP; for (j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { @@ -142,6 +144,8 @@ static void test_many_clients_tcp(void) static void test_many_clients_tcp_b(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; uint32_t index[NUM_TOXES_TCP]; @@ -181,8 +185,8 @@ static void test_many_clients_tcp_b(void) for (i = 0; i < NUM_FRIENDS; ++i) { loop_top: - pairs[i].tox1 = random_u32() % NUM_TOXES_TCP; - pairs[i].tox2 = (pairs[i].tox1 + random_u32() % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP; + pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP; + pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP; for (j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { diff --git a/auto_tests/tox_many_test.c b/auto_tests/tox_many_test.c index 7ae319e67d..8501b5c172 100644 --- a/auto_tests/tox_many_test.c +++ b/auto_tests/tox_many_test.c @@ -26,6 +26,8 @@ static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8 static void test_many_clients(void) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); time_t cur_time = time(nullptr); Tox *toxes[TCP_TEST_NUM_TOXES]; uint32_t index[TCP_TEST_NUM_TOXES]; @@ -54,8 +56,8 @@ static void test_many_clients(void) for (uint32_t i = 0; i < TCP_TEST_NUM_FRIENDS; ++i) { loop_top: - pairs[i].tox1 = random_u32() % TCP_TEST_NUM_TOXES; - pairs[i].tox2 = (pairs[i].tox1 + random_u32() % (TCP_TEST_NUM_TOXES - 1) + 1) % TCP_TEST_NUM_TOXES; + pairs[i].tox1 = random_u32(rng) % TCP_TEST_NUM_TOXES; + pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (TCP_TEST_NUM_TOXES - 1) + 1) % TCP_TEST_NUM_TOXES; for (uint32_t j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 669ea327d1..0433385e58 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -143,12 +143,13 @@ int main(int argc, char *argv[]) } Mono_Time *mono_time = mono_time_new(); + const Random *rng = system_random(); const uint16_t start_port = PORT; const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); const Network *ns = system_network(); - DHT *dht = new_dht(logger, ns, mono_time, new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr), true, true); - Onion *onion = new_onion(logger, mono_time, dht); - const Onion_Announce *onion_a = new_onion_announce(logger, mono_time, dht); + DHT *dht = new_dht(logger, rng, ns, mono_time, new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr), true, true); + Onion *onion = new_onion(logger, mono_time, rng, dht); + const Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht); #ifdef DHT_NODE_EXTRA_PACKETS bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD)); @@ -167,7 +168,7 @@ int main(int argc, char *argv[]) #ifdef TCP_RELAY_ENABLED #define NUM_PORTS 3 uint16_t ports[NUM_PORTS] = {443, 3389, PORT}; - TCP_Server *tcp_s = new_TCP_server(logger, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion); + TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion); if (tcp_s == nullptr) { printf("TCP server failed to initialize.\n"); diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index 154877deca..94e53bb839 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -c40a0017ec22042f0be897893a774b89a6b6fbb621ac4d7f68416134fe4a78a2 /usr/local/bin/tox-bootstrapd +f5e4829db74abffd2c625e2413730e474a4c8bf999d56a0d2009a38be9d01dec /usr/local/bin/tox-bootstrapd diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index 28afa4a5ee..95a8226ada 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -320,7 +320,8 @@ int main(int argc, char *argv[]) mono_time_update(mono_time); - DHT *const dht = new_dht(logger, ns, mono_time, net, true, enable_lan_discovery); + const Random *rng = system_random(); + DHT *const dht = new_dht(logger, rng, ns, mono_time, net, true, enable_lan_discovery); if (dht == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); @@ -333,7 +334,7 @@ int main(int argc, char *argv[]) return 1; } - Onion *onion = new_onion(logger, mono_time, dht); + Onion *onion = new_onion(logger, mono_time, rng, dht); if (!onion) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n"); @@ -347,7 +348,7 @@ int main(int argc, char *argv[]) return 1; } - Onion_Announce *onion_a = new_onion_announce(logger, mono_time, dht); + Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht); if (!onion_a) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n"); @@ -412,8 +413,8 @@ int main(int argc, char *argv[]) return 1; } - tcp_server = new_TCP_server(logger, ns, enable_ipv6, tcp_relay_port_count, tcp_relay_ports, - dht_get_self_secret_key(dht), onion); + tcp_server = new_TCP_server( + logger, rng, ns, enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion); free(tcp_relay_ports); diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index e162ddf072..0fd4aa3239 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -102,7 +102,7 @@ int main(int argc, char *argv[]) Messenger_Options options = {0}; options.ipv6enabled = ipv6enabled; Messenger_Error err; - m = new_messenger(mono_time, system_network(), &options, &err); + m = new_messenger(mono_time, system_random(), system_network(), &options, &err); if (!m) { fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err); diff --git a/toxav/BUILD.bazel b/toxav/BUILD.bazel index 5026b53a2b..bfaab8ec65 100644 --- a/toxav/BUILD.bazel +++ b/toxav/BUILD.bazel @@ -131,6 +131,7 @@ cc_library( "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:mono_time", + "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:util", "@opus", ], diff --git a/toxav/groupav.c b/toxav/groupav.c index 1dc904fa95..583304c6a3 100644 --- a/toxav/groupav.c +++ b/toxav/groupav.c @@ -10,6 +10,7 @@ #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/tox_struct.h" #include "../toxcore/util.h" #define GROUP_JBUF_SIZE 6 @@ -535,7 +536,7 @@ bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t groupnumber) */ int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata) { - const int groupnumber = add_groupchat(g_c, GROUPCHAT_TYPE_AV); + const int groupnumber = add_groupchat(g_c, &tox->rng, GROUPCHAT_TYPE_AV); if (groupnumber == -1) { return -1; diff --git a/toxav/rtp.c b/toxav/rtp.c index 212dd77435..878a70ca44 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c @@ -673,7 +673,7 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum // First entry is free. session->work_buffer_list->next_free_entry = 0; - session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : random_u32(); + session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : random_u32(m->rng); session->payload_type = payload_type; session->m = m; session->tox = tox; diff --git a/toxav/rtp_test.cc b/toxav/rtp_test.cc index 5700c0d546..b29c937ac9 100644 --- a/toxav/rtp_test.cc +++ b/toxav/rtp_test.cc @@ -6,30 +6,32 @@ namespace { -RTPHeader random_header() +RTPHeader random_header(const Random *rng) { return { - random_u16(), - random_u16(), - random_u16(), - random_u16(), - random_u16(), - random_u16(), - random_u16(), - random_u32(), - random_u32(), - random_u64(), - random_u32(), - random_u32(), - random_u32(), - random_u16(), - random_u16(), + random_u16(rng), + random_u16(rng), + random_u16(rng), + random_u16(rng), + random_u16(rng), + random_u16(rng), + random_u16(rng), + random_u32(rng), + random_u32(rng), + random_u64(rng), + random_u32(rng), + random_u32(rng), + random_u32(rng), + random_u16(rng), + random_u16(rng), }; } TEST(Rtp, Deserialisation) { - RTPHeader const header = random_header(); + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); + RTPHeader const header = random_header(rng); uint8_t rdata[RTP_HEADER_SIZE]; EXPECT_EQ(rtp_header_pack(rdata, &header), RTP_HEADER_SIZE); diff --git a/toxav/toxav.c b/toxav/toxav.c index 6c2a022bef..ef5f7b5ff1 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -1065,7 +1065,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", (double)loss * 100); /* if less than 10% data loss we do nothing! */ - if (loss < 0.1f) { + if (loss < 0.1F) { return; } diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 55c65f1253..2788b85ead 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -80,6 +80,7 @@ struct DHT { const Logger *log; const Network *ns; Mono_Time *mono_time; + const Random *rng; Networking_Core *net; bool hole_punching_enabled; @@ -342,8 +343,9 @@ void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *publi * @retval -1 on failure. * @return the length of the created packet on success. */ -int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet, - const uint8_t *recv_public_key, const uint8_t *data, uint32_t data_length, uint8_t request_id) +int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, + uint8_t *packet, const uint8_t *recv_public_key, + const uint8_t *data, uint32_t data_length, uint8_t request_id) { if (send_public_key == nullptr || packet == nullptr || recv_public_key == nullptr || data == nullptr) { return -1; @@ -354,7 +356,7 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke } uint8_t *const nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2; - random_nonce(nonce); + random_nonce(rng, nonce); uint8_t temp[MAX_CRYPTO_REQUEST_SIZE] = {0}; temp[0] = request_id; memcpy(temp + 1, data, data_length); @@ -514,7 +516,7 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_ } non_null() -static int dht_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], +static int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *shared_key, const uint8_t type, const uint8_t *plain, size_t plain_length, uint8_t *packet) { @@ -525,7 +527,7 @@ static int dht_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], return -1; } - random_nonce(nonce); + random_nonce(rng, nonce); const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted); @@ -1371,7 +1373,7 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c uint64_t ping_id = 0; - ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, plain_message, sizeof(receiver)); + ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, dht->rng, plain_message, sizeof(receiver)); if (ping_id == 0) { LOGGER_ERROR(dht->log, "adding ping id failed"); @@ -1387,7 +1389,7 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; dht_get_shared_key_sent(dht, shared_key, public_key); - const int len = dht_create_packet(dht->self_public_key, shared_key, NET_PACKET_GET_NODES, + const int len = dht_create_packet(dht->rng, dht->self_public_key, shared_key, NET_PACKET_GET_NODES, plain, sizeof(plain), data); crypto_memzero(shared_key, sizeof(shared_key)); @@ -1438,8 +1440,8 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE; VLA(uint8_t, data, 1 + nodes_length + length + crypto_size); - const int len = dht_create_packet(dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6, - plain, 1 + nodes_length + length, data); + const int len = dht_create_packet(dht->rng, dht->self_public_key, shared_encryption_key, + NET_PACKET_SEND_NODES_IPV6, plain, 1 + nodes_length + length, data); if (len != SIZEOF_VLA(data)) { return -1; @@ -1655,7 +1657,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback, *dht_friend = empty_dht_friend; memcpy(dht_friend->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); - dht_friend->nat.nat_ping_id = random_u64(); + dht_friend->nat.nat_ping_id = random_u64(dht->rng); ++dht->num_friends; dht_friend_lock(dht_friend, ip_callback, data, number, lock_count); @@ -1802,10 +1804,10 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL) || *bootstrap_times < MAX_BOOTSTRAP_TIMES)) { - uint32_t rand_node = random_range_u32(num_nodes); + uint32_t rand_node = random_range_u32(dht->rng, num_nodes); if ((num_nodes - 1) != rand_node) { - rand_node += random_range_u32(num_nodes - (rand_node + 1)); + rand_node += random_range_u32(dht->rng, num_nodes - (rand_node + 1)); } dht_getnodes(dht, &assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key); @@ -2162,7 +2164,7 @@ static uint32_t routeone_to_friend(const DHT *dht, const uint8_t *friend_id, con return 0; } - const uint32_t rand_idx = random_range_u32(n); + const uint32_t rand_idx = random_range_u32(dht->rng, n); const int retval = send_packet(dht->net, &ip_list[rand_idx], *packet); if ((unsigned int)retval == packet->length) { @@ -2185,8 +2187,8 @@ static int send_NATping(const DHT *dht, const uint8_t *public_key, uint64_t ping memcpy(data + 1, &ping_id, sizeof(uint64_t)); /* 254 is NAT ping request packet id */ const int len = create_request( - dht->self_public_key, dht->self_secret_key, packet_data, public_key, data, - sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING); + dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key, + data, sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING); if (len == -1) { return -1; @@ -2239,7 +2241,7 @@ static int handle_NATping(void *object, const IP_Port *source, const uint8_t *so if (packet[0] == NAT_PING_RESPONSE) { if (dht_friend->nat.nat_ping_id == ping_id) { - dht_friend->nat.nat_ping_id = random_u64(); + dht_friend->nat.nat_ping_id = random_u64(dht->rng); dht_friend->nat.hole_punching = true; return 0; } @@ -2416,8 +2418,8 @@ static void do_NAT(DHT *dht) * @return the number of nodes. */ non_null() -static uint16_t list_nodes(const Client_data *list, size_t length, uint64_t cur_time, - Node_format *nodes, uint16_t max_num) +static uint16_t list_nodes(const Random *rng, const Client_data *list, size_t length, + uint64_t cur_time, Node_format *nodes, uint16_t max_num) { if (max_num == 0) { return 0; @@ -2435,7 +2437,7 @@ static uint16_t list_nodes(const Client_data *list, size_t length, uint64_t cur_ if (!assoc_timeout(cur_time, &list[i - 1].assoc6)) { if (assoc == nullptr) { assoc = &list[i - 1].assoc6; - } else if ((random_u08() % 2) != 0) { + } else if ((random_u08(rng) % 2) != 0) { assoc = &list[i - 1].assoc6; } } @@ -2465,10 +2467,11 @@ uint16_t randfriends_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num) } uint16_t count = 0; - const uint32_t r = random_u32(); + const uint32_t r = random_u32(dht->rng); for (size_t i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) { - count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, dht->cur_time, + count += list_nodes(dht->rng, dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, + MAX_FRIEND_CLIENTS, dht->cur_time, nodes + count, max_num - count); if (count >= max_num) { @@ -2485,7 +2488,7 @@ uint16_t randfriends_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num) */ uint16_t closelist_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num) { - return list_nodes(dht->close_clientlist, LCLIENT_LIST, dht->cur_time, nodes, max_num); + return list_nodes(dht->rng, dht->close_clientlist, LCLIENT_LIST, dht->cur_time, nodes, max_num); } /*----------------------------------------------------------------------------------*/ @@ -2569,7 +2572,7 @@ static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_ /*----------------------------------------------------------------------------------*/ -DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Networking_Core *net, +DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled) { if (net == nullptr) { @@ -2587,11 +2590,12 @@ DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Network dht->cur_time = mono_time_get(mono_time); dht->log = log; dht->net = net; + dht->rng = rng; dht->hole_punching_enabled = hole_punching_enabled; dht->lan_discovery_enabled = lan_discovery_enabled; - dht->ping = ping_new(mono_time, dht); + dht->ping = ping_new(mono_time, rng, dht); if (dht->ping == nullptr) { kill_dht(dht); @@ -2604,7 +2608,7 @@ DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Network networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht); cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); - crypto_new_keypair(dht->self_public_key, dht->self_secret_key); + crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key); dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT); @@ -2617,7 +2621,7 @@ DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Network uint8_t random_public_key_bytes[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t random_secret_key_bytes[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(random_public_key_bytes, random_secret_key_bytes); + crypto_new_keypair(rng, random_public_key_bytes, random_secret_key_bytes); if (dht_addfriend(dht, random_public_key_bytes, nullptr, nullptr, 0, nullptr) != 0) { kill_dht(dht); diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 3d426fb6a7..e89c3486d8 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -92,9 +92,9 @@ extern "C" { * @return the length of the created packet on success. */ non_null() -int create_request( - const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet, - const uint8_t *recv_public_key, const uint8_t *data, uint32_t data_length, uint8_t request_id); +int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, + uint8_t *packet, const uint8_t *recv_public_key, + const uint8_t *data, uint32_t data_length, uint8_t request_id); /** * @brief Decrypts and unpacks a DHT request packet. @@ -470,7 +470,7 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length); /** Initialize DHT. */ non_null() -DHT *new_dht(const Logger *log, const Network *ns, Mono_Time *mono_time, Networking_Core *net, +DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled); non_null() diff --git a/toxcore/DHT_test.cc b/toxcore/DHT_test.cc index 86e38712fa..35efc652c2 100644 --- a/toxcore/DHT_test.cc +++ b/toxcore/DHT_test.cc @@ -16,7 +16,7 @@ struct KeyPair { PublicKey pk; SecretKey sk; - KeyPair() { crypto_new_keypair(pk.data(), sk.data()); } + explicit KeyPair(const Random *rng) { crypto_new_keypair(rng, pk.data(), sk.data()); } }; template @@ -27,17 +27,20 @@ std::array to_array(T const (&arr)[N]) return stdarr; } -PublicKey random_pk() +PublicKey random_pk(const Random *rng) { PublicKey pk; - random_bytes(pk.data(), pk.size()); + random_bytes(rng, pk.data(), pk.size()); return pk; } TEST(IdClosest, IdenticalKeysAreSameDistance) { - PublicKey pk0 = random_pk(); - PublicKey pk1 = random_pk(); + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); + + PublicKey pk0 = random_pk(rng); + PublicKey pk1 = random_pk(rng); PublicKey pk2 = pk1; EXPECT_EQ(id_closest(pk0.data(), pk1.data(), pk2.data()), 0); @@ -45,10 +48,13 @@ TEST(IdClosest, IdenticalKeysAreSameDistance) TEST(IdClosest, DistanceIsCommutative) { + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); + for (uint32_t i = 0; i < 100; ++i) { - PublicKey pk0 = random_pk(); - PublicKey pk1 = random_pk(); - PublicKey pk2 = random_pk(); + PublicKey pk0 = random_pk(rng); + PublicKey pk1 = random_pk(rng); + PublicKey pk2 = random_pk(rng); ASSERT_NE(pk1, pk2); // RNG can't produce the same random key twice @@ -124,9 +130,12 @@ TEST(AddToList, OverridesKeysWithCloserKeys) TEST(Request, CreateAndParse) { + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); + // Peers. - const KeyPair sender; - const KeyPair receiver; + const KeyPair sender(rng); + const KeyPair receiver(rng); const uint8_t sent_pkt_id = CRYPTO_PACKET_FRIEND_REQ; // Encoded packet. @@ -139,17 +148,17 @@ TEST(Request, CreateAndParse) // Request data: maximum payload is 918 bytes, so create a payload 1 byte larger than max. std::vector outgoing(919); - random_bytes(outgoing.data(), outgoing.size()); + random_bytes(rng, outgoing.data(), outgoing.size()); - EXPECT_LT(create_request(sender.pk.data(), sender.sk.data(), packet.data(), receiver.pk.data(), - outgoing.data(), outgoing.size(), sent_pkt_id), + EXPECT_LT(create_request(rng, sender.pk.data(), sender.sk.data(), packet.data(), + receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id), 0); // Pop one element so the payload is 918 bytes. Packing should now succeed. outgoing.pop_back(); - const int max_sent_length = create_request(sender.pk.data(), sender.sk.data(), packet.data(), - receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id); + const int max_sent_length = create_request(rng, sender.pk.data(), sender.sk.data(), + packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id); ASSERT_GT(max_sent_length, 0); // success. // Check that handle_request rejects packets larger than the maximum created packet size. @@ -160,8 +169,8 @@ TEST(Request, CreateAndParse) // Now try all possible packet sizes from max (918) to 0. while (!outgoing.empty()) { // Pack: - const int sent_length = create_request(sender.pk.data(), sender.sk.data(), packet.data(), - receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id); + const int sent_length = create_request(rng, sender.pk.data(), sender.sk.data(), + packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id); ASSERT_GT(sent_length, 0); // Unpack: diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index d9ae875f27..e0ad0b378f 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -3151,7 +3151,7 @@ static void m_handle_friend_request( * * if error is not NULL it will be set to one of the values in the enum above. */ -Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Options *options, Messenger_Error *error) +Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error) { if (options == nullptr) { return nullptr; @@ -3168,6 +3168,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti } m->mono_time = mono_time; + m->rng = rng; m->ns = ns; m->fr = friendreq_new(); @@ -3215,7 +3216,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti return nullptr; } - m->dht = new_dht(m->log, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled); + m->dht = new_dht(m->log, m->rng, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled); if (m->dht == nullptr) { kill_networking(m->net); @@ -3225,7 +3226,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti return nullptr; } - m->net_crypto = new_net_crypto(m->log, m->mono_time, m->ns, m->dht, &options->proxy_info); + m->net_crypto = new_net_crypto(m->log, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info); if (m->net_crypto == nullptr) { kill_dht(m->dht); @@ -3236,9 +3237,9 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti return nullptr; } - m->onion = new_onion(m->log, m->mono_time, m->dht); - m->onion_a = new_onion_announce(m->log, m->mono_time, m->dht); - m->onion_c = new_onion_client(m->log, m->mono_time, m->net_crypto); + m->onion = new_onion(m->log, m->mono_time, m->rng, m->dht); + m->onion_a = new_onion_announce(m->log, m->rng, m->mono_time, m->dht); + m->onion_c = new_onion_client(m->log, m->rng, m->mono_time, m->net_crypto); m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled); if (m->onion == nullptr || m->onion_a == nullptr || m->onion_c == nullptr || m->fr_c == nullptr) { @@ -3256,7 +3257,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti } if (options->tcp_server_port != 0) { - m->tcp_server = new_TCP_server(m->log, m->ns, options->ipv6enabled, 1, &options->tcp_server_port, + m->tcp_server = new_TCP_server(m->log, m->rng, m->ns, options->ipv6enabled, 1, &options->tcp_server_port, dht_get_self_secret_key(m->dht), m->onion); if (m->tcp_server == nullptr) { @@ -3281,7 +3282,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Opti m->options = *options; friendreq_init(m->fr, m->fr_c); - set_nospam(m->fr, random_u32()); + set_nospam(m->fr, random_u32(m->rng)); set_filter_function(m->fr, &friend_already_added, m); m->lastdump = 0; diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 51fc85ffce..9a68dda5b4 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -234,6 +234,7 @@ typedef struct Friend { struct Messenger { Logger *log; Mono_Time *mono_time; + const Random *rng; const Network *ns; Networking_Core *net; @@ -754,7 +755,7 @@ typedef enum Messenger_Error { * if error is not NULL it will be set to one of the values in the enum above. */ non_null() -Messenger *new_messenger(Mono_Time *mono_time, const Network *ns, Messenger_Options *options, Messenger_Error *error); +Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error); /** @brief Run this before closing shop. * diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 5651601e95..919048a2f3 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -286,11 +286,11 @@ non_null() static int generate_handshake(TCP_Client_Connection *tcp_conn) { uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; - crypto_new_keypair(plain, tcp_conn->temp_secret_key); - random_nonce(tcp_conn->con.sent_nonce); + crypto_new_keypair(tcp_conn->con.rng, plain, tcp_conn->temp_secret_key); + random_nonce(tcp_conn->con.rng, tcp_conn->con.sent_nonce); memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->con.sent_nonce, CRYPTO_NONCE_SIZE); memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - random_nonce(tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE); + random_nonce(tcp_conn->con.rng, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE); const int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); @@ -529,14 +529,10 @@ void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *o /** Create new TCP connection to ip_port/public_key */ TCP_Client_Connection *new_TCP_connection( - const Logger *logger, const Mono_Time *mono_time, const Network *ns, const IP_Port *ip_port, + const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, const TCP_Proxy_Info *proxy_info) { - if (networking_at_startup() != 0) { - return nullptr; - } - if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) { return nullptr; } @@ -577,6 +573,7 @@ TCP_Client_Connection *new_TCP_connection( } temp->con.ns = ns; + temp->con.rng = rng; temp->con.sock = sock; temp->con.ip_port = *ip_port; memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -837,7 +834,7 @@ static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, c tcp_send_ping_request(logger, conn); if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) { - uint64_t ping_id = random_u64(); + uint64_t ping_id = random_u64(conn->con.rng); if (ping_id == 0) { ++ping_id; diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index a8bcda8908..9c6e817d66 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h @@ -9,6 +9,7 @@ #ifndef C_TOXCORE_TOXCORE_TCP_CLIENT_H #define C_TOXCORE_TOXCORE_TCP_CLIENT_H +#include "crypto_core.h" #include "mono_time.h" #include "network.h" @@ -55,9 +56,9 @@ non_null() void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value); /** Create new TCP connection to ip_port/public_key */ -non_null(1, 2, 3, 4, 5, 6, 7) nullable(8) +non_null(1, 2, 3, 4, 5, 6, 7, 8) nullable(9) TCP_Client_Connection *new_TCP_connection( - const Logger *logger, const Mono_Time *mono_time, const Network *ns, const IP_Port *ip_port, + const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, const TCP_Proxy_Info *proxy_info); diff --git a/toxcore/TCP_common.h b/toxcore/TCP_common.h index f0115601ef..ca07bf5741 100644 --- a/toxcore/TCP_common.h +++ b/toxcore/TCP_common.h @@ -46,6 +46,7 @@ void wipe_priority_list(TCP_Priority_List *p); #define MAX_PACKET_SIZE 2048 typedef struct TCP_Connection { + const Random *rng; const Network *ns; Socket sock; IP_Port ip_port; // for debugging. diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index bd7eeef929..2ab79b1748 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c @@ -19,6 +19,7 @@ struct TCP_Connections { const Logger *logger; + const Random *rng; Mono_Time *mono_time; const Network *ns; DHT *dht; @@ -380,7 +381,7 @@ int send_packet_tcp_connection(const TCP_Connections *tcp_c, int connections_num */ int get_random_tcp_onion_conn_number(const TCP_Connections *tcp_c) { - const uint32_t r = random_u32(); + const uint32_t r = random_u32(tcp_c->rng); for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) { const uint32_t index = (i + r) % tcp_c->tcp_connections_length; @@ -813,7 +814,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE]; memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); kill_TCP_connection(tcp_con->connection); - tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); + tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (tcp_con->connection == nullptr) { kill_tcp_relay_connection(tcp_c, tcp_connections_number); @@ -901,7 +902,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti } tcp_con->connection = new_TCP_connection( - tcp_c->logger, tcp_c->mono_time, tcp_c->ns, &tcp_con->ip_port, + tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port, tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (tcp_con->connection == nullptr) { @@ -1186,7 +1187,7 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port TCP_con *tcp_con = &tcp_c->tcp_connections[tcp_connections_number]; tcp_con->connection = new_TCP_connection( - tcp_c->logger, tcp_c->mono_time, tcp_c->ns, &ipp_copy, + tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (tcp_con->connection == nullptr) { @@ -1354,7 +1355,7 @@ static bool copy_tcp_relay_conn(const TCP_Connections *tcp_c, Node_format *tcp_r */ uint32_t tcp_copy_connected_relays(const TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num) { - const uint32_t r = random_u32(); + const uint32_t r = random_u32(tcp_c->rng); uint32_t copied = 0; for (uint32_t i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) { @@ -1462,8 +1463,9 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status) * * Returns NULL on failure. */ -TCP_Connections *new_tcp_connections(const Logger *logger, Mono_Time *mono_time, const Network *ns, - const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info) +TCP_Connections *new_tcp_connections( + const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, const uint8_t *secret_key, + const TCP_Proxy_Info *proxy_info) { if (secret_key == nullptr) { return nullptr; @@ -1476,6 +1478,7 @@ TCP_Connections *new_tcp_connections(const Logger *logger, Mono_Time *mono_time, } temp->logger = logger; + temp->rng = rng; temp->mono_time = mono_time; temp->ns = ns; diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index 93fda5ac82..578f2d9243 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h @@ -251,8 +251,9 @@ uint32_t tcp_copy_connected_relays_index(const TCP_Connections *tcp_c, Node_form * Returns NULL on failure. */ non_null() -TCP_Connections *new_tcp_connections(const Logger *logger, Mono_Time *mono_time, const Network *ns, - const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info); +TCP_Connections *new_tcp_connections( + const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, + const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info); non_null() int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number); diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 9fdaa307da..ee32f6a05f 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -58,6 +58,7 @@ typedef struct TCP_Secure_Connection { struct TCP_Server { const Logger *logger; + const Random *rng; const Network *ns; Onion *onion; @@ -327,13 +328,13 @@ static int handle_TCP_handshake(const Logger *logger, TCP_Secure_Connection *con memcpy(con->public_key, data, CRYPTO_PUBLIC_KEY_SIZE); uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE]; - crypto_new_keypair(resp_plain, temp_secret_key); - random_nonce(con->con.sent_nonce); + crypto_new_keypair(con->con.rng, resp_plain, temp_secret_key); + random_nonce(con->con.rng, con->con.sent_nonce); memcpy(resp_plain + CRYPTO_PUBLIC_KEY_SIZE, con->con.sent_nonce, CRYPTO_NONCE_SIZE); memcpy(con->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; - random_nonce(response); + random_nonce(con->con.rng, response); len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE, response + CRYPTO_NONCE_SIZE); @@ -801,6 +802,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock) conn->status = TCP_STATUS_CONNECTED; conn->con.ns = tcp_server->ns; + conn->con.rng = tcp_server->rng; conn->con.sock = sock; conn->next_packet_length = 0; @@ -843,8 +845,9 @@ static Socket new_listening_TCP_socket(const Logger *logger, const Network *ns, return sock; } -TCP_Server *new_TCP_server(const Logger *logger, const Network *ns, bool ipv6_enabled, uint16_t num_sockets, - const uint16_t *ports, const uint8_t *secret_key, Onion *onion) +TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns, + bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports, + const uint8_t *secret_key, Onion *onion) { if (num_sockets == 0 || ports == nullptr) { LOGGER_ERROR(logger, "no sockets"); @@ -856,11 +859,6 @@ TCP_Server *new_TCP_server(const Logger *logger, const Network *ns, bool ipv6_en return nullptr; } - if (networking_at_startup() != 0) { - LOGGER_ERROR(logger, "network initialisation failed"); - return nullptr; - } - TCP_Server *temp = (TCP_Server *)calloc(1, sizeof(TCP_Server)); if (temp == nullptr) { @@ -870,6 +868,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Network *ns, bool ipv6_en temp->logger = logger; temp->ns = ns; + temp->rng = rng; temp->socks_listening = (Socket *)calloc(num_sockets, sizeof(Socket)); @@ -1089,7 +1088,7 @@ static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time) if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) { uint8_t ping[1 + sizeof(uint64_t)]; ping[0] = TCP_PACKET_PING; - uint64_t ping_id = random_u64(); + uint64_t ping_id = random_u64(conn->con.rng); if (ping_id == 0) { ++ping_id; diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h index a5d63eaa15..966bb0cfda 100644 --- a/toxcore/TCP_server.h +++ b/toxcore/TCP_server.h @@ -33,9 +33,10 @@ non_null() size_t tcp_server_listen_count(const TCP_Server *tcp_server); /** Create new TCP server instance. */ -non_null(1, 2, 5, 6) nullable(7) -TCP_Server *new_TCP_server(const Logger *logger, const Network *ns, bool ipv6_enabled, uint16_t num_sockets, - const uint16_t *ports, const uint8_t *secret_key, Onion *onion); +non_null(1, 2, 3, 6, 7) nullable(8) +TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns, + bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports, + const uint8_t *secret_key, Onion *onion); /** Run the TCP_server */ non_null() diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index f90ac5b8e0..cf9fa368d6 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -173,41 +173,37 @@ bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2) #endif } -uint8_t random_u08(void) +uint8_t random_u08(const Random *rng) { uint8_t randnum; - random_bytes(&randnum, 1); + random_bytes(rng, &randnum, 1); return randnum; } -uint16_t random_u16(void) +uint16_t random_u16(const Random *rng) { uint16_t randnum; - random_bytes((uint8_t *)&randnum, sizeof(randnum)); + random_bytes(rng, (uint8_t *)&randnum, sizeof(randnum)); return randnum; } -uint32_t random_u32(void) +uint32_t random_u32(const Random *rng) { uint32_t randnum; - random_bytes((uint8_t *)&randnum, sizeof(randnum)); + random_bytes(rng, (uint8_t *)&randnum, sizeof(randnum)); return randnum; } -uint64_t random_u64(void) +uint64_t random_u64(const Random *rng) { uint64_t randnum; - random_bytes((uint8_t *)&randnum, sizeof(randnum)); + random_bytes(rng, (uint8_t *)&randnum, sizeof(randnum)); return randnum; } -uint32_t random_range_u32(uint32_t upper_bound) +uint32_t random_range_u32(const Random *rng, uint32_t upper_bound) { -#ifdef VANILLA_NACL - return random_u32() % upper_bound; -#else - return randombytes_uniform(upper_bound); -#endif // VANILLA_NACL + return rng->funcs->random_uniform(rng->obj, upper_bound); } bool crypto_signature_create(uint8_t *signature, const uint8_t *message, uint64_t message_length, @@ -417,20 +413,20 @@ void increment_nonce_number(uint8_t *nonce, uint32_t increment) } } -void random_nonce(uint8_t *nonce) +void random_nonce(const Random *rng, uint8_t *nonce) { - random_bytes(nonce, crypto_box_NONCEBYTES); + random_bytes(rng, nonce, crypto_box_NONCEBYTES); } -void new_symmetric_key(uint8_t *key) +void new_symmetric_key(const Random *rng, uint8_t *key) { - random_bytes(key, CRYPTO_SYMMETRIC_KEY_SIZE); + random_bytes(rng, key, CRYPTO_SYMMETRIC_KEY_SIZE); } -int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key) +int32_t crypto_new_keypair(const Random *rng, uint8_t *public_key, uint8_t *secret_key) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - random_bytes(secret_key, CRYPTO_SECRET_KEY_SIZE); + random_bytes(rng, secret_key, CRYPTO_SECRET_KEY_SIZE); memset(public_key, 0, CRYPTO_PUBLIC_KEY_SIZE); // Make MSAN happy crypto_scalarmult_curve25519_base(public_key, secret_key); return 0; @@ -454,7 +450,8 @@ void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length) crypto_hash_sha512(hash, data, length); } -void random_bytes(uint8_t *bytes, size_t length) +non_null() +static void sys_random_bytes(void *obj, uint8_t *bytes, size_t length) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION fuzz_random_bytes(bytes, length); @@ -462,3 +459,40 @@ void random_bytes(uint8_t *bytes, size_t length) randombytes(bytes, length); #endif } + +non_null() +static uint32_t sys_random_uniform(void *obj, uint32_t upper_bound) +{ +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL) + uint32_t randnum; + sys_random_bytes(obj, (uint8_t *)&randnum, sizeof(randnum)); + return randnum % upper_bound; +#else + return randombytes_uniform(upper_bound); +#endif // VANILLA_NACL +} + +static const Random_Funcs system_random_funcs = { + sys_random_bytes, + sys_random_uniform, +}; + +static const Random system_random_obj = {&system_random_funcs}; + +const Random *system_random(void) +{ +#ifndef VANILLA_NACL + // It is safe to call this function more than once and from different + // threads -- subsequent calls won't have any effects. + if (sodium_init() == -1) { + return nullptr; + } +#endif + + return &system_random_obj; +} + +void random_bytes(const Random *rng, uint8_t *bytes, size_t length) +{ + rng->funcs->random_bytes(rng->obj, bytes, length); +} diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 1651af8558..b9b2893d52 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -75,6 +75,21 @@ extern "C" { */ #define CRYPTO_SHA512_SIZE 64 +typedef void crypto_random_bytes_cb(void *obj, uint8_t *bytes, size_t length); +typedef uint32_t crypto_random_uniform_cb(void *obj, uint32_t upper_bound); + +typedef struct Random_Funcs { + crypto_random_bytes_cb *random_bytes; + crypto_random_uniform_cb *random_uniform; +} Random_Funcs; + +typedef struct Random { + const Random_Funcs *funcs; + void *obj; +} Random; + +const Random *system_random(void); + /** * @brief The number of bytes in an encryption public key used by DHT group chats. */ @@ -154,22 +169,26 @@ bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2); /** * @brief Return a random 8 bit integer. */ -uint8_t random_u08(void); +non_null() +uint8_t random_u08(const Random *rng); /** * @brief Return a random 16 bit integer. */ -uint16_t random_u16(void); +non_null() +uint16_t random_u16(const Random *rng); /** * @brief Return a random 32 bit integer. */ -uint32_t random_u32(void); +non_null() +uint32_t random_u32(const Random *rng); /** * @brief Return a random 64 bit integer. */ -uint64_t random_u64(void); +non_null() +uint64_t random_u64(const Random *rng); /** * @brief Return a random 32 bit integer between 0 and upper_bound (excluded). @@ -177,7 +196,8 @@ uint64_t random_u64(void); * On libsodium builds this function guarantees a uniform distribution of possible outputs. * On vanilla NACL builds this function is equivalent to `random() % upper_bound`. */ -uint32_t random_range_u32(uint32_t upper_bound); +non_null() +uint32_t random_range_u32(const Random *rng, uint32_t upper_bound); /** @brief Cryptographically signs a message using the supplied secret key and puts the resulting signature * in the supplied buffer. @@ -213,13 +233,13 @@ bool crypto_signature_verify(const uint8_t *signature, const uint8_t *message, u * @brief Fill the given nonce with random bytes. */ non_null() -void random_nonce(uint8_t *nonce); +void random_nonce(const Random *rng, uint8_t *nonce); /** * @brief Fill an array of bytes with random values. */ non_null() -void random_bytes(uint8_t *bytes, size_t length); +void random_bytes(const Random *rng, uint8_t *bytes, size_t length); /** * @brief Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. @@ -248,7 +268,7 @@ bool create_extended_keypair(uint8_t *pk, uint8_t *sk); * Every call to this function is likely to generate a different keypair. */ non_null() -int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key); +int32_t crypto_new_keypair(const Random *rng, uint8_t *public_key, uint8_t *secret_key); /** * @brief Derive the public key from a given secret key. @@ -343,7 +363,7 @@ void increment_nonce_number(uint8_t *nonce, uint32_t increment); * @brief Fill a key @ref CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes. */ non_null() -void new_symmetric_key(uint8_t *key); +void new_symmetric_key(const Random *rng, uint8_t *key); /** * @brief Locks `length` bytes of memory pointed to by `data`. diff --git a/toxcore/crypto_core_test.cc b/toxcore/crypto_core_test.cc index 78c17963b8..9d4aac41ce 100644 --- a/toxcore/crypto_core_test.cc +++ b/toxcore/crypto_core_test.cc @@ -50,6 +50,9 @@ TEST(CryptoCore, IncrementNonceNumber) TEST(CryptoCore, Signatures) { + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); + ExtPublicKey pk; ExtSecretKey sk; @@ -59,7 +62,7 @@ TEST(CryptoCore, Signatures) // Try a few different sizes, including empty 0 length message. for (uint8_t i = 0; i < 100; ++i) { - message.push_back(random_u08()); + message.push_back(random_u08(rng)); Signature signature; EXPECT_TRUE(crypto_signature_create( signature.data(), message.data(), message.size(), get_sig_sk(sk.data()))); diff --git a/toxcore/group.c b/toxcore/group.c index 30bbb714b4..1411924f1d 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -1309,12 +1309,13 @@ static void remove_connection_reason(Group_Chats *g_c, Group_c *g, uint16_t i, u /** @brief Creates a new groupchat and puts it in the chats array. * + * @param rng Random number generator used for generating the group ID. * @param type is one of `GROUPCHAT_TYPE_*` * * @return group number on success. * @retval -1 on failure. */ -int add_groupchat(Group_Chats *g_c, uint8_t type) +int add_groupchat(Group_Chats *g_c, const Random *rng, uint8_t type) { const int32_t groupnumber = create_group_chat(g_c); @@ -1326,7 +1327,7 @@ int add_groupchat(Group_Chats *g_c, uint8_t type) g->status = GROUPCHAT_STATUS_CONNECTED; g->type = type; - new_symmetric_key(g->id); + new_symmetric_key(rng, g->id); g->peer_number = 0; /* Founder is peer 0. */ memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); const int peer_index = addpeer(g_c, groupnumber, g->real_pk, dht_get_self_public_key(g_c->m->dht), 0, nullptr, true, @@ -2177,12 +2178,12 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con /* TODO(irungentoo): what if two people enter the group at the * same time and are given the same peer_number by different * nodes? */ - peer_number = random_u16(); + peer_number = random_u16(m->rng); unsigned int tries = 0; while (get_peer_index(g, peer_number) != -1 || get_frozen_index(g, peer_number) != -1) { - peer_number = random_u16(); + peer_number = random_u16(m->rng); ++tries; if (tries > 32) { diff --git a/toxcore/group.h b/toxcore/group.h index 16d0432b59..be05598d93 100644 --- a/toxcore/group.h +++ b/toxcore/group.h @@ -93,13 +93,14 @@ void g_callback_peer_list_changed(Group_Chats *g_c, peer_list_changed_cb *functi /** @brief Creates a new groupchat and puts it in the chats array. * + * @param rng Random number generator used for generating the group ID. * @param type is one of `GROUPCHAT_TYPE_*` * * @return group number on success. * @retval -1 on failure. */ non_null() -int add_groupchat(Group_Chats *g_c, uint8_t type); +int add_groupchat(Group_Chats *g_c, const Random *rng, uint8_t type); /** @brief Delete a groupchat from the chats array, informing the group first as * appropriate. diff --git a/toxcore/group_moderation_test.cc b/toxcore/group_moderation_test.cc index 0f9c88c6c7..e632c3cc8f 100644 --- a/toxcore/group_moderation_test.cc +++ b/toxcore/group_moderation_test.cc @@ -84,11 +84,14 @@ TEST(ModList, UnpackingFromEmptyBufferFails) TEST(ModList, HashOfEmptyModListZeroesOutBuffer) { + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); + Moderation mods{}; // Fill with random data, check that it's zeroed. ModerationHash hash; - random_bytes(hash.data(), hash.size()); + random_bytes(rng, hash.data(), hash.size()); EXPECT_TRUE(mod_list_make_hash(&mods, hash.data())); EXPECT_EQ(hash, ModerationHash{}); } diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 6e9a7f7e47..0a1e9d9498 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -127,6 +127,7 @@ static const Crypto_Connection empty_crypto_connection = {{0}}; struct Net_Crypto { const Logger *log; + const Random *rng; Mono_Time *mono_time; const Network *ns; @@ -225,7 +226,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin dht_get_shared_key_sent(c->dht, shared_key, dht_public_key); uint8_t nonce[CRYPTO_NONCE_SIZE]; - random_nonce(nonce); + random_nonce(c->rng, nonce); packet[0] = NET_PACKET_COOKIE_REQUEST; memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); @@ -245,14 +246,14 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin * @retval 0 on success. */ non_null() -static int create_cookie(const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes, +static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes, const uint8_t *encryption_key) { uint8_t contents[COOKIE_CONTENTS_LENGTH]; const uint64_t temp_time = mono_time_get(mono_time); memcpy(contents, &temp_time, sizeof(temp_time)); memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH); - random_nonce(cookie); + random_nonce(rng, cookie); const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE); if (len != COOKIE_LENGTH - CRYPTO_NONCE_SIZE) { @@ -308,13 +309,13 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; - if (create_cookie(c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { + if (create_cookie(c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t)); packet[0] = NET_PACKET_COOKIE_RESPONSE; - random_nonce(packet + 1); + random_nonce(c->rng, packet + 1); const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE); if (len != COOKIE_RESPONSE_LENGTH - (1 + CRYPTO_NONCE_SIZE)) { @@ -480,12 +481,12 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - if (create_cookie(c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, + if (create_cookie(c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } - random_nonce(packet + 1 + COOKIE_LENGTH); + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); @@ -2107,8 +2108,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - random_nonce(conn->sent_nonce); - crypto_new_keypair(conn->sessionpublic_key, conn->sessionsecret_key); + random_nonce(c->rng, conn->sent_nonce); + crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -2162,8 +2163,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u conn->connection_number_tcp = connection_number_tcp; memcpy(conn->public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE); - random_nonce(conn->sent_nonce); - crypto_new_keypair(conn->sessionpublic_key, conn->sessionsecret_key); + random_nonce(c->rng, conn->sent_nonce); + crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); conn->status = CRYPTO_CONN_COOKIE_REQUESTING; conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; @@ -2171,7 +2172,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u conn->rtt_time = DEFAULT_PING_CONNECTION; memcpy(conn->dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); - conn->cookie_request_number = random_u64(); + conn->cookie_request_number = random_u64(c->rng); uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, @@ -3048,7 +3049,7 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool void new_keys(Net_Crypto *c) { - crypto_new_keypair(c->self_public_key, c->self_secret_key); + crypto_new_keypair(c->rng, c->self_public_key, c->self_secret_key); } /** @brief Save the public and private keys to the keys array. @@ -3074,7 +3075,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk) /** @brief Create new instance of Net_Crypto. * Sets all the global connection variables to their default values. */ -Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, const Network *ns, DHT *dht, const TCP_Proxy_Info *proxy_info) +Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info) { if (dht == nullptr) { return nullptr; @@ -3087,10 +3088,11 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, const Networ } temp->log = log; + temp->rng = rng; temp->mono_time = mono_time; temp->ns = ns; - temp->tcp_c = new_tcp_connections(log, mono_time, ns, dht_get_self_secret_key(dht), proxy_info); + temp->tcp_c = new_tcp_connections(log, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info); if (temp->tcp_c == nullptr) { free(temp); @@ -3110,7 +3112,7 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, const Networ temp->dht = dht; new_keys(temp); - new_symmetric_key(temp->secret_symmetric_key); + new_symmetric_key(rng, temp->secret_symmetric_key); temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 2a68174e44..aaf4317263 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -376,7 +376,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk); * Sets all the global connection variables to their default values. */ non_null() -Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, const Network *ns, DHT *dht, const TCP_Proxy_Info *proxy_info); +Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info); /** return the optimal interval in ms for running do_net_crypto. */ non_null() diff --git a/toxcore/network.c b/toxcore/network.c index bab07d56cf..e9a9e36a0d 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -608,9 +608,26 @@ static const Network system_network_obj = {&system_network_funcs}; const Network *system_network(void) { +#ifdef OS_WIN32 + WSADATA wsaData; + + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { + return nullptr; + } +#endif return &system_network_obj; } +#if 0 +/* TODO(iphydf): Call this from functions that use `system_network()`. */ +void system_network_deinit(const Network *ns) +{ +#ifdef OS_WIN32 + WSACleanup(); +#endif +} +#endif + non_null() static int net_setsockopt(const Network *ns, Socket sock, int level, int optname, const void *optval, size_t optlen) { @@ -979,52 +996,6 @@ void networking_poll(const Networking_Core *net, void *userdata) } } -//!TOKSTYLE- -// Global mutable state is not allowed in Tokstyle. -static uint8_t at_startup_ran = 0; -//!TOKSTYLE+ -int networking_at_startup(void) -{ - if (at_startup_ran != 0) { - return 0; - } - -#ifndef VANILLA_NACL - -#ifdef USE_RANDOMBYTES_STIR - randombytes_stir(); -#else - - if (sodium_init() == -1) { - return -1; - } - -#endif /*USE_RANDOMBYTES_STIR*/ - -#endif/*VANILLA_NACL*/ - -#ifdef OS_WIN32 - WSADATA wsaData; - - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { - return -1; - } - -#endif - at_startup_ran = 1; - return 0; -} - -/* TODO(irungentoo): Put this somewhere */ -#if 0 -static void at_shutdown(void) -{ -#ifdef OS_WIN32 - WSACleanup(); -#endif -} -#endif - /** @brief Initialize networking. * Bind to ip and port. * ip must be in network order EX: 127.0.0.1 = (7F000001). @@ -1066,10 +1037,6 @@ Networking_Core *new_networking_ex( return nullptr; } - if (networking_at_startup() != 0) { - return nullptr; - } - Networking_Core *temp = (Networking_Core *)calloc(1, sizeof(Networking_Core)); if (temp == nullptr) { @@ -1273,10 +1240,6 @@ Networking_Core *new_networking_ex( Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns) { - if (networking_at_startup() != 0) { - return nullptr; - } - /* this is the easiest way to completely disable UDP without changing too much code. */ Networking_Core *net = (Networking_Core *)calloc(1, sizeof(Networking_Core)); @@ -1284,6 +1247,7 @@ Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns) return nullptr; } + net->ns = ns; net->log = log; net->ns = ns; @@ -1556,10 +1520,6 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. - if (networking_at_startup() != 0) { - return 0; - } - struct addrinfo *server = nullptr; const int rc = getaddrinfo(address, nullptr, &hints, &server); diff --git a/toxcore/network.h b/toxcore/network.h index 90bdddfbc1..0bb4e40ac7 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -428,13 +428,6 @@ Family net_family(const Networking_Core *net); non_null() uint16_t net_port(const Networking_Core *net); -/** @brief Run this before creating sockets. - * - * return 0 on success - * return -1 on failure - */ -int networking_at_startup(void); - /** Close the socket. */ non_null() void kill_sock(const Network *ns, Socket sock); @@ -581,6 +574,7 @@ non_null(1, 2, 3) nullable(6) Networking_Core *new_networking_ex( const Logger *log, const Network *ns, const IP *ip, uint16_t port_from, uint16_t port_to, unsigned int *error); + non_null() Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns); diff --git a/toxcore/onion.c b/toxcore/onion.c index 25218a00f5..d7e3f02665 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -26,12 +26,13 @@ #define SEND_1 ONION_SEND_1 #define KEY_REFRESH_INTERVAL (2 * 60 * 60) + /** Change symmetric keys every 2 hours to make paths expire eventually. */ non_null() static void change_symmetric_key(Onion *onion) { if (mono_time_is_timeout(onion->mono_time, onion->timestamp, KEY_REFRESH_INTERVAL)) { - new_symmetric_key(onion->secret_symmetric_key); + new_symmetric_key(onion->rng, onion->secret_symmetric_key); onion->timestamp = mono_time_get(onion->mono_time); } } @@ -107,7 +108,7 @@ static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data * return -1 on failure. * return 0 on success. */ -int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *nodes) +int create_onion_path(const Random *rng, const DHT *dht, Onion_Path *new_path, const Node_format *nodes) { if (new_path == nullptr || nodes == nullptr) { return -1; @@ -119,11 +120,11 @@ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *n uint8_t random_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t random_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(random_public_key, random_secret_key); + crypto_new_keypair(rng, random_public_key, random_secret_key); encrypt_precompute(nodes[1].public_key, random_secret_key, new_path->shared_key2); memcpy(new_path->public_key2, random_public_key, CRYPTO_PUBLIC_KEY_SIZE); - crypto_new_keypair(random_public_key, random_secret_key); + crypto_new_keypair(rng, random_public_key, random_secret_key); encrypt_precompute(nodes[2].public_key, random_secret_key, new_path->shared_key3); memcpy(new_path->public_key3, random_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -170,7 +171,8 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_ * return -1 on failure. * return length of created packet on success. */ -int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, +int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length, + const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) { if (1 + length + SEND_1 > max_packet_length || length == 0) { @@ -183,7 +185,7 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion memcpy(step1 + SIZE_IPPORT, data, length); uint8_t nonce[CRYPTO_NONCE_SIZE]; - random_nonce(nonce); + random_nonce(rng, nonce); VLA(uint8_t, step2, SIZE_IPPORT + SEND_BASE + length); ipport_pack(step2, &path->ip_port3); @@ -229,7 +231,8 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion * return -1 on failure. * return length of created packet on success. */ -int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, +int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length, + const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) { if (CRYPTO_NONCE_SIZE + SIZE_IPPORT + SEND_BASE * 2 + length > max_packet_length || length == 0) { @@ -242,7 +245,7 @@ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const O memcpy(step1 + SIZE_IPPORT, data, length); uint8_t nonce[CRYPTO_NONCE_SIZE]; - random_nonce(nonce); + random_nonce(rng, nonce); VLA(uint8_t, step2, SIZE_IPPORT + SEND_BASE + length); ipport_pack(step2, &path->ip_port3); @@ -349,7 +352,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I memcpy(data + 1 + CRYPTO_NONCE_SIZE, plain + SIZE_IPPORT, len - SIZE_IPPORT); uint16_t data_len = 1 + CRYPTO_NONCE_SIZE + (len - SIZE_IPPORT); uint8_t *ret_part = data + data_len; - random_nonce(ret_part); + random_nonce(onion->rng, ret_part); len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT, ret_part + CRYPTO_NONCE_SIZE); @@ -404,7 +407,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac memcpy(data + 1 + CRYPTO_NONCE_SIZE, plain + SIZE_IPPORT, len - SIZE_IPPORT); uint16_t data_len = 1 + CRYPTO_NONCE_SIZE + (len - SIZE_IPPORT); uint8_t *ret_part = data + data_len; - random_nonce(ret_part); + random_nonce(onion->rng, ret_part); uint8_t ret_data[RETURN_1 + SIZE_IPPORT]; ipport_pack(ret_data, source); memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1); @@ -468,7 +471,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac memcpy(data, plain + SIZE_IPPORT, len - SIZE_IPPORT); uint16_t data_len = len - SIZE_IPPORT; uint8_t *ret_part = data + (len - SIZE_IPPORT); - random_nonce(ret_part); + random_nonce(onion->rng, ret_part); uint8_t ret_data[RETURN_2 + SIZE_IPPORT]; ipport_pack(ret_data, source); memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2); @@ -641,7 +644,7 @@ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *o onion->callback_object = object; } -Onion *new_onion(const Logger *log, const Mono_Time *mono_time, DHT *dht) +Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht) { if (dht == nullptr) { return nullptr; @@ -657,7 +660,8 @@ Onion *new_onion(const Logger *log, const Mono_Time *mono_time, DHT *dht) onion->dht = dht; onion->net = dht_get_net(dht); onion->mono_time = mono_time; - new_symmetric_key(onion->secret_symmetric_key); + onion->rng = rng; + new_symmetric_key(rng, onion->secret_symmetric_key); onion->timestamp = mono_time_get(onion->mono_time); networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, &handle_send_initial, onion); diff --git a/toxcore/onion.h b/toxcore/onion.h index 24a95fe1e8..24b0370eb6 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -18,6 +18,7 @@ typedef int onion_recv_1_cb(void *object, const IP_Port *dest, const uint8_t *da typedef struct Onion { const Logger *log; const Mono_Time *mono_time; + const Random *rng; DHT *dht; Networking_Core *net; uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; @@ -78,7 +79,7 @@ typedef struct Onion_Path { * return 0 on success. */ non_null() -int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *nodes); +int create_onion_path(const Random *rng, const DHT *dht, Onion_Path *new_path, const Node_format *nodes); /** @brief Dump nodes in onion path to nodes of length num_nodes. * @@ -98,7 +99,8 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_ * return length of created packet on success. */ non_null() -int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, +int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length, + const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length); @@ -112,7 +114,8 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion * return length of created packet on success. */ non_null() -int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, +int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length, + const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length); /** @brief Create and send a onion response sent initially to dest with. @@ -143,7 +146,7 @@ non_null(1) nullable(2, 3) void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object); non_null() -Onion *new_onion(const Logger *log, const Mono_Time *mono_time, DHT *dht); +Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht); non_null() void kill_onion(Onion *onion); diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 1b781a800d..fa8122bc81 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -45,6 +45,7 @@ typedef struct Onion_Announce_Entry { struct Onion_Announce { const Logger *log; const Mono_Time *mono_time; + const Random *rng; DHT *dht; Networking_Core *net; Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES]; @@ -97,7 +98,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint * return -1 on failure. * return packet length on success. */ -int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, +int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data) { @@ -114,7 +115,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u sizeof(sendback_data)); packet[0] = NET_PACKET_ANNOUNCE_REQUEST_OLD; - random_nonce(packet + 1); + random_nonce(rng, packet + 1); const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); @@ -140,7 +141,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u * return -1 on failure. * return 0 on success. */ -int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, +int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length) { if (DATA_REQUEST_MIN_SIZE + length > max_packet_length) { @@ -157,7 +158,7 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8 uint8_t random_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t random_secret_key[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(random_public_key, random_secret_key); + crypto_new_keypair(rng, random_public_key, random_secret_key); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, random_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -186,13 +187,14 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8 * return -1 on failure. * return 0 on success. */ -int send_announce_request(const Networking_Core *net, const Onion_Path *path, const Node_format *dest, +int send_announce_request(const Networking_Core *net, const Random *rng, + const Onion_Path *path, const Node_format *dest, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data) { uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE]; - int len = create_announce_request(request, sizeof(request), dest->public_key, public_key, secret_key, ping_id, + int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id, client_id, data_public_key, sendback_data); if (len != sizeof(request)) { @@ -200,7 +202,7 @@ int send_announce_request(const Networking_Core *net, const Onion_Path *path, co } uint8_t packet[ONION_MAX_PACKET_SIZE]; - len = create_onion_packet(packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request)); + len = create_onion_packet(rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request)); if (len == -1) { return -1; @@ -229,19 +231,19 @@ int send_announce_request(const Networking_Core *net, const Onion_Path *path, co * return -1 on failure. * return 0 on success. */ -int send_data_request(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest, - const uint8_t *public_key, - const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length) +int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, + const uint8_t *data, uint16_t length) { uint8_t request[ONION_MAX_DATA_SIZE]; - int len = create_data_request(request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); + int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); if (len == -1) { return -1; } uint8_t packet[ONION_MAX_PACKET_SIZE]; - len = create_onion_packet(packet, sizeof(packet), path, dest, request, len); + len = create_onion_packet(rng, packet, sizeof(packet), path, dest, request, len); if (len == -1) { return -1; @@ -490,7 +492,7 @@ static int handle_announce_request_common( assert(num_nodes <= UINT8_MAX); uint8_t nonce[CRYPTO_NONCE_SIZE]; - random_nonce(nonce); + random_nonce(onion_a->rng, nonce); const uint16_t nodes_offset = 1 + ONION_PING_ID_SIZE + (want_node_count ? 1 : 0); const uint16_t response_size = nodes_offset @@ -648,7 +650,7 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_ return 0; } -Onion_Announce *new_onion_announce(const Logger *log, const Mono_Time *mono_time, DHT *dht) +Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht) { if (dht == nullptr) { return nullptr; @@ -661,13 +663,14 @@ Onion_Announce *new_onion_announce(const Logger *log, const Mono_Time *mono_time } onion_a->log = log; + onion_a->rng = rng; onion_a->mono_time = mono_time; onion_a->dht = dht; onion_a->net = dht_get_net(dht); onion_a->extra_data_max_size = 0; onion_a->extra_data_callback = nullptr; onion_a->extra_data_object = nullptr; - new_symmetric_key(onion_a->secret_bytes); + new_symmetric_key(rng, onion_a->secret_bytes); networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_announce_request, onion_a); networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST_OLD, &handle_announce_request_old, onion_a); diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 32ad3cd826..32d3565d89 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -57,7 +57,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint * return packet length on success. */ non_null() -int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, +int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data); @@ -74,7 +74,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u * return 0 on success. */ non_null() -int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, +int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length); /** @brief Create and send an onion announce request packet. @@ -92,10 +92,11 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8 * return 0 on success. */ non_null() -int send_announce_request(const Networking_Core *net, const Onion_Path *path, const Node_format *dest, +int send_announce_request(const Networking_Core *net, const Random *rng, + const Onion_Path *path, const Node_format *dest, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, - const uint8_t *data_public_key, uint64_t sendback_data); + const uint8_t *data_public_key, uint64_t sendback_data); /** @brief Create and send an onion data request packet. * @@ -114,9 +115,9 @@ int send_announce_request(const Networking_Core *net, const Onion_Path *path, co * return 0 on success. */ non_null() -int send_data_request(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest, - const uint8_t *public_key, - const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length); +int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, + const uint8_t *data, uint16_t length); typedef int pack_extra_data_cb(void *object, const Logger *logger, const Mono_Time *mono_time, @@ -128,10 +129,9 @@ void onion_announce_extra_data_callback(Onion_Announce *onion_a, uint16_t extra_ pack_extra_data_cb *extra_data_callback, void *extra_data_object); non_null() -Onion_Announce *new_onion_announce(const Logger *log, const Mono_Time *mono_time, DHT *dht); +Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht); non_null() void kill_onion_announce(Onion_Announce *onion_a); - #endif diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 6345937e53..f39ecaab79 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -100,6 +100,7 @@ typedef struct Onion_Data_Handler { struct Onion_Client { const Mono_Time *mono_time; const Logger *logger; + const Random *rng; DHT *dht; Net_Crypto *c; @@ -278,7 +279,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format } for (unsigned int i = 0; i < max_num; ++i) { - const uint32_t rand_idx = random_range_u32(num_nodes); + const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes); nodes[i] = onion_c->path_nodes[rand_idx]; } } else { @@ -294,7 +295,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp; for (unsigned int i = 1; i < max_num; ++i) { - const uint32_t rand_idx = random_range_u32(num_nodes); + const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes); nodes[i] = onion_c->path_nodes[rand_idx]; } } else { @@ -309,7 +310,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp; for (unsigned int i = 1; i < max_num; ++i) { - const uint32_t rand_idx = random_range_u32(num_nodes_bs); + const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes_bs); nodes[i] = onion_c->path_nodes_bs[rand_idx]; } } @@ -379,7 +380,7 @@ non_null() static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path) { if (pathnum == UINT32_MAX) { - pathnum = random_range_u32(NUMBER_ONION_PATHS); + pathnum = random_range_u32(onion_c->rng, NUMBER_ONION_PATHS); } else { pathnum = pathnum % NUMBER_ONION_PATHS; } @@ -394,7 +395,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa const int n = is_path_used(onion_c->mono_time, onion_paths, nodes); if (n == -1) { - if (create_onion_path(onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) { + if (create_onion_path(onion_c->rng, onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) { return -1; } @@ -402,7 +403,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa onion_paths->last_path_success[pathnum] = onion_paths->path_creation_time[pathnum]; onion_paths->last_path_used_times[pathnum] = ONION_PATH_MAX_NO_RESPONSE_USES / 2; - uint32_t path_num = random_u32(); + uint32_t path_num = random_u32(onion_c->rng); path_num /= NUMBER_ONION_PATHS; path_num *= NUMBER_ONION_PATHS; path_num += pathnum; @@ -478,7 +479,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa { if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - const int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length); if (len == -1) { return -1; @@ -493,7 +494,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa if (net_family_is_tcp_family(path->ip_port1.ip.family)) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - int len = create_onion_packet_tcp(packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length); if (len == -1) { return -1; @@ -529,7 +530,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, ip_port, sizeof(IP_Port)); memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t)); - *sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data)); + *sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, onion_c->rng, data, sizeof(data)); if (*sendback == 0) { return -1; @@ -604,13 +605,15 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con int len; if (num == 0) { - len = create_announce_request(request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c), - nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c), - onion_c->temp_public_key, sendback); + len = create_announce_request( + onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c), + nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c), + onion_c->temp_public_key, sendback); } else { - len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key, - onion_c->friends_list[num - 1].temp_secret_key, ping_id, - onion_c->friends_list[num - 1].real_public_key, zero_ping_id, sendback); + len = create_announce_request( + onion_c->rng, request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key, + onion_c->friends_list[num - 1].temp_secret_key, ping_id, + onion_c->friends_list[num - 1].real_public_key, zero_ping_id, sendback); } if (len == -1) { @@ -1098,7 +1101,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, } uint8_t nonce[CRYPTO_NONCE_SIZE]; - random_nonce(nonce); + random_nonce(onion_c->rng, nonce); VLA(uint8_t, packet, DATA_IN_RESPONSE_MIN_SIZE + length); memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); @@ -1120,8 +1123,9 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, } uint8_t o_packet[ONION_MAX_PACKET_SIZE]; - len = create_data_request(o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key, - node_list[good_nodes[i]].data_public_key, nonce, packet, SIZEOF_VLA(packet)); + len = create_data_request( + onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key, + node_list[good_nodes[i]].data_public_key, nonce, packet, SIZEOF_VLA(packet)); if (len == -1) { continue; @@ -1154,7 +1158,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin } uint8_t nonce[CRYPTO_NONCE_SIZE]; - random_nonce(nonce); + random_nonce(onion_c->rng, nonce); VLA(uint8_t, temp, DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE + length); memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); @@ -1168,8 +1172,9 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin } uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE]; - len = create_request(dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data, - onion_c->friends_list[friend_num].dht_public_key, temp, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK); + len = create_request( + onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data, + onion_c->friends_list[friend_num].dht_public_key, temp, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK); assert(len <= UINT16_MAX); const Packet packet = {packet_data, (uint16_t)len}; @@ -1345,7 +1350,7 @@ int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key) onion_c->friends_list[index].is_valid = true; memcpy(onion_c->friends_list[index].real_public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); - crypto_new_keypair(onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key); + crypto_new_keypair(onion_c->rng, onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key); return index; } @@ -1679,7 +1684,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) o_friend->last_populated = tm; for (uint16_t i = 0; i < n; ++i) { - const uint32_t num = random_range_u32(num_nodes); + const uint32_t num = random_range_u32(onion_c->rng, num_nodes); client_send_announce_request(onion_c, friendnum + 1, &onion_c->path_nodes[num].ip_port, onion_c->path_nodes[num].public_key, nullptr, -1); } @@ -1789,7 +1794,7 @@ static void do_announce(Onion_Client *onion_c) } for (unsigned int i = 0; i < (MAX_ONION_CLIENTS_ANNOUNCE / 2); ++i) { - const uint32_t num = random_range_u32(num_nodes); + const uint32_t num = random_range_u32(onion_c->rng, num_nodes); client_send_announce_request(onion_c, 0, &path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, -1); } } @@ -1920,7 +1925,7 @@ void do_onion_client(Onion_Client *onion_c) onion_c->last_run = mono_time_get(onion_c->mono_time); } -Onion_Client *new_onion_client(const Logger *logger, const Mono_Time *mono_time, Net_Crypto *c) +Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c) { if (c == nullptr) { return nullptr; @@ -1941,11 +1946,12 @@ Onion_Client *new_onion_client(const Logger *logger, const Mono_Time *mono_time, onion_c->mono_time = mono_time; onion_c->logger = logger; + onion_c->rng = rng; onion_c->dht = nc_get_dht(c); onion_c->net = dht_get_net(onion_c->dht); onion_c->c = c; - new_symmetric_key(onion_c->secret_symmetric_key); - crypto_new_keypair(onion_c->temp_public_key, onion_c->temp_secret_key); + new_symmetric_key(rng, onion_c->secret_symmetric_key); + crypto_new_keypair(rng, onion_c->temp_public_key, onion_c->temp_secret_key); networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_announce_response, onion_c); networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c); diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index ad68bd0835..d34e8444e7 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h @@ -197,7 +197,7 @@ non_null() void do_onion_client(Onion_Client *onion_c); non_null() -Onion_Client *new_onion_client(const Logger *logger, const Mono_Time *mono_time, Net_Crypto *c); +Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c); non_null() void kill_onion_client(Onion_Client *onion_c); diff --git a/toxcore/ping.c b/toxcore/ping.c index 9603f794f3..91a780b123 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c @@ -30,6 +30,7 @@ struct Ping { const Mono_Time *mono_time; + const Random *rng; DHT *dht; Ping_Array *ping_array; @@ -60,7 +61,7 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key uint8_t data[PING_DATA_SIZE]; pk_copy(data, public_key); memcpy(data + CRYPTO_PUBLIC_KEY_SIZE, ipp, sizeof(IP_Port)); - ping_id = ping_array_add(ping->ping_array, ping->mono_time, data, sizeof(data)); + ping_id = ping_array_add(ping->ping_array, ping->mono_time, ping->rng, data, sizeof(data)); if (ping_id == 0) { crypto_memzero(shared_key, sizeof(shared_key)); @@ -73,7 +74,7 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key pk[0] = NET_PACKET_PING_REQUEST; pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey - random_nonce(pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce + random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce rc = encrypt_data_symmetric(shared_key, @@ -107,7 +108,7 @@ static int ping_send_response(const Ping *ping, const IP_Port *ipp, const uint8_ pk[0] = NET_PACKET_PING_RESPONSE; pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey - random_nonce(pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce + random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce // Encrypt ping_id using recipient privkey const int rc = encrypt_data_symmetric(shared_encryption_key, @@ -347,7 +348,7 @@ void ping_iterate(Ping *ping) } -Ping *ping_new(const Mono_Time *mono_time, DHT *dht) +Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht) { Ping *ping = (Ping *)calloc(1, sizeof(Ping)); @@ -363,6 +364,7 @@ Ping *ping_new(const Mono_Time *mono_time, DHT *dht) } ping->mono_time = mono_time; + ping->rng = rng; ping->dht = dht; networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, &handle_ping_request, dht); networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, &handle_ping_response, dht); diff --git a/toxcore/ping.h b/toxcore/ping.h index 12b4ec9656..88983c3003 100644 --- a/toxcore/ping.h +++ b/toxcore/ping.h @@ -18,7 +18,7 @@ typedef struct Ping Ping; non_null() -Ping *ping_new(const struct Mono_Time *mono_time, DHT *dht); +Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht); non_null() void ping_kill(Ping *ping); diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c index 60d4dbbda7..e22a2e6c1c 100644 --- a/toxcore/ping_array.c +++ b/toxcore/ping_array.c @@ -103,8 +103,8 @@ static void ping_array_clear_timedout(Ping_Array *array, const Mono_Time *mono_t } } -uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uint8_t *data, - uint32_t length) +uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const Random *rng, + const uint8_t *data, uint32_t length) { ping_array_clear_timedout(array, mono_time); const uint32_t index = array->last_added % array->total_size; @@ -124,7 +124,7 @@ uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uin array->entries[index].length = length; array->entries[index].ping_time = mono_time_get(mono_time); ++array->last_added; - uint64_t ping_id = random_u64(); + uint64_t ping_id = random_u64(rng); ping_id /= array->total_size; ping_id *= array->total_size; ping_id += index; diff --git a/toxcore/ping_array.h b/toxcore/ping_array.h index b55df5a1c4..bfb248793e 100644 --- a/toxcore/ping_array.h +++ b/toxcore/ping_array.h @@ -12,6 +12,7 @@ #include #include +#include "crypto_core.h" #include "mono_time.h" #ifdef __cplusplus @@ -34,7 +35,7 @@ struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout); * @brief Free all the allocated memory in a @ref Ping_Array. */ non_null() -void ping_array_kill(struct Ping_Array *array); +void ping_array_kill(Ping_Array *array); /** * @brief Add a data with length to the @ref Ping_Array list and return a ping_id. @@ -42,8 +43,8 @@ void ping_array_kill(struct Ping_Array *array); * @return ping_id on success, 0 on failure. */ non_null() -uint64_t ping_array_add(struct Ping_Array *array, const struct Mono_Time *mono_time, const uint8_t *data, - uint32_t length); +uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const Random *rng, + const uint8_t *data, uint32_t length); /** * @brief Check if @p ping_id is valid and not timed out. @@ -53,7 +54,7 @@ uint64_t ping_array_add(struct Ping_Array *array, const struct Mono_Time *mono_t * @return length of data copied on success, -1 on failure. */ non_null() -int32_t ping_array_check(struct Ping_Array *array, const struct Mono_Time *mono_time, uint8_t *data, size_t length, +int32_t ping_array_check(Ping_Array *array, const Mono_Time *mono_time, uint8_t *data, size_t length, uint64_t ping_id); #ifdef __cplusplus diff --git a/toxcore/ping_array_test.cc b/toxcore/ping_array_test.cc index c4856a4e27..2ac76ddda5 100644 --- a/toxcore/ping_array_test.cc +++ b/toxcore/ping_array_test.cc @@ -50,10 +50,12 @@ TEST(PingArray, StoredDataCanBeRetrieved) { Ping_Array_Ptr const arr(ping_array_new(2, 1)); Mono_Time_Ptr const mono_time(mono_time_new()); + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); ASSERT_NE(mono_time, nullptr); - uint64_t const ping_id - = ping_array_add(arr.get(), mono_time.get(), std::vector{1, 2, 3, 4}.data(), 4); + uint64_t const ping_id = ping_array_add( + arr.get(), mono_time.get(), rng, std::vector{1, 2, 3, 4}.data(), 4); EXPECT_NE(ping_id, 0); std::vector data(4); @@ -65,10 +67,12 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) { Ping_Array_Ptr const arr(ping_array_new(2, 1)); Mono_Time_Ptr const mono_time(mono_time_new()); + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); ASSERT_NE(mono_time, nullptr); - uint64_t const ping_id - = ping_array_add(arr.get(), mono_time.get(), (std::vector{1, 2, 3, 4}).data(), 4); + uint64_t const ping_id = ping_array_add( + arr.get(), mono_time.get(), rng, (std::vector{1, 2, 3, 4}).data(), 4); EXPECT_NE(ping_id, 0); std::vector data(4); @@ -84,10 +88,12 @@ TEST(PingArray, ZeroLengthDataCanBeAdded) { Ping_Array_Ptr const arr(ping_array_new(2, 1)); Mono_Time_Ptr const mono_time(mono_time_new()); + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; - uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c)); + uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c)); EXPECT_NE(ping_id, 0); EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), ping_id), 1); @@ -108,10 +114,12 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce) { Ping_Array_Ptr const arr(ping_array_new(2, 1)); Mono_Time_Ptr const mono_time(mono_time_new()); + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; - uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c)); + uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c)); EXPECT_NE(ping_id, 0); EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), ping_id), 1); @@ -122,10 +130,12 @@ TEST(PingArray, PingIdMustMatchOnCheck) { Ping_Array_Ptr const arr(ping_array_new(1, 1)); Mono_Time_Ptr const mono_time(mono_time_new()); + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; - uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c)); + uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c)); EXPECT_NE(ping_id, 0); uint64_t const bad_ping_id = ping_id == 1 ? 2 : 1; diff --git a/toxcore/tox.c b/toxcore/tox.c index 31f31987e3..b0087d367a 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -549,6 +549,17 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts)); } + const Random *rng = system_random(); + + if (rng == nullptr) { + // TODO(iphydf): Not quite right, but similar. + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); + tox_options_free(default_options); + free(tox); + return nullptr; + } + + tox->rng = *rng; tox->mono_time = mono_time_new(); if (tox->mono_time == nullptr) { @@ -581,7 +592,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) tox_lock(tox); Messenger_Error m_error; - tox->m = new_messenger(tox->mono_time, &tox->ns, &m_options, &m_error); + tox->m = new_messenger(tox->mono_time, &tox->rng, &tox->ns, &m_options, &m_error); if (tox->m == nullptr) { if (m_error == MESSENGER_ERROR_PORT) { @@ -1117,7 +1128,7 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message if (ret >= 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OK); tox_unlock(tox); - return ret; + return (uint32_t)ret; } set_friend_error(tox->m->log, ret, error); @@ -1140,7 +1151,7 @@ uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, Tox_Err_F if (ret >= 0) { SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OK); tox_unlock(tox); - return ret; + return (uint32_t)ret; } set_friend_error(tox->m->log, ret, error); @@ -1184,7 +1195,8 @@ uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, Tox } SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK); - return ret; + assert(ret >= 0); + return (uint32_t)ret; } bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key, @@ -1685,7 +1697,7 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t if (file_id == nullptr) { /* Tox keys are 32 bytes like FILE_ID_LENGTH. */ - new_symmetric_key(f_id); + new_symmetric_key(&tox->rng, f_id); file_id = f_id; } @@ -1840,7 +1852,7 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error) { assert(tox != nullptr); tox_lock(tox); - const int ret = add_groupchat(tox->m->conferences_object, GROUPCHAT_TYPE_TEXT); + const int ret = add_groupchat(tox->m->conferences_object, &tox->rng, GROUPCHAT_TYPE_TEXT); tox_unlock(tox); if (ret == -1) { @@ -2382,7 +2394,8 @@ uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, Tox_Err_Confere } SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_ID_OK); - return ret; + assert(ret >= 0); + return (uint32_t)ret; } // TODO(iphydf): Delete in 0.3.0. diff --git a/toxcore/tox_events_test.cc b/toxcore/tox_events_test.cc index 5973b6da50..40a78e962d 100644 --- a/toxcore/tox_events_test.cc +++ b/toxcore/tox_events_test.cc @@ -11,8 +11,10 @@ namespace { TEST(ToxEvents, UnpackRandomDataDoesntCrash) { + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); std::array data; - random_bytes(data.data(), data.size()); + random_bytes(rng, data.data(), data.size()); tox_events_free(tox_events_load(data.data(), data.size())); } diff --git a/toxcore/tox_struct.h b/toxcore/tox_struct.h index c69f87ccd3..22d1c54a27 100644 --- a/toxcore/tox_struct.h +++ b/toxcore/tox_struct.h @@ -17,6 +17,7 @@ extern "C" { struct Tox { Messenger *m; Mono_Time *mono_time; + Random rng; Network ns; pthread_mutex_t *mutex; diff --git a/toxcore/tox_test.cc b/toxcore/tox_test.cc index 249ba8f715..cae98e1972 100644 --- a/toxcore/tox_test.cc +++ b/toxcore/tox_test.cc @@ -10,14 +10,15 @@ namespace { -static void set_random_name_and_status_message(Tox *tox, uint8_t *name, uint8_t *status_message) +static void set_random_name_and_status_message( + Tox *tox, const Random *rng, uint8_t *name, uint8_t *status_message) { for (uint16_t i = 0; i < tox_max_name_length(); ++i) { - name[i] = random_u08(); + name[i] = random_u08(rng); } for (uint16_t i = 0; i < tox_max_status_message_length(); ++i) { - status_message[i] = random_u08(); + status_message[i] = random_u08(rng); } } @@ -84,10 +85,12 @@ TEST(Tox, OneTest) Tox *tox1 = tox_new(options, nullptr); ASSERT_NE(tox1, nullptr); - set_random_name_and_status_message(tox1, name.data(), status_message.data()); + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); + set_random_name_and_status_message(tox1, rng, name.data(), status_message.data()); Tox *tox2 = tox_new(options, nullptr); ASSERT_NE(tox2, nullptr); - set_random_name_and_status_message(tox2, name2.data(), status_message2.data()); + set_random_name_and_status_message(tox2, rng, name2.data(), status_message2.data()); std::array address; tox_self_get_address(tox1, address.data()); diff --git a/toxcore/util_test.cc b/toxcore/util_test.cc index c8b481fdd4..47bf258766 100644 --- a/toxcore/util_test.cc +++ b/toxcore/util_test.cc @@ -8,24 +8,28 @@ namespace { TEST(Util, TwoRandomIdsAreNotEqual) { + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(pk1, sk1); - crypto_new_keypair(pk2, sk2); + crypto_new_keypair(rng, pk1, sk1); + crypto_new_keypair(rng, pk2, sk2); EXPECT_FALSE(pk_equal(pk1, pk2)); } TEST(Util, IdCopyMakesKeysEqual) { + const Random *rng = system_random(); + ASSERT_NE(rng, nullptr); uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0}; - crypto_new_keypair(pk1, sk1); + crypto_new_keypair(rng, pk1, sk1); pk_copy(pk2, pk1); EXPECT_TRUE(pk_equal(pk1, pk2)); diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c index baabb14faa..7564706ca2 100644 --- a/toxencryptsave/toxencryptsave.c +++ b/toxencryptsave/toxencryptsave.c @@ -101,7 +101,7 @@ Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passphrase_l Tox_Err_Key_Derivation *error) { uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; - random_bytes(salt, sizeof(salt)); + random_bytes(system_random(), salt, sizeof(salt)); return tox_pass_key_derive_with_salt(passphrase, passphrase_len, salt, error); } @@ -185,7 +185,7 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *plaintext, siz ciphertext += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; uint8_t nonce[crypto_box_NONCEBYTES]; - random_nonce(nonce); + random_nonce(system_random(), nonce); memcpy(ciphertext, nonce, crypto_box_NONCEBYTES); ciphertext += crypto_box_NONCEBYTES;