feat: Add support for custom random number generator.

This can be used by fuzzers to make RNG-driven code deterministic (i.e.
based on the fuzzer input).
This commit is contained in:
iphydf 2022-03-27 21:34:12 +00:00
parent 660e346fce
commit cc31ff07fa
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
59 changed files with 587 additions and 458 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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");

View File

@ -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");

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 {

View File

@ -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);

View File

@ -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) {

View File

@ -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) {

View File

@ -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");

View File

@ -1 +1 @@
c40a0017ec22042f0be897893a774b89a6b6fbb621ac4d7f68416134fe4a78a2 /usr/local/bin/tox-bootstrapd
f5e4829db74abffd2c625e2413730e474a4c8bf999d56a0d2009a38be9d01dec /usr/local/bin/tox-bootstrapd

View File

@ -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);

View File

@ -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);

View File

@ -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",
],

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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()

View File

@ -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 <typename T, size_t N>
@ -27,17 +27,20 @@ std::array<T, N> 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<uint8_t> 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:

View File

@ -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;

View File

@ -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.
*

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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()

View File

@ -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);
}

View File

@ -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`.

View File

@ -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())));

View File

@ -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) {

View File

@ -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.

View File

@ -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{});
}

View File

@ -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;

View File

@ -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()

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -12,6 +12,7 @@
#include <stddef.h>
#include <stdint.h>
#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

View File

@ -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<uint8_t>{1, 2, 3, 4}.data(), 4);
uint64_t const ping_id = ping_array_add(
arr.get(), mono_time.get(), rng, std::vector<uint8_t>{1, 2, 3, 4}.data(), 4);
EXPECT_NE(ping_id, 0);
std::vector<uint8_t> 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<uint8_t>{1, 2, 3, 4}).data(), 4);
uint64_t const ping_id = ping_array_add(
arr.get(), mono_time.get(), rng, (std::vector<uint8_t>{1, 2, 3, 4}).data(), 4);
EXPECT_NE(ping_id, 0);
std::vector<uint8_t> 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;

View File

@ -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.

View File

@ -11,8 +11,10 @@ namespace {
TEST(ToxEvents, UnpackRandomDataDoesntCrash)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
std::array<uint8_t, 128> data;
random_bytes(data.data(), data.size());
random_bytes(rng, data.data(), data.size());
tox_events_free(tox_events_load(data.data(), data.size()));
}

View File

@ -17,6 +17,7 @@ extern "C" {
struct Tox {
Messenger *m;
Mono_Time *mono_time;
Random rng;
Network ns;
pthread_mutex_t *mutex;

View File

@ -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<uint8_t, TOX_ADDRESS_SIZE> address;
tox_self_get_address(tox1, address.data());

View File

@ -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));

View File

@ -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;