diff --git a/toxcore-git b/toxcore-git index 0938ba0..94cc8b1 160000 --- a/toxcore-git +++ b/toxcore-git @@ -1 +1 @@ -Subproject commit 0938ba08d9a839df4111168f3414099268d69737 +Subproject commit 94cc8b11ff473064526737936f64b6f9a19c239d diff --git a/toxcore.podspec b/toxcore.podspec index e03d395..c62cfc4 100644 --- a/toxcore.podspec +++ b/toxcore.podspec @@ -9,7 +9,7 @@ Pod::Spec.new do |s| s.name = "toxcore" - s.version = "0.0.1-0938ba0" + s.version = "0.0.1-94cc8b1" s.summary = "Cocoapods wrapper for toxcore" s.homepage = "https://github.com/Antidote-for-Tox/toxcore" s.license = 'GPLv3' diff --git a/toxcore/toxav/rtp.h b/toxcore/toxav/rtp.h index 7daa6fd..4d62a46 100644 --- a/toxcore/toxav/rtp.h +++ b/toxcore/toxav/rtp.h @@ -65,7 +65,7 @@ struct RTPHeader { } __attribute__ ((packed)); /* Check alignment */ -typedef char __fail_if_misaligned [ sizeof(struct RTPHeader) == 80 ? 1 : -1 ]; +typedef char __fail_if_misaligned_1 [ sizeof(struct RTPHeader) == 80 ? 1 : -1 ]; struct RTPMessage { uint16_t len; @@ -75,7 +75,7 @@ struct RTPMessage { } __attribute__ ((packed)); /* Check alignment */ -typedef char __fail_if_misaligned [ sizeof(struct RTPMessage) == 82 ? 1 : -1 ]; +typedef char __fail_if_misaligned_2 [ sizeof(struct RTPMessage) == 82 ? 1 : -1 ]; /** * RTP control session. diff --git a/toxcore/toxcore/DHT.h b/toxcore/toxcore/DHT.h index c213da4..aea3d73 100644 --- a/toxcore/toxcore/DHT.h +++ b/toxcore/toxcore/DHT.h @@ -31,8 +31,13 @@ /* Maximum number of clients stored per friend. */ #define MAX_FRIEND_CLIENTS 8 +#define LCLIENT_NODES (MAX_FRIEND_CLIENTS) +#define LCLIENT_LENGTH 128 + /* A list of the clients mathematically closest to ours. */ -#define LCLIENT_LIST 32 +#define LCLIENT_LIST (LCLIENT_LENGTH * LCLIENT_NODES) + +#define MAX_CLOSE_TO_BOOTSTRAP_NODES 8 /* The max number of nodes to send with send nodes. */ #define MAX_SENT_NODES 4 @@ -58,7 +63,7 @@ #define TOX_TCP_INET6 138 /* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */ -#define DHT_FAKE_FRIEND_NUMBER 4 +#define DHT_FAKE_FRIEND_NUMBER 2 /* Functions to transfer ips safely across wire. */ void to_net_family(IP *ip); @@ -232,7 +237,7 @@ typedef struct { Cryptopacket_Handles cryptopackethandlers[256]; - Node_format to_bootstrap[MAX_SENT_NODES]; + Node_format to_bootstrap[MAX_CLOSE_TO_BOOTSTRAP_NODES]; unsigned int num_to_bootstrap; } DHT; /*----------------------------------------------------------------------------------*/ @@ -307,6 +312,10 @@ int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2); _Bool add_to_list(Node_format *nodes_list, unsigned int length, const uint8_t *pk, IP_Port ip_port, const uint8_t *cmp_pk); +/* Return 1 if node can be added to close list, 0 if it can't. + */ +_Bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port); + /* Get the (maximum MAX_SENT_NODES) closest nodes to public_key we know * and put them in nodes_list (must be MAX_SENT_NODES big). * diff --git a/toxcore/toxcore/DHT.m b/toxcore/toxcore/DHT.m index 14c59a3..6d9479a 100644 --- a/toxcore/toxcore/DHT.m +++ b/toxcore/toxcore/DHT.m @@ -75,47 +75,41 @@ int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2) { size_t i; uint8_t distance1, distance2; - _Bool d1_abs = 0, d2_abs = 0; for (i = 0; i < crypto_box_PUBLICKEYBYTES; ++i) { distance1 = pk[i] ^ pk1[i]; distance2 = pk[i] ^ pk2[i]; - if (!i) { - if (distance1 & (1 << 7)) { - d1_abs = 1; - } + if (distance1 < distance2) + return 1; - if (distance2 & (1 << 7)) { - d2_abs = 1; - } - } + if (distance1 > distance2) + return 2; + } - if (d1_abs) - distance1 = ~distance1; + return 0; +} - if (d2_abs) - distance2 = ~distance2; +/* Return index of first unequal bit number. + */ +static unsigned int bit_by_bit_cmp(const uint8_t *pk1, const uint8_t *pk2) +{ + unsigned int i, j = 0; - if (i == (crypto_box_PUBLICKEYBYTES - 1)) { - if (d1_abs) - if (distance1 != UINT8_MAX) - ++distance1; + for (i = 0; i < crypto_box_PUBLICKEYBYTES; ++i) { + if (pk1[i] == pk2[i]) + continue; - if (d2_abs) - if (distance2 != UINT8_MAX) - ++distance2; + for (j = 0; j < 8; ++j) { + if ((pk1[i] & (1 << (7 - j))) != (pk2[i] & (1 << (7 - j)))) + break; } - if (distance1 < distance2) - return 1; - - if (distance1 > distance2) - return 2; + break; } - return 0; + return i * 8 + j; } /* Shared key generations are costly, it is therefor smart to store commonly used @@ -132,7 +126,7 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t int index = public_key[30] * MAX_KEYS_PER_SLOT + i; if (shared_keys->keys[index].stored) { - if (memcmp(public_key, shared_keys->keys[index].public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(public_key, shared_keys->keys[index].public_key) == 0) { memcpy(shared_key, shared_keys->keys[index].shared_key, crypto_box_BEFORENMBYTES); ++shared_keys->keys[index].times_requested; shared_keys->keys[index].time_last_requested = unix_time(); @@ -239,6 +233,7 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_ int ipv6 = -1; uint8_t net_family; + // FIXME use functions to convert endianness if (nodes[i].ip_port.ip.family == AF_INET) { ipv6 = 0; net_family = TOX_AF_INET; @@ -586,7 +581,7 @@ static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, N { uint32_t num_nodes = 0, i; get_close_nodes_inner(public_key, nodes_list, sa_family, - dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good); + dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, 0); /*TODO uncomment this when hardening is added to close friend clients for (i = 0; i < dht->num_friends; ++i) @@ -780,6 +775,68 @@ static int replace_all( Client_data *list, return 0; } +/* Add node to close list. + * + * simulate is set to 1 if we want to check if a node can be added to the list without adding it. + * + * return -1 on failure. + * return 0 on success. + */ +static int add_to_close(DHT *dht, const uint8_t *public_key, IP_Port ip_port, _Bool simulate) +{ + unsigned int i; + + unsigned int index = bit_by_bit_cmp(public_key, dht->self_public_key); + + if (index > LCLIENT_LENGTH) + index = LCLIENT_LENGTH - 1; + + for (i = 0; i < LCLIENT_NODES; ++i) { + Client_data *client = &dht->close_clientlist[(index * LCLIENT_NODES) + i]; + + if (is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) { + if (!simulate) { + IPPTsPng *ipptp_write = NULL; + IPPTsPng *ipptp_clear = NULL; + + if (ip_port.ip.family == AF_INET) { + ipptp_write = &client->assoc4; + ipptp_clear = &client->assoc6; + } else { + ipptp_write = &client->assoc6; + ipptp_clear = &client->assoc4; + } + + id_copy(client->public_key, public_key); + ipptp_write->ip_port = ip_port; + ipptp_write->timestamp = unix_time(); + + ip_reset(&ipptp_write->ret_ip_port.ip); + ipptp_write->ret_ip_port.port = 0; + ipptp_write->ret_timestamp = 0; + + /* zero out other address */ + memset(ipptp_clear, 0, sizeof(*ipptp_clear)); + } + + return 0; + } + } + + return -1; +} + +/* Return 1 if node can be added to close list, 0 if it can't. + */ +_Bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port) +{ + if (add_to_close(dht, public_key, ip_port, 1) == 0) { + return 1; + } + + return 0; +} + static _Bool is_pk_in_client_list(Client_data *list, unsigned int client_list_length, const uint8_t *public_key, IP_Port ip_port) { @@ -788,7 +845,7 @@ static _Bool is_pk_in_client_list(Client_data *list, unsigned int client_list_le for (i = 0; i < client_list_length; ++i) { if ((ip_port.ip.family == AF_INET && !is_timeout(list[i].assoc4.timestamp, BAD_NODE_TIMEOUT)) || (ip_port.ip.family == AF_INET6 && !is_timeout(list[i].assoc6.timestamp, BAD_NODE_TIMEOUT))) { - if (memcmp(list[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(list[i].public_key, public_key) == 0) { return 1; } } @@ -807,23 +864,18 @@ static unsigned int ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_k { _Bool ret = 0; - if (store_node_ok(&dht->close_clientlist[1], public_key, dht->self_public_key)) { + if (add_to_close(dht, public_key, ip_port, 1) == 0) { ret = 1; } - if (store_node_ok(&dht->close_clientlist[0], public_key, dht->self_public_key)) { - ret = 1; - } - - if (ret && !client_in_nodelist(dht->to_bootstrap, dht->num_to_bootstrap, public_key) - && !is_pk_in_client_list(dht->close_clientlist, LCLIENT_LIST, public_key, ip_port)) { - if (dht->num_to_bootstrap < MAX_SENT_NODES) { + if (ret && !client_in_nodelist(dht->to_bootstrap, dht->num_to_bootstrap, public_key)) { + if (dht->num_to_bootstrap < MAX_CLOSE_TO_BOOTSTRAP_NODES) { memcpy(dht->to_bootstrap[dht->num_to_bootstrap].public_key, public_key, crypto_box_PUBLICKEYBYTES); dht->to_bootstrap[dht->num_to_bootstrap].ip_port = ip_port; ++dht->num_to_bootstrap; } else { //TODO: ipv6 vs v4 - add_to_list(dht->to_bootstrap, MAX_SENT_NODES, public_key, ip_port, dht->self_public_key); + add_to_list(dht->to_bootstrap, MAX_CLOSE_TO_BOOTSTRAP_NODES, public_key, ip_port, dht->self_public_key); } } @@ -878,7 +930,7 @@ int addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key) * to replace the first ip by the second. */ if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, public_key, ip_port)) { - if (replace_all(dht->close_clientlist, LCLIENT_LIST, public_key, ip_port, dht->self_public_key)) + if (add_to_close(dht, public_key, ip_port, 0)) used++; } else used++; @@ -893,7 +945,7 @@ int addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key) DHT_Friend *friend = &dht->friends_list[i]; - if (memcmp(public_key, friend->public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(public_key, friend->public_key) == 0) { friend_foundip = friend; } @@ -902,7 +954,7 @@ int addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key) } else { DHT_Friend *friend = &dht->friends_list[i]; - if (memcmp(public_key, friend->public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(public_key, friend->public_key) == 0) { friend_foundip = friend; } @@ -1079,18 +1131,19 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public Node_format nodes_list[MAX_SENT_NODES]; uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, 0, LAN_ip(ip_port.ip) == 0, 1); - if (num_nodes == 0) - return 0; - uint8_t plain[1 + Node_format_size * MAX_SENT_NODES + length]; uint8_t encrypt[sizeof(plain) + crypto_box_MACBYTES]; uint8_t nonce[crypto_box_NONCEBYTES]; new_nonce(nonce); - int nodes_length = pack_nodes(plain + 1, Node_format_size * MAX_SENT_NODES, nodes_list, num_nodes); + int nodes_length = 0; - if (nodes_length <= 0) - return -1; + if (num_nodes) { + nodes_length = pack_nodes(plain + 1, Node_format_size * MAX_SENT_NODES, nodes_list, num_nodes); + + if (nodes_length <= 0) + return -1; + } plain[0] = num_nodes; memcpy(plain + 1 + nodes_length, sendback_data, length); @@ -1160,7 +1213,7 @@ static uint8_t sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port Node_format test; memcpy(&test, data, sizeof(Node_format)); - if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.public_key, public_key, crypto_box_PUBLICKEYBYTES) != 0) + if (!ipport_equal(&test.ip_port, &node_ip_port) || public_key_cmp(test.public_key, public_key) != 0) return 0; return 1; @@ -1176,7 +1229,7 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa DHT *dht = object; uint32_t cid_size = 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1 + sizeof(uint64_t) + crypto_box_MACBYTES; - if (length <= cid_size) /* too short */ + if (length < cid_size) /* too short */ return 1; uint32_t data_size = length - cid_size; @@ -1200,7 +1253,7 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa if ((unsigned int)len != sizeof(plain)) return 1; - if (plain[0] > size_plain_nodes || plain[0] == 0) + if (plain[0] > size_plain_nodes) return 1; Node_format sendback_node; @@ -1220,7 +1273,7 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa if (num_nodes != plain[0]) return 1; - if (num_nodes <= 0) + if (num_nodes < 0) return 1; /* store the address the *request* was sent to */ @@ -1390,54 +1443,9 @@ int DHT_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port) return -1; } -static void abs_divide_by_2(uint8_t *public_key_dist) -{ - unsigned int i; - _Bool one = 0, abs = 0; - - if (public_key_dist[0] & (1 << 7)) { - for (i = 0; i < crypto_box_PUBLICKEYBYTES; ++i) { - public_key_dist[i] = ~public_key_dist[i]; - } - - if (public_key_dist[crypto_box_PUBLICKEYBYTES - 1] != UINT8_MAX) - ++public_key_dist[crypto_box_PUBLICKEYBYTES - 1]; - } - - for (i = 0; i < crypto_box_PUBLICKEYBYTES; ++i) { - _Bool temp = 0; - - if (public_key_dist[i] & (1)) { - temp = 1; - } - - public_key_dist[i] >>= 1; - - if (one) - public_key_dist[i] += (1 << 7); - - one = temp; - } -} - -static void find_midpoint(uint8_t *out, const uint8_t *top, const uint8_t *bot) -{ - unsigned int i; - - for (i = 0; i < crypto_box_PUBLICKEYBYTES; ++i) { - out[i] = top[i] ^ bot[i]; - } - - abs_divide_by_2(out); - - for (i = 0; i < crypto_box_PUBLICKEYBYTES; ++i) { - out[i] ^= bot[i]; - } -} - /* returns number of nodes not in kill-timeout */ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, const uint8_t *public_key, - Client_data *list, uint32_t list_count, uint32_t *bootstrap_times) + Client_data *list, uint32_t list_count, uint32_t *bootstrap_times, _Bool sortable) { uint32_t i; uint8_t not_kill = 0; @@ -1481,33 +1489,19 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co } } - if (sort_ok) { + if (sortable && sort_ok) { sort_client_list(list, list_count, public_key); } if ((num_nodes != 0) && (is_timeout(*lastgetnode, GET_NODE_INTERVAL) || *bootstrap_times < MAX_BOOTSTRAP_TIMES)) { - uint32_t rand_node = rand() % (num_nodes * 2); - - if (rand_node >= num_nodes) { - rand_node = rand_node % num_nodes; - - if ((num_nodes - 1) != rand_node) { - rand_node += rand() % (num_nodes - (rand_node + 1)); - } - - if (memcmp(client_list[rand_node]->public_key, public_key, crypto_box_PUBLICKEYBYTES) != 0) { - uint8_t get_pk[crypto_box_PUBLICKEYBYTES]; - find_midpoint(get_pk, client_list[rand_node]->public_key, public_key); - getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, get_pk, NULL); - } - } else { - if ((num_nodes - 1) != rand_node) { - rand_node += rand() % (num_nodes - (rand_node + 1)); - } + uint32_t rand_node = rand() % (num_nodes); - getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key, NULL); + if ((num_nodes - 1) != rand_node) { + rand_node += rand() % (num_nodes - (rand_node + 1)); } + getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key, NULL); + *lastgetnode = temp_time; ++*bootstrap_times; } @@ -1532,7 +1526,7 @@ static void do_DHT_friends(DHT *dht) friend->num_to_bootstrap = 0; do_ping_and_sendnode_requests(dht, &friend->lastgetnode, friend->public_key, friend->client_list, MAX_FRIEND_CLIENTS, - &friend->bootstrap_times); + &friend->bootstrap_times, 1); } } @@ -1550,7 +1544,7 @@ static void do_Close(DHT *dht) dht->num_to_bootstrap = 0; uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->self_public_key, - dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times); + dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times, 0); if (!not_killed) { /* all existing nodes are at least KILL_NODE_TIMEOUT, @@ -2088,7 +2082,7 @@ static int send_hardening_getnode_res(const DHT *dht, const Node_format *sendto, uint32_t i; for (i = 0; i < LCLIENT_LIST; ++i) { - if (memcmp(dht->close_clientlist[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) != 0) + if (public_key_cmp(dht->close_clientlist[i].public_key, public_key) != 0) continue; if (sa_family == AF_INET) @@ -2185,7 +2179,7 @@ static int handle_hardening(void *object, IP_Port source, const uint8_t *source_ if (is_timeout(temp->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) return 1; - if (memcmp(temp->hardening.send_nodes_pingedid, source_pubkey, crypto_box_PUBLICKEYBYTES) != 0) + if (public_key_cmp(temp->hardening.send_nodes_pingedid, source_pubkey) != 0) return 1; /* If Nodes look good and the request checks out */ @@ -2358,7 +2352,7 @@ static int cryptopacket_handle(void *object, IP_Port source, const uint8_t *pack length > MAX_CRYPTO_REQUEST_SIZE + crypto_box_MACBYTES) return 1; - if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. + if (public_key_cmp(packet + 1, dht->self_public_key) == 0) { // Check if request is for us. uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t data[MAX_CRYPTO_REQUEST_SIZE]; uint8_t number; @@ -2452,7 +2446,7 @@ void do_DHT(DHT *dht) do_DHT_friends(dht); do_NAT(dht); do_to_ping(dht->ping); - do_hardening(dht); + //do_hardening(dht); #ifdef ENABLE_ASSOC_DHT if (dht->assoc) diff --git a/toxcore/toxcore/Messenger.m b/toxcore/toxcore/Messenger.m index 6d45077..34296c2 100644 --- a/toxcore/toxcore/Messenger.m +++ b/toxcore/toxcore/Messenger.m @@ -2660,7 +2660,7 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 set_nospam(&(m->fr), *(uint32_t *)data); load_secret_key(m->net_crypto, (&data[sizeof(uint32_t)]) + crypto_box_PUBLICKEYBYTES); - if (memcmp((&data[sizeof(uint32_t)]), m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) != 0) { + if (public_key_cmp((&data[sizeof(uint32_t)]), m->net_crypto->self_public_key) != 0) { return -1; } } else diff --git a/toxcore/toxcore/TCP_client.m b/toxcore/toxcore/TCP_client.m index 1bd11a1..752deec 100644 --- a/toxcore/toxcore/TCP_client.m +++ b/toxcore/toxcore/TCP_client.m @@ -151,7 +151,7 @@ static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn) if (ret == -1) return 0; - if (data[0] == 5 && data[1] == 0) + if (data[0] == 5 && data[1] == 0) // FIXME magic numbers return 1; return -1; @@ -251,7 +251,7 @@ static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data memcpy(TCP_conn->recv_nonce, plain + crypto_box_PUBLICKEYBYTES, crypto_box_NONCEBYTES); encrypt_precompute(plain, TCP_conn->temp_secret_key, TCP_conn->shared_key); - memset(TCP_conn->temp_secret_key, 0, crypto_box_SECRETKEYBYTES); + sodium_memzero(TCP_conn->temp_secret_key, crypto_box_SECRETKEYBYTES); return 0; } @@ -962,6 +962,6 @@ void kill_TCP_connection(TCP_Client_Connection *TCP_connection) wipe_priority_list(TCP_connection); kill_sock(TCP_connection->sock); - memset(TCP_connection, 0, sizeof(TCP_Client_Connection)); + sodium_memzero(TCP_connection, sizeof(TCP_Client_Connection)); free(TCP_connection); } diff --git a/toxcore/toxcore/TCP_connection.m b/toxcore/toxcore/TCP_connection.m index 5f38b5d..027779d 100644 --- a/toxcore/toxcore/TCP_connection.m +++ b/toxcore/toxcore/TCP_connection.m @@ -384,7 +384,7 @@ static int find_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_ TCP_Connection_to *con_to = get_connection(tcp_c, i); if (con_to) { - if (memcmp(con_to->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(con_to->public_key, public_key) == 0) { return i; } } @@ -407,11 +407,11 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela if (tcp_con) { if (tcp_con->status == TCP_CONN_SLEEPING) { - if (memcmp(tcp_con->relay_pk, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(tcp_con->relay_pk, relay_pk) == 0) { return i; } } else { - if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(tcp_con->connection->public_key, relay_pk) == 0) { return i; } } diff --git a/toxcore/toxcore/TCP_server.m b/toxcore/toxcore/TCP_server.m index cf997d3..d4944ae 100644 --- a/toxcore/toxcore/TCP_server.m +++ b/toxcore/toxcore/TCP_server.m @@ -169,7 +169,7 @@ static int del_accepted(TCP_Server *TCP_server, int index) if (!bs_list_remove(&TCP_server->accepted_key_list, TCP_server->accepted_connection_array[index].public_key, index)) return -1; - memset(&TCP_server->accepted_connection_array[index], 0, sizeof(TCP_Secure_Connection)); + sodium_memzero(&TCP_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection)); --TCP_server->num_accepted_connections; if (TCP_server->num_accepted_connections == 0) @@ -447,7 +447,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const static void kill_TCP_connection(TCP_Secure_Connection *con) { kill_sock(con->sock); - memset(con, 0, sizeof(TCP_Secure_Connection)); + sodium_memzero(con, sizeof(TCP_Secure_Connection)); } static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number); @@ -583,7 +583,7 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; /* If person tries to cennect to himself we deny the request*/ - if (memcmp(con->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(con->public_key, public_key) == 0) { if (send_routing_response(con, 0, public_key) == -1) return -1; @@ -592,7 +592,7 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { if (con->connections[i].status != 0) { - if (memcmp(public_key, con->connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(public_key, con->connections[i].public_key) == 0) { if (send_routing_response(con, i + NUM_RESERVED_PORTS, public_key) == -1) { return -1; } else { @@ -629,7 +629,7 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { if (other_conn->connections[i].status == 1 - && memcmp(other_conn->connections[i].public_key, con->public_key, crypto_box_PUBLICKEYBYTES) == 0) { + && public_key_cmp(other_conn->connections[i].public_key, con->public_key) == 0) { other_id = i; break; } @@ -868,7 +868,7 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection return -1; } - memset(con, 0, sizeof(TCP_Secure_Connection)); + sodium_memzero(con, sizeof(TCP_Secure_Connection)); if (handle_TCP_packet(TCP_server, index, data, length) == -1) { kill_accepted(TCP_server, index); @@ -1056,7 +1056,7 @@ static int do_incoming(TCP_Server *TCP_server, uint32_t i) kill_TCP_connection(conn_new); memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection)); - memset(conn_old, 0, sizeof(TCP_Secure_Connection)); + sodium_memzero(conn_old, sizeof(TCP_Secure_Connection)); ++TCP_server->unconfirmed_connection_queue_index; return index_new; diff --git a/toxcore/toxcore/crypto_core.h b/toxcore/toxcore/crypto_core.h index 9147d00..5c381a4 100644 --- a/toxcore/toxcore/crypto_core.h +++ b/toxcore/toxcore/crypto_core.h @@ -37,6 +37,9 @@ #include #include #define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) +/* I know */ +#define sodium_memcmp(a, b, c) memcmp(a, b, c) +#define sodium_memzero(a, c) memset(a, 0, c) #endif #define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES) @@ -108,7 +111,7 @@ int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, cons void increment_nonce(uint8_t *nonce); /* increment the given nonce by num */ -void increment_nonce_number(uint8_t *nonce, uint32_t num); +void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num); /* Fill the given nonce with random bytes. */ void random_nonce(uint8_t *nonce); diff --git a/toxcore/toxcore/crypto_core.m b/toxcore/toxcore/crypto_core.m index d1549b2..a733c38 100644 --- a/toxcore/toxcore/crypto_core.m +++ b/toxcore/toxcore/crypto_core.m @@ -84,7 +84,7 @@ void encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, ui int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length, uint8_t *encrypted) { - if (length == 0) + if (length == 0 || !secret_key || !nonce || !plain || !encrypted) return -1; uint8_t temp_plain[length + crypto_box_ZEROBYTES]; @@ -104,7 +104,7 @@ int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, cons int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, uint32_t length, uint8_t *plain) { - if (length <= crypto_box_BOXZEROBYTES) + if (length <= crypto_box_BOXZEROBYTES || !secret_key || !nonce || !encrypted || !plain) return -1; uint8_t temp_plain[length + crypto_box_ZEROBYTES]; @@ -123,53 +123,72 @@ int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, cons int encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length, uint8_t *encrypted) { + if (!public_key || !secret_key) + return -1; + uint8_t k[crypto_box_BEFORENMBYTES]; encrypt_precompute(public_key, secret_key, k); - return encrypt_data_symmetric(k, nonce, plain, length, encrypted); + int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted); + sodium_memzero(k, sizeof k); + return ret; } int decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, uint32_t length, uint8_t *plain) { + if (!public_key || !secret_key) + return -1; + uint8_t k[crypto_box_BEFORENMBYTES]; encrypt_precompute(public_key, secret_key, k); - return decrypt_data_symmetric(k, nonce, encrypted, length, plain); + int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain); + sodium_memzero(k, sizeof k); + return ret; } /* Increment the given nonce by 1. */ void increment_nonce(uint8_t *nonce) { - uint32_t i; - - for (i = crypto_box_NONCEBYTES; i != 0; --i) { - ++nonce[i - 1]; - - if (nonce[i - 1] != 0) - break; + /* FIXME use increment_nonce_number(nonce, 1) or sodium_increment (change to little endian) + * NOTE don't use breaks inside this loop + * In particular, make sure, as far as possible, + * that loop bounds and their potential underflow or overflow + * are independent of user-controlled input (you may have heard of the Heartbleed bug). + */ + uint32_t i = crypto_box_NONCEBYTES; + uint_fast16_t carry = 1U; + + for (; i != 0; --i) { + carry += (uint_fast16_t) nonce[i - 1]; + nonce[i - 1] = (uint8_t) carry; + carry >>= 8; } } /* increment the given nonce by num */ -void increment_nonce_number(uint8_t *nonce, uint32_t num) +void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num) { - uint32_t num1, num2; - memcpy(&num1, nonce + (crypto_box_NONCEBYTES - sizeof(num1)), sizeof(num1)); - num1 = ntohl(num1); - num2 = num + num1; - - if (num2 < num1) { - uint32_t i; - - for (i = crypto_box_NONCEBYTES - sizeof(num1); i != 0; --i) { - ++nonce[i - 1]; - - if (nonce[i - 1] != 0) - break; - } + /* NOTE don't use breaks inside this loop + * In particular, make sure, as far as possible, + * that loop bounds and their potential underflow or overflow + * are independent of user-controlled input (you may have heard of the Heartbleed bug). + */ + const uint32_t big_endian_num = htonl(host_order_num); + const uint8_t *const num_vec = (const uint8_t *) &big_endian_num; + uint8_t num_as_nonce[crypto_box_NONCEBYTES] = {0}; + num_as_nonce[crypto_box_NONCEBYTES - 4] = num_vec[0]; + num_as_nonce[crypto_box_NONCEBYTES - 3] = num_vec[1]; + num_as_nonce[crypto_box_NONCEBYTES - 2] = num_vec[2]; + num_as_nonce[crypto_box_NONCEBYTES - 1] = num_vec[3]; + + uint32_t i = crypto_box_NONCEBYTES; + uint_fast16_t carry = 0U; + + for (; i != 0; --i) { + carry += (uint_fast16_t) nonce[i - 1] + (uint_fast16_t) num_as_nonce[i - 1]; + nonce[i - 1] = (unsigned char) carry; + carry >>= 8; } - - num2 = htonl(num2); - memcpy(nonce + (crypto_box_NONCEBYTES - sizeof(num2)), &num2, sizeof(num2)); } /* Fill the given nonce with random bytes. */ @@ -203,15 +222,18 @@ void new_nonce(uint8_t *nonce) 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 length, uint8_t request_id) { + if (!send_public_key || !packet || !recv_public_key || !data) + return -1; + if (MAX_CRYPTO_REQUEST_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES) return -1; - uint8_t nonce[crypto_box_NONCEBYTES]; - uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; + uint8_t *nonce = packet + 1 + crypto_box_PUBLICKEYBYTES * 2; + new_nonce(nonce); + uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; // FIXME sodium_memzero before exit function memcpy(temp + 1, data, length); temp[0] = request_id; - new_nonce(nonce); int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); @@ -221,7 +243,6 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke packet[0] = NET_PACKET_CRYPTO; memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES); memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES); - memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; } @@ -235,17 +256,19 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, uint8_t *request_id, const uint8_t *packet, uint16_t length) { + if (!self_public_key || !public_key || !data || !request_id || !packet) + return -1; + if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES || length > MAX_CRYPTO_REQUEST_SIZE) return -1; - if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) != 0) + if (public_key_cmp(packet + 1, self_public_key) != 0) return -1; memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); - uint8_t nonce[crypto_box_NONCEBYTES]; - uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; - memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); + const uint8_t *nonce = packet + 1 + crypto_box_PUBLICKEYBYTES * 2; + uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; // FIXME sodium_memzero before exit function int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); diff --git a/toxcore/toxcore/friend_connection.m b/toxcore/toxcore/friend_connection.m index 04deaf8..e7c8432 100644 --- a/toxcore/toxcore/friend_connection.m +++ b/toxcore/toxcore/friend_connection.m @@ -138,7 +138,7 @@ int getfriend_conn_id_pk(Friend_Connections *fr_c, const uint8_t *real_pk) Friend_Conn *friend_con = get_conn(fr_c, i); if (friend_con) { - if (memcmp(friend_con->real_public_key, real_pk, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(friend_con->real_public_key, real_pk) == 0) return i; } } @@ -159,7 +159,7 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_ return -1; /* Local ip and same pk means that they are hosting a TCP relay. */ - if (Local_ip(ip_port.ip) && memcmp(friend_con->dht_temp_pk, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (Local_ip(ip_port.ip) && public_key_cmp(friend_con->dht_temp_pk, public_key) == 0) { if (friend_con->dht_ip_port.ip.family != 0) { ip_port.ip = friend_con->dht_ip_port.ip; } else { @@ -173,7 +173,7 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_ for (i = 0; i < FRIEND_MAX_STORED_TCP_RELAYS; ++i) { if (friend_con->tcp_relays[i].ip_port.ip.family != 0 - && memcmp(friend_con->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + && public_key_cmp(friend_con->tcp_relays[i].public_key, public_key) == 0) { memset(&friend_con->tcp_relays[i], 0, sizeof(Node_format)); } } @@ -356,7 +356,7 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub if (!friend_con) return; - if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(friend_con->dht_temp_pk, dht_public_key) == 0) return; change_dht_pk(fr_c, number, dht_public_key); @@ -479,7 +479,7 @@ static int handle_new_connections(void *object, New_Connection *n_c) friend_con->dht_ip_port_lastrecv = unix_time(); } - if (memcmp(friend_con->dht_temp_pk, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES) != 0) { + if (public_key_cmp(friend_con->dht_temp_pk, n_c->dht_public_key) != 0) { change_dht_pk(fr_c, friendcon_id, n_c->dht_public_key); } diff --git a/toxcore/toxcore/friend_requests.m b/toxcore/toxcore/friend_requests.m index dae1694..7d4fecd 100644 --- a/toxcore/toxcore/friend_requests.m +++ b/toxcore/toxcore/friend_requests.m @@ -94,7 +94,7 @@ int remove_request_received(Friend_Requests *fr, const uint8_t *real_pk) for (i = 0; i < MAX_RECEIVED_STORED; ++i) { if (id_equal(fr->received_requests[i], real_pk)) { - memset(fr->received_requests[i], 0, crypto_box_PUBLICKEYBYTES); + sodium_memzero(fr->received_requests[i], crypto_box_PUBLICKEYBYTES); return 0; } } diff --git a/toxcore/toxcore/group.m b/toxcore/toxcore/group.m index 2eadaf7..9313a24 100644 --- a/toxcore/toxcore/group.m +++ b/toxcore/toxcore/group.m @@ -106,7 +106,7 @@ static int wipe_group_chat(Group_Chats *g_c, int groupnumber) return -1; uint32_t i; - memset(&(g_c->chats[groupnumber]), 0 , sizeof(Group_c)); + sodium_memzero(&(g_c->chats[groupnumber]), sizeof(Group_c)); for (i = g_c->num_chats; i != 0; --i) { if (g_c->chats[i - 1].status != GROUPCHAT_STATUS_NONE) @@ -162,7 +162,7 @@ static int get_group_num(const Group_Chats *g_c, const uint8_t *identifier) uint32_t i; for (i = 0; i < g_c->num_chats; ++i) - if (memcmp(g_c->chats[i].identifier, identifier, GROUP_IDENTIFIER_LENGTH) == 0) + if (sodium_memcmp(g_c->chats[i].identifier, identifier, GROUP_IDENTIFIER_LENGTH) == 0) return i; return -1; @@ -218,14 +218,14 @@ static int add_to_closest(Group_Chats *g_c, int groupnumber, const uint8_t *real if (!g) return -1; - if (memcmp(g->real_pk, real_pk, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(g->real_pk, real_pk) == 0) return -1; unsigned int i; unsigned int index = DESIRED_CLOSE_CONNECTIONS; for (i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { - if (g->closest_peers[i].entry && memcmp(real_pk, g->closest_peers[i].real_pk, crypto_box_PUBLICKEYBYTES) == 0) { + if (g->closest_peers[i].entry && public_key_cmp(real_pk, g->closest_peers[i].real_pk) == 0) { return 0; } } @@ -299,7 +299,7 @@ static unsigned int pk_in_closest_peers(Group_c *g, uint8_t *real_pk) if (!g->closest_peers[i].entry) continue; - if (memcmp(g->closest_peers[i].real_pk, real_pk, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(g->closest_peers[i].real_pk, real_pk) == 0) return 1; } @@ -1277,7 +1277,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con if (!g) return; - if (memcmp(data + 1 + sizeof(uint16_t) * 2, g->identifier, GROUP_IDENTIFIER_LENGTH) != 0) + if (sodium_memcmp(data + 1 + sizeof(uint16_t) * 2, g->identifier, GROUP_IDENTIFIER_LENGTH) != 0) return; uint16_t peer_number = rand(); /* TODO: what if two people enter the group at the same time and @@ -1525,7 +1525,7 @@ static int handle_send_peers(Group_Chats *g_c, int groupnumber, const uint8_t *d return -1; if (g->status == GROUPCHAT_STATUS_VALID - && memcmp(d, g_c->m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { + && public_key_cmp(d, g_c->m->net_crypto->self_public_key) == 0) { g->peer_number = peer_num; g->status = GROUPCHAT_STATUS_CONNECTED; group_name_send(g_c, groupnumber, g_c->m->name, g_c->m->name_length); @@ -2011,7 +2011,7 @@ static unsigned int lossy_packet_not_received(Group_c *g, int peer_index, uint16 uint16_t top_distance = message_number - g->group[peer_index].top_lossy_number; if (top_distance >= MAX_LOSSY_COUNT) { - memset(g->group[peer_index].recv_lossy, 0, sizeof(g->group[peer_index].recv_lossy)); + sodium_memzero(g->group[peer_index].recv_lossy, sizeof(g->group[peer_index].recv_lossy)); g->group[peer_index].top_lossy_number = message_number; g->group[peer_index].bottom_lossy_number = (message_number - MAX_LOSSY_COUNT) + 1; g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT] = 1; diff --git a/toxcore/toxcore/net_crypto.m b/toxcore/toxcore/net_crypto.m index f6234a0..f8a85ad 100644 --- a/toxcore/toxcore/net_crypto.m +++ b/toxcore/toxcore/net_crypto.m @@ -244,7 +244,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c if (handle_cookie_request(c, request_plain, shared_key, dht_public_key_temp, packet, length) != 0) return -1; - if (memcmp(dht_public_key, dht_public_key_temp, crypto_box_PUBLICKEYBYTES) != 0) + if (public_key_cmp(dht_public_key, dht_public_key_temp) != 0) return -1; uint8_t data[COOKIE_RESPONSE_LENGTH]; @@ -363,7 +363,8 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t if (len != sizeof(plain)) return -1; - if (memcmp(cookie_hash, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, crypto_hash_sha512_BYTES) != 0) + if (sodium_memcmp(cookie_hash, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, + crypto_hash_sha512_BYTES) != 0) return -1; memcpy(nonce, plain, crypto_box_NONCEBYTES); @@ -1518,7 +1519,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) /* Keep mutex, only destroy it when connection is realloced out. */ pthread_mutex_t mutex = c->crypto_connections[crypt_connection_id].mutex; - memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection)); + sodium_memzero(&(c->crypto_connections[crypt_connection_id]), sizeof(Crypto_Connection)); c->crypto_connections[crypt_connection_id].mutex = mutex; for (i = c->crypto_connections_length; i != 0; --i) { @@ -1548,7 +1549,7 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key) for (i = 0; i < c->crypto_connections_length; ++i) { if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION) - if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(public_key, c->crypto_connections[i].public_key) == 0) return i; } @@ -1704,6 +1705,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) memcpy(conn->dht_public_key, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES); conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; + conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; conn->rtt_time = DEFAULT_PING_CONNECTION; crypto_connection_add_source(c, crypt_connection_id, n_c->source); @@ -1746,6 +1748,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u crypto_box_keypair(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; conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; conn->rtt_time = DEFAULT_PING_CONNECTION; memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); @@ -2707,6 +2710,6 @@ void kill_net_crypto(Net_Crypto *c) networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_HS, NULL, NULL); networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_DATA, NULL, NULL); - memset(c, 0, sizeof(Net_Crypto)); + sodium_memzero(c, sizeof(Net_Crypto)); free(c); } diff --git a/toxcore/toxcore/network.m b/toxcore/toxcore/network.m index 2a4e854..92a2cf1 100644 --- a/toxcore/toxcore/network.m +++ b/toxcore/toxcore/network.m @@ -699,6 +699,9 @@ static void at_shutdown(void) /* Function to cleanup networking stuff. */ void kill_networking(Networking_Core *net) { + if (!net) + return; + if (net->family != 0) /* Socket not initialized */ kill_sock(net->sock); @@ -823,7 +826,7 @@ void ipport_copy(IP_Port *target, const IP_Port *source) * writes error message into the buffer on error */ /* there would be INET6_ADDRSTRLEN, but it might be too short for the error message */ -static char addresstext[96]; +static char addresstext[96]; // FIXME magic number. Why not INET6_ADDRSTRLEN ? const char *ip_ntoa(const IP *ip) { if (ip) { @@ -964,10 +967,10 @@ int addr_resolve(const char *address, IP *to, IP *extra) return 0; } - IP4 ip4; - memset(&ip4, 0, sizeof(ip4)); - IP6 ip6; - memset(&ip6, 0, sizeof(ip6)); + IP ip4; + ip_init(&ip4, /* ipv6? */ false); + IP ip6; + ip_init(&ip6, /* ipv6? */ true); for (walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) { switch (walker->ai_family) { @@ -975,11 +978,11 @@ int addr_resolve(const char *address, IP *to, IP *extra) if (walker->ai_family == family) { /* AF_INET requested, done */ struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; to->ip4.in_addr = addr->sin_addr; - rc = 3; + rc = 3; // TODO do we really have to reuse variable instead of creating a new one? } else if (!(rc & 1)) { /* AF_UNSPEC requested, store away */ struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; - ip4.in_addr = addr->sin_addr; - rc |= 1; + ip4.ip4.in_addr = addr->sin_addr; + rc |= 1; // FIXME magic number } break; /* switch */ @@ -994,7 +997,7 @@ int addr_resolve(const char *address, IP *to, IP *extra) } else if (!(rc & 2)) { /* AF_UNSPEC requested, store away */ if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; - ip6.in6_addr = addr->sin6_addr; + ip6.ip6.in6_addr = addr->sin6_addr; rc |= 2; } } @@ -1004,17 +1007,14 @@ int addr_resolve(const char *address, IP *to, IP *extra) } if (to->family == AF_UNSPEC) { - if (rc & 2) { - to->family = AF_INET6; - to->ip6 = ip6; + if (rc & 2) { // FIXME magic number + ip_copy(to, &ip6); if ((rc & 1) && (extra != NULL)) { - extra->family = AF_INET; - extra->ip4 = ip4; + ip_copy(extra, &ip4); } } else if (rc & 1) { - to->family = AF_INET; - to->ip4 = ip4; + ip_copy(to, &ip4); } else rc = 0; } diff --git a/toxcore/toxcore/onion_announce.m b/toxcore/toxcore/onion_announce.m index 25f3e0f..676b38d 100644 --- a/toxcore/toxcore/onion_announce.m +++ b/toxcore/toxcore/onion_announce.m @@ -211,7 +211,7 @@ static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key) for (i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) { if (!is_timeout(onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT) - && memcmp(onion_a->entries[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) + && public_key_cmp(onion_a->entries[i].public_key, public_key) == 0) return i; } @@ -316,7 +316,8 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t * uint8_t *data_public_key = plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES; - if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) { + if (sodium_memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 + || sodium_memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) { index = add_to_entries(onion_a, source, packet_public_key, data_public_key, packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)); } else { @@ -336,8 +337,8 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t * pl[0] = 0; memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE); } else { - if (memcmp(onion_a->entries[index].public_key, packet_public_key, crypto_box_PUBLICKEYBYTES) == 0) { - if (memcmp(onion_a->entries[index].data_public_key, data_public_key, crypto_box_PUBLICKEYBYTES) != 0) { + if (public_key_cmp(onion_a->entries[index].public_key, packet_public_key) == 0) { + if (public_key_cmp(onion_a->entries[index].data_public_key, data_public_key) != 0) { pl[0] = 0; memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE); } else { diff --git a/toxcore/toxcore/onion_client.m b/toxcore/toxcore/onion_client.m index d6d078e..b879f39 100644 --- a/toxcore/toxcore/onion_client.m +++ b/toxcore/toxcore/onion_client.m @@ -46,7 +46,7 @@ int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t unsigned int i; for (i = 0; i < MAX_PATH_NODES; ++i) { - if (memcmp(public_key, onion_c->path_nodes_bs[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(public_key, onion_c->path_nodes_bs[i].public_key) == 0) return -1; } @@ -76,7 +76,7 @@ static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uin unsigned int i; for (i = 0; i < MAX_PATH_NODES; ++i) { - if (memcmp(public_key, onion_c->path_nodes[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(public_key, onion_c->path_nodes[i].public_key) == 0) return -1; } @@ -190,6 +190,7 @@ static int is_path_used(const Onion_Client_Paths *onion_paths, const Node_format continue; } + // TODO: do we really have to check it with the last node? if (ipport_equal(&onion_paths->paths[i].ip_port1, &nodes[ONION_PATH_LENGTH - 1].ip_port)) { return i; } @@ -484,7 +485,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t reference_id = onion_c->c->self_public_key; list_length = MAX_ONION_CLIENTS_ANNOUNCE; - if (is_stored == 1 && memcmp(pingid_or_key, onion_c->temp_public_key, crypto_box_PUBLICKEYBYTES) != 0) { + if (is_stored == 1 && public_key_cmp(pingid_or_key, onion_c->temp_public_key) != 0) { is_stored = 0; } @@ -509,7 +510,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t } for (i = 0; i < list_length; ++i) { - if (memcmp(list_nodes[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(list_nodes[i].public_key, public_key) == 0) { index = i; stored = 1; break; @@ -547,7 +548,7 @@ static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, co for (i = 0; i < MAX_STORED_PINGED_NODES; ++i) { if (!is_timeout(last_pinged[i].timestamp, MIN_NODE_PING_TIME)) - if (memcmp(last_pinged[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(last_pinged[i].public_key, public_key) == 0) return 0; } @@ -602,7 +603,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for || id_closest(reference_id, list_nodes[1].public_key, nodes[i].public_key) == 2 ) { /* check if node is already in list. */ for (j = 0; j < list_length; ++j) { - if (memcmp(list_nodes[j].public_key, nodes[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(list_nodes[j].public_key, nodes[i].public_key) == 0) { break; } } @@ -912,7 +913,7 @@ static int handle_dht_dhtpk(void *object, IP_Port source, const uint8_t *source_ if (len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)) return 1; - if (memcmp(source_pubkey, plain + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES) != 0) + if (public_key_cmp(source_pubkey, plain + 1 + sizeof(uint64_t)) != 0) return 1; return handle_dhtpk_announce(onion_c, packet, plain, len); @@ -981,7 +982,7 @@ int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key) if (onion_c->friends_list[i].status == 0) continue; - if (memcmp(public_key, onion_c->friends_list[i].real_public_key, crypto_box_PUBLICKEYBYTES) == 0) + if (public_key_cmp(public_key, onion_c->friends_list[i].real_public_key) == 0) return i; } @@ -1059,7 +1060,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num) //if (onion_c->friends_list[friend_num].know_dht_public_key) // DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, 0); - memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend)); + sodium_memzero(&(onion_c->friends_list[friend_num]), sizeof(Onion_Friend)); unsigned int i; for (i = onion_c->num_friends; i != 0; --i) { @@ -1129,7 +1130,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin return -1; if (onion_c->friends_list[friend_num].know_dht_public_key) { - if (memcmp(dht_key, onion_c->friends_list[friend_num].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(dht_key, onion_c->friends_list[friend_num].dht_public_key) == 0) { return -1; } @@ -1522,7 +1523,7 @@ void kill_onion_client(Onion_Client *onion_c) oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL); cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL); set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, NULL, NULL); - memset(onion_c, 0, sizeof(Onion_Client)); + sodium_memzero(onion_c, sizeof(Onion_Client)); free(onion_c); } diff --git a/toxcore/toxcore/ping.m b/toxcore/toxcore/ping.m index 6a480f6..f81766c 100644 --- a/toxcore/toxcore/ping.m +++ b/toxcore/toxcore/ping.m @@ -39,10 +39,10 @@ #define PING_NUM_MAX 512 /* Maximum newly announced nodes to ping per TIME_TO_PING seconds. */ -#define MAX_TO_PING 16 +#define MAX_TO_PING 32 /* Ping newly announced nodes to ping per TIME_TO_PING seconds*/ -#define TIME_TO_PING 4 +#define TIME_TO_PING 2 struct PING { @@ -262,9 +262,11 @@ int add_to_ping(PING *ping, const uint8_t *public_key, IP_Port ip_port) if (!ip_isset(&ip_port.ip)) return -1; - if (in_list(ping->dht->close_clientlist, LCLIENT_LIST, public_key, ip_port)) + if (!node_addable_to_close_list(ping->dht, public_key, ip_port)) return -1; + if (in_list(ping->dht->close_clientlist, LCLIENT_LIST, public_key, ip_port)) + return -1; IP_Port temp; @@ -282,7 +284,7 @@ int add_to_ping(PING *ping, const uint8_t *public_key, IP_Port ip_port) return 0; } - if (memcmp(ping->to_ping[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { + if (public_key_cmp(ping->to_ping[i].public_key, public_key) == 0) { return -1; } } @@ -311,6 +313,9 @@ void do_to_ping(PING *ping) if (!ip_isset(&ping->to_ping[i].ip_port.ip)) break; + if (!node_addable_to_close_list(ping->dht, ping->to_ping[i].public_key, ping->to_ping[i].ip_port)) + continue; + send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key); ip_reset(&ping->to_ping[i].ip_port.ip); } diff --git a/toxcore/toxcore/tox.m b/toxcore/toxcore/tox.m index 3e9db76..c28c517 100644 --- a/toxcore/toxcore/tox.m +++ b/toxcore/toxcore/tox.m @@ -153,7 +153,7 @@ void tox_options_free(struct Tox_Options *options) return NULL; } - if (memcmp(options->savedata_data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) { + if (sodium_memcmp(options->savedata_data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED); return NULL; } diff --git a/toxcore/toxcore/util.m b/toxcore/toxcore/util.m index 28d8721..ea1988e 100644 --- a/toxcore/toxcore/util.m +++ b/toxcore/toxcore/util.m @@ -60,7 +60,7 @@ int is_timeout(uint64_t timestamp, uint64_t timeout) /* id functions */ bool id_equal(const uint8_t *dest, const uint8_t *src) { - return memcmp(dest, src, crypto_box_PUBLICKEYBYTES) == 0; + return public_key_cmp(dest, src) == 0; } uint32_t id_copy(uint8_t *dest, const uint8_t *src) diff --git a/toxcore/toxencryptsave/Makefile.inc b/toxcore/toxencryptsave/Makefile.inc index 1155e95..20c8b1b 100644 --- a/toxcore/toxencryptsave/Makefile.inc +++ b/toxcore/toxencryptsave/Makefile.inc @@ -5,7 +5,12 @@ libtoxencryptsave_la_include_HEADERS = \ libtoxencryptsave_la_includedir = $(includedir)/tox -libtoxencryptsave_la_SOURCES = ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h \ +libtoxencryptsave_la_SOURCES = ../toxencryptsave/toxencryptsave.h \ + ../toxencryptsave/toxencryptsave.c + + +if WITH_NACL +libtoxencryptsave_la_SOURCES += ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h \ ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h \ ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c \ ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c \ @@ -19,10 +24,8 @@ libtoxencryptsave_la_SOURCES = ../toxencryptsave/crypto_pwhash_scryptsalsa208sha ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h \ ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.h \ ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c \ - ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c \ - ../toxencryptsave/toxencryptsave.h \ - ../toxencryptsave/toxencryptsave.c - + ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c +endif libtoxencryptsave_la_CFLAGS = -I$(top_srcdir) \ -I$(top_srcdir)/toxcore \ diff --git a/toxcore/toxencryptsave/toxencryptsave.m b/toxcore/toxencryptsave/toxencryptsave.m index e6150ce..5c40f63 100644 --- a/toxcore/toxencryptsave/toxencryptsave.m +++ b/toxcore/toxencryptsave/toxencryptsave.m @@ -32,7 +32,6 @@ #ifdef VANILLA_NACL #include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h" -#include "crypto_pwhash_scryptsalsa208sha256/utils.h" /* sodium_memzero */ #include #endif