summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/crypto_core.h2
-rw-r--r--toxcore/net_crypto.c231
-rw-r--r--toxcore/net_crypto.h36
-rw-r--r--toxcore/network.h3
4 files changed, 240 insertions, 32 deletions
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h
index de8656c7..1fca8078 100644
--- a/toxcore/crypto_core.h
+++ b/toxcore/crypto_core.h
@@ -29,7 +29,7 @@
29/* return zero if the buffer contains only zeros. */ 29/* return zero if the buffer contains only zeros. */
30uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen); 30uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen);
31 31
32/* Use this instead of memcmp; not vulnerable to timing attacks. 32/* Use this instead of memcmp; not vulnerable to timing attacks.
33 returns 0 if both mem locations of length are equal. */ 33 returns 0 if both mem locations of length are equal. */
34unsigned int crypto_cmp(uint8_t *mem1, uint8_t *mem2, uint32_t length); 34unsigned int crypto_cmp(uint8_t *mem1, uint8_t *mem2, uint32_t length);
35 35
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 97533512..81cff70a 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -212,7 +212,7 @@ static int handle_cookie_response(Net_Crypto *c, uint8_t *cookie, uint8_t *packe
212 return COOKIE_LENGTH; 212 return COOKIE_LENGTH;
213} 213}
214 214
215#define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 215#define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH + crypto_box_MACBYTES)
216 216
217/* Create a handshake packet and put it in packet. 217/* Create a handshake packet and put it in packet.
218 * cookie must be COOKIE_LENGTH bytes. 218 * cookie must be COOKIE_LENGTH bytes.
@@ -224,9 +224,18 @@ static int handle_cookie_response(Net_Crypto *c, uint8_t *cookie, uint8_t *packe
224static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk, 224static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk,
225 uint8_t *peer_real_pk) 225 uint8_t *peer_real_pk)
226{ 226{
227 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 227 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH];
228 memcpy(plain, nonce, crypto_box_NONCEBYTES); 228 memcpy(plain, nonce, crypto_box_NONCEBYTES);
229 memcpy(plain + crypto_box_NONCEBYTES, session_pk, crypto_box_PUBLICKEYBYTES); 229 memcpy(plain + crypto_box_NONCEBYTES, session_pk, crypto_box_PUBLICKEYBYTES);
230 crypto_hash_sha512(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, cookie, COOKIE_LENGTH);
231 uint8_t cookie_plain[COOKIE_REQUEST_PLAIN_LENGTH];
232 memcpy(cookie_plain, peer_real_pk, crypto_box_PUBLICKEYBYTES);
233 memcpy(cookie_plain + crypto_box_PUBLICKEYBYTES, c->self_public_key, crypto_box_PUBLICKEYBYTES);
234
235 if (create_cookie(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, cookie_plain,
236 c->secret_symmetric_key) != 0)
237 return -1;
238
230 new_nonce(packet + 1 + COOKIE_LENGTH); 239 new_nonce(packet + 1 + COOKIE_LENGTH);
231 int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), 240 int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
232 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES); 241 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES);
@@ -242,18 +251,23 @@ static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cook
242 251
243/* Handle a crypto handshake packet of length. 252/* Handle a crypto handshake packet of length.
244 * put the nonce contained in the packet in nonce, 253 * put the nonce contained in the packet in nonce,
245 * the session public key in session_pk and 254 * the session public key in session_pk
246 * the real public key of the peer in peer_real_pk. 255 * the real public key of the peer in peer_real_pk and
256 * the cookie inside the encrypted part of the packet in cookie.
257 *
258 * if expected_real_pk isn't NULL it denotes the real public key
259 * the packet should be from.
247 * 260 *
248 * nonce must be at least crypto_box_NONCEBYTES 261 * nonce must be at least crypto_box_NONCEBYTES
249 * session_pk must be at least crypto_box_PUBLICKEYBYTES 262 * session_pk must be at least crypto_box_PUBLICKEYBYTES
250 * peer_real_pk must be at least crypto_box_PUBLICKEYBYTES 263 * peer_real_pk must be at least crypto_box_PUBLICKEYBYTES
264 * cookie must be at least COOKIE_LENGTH
251 * 265 *
252 * return -1 on failure. 266 * return -1 on failure.
253 * return 0 on success. 267 * return 0 on success.
254 */ 268 */
255static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, 269static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk,
256 uint8_t *packet, uint32_t length) 270 uint8_t *cookie, uint8_t *packet, uint32_t length, uint8_t *expected_real_pk)
257{ 271{
258 if (length != HANDSHAKE_PACKET_LENGTH) 272 if (length != HANDSHAKE_PACKET_LENGTH)
259 return -1; 273 return -1;
@@ -263,10 +277,17 @@ static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *sessi
263 if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0) 277 if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0)
264 return -1; 278 return -1;
265 279
280 if (expected_real_pk)
281 if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0)
282 return -1;
283
266 if (crypto_cmp(cookie_plain + crypto_box_PUBLICKEYBYTES, c->self_public_key, crypto_box_PUBLICKEYBYTES) != 0) 284 if (crypto_cmp(cookie_plain + crypto_box_PUBLICKEYBYTES, c->self_public_key, crypto_box_PUBLICKEYBYTES) != 0)
267 return -1; 285 return -1;
268 286
269 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 287 uint8_t cookie_hash[crypto_hash_sha512_BYTES];
288 crypto_hash_sha512(cookie_hash, packet + 1, COOKIE_LENGTH);
289
290 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH];
270 int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, 291 int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
271 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES, 292 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES,
272 HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain); 293 HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain);
@@ -274,41 +295,207 @@ static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *sessi
274 if (len != sizeof(plain)) 295 if (len != sizeof(plain))
275 return -1; 296 return -1;
276 297
298 if (memcmp(cookie_hash, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, crypto_hash_sha512_BYTES) != 0)
299 return -1;
300
277 memcpy(nonce, plain, crypto_box_NONCEBYTES); 301 memcpy(nonce, plain, crypto_box_NONCEBYTES);
278 memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); 302 memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
303 memcpy(cookie, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, COOKIE_LENGTH);
279 memcpy(peer_real_pk, cookie_plain, crypto_box_PUBLICKEYBYTES); 304 memcpy(peer_real_pk, cookie_plain, crypto_box_PUBLICKEYBYTES);
280 return 0; 305 return 0;
281} 306}
282 307
283/* Handle a crypto handshake packet of length without opening the cookie from peer 308
284 * with the real public key peer_real_pk. 309static Crypto_Connection *get_crypto_connection(Net_Crypto *c, int crypt_connection_id)
285 * put the nonce contained in the packet in nonce and the session public key in 310{
286 * session_pk. 311 if (crypt_connection_id_not_valid(c, crypt_connection_id))
312 return 0;
313
314 return &c->crypto_connections[crypt_connection_id];
315}
316
317
318/* Sends a packet to the peer using the fastest route.
287 * 319 *
288 * nonce must be at least crypto_box_NONCEBYTES 320 * return -1 on failure.
289 * session_pk must be at least crypto_box_PUBLICKEYBYTES 321 * return 0 on success.
322 */
323static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length)
324{
325//TODO
326
327
328}
329
330/* Add a new temp packet to send repeatedly.
290 * 331 *
291 * return -1 on failure. 332 * return -1 on failure.
292 * return 0 on success. 333 * return 0 on success.
293 */ 334 */
294static int handle_crypto_handshake_nocookie(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *packet, 335static int new_temp_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length)
295 uint32_t length, uint8_t *peer_real_pk)
296{ 336{
297 if (length != HANDSHAKE_PACKET_LENGTH) 337 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
298 return -1; 338 return -1;
299 339
300 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 340 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
301 int len = decrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
302 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES,
303 HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain);
304 341
305 if (len != sizeof(plain)) 342 if (conn == 0)
306 return -1; 343 return -1;
307 344
308 memcpy(nonce, plain, crypto_box_NONCEBYTES); 345 uint8_t *temp_packet = malloc(length);
309 memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); 346
347 if (temp_packet == 0)
348 return -1;
349
350 if (conn->temp_packet)
351 free(conn->temp_packet);
352
353 memcpy(temp_packet, packet, length);
354 conn->temp_packet = temp_packet;
355 conn->temp_packet_length = length;
356 conn->temp_packet_sent_time = 0;
357 return 0;
358}
359
360/* Clear the temp packet.
361 *
362 * return -1 on failure.
363 * return 0 on success.
364 */
365static int clear_temp_packet(Net_Crypto *c, int crypt_connection_id)
366{
367 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
368
369 if (conn == 0)
370 return -1;
371
372 if (conn->temp_packet)
373 free(conn->temp_packet);
374
375 conn->temp_packet = 0;
376 conn->temp_packet_length = 0;
377 conn->temp_packet_sent_time = 0;
378 return 0;
379}
380
381
382/* Send the temp packet.
383 *
384 * return -1 on failure.
385 * return 0 on success.
386 */
387static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
388{
389 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
390
391 if (conn == 0)
392 return -1;
393
394 if (!conn->temp_packet)
395 return -1;
396
397 if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0)
398 return -1;
399
400 conn->temp_packet_sent_time = current_time();
401 return 0;
402}
403
404/* Handle a packet that was recieved for the connection.
405 *
406 * return -1 on failure.
407 * return 0 on success.
408 */
409static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length)
410{
411 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
412 return -1;
413
414 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
415
416 if (conn == 0)
417 return -1;
418
419 switch (packet[0]) {
420 case NET_PACKET_COOKIE_RESPONSE: {
421 if (conn->status != CRYPTO_CONN_COOKIE_REQUESTED)
422 return -1;
423
424 uint8_t cookie[COOKIE_LENGTH];
425
426 if (handle_cookie_response(c, cookie, packet, length, conn->shared_key) != sizeof(cookie))
427 return -1;
428
429 uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH];
430
431 if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionpublic_key,
432 conn->public_key) != sizeof(handshake_packet))
433 return -1;
434
435 if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0)
436 return -1;
437
438 send_temp_packet(c, crypt_connection_id);
439 conn->status = CRYPTO_CONN_HANDSHAKE_SENT;
440 return 0;
441 }
442
443 case NET_PACKET_CRYPTO_HS: {
444 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTED || conn->status == CRYPTO_CONN_HANDSHAKE_SENT) {
445 uint8_t peer_real_pk[crypto_box_PUBLICKEYBYTES];
446 uint8_t cookie[COOKIE_LENGTH];
447
448 if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, cookie, packet, length,
449 conn->public_key) != 0)
450 return -1;
451
452 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
453
454 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
455 } else {
456 return -1;
457 }
458
459 return 0;
460 }
461
462 case NET_PACKET_CRYPTO_DATA: {
463 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) {
464 //TODO
465 } else {
466 return -1;
467 }
468
469 return 0;
470 }
471
472 default: {
473 return -1;
474 }
475 }
476
310 return 0; 477 return 0;
311} 478}
479
480
481void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c),
482 void *object)
483{
484 c->new_connection_callback = new_connection_callback;
485 c->new_connection_callback_object = object;
486}
487
488static int handle_new_connection_handshake(Net_Crypto *c, uint8_t *data, uint16_t length)
489{
490
491
492}
493
494int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
495{
496
497
498}
312/* return 0 if there is no received data in the buffer. 499/* return 0 if there is no received data in the buffer.
313 * return -1 if the packet was discarded. 500 * return -1 if the packet was discarded.
314 * return length of received data if successful. 501 * return length of received data if successful.
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index b2b9f4f5..85aeede6 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -30,10 +30,15 @@
30#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2) 30#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2)
31 31
32#define CRYPTO_CONN_NO_CONNECTION 0 32#define CRYPTO_CONN_NO_CONNECTION 0
33#define CRYPTO_CONN_HANDSHAKE_SENT 1 33#define CRYPTO_CONN_COOKIE_REQUESTED 1 //send cookie request packets
34#define CRYPTO_CONN_NOT_CONFIRMED 2 34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets
35#define CRYPTO_CONN_ESTABLISHED 3 35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets
36#define CRYPTO_CONN_TIMED_OUT 4 36#define CRYPTO_CONN_ESTABLISHED 4
37#define CRYPTO_CONN_TIMED_OUT 5
38
39#define CRYPTO_PACKET_BUFFER_SIZE 64
40
41#define MAX_CRYPTO_PACKET_SIZE 1400
37 42
38typedef struct { 43typedef struct {
39 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */ 44 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
@@ -43,15 +48,27 @@ typedef struct {
43 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* Our private key for this session. */ 48 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* Our private key for this session. */
44 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ 49 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
45 uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* The precomputed shared key from encrypt_precompute. */ 50 uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* The precomputed shared key from encrypt_precompute. */
46 uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet 51 uint8_t status; /* 0 if no connection, 1 we are sending cookie request packets,
47 * (we have received a handshake but no empty data packet), 3 if the connection is established. 52 * 2 if we are sending handshake packets
48 * 4 if the connection is timed out. 53 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet),
54 * 4 if the connection is established.
55 * 5 if the connection is timed out.
49 */ 56 */
50 uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ 57 uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */
51 uint64_t timeout; 58 uint64_t timeout;
52 59
60 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
61 uint16_t temp_packet_length;
62 uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */
53} Crypto_Connection; 63} Crypto_Connection;
54 64
65typedef struct {
66 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
67 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */
68 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
69 uint8_t *cookie;
70 uint8_t cookie_length;
71} New_Connection;
55 72
56typedef struct { 73typedef struct {
57 Lossless_UDP *lossless_udp; 74 Lossless_UDP *lossless_udp;
@@ -67,9 +84,12 @@ typedef struct {
67 84
68 /* The secret key used for cookies */ 85 /* The secret key used for cookies */
69 uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; 86 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
87
88 int (*new_connection_callback)(void *object, New_Connection *n_c);
89 void *new_connection_callback_object;
70} Net_Crypto; 90} Net_Crypto;
71 91
72#include "DHT.h" 92
73 93
74/* return 0 if there is no received data in the buffer. 94/* return 0 if there is no received data in the buffer.
75 * return -1 if the packet was discarded. 95 * return -1 if the packet was discarded.
diff --git a/toxcore/network.h b/toxcore/network.h
index 17b18a65..21e225a0 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -104,6 +104,7 @@ typedef int sock_t;
104#include <crypto_box.h> 104#include <crypto_box.h>
105#include <randombytes.h> 105#include <randombytes.h>
106#include <crypto_hash_sha256.h> 106#include <crypto_hash_sha256.h>
107#include <crypto_hash_sha512.h>
107#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 108#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
108#endif 109#endif
109 110
@@ -334,7 +335,7 @@ int set_socket_nosigpipe(sock_t sock);
334 */ 335 */
335int set_socket_dualstack(sock_t sock); 336int set_socket_dualstack(sock_t sock);
336 337
337/* return current time in milleseconds since the epoch. */ 338/* return current UNIX time in microseconds (us). */
338uint64_t current_time(void); 339uint64_t current_time(void);
339 340
340/* return a random number. 341/* return a random number.