diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index 2b1110e3..33205e89 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 b8c05574..f0557fd9 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 fd0ebdb6..b5520200 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 0c7866f9..f4fdf3e2 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 13881705..fb49c4e2 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 f79d86e3..6d105262 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 dbb8d344..0e7a5e2e 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 91c60cda..bf016608 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 5002c2fa..80a6ed03 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 b406bc83..f466e3e1 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 @@ loop_top: 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 7ae319e6..8501b5c1 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 669ea327..0433385e 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 154877de..94e53bb8 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 28afa4a5..95a8226a 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 e162ddf0..0fd4aa32 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 5026b53a..bfaab8ec 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 1dc904fa..583304c6 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 212dd774..878a70ca 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 5700c0d5..b29c937a 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 6c2a022b..ef5f7b5f 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 55c65f12..2788b85e 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 3d426fb6..e89c3486 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 86e38712..35efc652 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 d9ae875f..e0ad0b37 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 51fc85ff..9a68dda5 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 5651601e..919048a2 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 a8bcda89..9c6e817d 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 f0115601..ca07bf57 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 bd7eeef9..2ab79b17 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 93fda5ac..578f2d92 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 9fdaa307..ee32f6a0 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 a5d63eaa..966bb0cf 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 f90ac5b8..cf9fa368 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 1651af85..b9b2893d 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 78c17963..9d4aac41 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 30bbb714..1411924f 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 16d0432b..be05598d 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 0f9c88c6..e632c3cc 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 6e9a7f7e..0a1e9d94 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 2a68174e..aaf43172 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 bab07d56..e9a9e36a 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 90bdddfb..0bb4e40a 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 25218a00..d7e3f026 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 24a95fe1..24b0370e 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 1b781a80..fa8122bc 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 32ad3cd8..32d3565d 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 6345937e..f39ecaab 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 ad68bd08..d34e8444 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 9603f794..91a780b1 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 12b4ec96..88983c30 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 60d4dbbd..e22a2e6c 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 b55df5a1..bfb24879 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 c4856a4e..2ac76ddd 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 31f31987..b0087d36 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 5973b6da..40a78e96 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 c69f87cc..22d1c54a 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 249ba8f7..cae98e19 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 c8b481fd..47bf2587 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 baabb14f..7564706c 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;