From 44526aaae68afa800d2a2c60ed4c471c91b76f6b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 10 May 2023 19:31:43 +0200 Subject: [PATCH 001/150] Started implementing an XAEAD function based on XChaCha20-Poly1305/libsodium in crypto core, which is to be used during the Noise-based handshake. --- toxcore/crypto_core.c | 110 ++++++++++++++++++++++++++++++++++++++++++ toxcore/crypto_core.h | 29 +++++++++++ toxcore/net_crypto.c | 1 + 3 files changed, 140 insertions(+) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 14025252c4..0c72739a42 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -285,6 +285,116 @@ int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, #endif } +int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, + const uint8_t *plain, size_t plain_length, uint8_t *encrypted, + size_t encrypted_length, const uint8_t *ad, size_t ad_length) +{ + //TODO: add ad? and new length? + if (length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { + return -1; + } + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + // Don't encrypt anything. + memcpy(encrypted, plain, length); + // Zero MAC to avoid uninitialized memory reads. + memset(encrypted + length, 0, crypto_box_MACBYTES); +#else + + const size_t size_temp_plain = length + crypto_box_ZEROBYTES; + const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES; + + uint8_t *temp_plain = crypto_malloc(size_temp_plain); + uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted); + + if (temp_plain == nullptr || temp_encrypted == nullptr) { + crypto_free(temp_plain, size_temp_plain); + crypto_free(temp_encrypted, size_temp_encrypted); + return -1; + } + + // crypto_box_afternm requires the entire range of the output array be + // initialised with something. It doesn't matter what it's initialised with, + // so we'll pick 0x00. + memset(temp_encrypted, 0, size_temp_encrypted); + + memset(temp_plain, 0, crypto_box_ZEROBYTES); + // Pad the message with 32 0 bytes. + memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); + + //TODO: Continue here + //TODO: change to crypto_aead_xchacha20poly1305_ietf_encrypt() + //TODO: const unsigned char *nsec param = always NULL + + if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, + shared_key) != 0) { + crypto_free(temp_plain, size_temp_plain); + crypto_free(temp_encrypted, size_temp_encrypted); + return -1; + } + + // Unpad the encrypted message. + memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); + + crypto_free(temp_plain, size_temp_plain); + crypto_free(temp_encrypted, size_temp_encrypted); +#endif + assert(length < INT32_MAX - crypto_box_MACBYTES); + return (int32_t)(length + crypto_box_MACBYTES); +} + +int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, + const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, + size_t plain_length, const uint8_t *ad, size_t ad_length) +{ + if (length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr + || plain == nullptr) { + return -1; + } + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + assert(length >= crypto_box_MACBYTES); + memcpy(plain, encrypted, length - crypto_box_MACBYTES); // Don't encrypt anything +#else + + const size_t size_temp_plain = length + crypto_box_ZEROBYTES; + const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES; + + uint8_t *temp_plain = crypto_malloc(size_temp_plain); + uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted); + + if (temp_plain == nullptr || temp_encrypted == nullptr) { + crypto_free(temp_plain, size_temp_plain); + crypto_free(temp_encrypted, size_temp_encrypted); + return -1; + } + + // crypto_box_open_afternm requires the entire range of the output array be + // initialised with something. It doesn't matter what it's initialised with, + // so we'll pick 0x00. + memset(temp_plain, 0, size_temp_plain); + + memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES); + // Pad the message with 16 0 bytes. + memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); + + if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, + shared_key) != 0) { + crypto_free(temp_plain, size_temp_plain); + crypto_free(temp_encrypted, size_temp_encrypted); + return -1; + } + + memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); + + crypto_free(temp_plain, size_temp_plain); + crypto_free(temp_encrypted, size_temp_encrypted); +#endif + assert(length > crypto_box_MACBYTES); + assert(length < INT32_MAX); + return (int32_t)(length - crypto_box_MACBYTES); +} + int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t length, uint8_t *encrypted) { diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 0aaadeacf1..5215840372 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -365,6 +365,35 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const non_null() int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *shared_key); +/** + * @brief Encrypt message with precomputed shared key using XChaCha20-Poly1305. + * + * Encrypts plain of length length to encrypted of length + @ref CRYPTO_MAC_SIZE + * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NONCE_SIZE + * byte nonce. The encrypted message, as well as a tag authenticating both the confidential + * message m and adlen bytes of non-confidential data ad, are put into encrypted. + * + * @retval -1 if there was a problem. + * @return length of encrypted data if everything was fine. + */ +non_null() +int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, + uint8_t *encrypted), size_t encrypted_length, const uint8_t *ad, size_t ad_length); + +/** + * @brief Decrypt message with precomputed shared key using XChaCha20-Poly1305. + * + * Decrypts encrypted of length encrypted_length to plain of plain_length + * `length - CRYPTO_MAC_SIZE` using a shared key @ref CRYPTO_SHARED_KEY_SIZE + * big and a @ref CRYPTO_NONCE_SIZE byte nonce. + * + * @retval -1 if there was a problem (decryption failed). + * @return length of plain data if everything was fine. + */ +non_null() +int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, + uint8_t *plain, size_t plain_length, const uint8_t *ad, size_t ad_length); + /** * @brief Encrypt message with precomputed shared key. * diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 71f6e39e64..4d01aa301b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -19,6 +19,7 @@ #include "mono_time.h" #include "util.h" +static const uint8_t NOISE_PROTOCOL_NAME[34] = "Noise_IK_25519_XChaChaPoly_SHA512"; typedef struct Packet_Data { uint64_t sent_time; uint16_t length; From e8af1d3c0a55b744fbde9f5f2bda4db081a9fb8a Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 13 Jun 2023 18:12:06 +0200 Subject: [PATCH 002/150] Added XAEAD functions, added HMAC-SHA512 functions, added HKDF for Noise in crypto_core. Added noise_handshake struct to net_crypto.h. Started Noise-based handshake implementation. --- toxcore/crypto_core.c | 167 +++++++++++++++++++++--------------------- toxcore/net_crypto.c | 57 ++++++++++++++ toxcore/net_crypto.h | 21 ++++++ 3 files changed, 160 insertions(+), 85 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 0c72739a42..1e02f4b25d 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -289,110 +289,39 @@ int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *n const uint8_t *plain, size_t plain_length, uint8_t *encrypted, size_t encrypted_length, const uint8_t *ad, size_t ad_length) { - //TODO: add ad? and new length? - if (length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { + // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium + if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { return -1; } -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - // Don't encrypt anything. - memcpy(encrypted, plain, length); - // Zero MAC to avoid uninitialized memory reads. - memset(encrypted + length, 0, crypto_box_MACBYTES); -#else - - const size_t size_temp_plain = length + crypto_box_ZEROBYTES; - const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES; - - uint8_t *temp_plain = crypto_malloc(size_temp_plain); - uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted); - - if (temp_plain == nullptr || temp_encrypted == nullptr) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + // nsec is not used by this particular construction and should always be NULL. + if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, encrypted_length, plain, plain_length, + ad, ad_length, NULL, nonce, shared_key) != 0) { return -1; } - // crypto_box_afternm requires the entire range of the output array be - // initialised with something. It doesn't matter what it's initialised with, - // so we'll pick 0x00. - memset(temp_encrypted, 0, size_temp_encrypted); - - memset(temp_plain, 0, crypto_box_ZEROBYTES); - // Pad the message with 32 0 bytes. - memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); - - //TODO: Continue here - //TODO: change to crypto_aead_xchacha20poly1305_ietf_encrypt() - //TODO: const unsigned char *nsec param = always NULL - - if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, - shared_key) != 0) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); - return -1; - } - - // Unpad the encrypted message. - memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); - - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); -#endif - assert(length < INT32_MAX - crypto_box_MACBYTES); - return (int32_t)(length + crypto_box_MACBYTES); + //assert(length < INT32_MAX - crypto_box_MACBYTES); + return (int32_t)(encrypted_length); } int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, size_t plain_length, const uint8_t *ad, size_t ad_length) { - if (length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr + // plain_length is calculated by libsodium + if (encrypted_length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr || plain == nullptr) { return -1; } -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - assert(length >= crypto_box_MACBYTES); - memcpy(plain, encrypted, length - crypto_box_MACBYTES); // Don't encrypt anything -#else - - const size_t size_temp_plain = length + crypto_box_ZEROBYTES; - const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES; - - uint8_t *temp_plain = crypto_malloc(size_temp_plain); - uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted); - - if (temp_plain == nullptr || temp_encrypted == nullptr) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); - return -1; - } - - // crypto_box_open_afternm requires the entire range of the output array be - // initialised with something. It doesn't matter what it's initialised with, - // so we'll pick 0x00. - memset(temp_plain, 0, size_temp_plain); - - memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES); - // Pad the message with 16 0 bytes. - memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); - - if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, - shared_key) != 0) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, plain_length, NULL, encrypted, + encrypted_length, ad, ad_length, nonce, shared_key) != 0) { return -1; } - memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); - - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); -#endif - assert(length > crypto_box_MACBYTES); - assert(length < INT32_MAX); - return (int32_t)(length - crypto_box_MACBYTES); + // assert(length > crypto_box_MACBYTES); + // assert(length < INT32_MAX); + return (int32_t)(plain_length); } int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, @@ -620,6 +549,74 @@ bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[ #endif } +/* +* HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of +* `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of +* of 32 bytes (SHA512-256 HASHLEN). +*/ +void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, + size_t length) +{ + crypto_auth_hmacsha512(auth, data, length, key); +} +//TODO: verify needed? +bool crypto_hmac512_verify(const uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], + const uint8_t *data, size_t length) +{ + return crypto_auth_hmacsha512_verify(auth, data, length, key) == 0; +} + +/* This is Hugo Krawczyk's HKDF: + * - https://eprint.iacr.org/2010/264.pdf + * - https://tools.ietf.org/html/rfc5869 + * HKDF(chaining_key, input_key_material, num_outputs): Takes a +chaining_key byte sequence of length HASHLEN, and an input_key_material +byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes. +Returns a pair or triple of byte sequences each of length HASHLEN, +depending on whether num_outputs is two or three: +– Sets temp_key = HMAC-HASH(chaining_key, input_key_material). +– Sets output1 = HMAC-HASH(temp_key, byte(0x01)). +– Sets output2 = HMAC-HASH(temp_key, output1 || byte(0x02)). +– If num_outputs == 2 then returns the pair (output1, output2). +– Sets output3 = HMAC-HASH(temp_key, output2 || byte(0x03)). +– Returns the triple (output1, output2, output3). + +Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in +length. Also note that the HKDF() function is simply HKDF from [4] with the +chaining_key as HKDF salt, and zero-length HKDF info. + */ +void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, + size_t first_len, size_t second_len, size_t third_len, + size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) +{ + uint8_t output[CRYPTO_SHA512_SIZE + 1]; + // temp_key = secret in WG + uint8_t temp_key[CRYPTO_SHA512_SIZE]; + + /* Extract entropy from data into temp_key */ + // data => input_key_material => DH result in Noise + crypto_hmac512(temp_key, chaining_key, data, data_len); + + /* Expand first key: key = temp_key, data = 0x1 */ + output[0] = 1; + crypto_hmac512(output, temp_key, output, 1); + memcpy(output1, output, first_len); + + /* Expand second key: key = secret, data = first-key || 0x2 */ + output[CRYPTO_SHA512_SIZE] = 2; + crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); + memcpy(output2, output, second_len); + + /* Expand third key: key = temp_key, data = second-key || 0x3 */ + output[CRYPTO_SHA512_SIZE] = 3; + crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); + memcpy(output3, output, third_len); + + /* Clear sensitive data from stack */ + crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); + crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); +} + void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 4d01aa301b..99a5f8bcdd 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -50,6 +50,7 @@ typedef struct Crypto_Connection { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ + // Necessary for non-Noise handshake uint8_t sessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public key for this session. */ uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private key for this session. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ @@ -58,6 +59,8 @@ typedef struct Crypto_Connection { uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ + noise_handshake *handshake; + uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ uint16_t temp_packet_length; uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */ @@ -2134,6 +2137,57 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return crypt_connection_id; } +/* + * Initializes a Noise HandshakeState with TODO: + * + * return -1 on failure + * return 0 on success + */ +static int initialize_handshake +(noise_handshake *handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +{ + + //TODO: NOISE_PROTOCOL_NAME + + // crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); + + if (self_secret_key) { + + } else { + fprintf(stderr, "Client private key required, but not provided.\n"); + return -1; + } + + //TODO: initiator? + + if (role == NOISE_ROLE_INITIATOR) { + if (peer_public_key) { + + } else { + fprintf(stderr, "Server public key required, but not provided.\n"); + return -1; + } + } + + /* Ready to go */ + return 0; +} + +//TODO: Continue here +static bool mix_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], + uint8_t key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) +{ + uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; + + + crypto_hkdf(chaining_key, key, NULL, dh_calculation, CRYPTO_SHA512_SIZE, + CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); + crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); + return true; +} + /** @brief Create a crypto connection. * If one to that real public key already exists, return it. * @@ -3205,6 +3259,9 @@ void do_net_crypto(Net_Crypto *c, void *userdata) send_crypto_packets(c); } +//TODO: implement +//static void handshake_zero(struct noise_handshake *handshake) + void kill_net_crypto(Net_Crypto *c) { if (c == nullptr) { diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 0c3dfd0d45..742685088c 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -120,12 +120,29 @@ non_null() const uint8_t *nc_get_self_secret_key(const Net_Crypto *c); non_null() TCP_Connections *nc_get_tcp_c(const Net_Crypto *c); non_null() DHT *nc_get_dht(const Net_Crypto *c); +//TODO: correct? +struct noise_handshake { + //TODO: static_private? + uint8_t ephemeral_private[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; + + uint8_t hash[CRYPTO_SHA512_SIZE]; + uint8_t chaining_key[CRYPTO_SHA512_SIZE]; + + bool initiator; +}; + typedef struct New_Connection { IP_Port source; + // Necessary for non-Noise handshake uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ + // Necessary for non-Noise handshake uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ + noise_handshake *handshake; uint8_t *cookie; uint8_t cookie_length; } New_Connection; @@ -411,4 +428,8 @@ void do_net_crypto(Net_Crypto *c, void *userdata); nullable(1) void kill_net_crypto(Net_Crypto *c); +//TODO: comment +static void handshake_zero(struct noise_handshake *handshake); + + #endif From f8e28cc8cae0b77fb6a955b3c3ef46677206dcde Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 14 Jun 2023 17:52:54 +0200 Subject: [PATCH 003/150] Added HMAC+HKDF functions to crypto_core.h, fixed wrong ). Fixed minor issues in crypto_core.c. Started handshake_init in net_crypto.c, added Noise functions MixKey(), MixHash(), EncryptAndHash(), DecryptAndHash(). --- toxcore/crypto_core.c | 11 ++-- toxcore/crypto_core.h | 43 ++++++++++++++- toxcore/net_crypto.c | 121 +++++++++++++++++++++++++++++++++++------- toxcore/net_crypto.h | 5 +- 4 files changed, 153 insertions(+), 27 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 1e02f4b25d..7d8d3c513f 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -293,9 +293,9 @@ int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *n if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { return -1; } - + // nsec is not used by this particular construction and should always be NULL. - if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, encrypted_length, plain, plain_length, + if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, ad, ad_length, NULL, nonce, shared_key) != 0) { return -1; } @@ -314,7 +314,7 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *n return -1; } - if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, plain_length, NULL, encrypted, + if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, NULL, encrypted, encrypted_length, ad, ad_length, nonce, shared_key) != 0) { return -1; } @@ -553,14 +553,15 @@ bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[ * HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of * `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of * of 32 bytes (SHA512-256 HASHLEN). +* TODO: key size correct? */ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t length) { crypto_auth_hmacsha512(auth, data, length, key); } -//TODO: verify needed? -bool crypto_hmac512_verify(const uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], +//TODO: verify needed? TODO: key size correct? +bool crypto_hmac512_verify(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t length) { return crypto_auth_hmacsha512_verify(auth, data, length, key) == 0; diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 5215840372..83a6ea911c 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -174,6 +174,47 @@ non_null() bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[CRYPTO_HMAC_KEY_SIZE], const uint8_t *data, size_t length); +/** + * @brief Compute an HMAC authenticator (32 bytes). + * + * @param auth Resulting authenticator. + * @param key Secret key + */ +non_null() +void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, + size_t length); + +/** + * @brief Verify an HMAC authenticator. + * TODO: verify needed? + */ +non_null() +bool crypto_hmac512_verify(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], + const uint8_t *data, size_t length); + +/* This is Hugo Krawczyk's HKDF: + * - https://eprint.iacr.org/2010/264.pdf + * - https://tools.ietf.org/html/rfc5869 + * HKDF(chaining_key, input_key_material, num_outputs): Takes a +chaining_key byte sequence of length HASHLEN, and an input_key_material +byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes. +Returns a pair or triple of byte sequences each of length HASHLEN, +depending on whether num_outputs is two or three: +– Sets temp_key = HMAC-HASH(chaining_key, input_key_material). +– Sets output1 = HMAC-HASH(temp_key, byte(0x01)). +– Sets output2 = HMAC-HASH(temp_key, output1 || byte(0x02)). +– If num_outputs == 2 then returns the pair (output1, output2). +– Sets output3 = HMAC-HASH(temp_key, output2 || byte(0x03)). +– Returns the triple (output1, output2, output3). + +Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in +length. Also note that the HKDF() function is simply HKDF from [4] with the +chaining_key as HKDF salt, and zero-length HKDF info. + */ +void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, + size_t first_len, size_t second_len, size_t third_len, + size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); + /** * @brief Compare 2 public keys of length @ref CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to * timing attacks. @@ -378,7 +419,7 @@ int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, */ non_null() int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, - uint8_t *encrypted), size_t encrypted_length, const uint8_t *ad, size_t ad_length); + uint8_t *encrypted, size_t encrypted_length, const uint8_t *ad, size_t ad_length); /** * @brief Decrypt message with precomputed shared key using XChaCha20-Poly1305. diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 99a5f8bcdd..fa35e01a54 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -13,6 +13,8 @@ #include #include #include +//TODO: remove +#include #include "ccompat.h" #include "list.h" @@ -47,6 +49,7 @@ typedef enum Crypto_Conn_State { } Crypto_Conn_State; typedef struct Crypto_Connection { + //TODO: necessary here? uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ @@ -59,7 +62,10 @@ typedef struct Crypto_Connection { uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ + // For Noise noise_handshake *handshake; + uint8_t send_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t recv_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ uint16_t temp_packet_length; @@ -466,6 +472,8 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, } #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /** @brief Create a handshake packet and put it in packet. * @param cookie must be COOKIE_LENGTH bytes. @@ -2143,13 +2151,38 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) * return -1 on failure * return 0 on success */ -static int initialize_handshake -(noise_handshake *handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) -{ - - //TODO: NOISE_PROTOCOL_NAME - - // crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); +static int noise_handshake_init +(struct noise_handshake *handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +{ + //TODO: ? memset(handshake, 0, sizeof(*handshake)); + + // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h + uint8_t temp_hash[CRYPTO_SHA512_SIZE]; + memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); + memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); + memcpy(handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + + // Sets the initiator, s, e, rs, and re variables to the corresponding arguments. + handshake->initiator = initiator; + memcpy(handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: Continue here + //TODO: precompute_static_static ? + + //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); + +// void wg_noise_handshake_init(struct noise_handshake *handshake, +// struct noise_static_identity *static_identity, +// const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], +// const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], +// struct wg_peer *peer) +// { +// memset(handshake, 0, sizeof(*handshake)); +// memcpy(handshake->remote_static, peer_public_key, NOISE_PUBLIC_KEY_LEN); +// handshake->static_identity = static_identity; +// handshake->state = HANDSHAKE_ZEROED; +// wg_noise_precompute_static_static(peer); +// } if (self_secret_key) { @@ -2160,34 +2193,76 @@ static int initialize_handshake //TODO: initiator? - if (role == NOISE_ROLE_INITIATOR) { - if (peer_public_key) { + // if (role == NOISE_ROLE_INITIATOR) { + // if (peer_public_key) { - } else { - fprintf(stderr, "Server public key required, but not provided.\n"); - return -1; - } - } + // } else { + // fprintf(stderr, "Server public key required, but not provided.\n"); + // return -1; + // } + // } /* Ready to go */ return 0; } -//TODO: Continue here -static bool mix_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], +//TODO: MixKey(input_key_material), CURRENTLY NOT as defined in Noise spec +static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) { uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; - + //TODO: DH CALC - returns plain DH result, afterwards hashed with HKDF + // if (unlikely(!curve25519(dh_calculation, private, public))) + // return false; crypto_hkdf(chaining_key, key, NULL, dh_calculation, CRYPTO_SHA512_SIZE, CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); + //TODO: truncate temp_k to 32 bytes + //TODO: where to InitializeKey(temp_k)? + crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); return true; } +// MixHash(data) as defined in Noise spec +static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) +{ + uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; + memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); + memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); + crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); +} + +// EncryptAndHash(plaintext) as defined in Noise spec +static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, + size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) +{ + //TODO: Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext. + int32_t encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, + plaintext, plain_length, ciphertext, + plain_length + CRYPTO_MAC_SIZE, hash, CRYPTO_SHA512_SIZE); + noise_mix_hash(hash, ciphertext, encrypted_length); +} + +static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, + size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) +{ + //TODO: Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext + int32_t plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, + ciphertext, encrypted_length, plaintext, + encrypted_length - CRYPTO_MAC_SIZE, hash, CRYPTO_SHA512_SIZE); + if (plaintext_length != (encrypted_length - CRYPTO_MAC_SIZE)) + { + return -1; + } + noise_mix_hash(hash, ciphertext, encrypted_length); + return 0; +} + /** @brief Create a crypto connection. * If one to that real public key already exists, return it. * @@ -3259,8 +3334,16 @@ void do_net_crypto(Net_Crypto *c, void *userdata) send_crypto_packets(c); } -//TODO: implement -//static void handshake_zero(struct noise_handshake *handshake) +//TODO: adapt and implement +// static void noise_handshake_zero(struct noise_handshake *handshake) +// { +// memset(&handshake->ephemeral_private, 0, CRYPTO_PUBLIC_KEY_SIZE); +// memset(&handshake->remote_ephemeral, 0, CRYPTO_PUBLIC_KEY_SIZE); +// memset(&handshake->hash, 0, CRYPTO_SHA512_SIZE); +// memset(&handshake->chaining_key, 0, CRYPTO_SHA512_SIZE); +// handshake->remote_index = 0; +// handshake->state = HANDSHAKE_ZEROED; +// } void kill_net_crypto(Net_Crypto *c) { diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 742685088c..6f91af921e 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -121,9 +121,10 @@ non_null() TCP_Connections *nc_get_tcp_c(const Net_Crypto *c); non_null() DHT *nc_get_dht(const Net_Crypto *c); //TODO: correct? -struct noise_handshake { +typedef struct noise_handshake { //TODO: static_private? uint8_t ephemeral_private[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; @@ -132,7 +133,7 @@ struct noise_handshake { uint8_t chaining_key[CRYPTO_SHA512_SIZE]; bool initiator; -}; +} noise_handshake; typedef struct New_Connection { IP_Port source; From 2ce1787fdbfc9d54ad827c42a449371ce8adaab1 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 16 Jun 2023 15:49:12 +0200 Subject: [PATCH 004/150] Continued Noise handshake implementation. --- toxcore/net_crypto.c | 169 +++++++++++++++++++++++++++++++------------ toxcore/net_crypto.h | 13 +++- 2 files changed, 134 insertions(+), 48 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index fa35e01a54..40ec17a0de 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -49,11 +49,10 @@ typedef enum Crypto_Conn_State { } Crypto_Conn_State; typedef struct Crypto_Connection { - //TODO: necessary here? + // Necessary for non-Noise handshake uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ - // Necessary for non-Noise handshake uint8_t sessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public key for this session. */ uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private key for this session. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ @@ -63,9 +62,15 @@ typedef struct Crypto_Connection { uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ // For Noise + //TODO: necessary? noise_handshake *handshake; - uint8_t send_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t recv_key[CRYPTO_PUBLIC_KEY_SIZE]; + // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; + // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; + // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; + // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; + // bool initiator; + //TODO: necessary? + // uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ uint16_t temp_packet_length; @@ -472,8 +477,9 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, } #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +// Necessary for Noise +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /** @brief Create a handshake packet and put it in packet. * @param cookie must be COOKIE_LENGTH bytes. @@ -512,6 +518,92 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return HANDSHAKE_PACKET_LENGTH; } +/** @brief Create a handshake packet and put it in packet. + * @param cookie must be COOKIE_LENGTH bytes. + * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. + * + * @retval -1 on failure. + * @retval HANDSHAKE_PACKET_LENGTH on success. + */ +non_null() +//TODO: peer_real_pk necessary as responder +static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, + const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) +{ + /* Initiator: Handshake packet structure + [uint8_t 26] + [Cookie 112 bytes] + [session public key of the peer (32 bytes)] + + [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise + [MAC encrypted static pubkey 16 bytes] + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce -> Nonce patched + [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + ] + [MAC 16 bytes] + */ + if (noise_handshake->initiator) { + // set static public, set ephemeral private+public + memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + /* e */ + noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + /* es */ + //TODO: add shared key as param? + //TODO: Continue here, TODO: fix/finish noise_mix_key_dh() + //noise_mix_key_dh(noise_handshake->chaining_key,) + + // Create handshake payload + uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); + crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + + // OtherCookie is added to payload + if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, + cookie_plain, c->secret_symmetric_key) != 0) { + return -1; + } + + // Add Handshake payload nonce + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); + const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, handshake_payload_plain, sizeof(handshake_payload_plain), + packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); + + if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { + return -1; + } + + packet[0] = NET_PACKET_CRYPTO_HS; + memcpy(packet + 1, cookie, COOKIE_LENGTH); + + return HANDSHAKE_PACKET_LENGTH; + } + else if (!noise_handshake->initiator) { + /* Responder: Handshake packet structure + [uint8_t 26] + [Cookie 112 bytes] + [session public key of the peer (32 bytes)] => handled by Noise + [24 bytes handshake nonce] + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce + [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + ] + [MAC 16 bytes] + */ + } + else { + return -1; + } +} /** @brief Handle a crypto handshake packet of length. * put the nonce contained in the packet in nonce, @@ -2152,7 +2244,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) * return 0 on success */ static int noise_handshake_init -(struct noise_handshake *handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +(struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { //TODO: ? memset(handshake, 0, sizeof(*handshake)); @@ -2160,47 +2252,32 @@ static int noise_handshake_init uint8_t temp_hash[CRYPTO_SHA512_SIZE]; memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); - memcpy(handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); - memcpy(handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); - - // Sets the initiator, s, e, rs, and re variables to the corresponding arguments. - handshake->initiator = initiator; - memcpy(handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: Continue here - //TODO: precompute_static_static ? - - //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); - -// void wg_noise_handshake_init(struct noise_handshake *handshake, -// struct noise_static_identity *static_identity, -// const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], -// const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], -// struct wg_peer *peer) -// { -// memset(handshake, 0, sizeof(*handshake)); -// memcpy(handshake->remote_static, peer_public_key, NOISE_PUBLIC_KEY_LEN); -// handshake->static_identity = static_identity; -// handshake->state = HANDSHAKE_ZEROED; -// wg_noise_precompute_static_static(peer); -// } + memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + // Sets the initiator, s, e, rs, and re variables to the corresponding arguments. => Rest is set afterwards + noise_handshake->initiator = initiator; if (self_secret_key) { - + memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); } else { - fprintf(stderr, "Client private key required, but not provided.\n"); + fprintf(stderr, "Local static private key required, but not provided.\n"); return -1; } + //TODO: only possible if initiator? + if (initiator) { + if (peer_public_key) { + memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // Calls MixHash() once for each public key listed in the pre-messages from Noise IK + noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + } else { + fprintf(stderr, "Remote peer static public key required, but not provided.\n"); + return -1; + } + } - //TODO: initiator? + //TODO: precompute_static_static ? - // if (role == NOISE_ROLE_INITIATOR) { - // if (peer_public_key) { - - // } else { - // fprintf(stderr, "Server public key required, but not provided.\n"); - // return -1; - // } - // } + //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); /* Ready to go */ return 0; @@ -2208,16 +2285,16 @@ static int noise_handshake_init //TODO: MixKey(input_key_material), CURRENTLY NOT as defined in Noise spec static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], - uint8_t key[CRYPTO_SHARED_KEY_SIZE], + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) { uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; - //TODO: DH CALC - returns plain DH result, afterwards hashed with HKDF - // if (unlikely(!curve25519(dh_calculation, private, public))) - // return false; - crypto_hkdf(chaining_key, key, NULL, dh_calculation, CRYPTO_SHA512_SIZE, + // DH CALC - returns plain DH result, afterwards hashed with HKDF + + encrypt_precompute(public, private, shared_key); + crypto_hkdf(chaining_key, shared_key, NULL, dh_calculation, CRYPTO_SHA512_SIZE, CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); //TODO: truncate temp_k to 32 bytes //TODO: where to InitializeKey(temp_k)? diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 6f91af921e..2875a78cf6 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -120,13 +120,16 @@ non_null() const uint8_t *nc_get_self_secret_key(const Net_Crypto *c); non_null() TCP_Connections *nc_get_tcp_c(const Net_Crypto *c); non_null() DHT *nc_get_dht(const Net_Crypto *c); -//TODO: correct? +//TODO: struct necessary? typedef struct noise_handshake { //TODO: static_private? + uint8_t static_private[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t static_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t ephemeral_private[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; + //TODO: necessary? uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t hash[CRYPTO_SHA512_SIZE]; @@ -141,9 +144,15 @@ typedef struct New_Connection { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ - // Necessary for non-Noise handshake uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ noise_handshake *handshake; + // Necessary for Noise + // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; + // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; + // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; + // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; + // bool initiator; + uint8_t *cookie; uint8_t cookie_length; } New_Connection; From abfeefa9e90a67b4e756f9055047e45b8fc3ca6b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 19 Jun 2023 18:33:34 +0200 Subject: [PATCH 005/150] Adapted create_crypto_handshake() for Noise Initiator and Responder, cf. Noise Spec WriteMessage(). Started to adapt handle_crypto_handshake() for Noise, cf. Noise Spec ReadMessage(). --- toxcore/net_crypto.c | 294 +++++++++++++++++++++++++++++++------------ 1 file changed, 216 insertions(+), 78 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 40ec17a0de..3935fc57a2 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -518,7 +518,65 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return HANDSHAKE_PACKET_LENGTH; } -/** @brief Create a handshake packet and put it in packet. + +// Implements MixKey(input_key_material) +static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) +{ + uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; + + // X25519 - returns plain DH result, afterwards hashed with HKDF + encrypt_precompute(public, private, shared_key); + // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! + crypto_hkdf(chaining_key, shared_key, NULL, dh_calculation, CRYPTO_SHA512_SIZE, + CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); + //If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() + //TODO: where to InitializeKey(temp_k)? here? need to provide key if I want to set here + + crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); + return true; +} + +// MixHash(data) as defined in Noise spec +static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) +{ + uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; + memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); + memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); + crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); +} + +// EncryptAndHash(plaintext) as defined in Noise spec +static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, + size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) +{ + //TODO: Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext. TODO: does that even happen? + int32_t encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, + plaintext, plain_length, ciphertext, + plain_length + CRYPTO_MAC_SIZE, hash, CRYPTO_SHA512_SIZE); + noise_mix_hash(hash, ciphertext, encrypted_length); +} + +static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, + size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) +{ + //TODO: Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext + int32_t plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, + ciphertext, encrypted_length, plaintext, + encrypted_length - CRYPTO_MAC_SIZE, hash, CRYPTO_SHA512_SIZE); + if (plaintext_length != (encrypted_length - CRYPTO_MAC_SIZE)) + { + return -1; + } + noise_mix_hash(hash, ciphertext, encrypted_length); + return 0; +} + +/** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. * @param cookie must be COOKIE_LENGTH bytes. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. * @@ -526,7 +584,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u * @retval HANDSHAKE_PACKET_LENGTH on success. */ non_null() -//TODO: peer_real_pk necessary as responder static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) { @@ -534,16 +591,18 @@ static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, c [uint8_t 26] [Cookie 112 bytes] [session public key of the peer (32 bytes)] - + [24 bytes nonce static pub key encryption] [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise [MAC encrypted static pubkey 16 bytes] + [24 bytes nonce handshake payload encryption] [Encrypted message containing: [24 bytes base nonce] => WITH base Nonce -> Nonce patched + TODO: authenticate Cookie via AD in XAEAD? [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - ] [MAC 16 bytes] */ + /* -> e, es, s, ss */ if (noise_handshake->initiator) { // set static public, set ephemeral private+public memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -553,11 +612,18 @@ static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, c /* e */ noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* es */ - //TODO: add shared key as param? - //TODO: Continue here, TODO: fix/finish noise_mix_key_dh() - //noise_mix_key_dh(noise_handshake->chaining_key,) - - // Create handshake payload + //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); + /* s */ + // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + /* ss */ + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + + /* Noise Handshake Payload */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); @@ -573,32 +639,74 @@ static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, c } // Add Handshake payload nonce - random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); - const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, handshake_payload_plain, sizeof(handshake_payload_plain), - packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); - - if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { - return -1; - } + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); packet[0] = NET_PACKET_CRYPTO_HS; memcpy(packet + 1, cookie, COOKIE_LENGTH); - return HANDSHAKE_PACKET_LENGTH; + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + + return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } + /* <- e, ee, se */ else if (!noise_handshake->initiator) { /* Responder: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] - [session public key of the peer (32 bytes)] => handled by Noise - [24 bytes handshake nonce] + [session public key of the peer (32 bytes)] + [24 bytes nonce handshake payload encryption] [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce + [24 bytes base nonce] => WITH base Nonce -> Nonce patched + TODO: authenticate Cookie via AD in XAEAD? [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - ] [MAC 16 bytes] */ + // set static public, set ephemeral private+public + memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + /* e */ + noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + /* ee */ + //TODO: add shared key as param to this function? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); + /* se */ + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + + /* Noise Handshake Payload */ + uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); + crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + + // OtherCookie is added to payload + if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, + cookie_plain, c->secret_symmetric_key) != 0) { + return -1; + } + + // Add Handshake payload nonce + // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + + packet[0] = NET_PACKET_CRYPTO_HS; + memcpy(packet + 1, cookie, COOKIE_LENGTH); + + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + + return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } else { return -1; @@ -665,6 +773,93 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } +/** TODO: adapt, cf. Noise ReadMessage() @brief Handle a crypto handshake packet of length. + * put the nonce contained in the packet in nonce, + * the session public key in session_pk + * the real public key of the peer in peer_real_pk + * the dht public key of the peer in dht_public_key and + * the cookie inside the encrypted part of the packet in cookie. + * + * if expected_real_pk isn't NULL it denotes the real public key + * the packet should be from. + * + * nonce must be at least CRYPTO_NONCE_SIZE + * session_pk must be at least CRYPTO_PUBLIC_KEY_SIZE + * peer_real_pk must be at least CRYPTO_PUBLIC_KEY_SIZE + * cookie must be at least COOKIE_LENGTH + * + * @retval false on failure. + * @retval true on success. + */ +non_null(1, 2, 3, 4, 5, 6, 7) nullable(9) +static bool noise_handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, + uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, + noise_handshake *noise_handshake) +{ + if (!noise_handshake->initiator) { + if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + return false; + } + } else if (noise_handshake->initiator) { + if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + return false; + } + } else { + return false; + } + + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + + if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + return false; + } + + if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { + return false; + } + + uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; + crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); + + if(!noise_handshake->initiator) { + //TODO: Continue Here (cf. Noise ReadMessage()) + /* e */ + + /* es */ + + /* s */ + + /* ss */ + + /* old */ + uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, + packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, + HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); + + if (len != sizeof(plain)) { + return false; + } + + if (!crypto_sha512_eq(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE)) { + return false; + } + + memcpy(nonce, plain, CRYPTO_NONCE_SIZE); + memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + return true; + /* old */ + } + else if(noise_handshake->initiator) { + + } else { + return false; + } +} + non_null() static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_connection_id) @@ -2283,63 +2478,6 @@ static int noise_handshake_init return 0; } -//TODO: MixKey(input_key_material), CURRENTLY NOT as defined in Noise spec -static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], - const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) -{ - uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; - - // DH CALC - returns plain DH result, afterwards hashed with HKDF - - encrypt_precompute(public, private, shared_key); - crypto_hkdf(chaining_key, shared_key, NULL, dh_calculation, CRYPTO_SHA512_SIZE, - CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); - //TODO: truncate temp_k to 32 bytes - //TODO: where to InitializeKey(temp_k)? - - crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); - return true; -} - -// MixHash(data) as defined in Noise spec -static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) -{ - uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; - memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); - memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); - crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); -} - -// EncryptAndHash(plaintext) as defined in Noise spec -static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, - size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) -{ - //TODO: Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext. - int32_t encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, - plaintext, plain_length, ciphertext, - plain_length + CRYPTO_MAC_SIZE, hash, CRYPTO_SHA512_SIZE); - noise_mix_hash(hash, ciphertext, encrypted_length); -} - -static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, - size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) -{ - //TODO: Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext - int32_t plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, - ciphertext, encrypted_length, plaintext, - encrypted_length - CRYPTO_MAC_SIZE, hash, CRYPTO_SHA512_SIZE); - if (plaintext_length != (encrypted_length - CRYPTO_MAC_SIZE)) - { - return -1; - } - noise_mix_hash(hash, ciphertext, encrypted_length); - return 0; -} - /** @brief Create a crypto connection. * If one to that real public key already exists, return it. * From 8711b20c0223f7e17110d1b69628bbdae2f81eef Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 20 Jun 2023 15:30:50 +0200 Subject: [PATCH 006/150] Fixed noise_handshake_init() which lead to minor adaptions in noise_create_crypto_handshake(). Adapted handle?crypto_handshake() for Noise - initiator and responder cases. --- toxcore/net_crypto.c | 208 +++++++++++++++++++++++++++++-------------- 1 file changed, 143 insertions(+), 65 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 3935fc57a2..e68b5bbfa8 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -480,45 +480,6 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, // Necessary for Noise #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) - -/** @brief Create a handshake packet and put it in packet. - * @param cookie must be COOKIE_LENGTH bytes. - * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. - * - * @retval -1 on failure. - * @retval HANDSHAKE_PACKET_LENGTH on success. - */ -non_null() -static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, - const uint8_t *session_pk, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey) -{ - uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - memcpy(plain, nonce, CRYPTO_NONCE_SIZE); - memcpy(plain + CRYPTO_NONCE_SIZE, session_pk, CRYPTO_PUBLIC_KEY_SIZE); - crypto_sha512(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, cookie, COOKIE_LENGTH); - uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - 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->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(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); - - if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { - return -1; - } - - packet[0] = NET_PACKET_CRYPTO_HS; - memcpy(packet + 1, cookie, COOKIE_LENGTH); - - return HANDSHAKE_PACKET_LENGTH; -} - // Implements MixKey(input_key_material) static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], @@ -576,6 +537,44 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, return 0; } +/** @brief Create a handshake packet and put it in packet. + * @param cookie must be COOKIE_LENGTH bytes. + * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. + * + * @retval -1 on failure. + * @retval HANDSHAKE_PACKET_LENGTH on success. + */ +non_null() +static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, + const uint8_t *session_pk, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey) +{ + uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(plain, nonce, CRYPTO_NONCE_SIZE); + memcpy(plain + CRYPTO_NONCE_SIZE, session_pk, CRYPTO_PUBLIC_KEY_SIZE); + crypto_sha512(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, cookie, COOKIE_LENGTH); + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + 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->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(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); + + if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { + return -1; + } + + packet[0] = NET_PACKET_CRYPTO_HS; + memcpy(packet + 1, cookie, COOKIE_LENGTH); + + return HANDSHAKE_PACKET_LENGTH; +} + /** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. * @param cookie must be COOKIE_LENGTH bytes. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. @@ -604,12 +603,14 @@ static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, c */ /* -> e, es, s, ss */ if (noise_handshake->initiator) { - // set static public, set ephemeral private+public - memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // static public set in noise_handshake_init() + // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // set ephemeral private+public memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* e */ + memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* es */ //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? @@ -665,12 +666,14 @@ static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, c [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC 16 bytes] */ - // set static public, set ephemeral private+public - memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // static public set in noise_handshake_init() + // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // set ephemeral private+public memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* e */ + memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* ee */ //TODO: add shared key as param to this function? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? @@ -679,7 +682,7 @@ static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, c /* se */ noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); - /* Noise Handshake Payload */ + /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); @@ -821,40 +824,99 @@ static bool noise_handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, u uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); + /* -> e, es, s, ss */ if(!noise_handshake->initiator) { - //TODO: Continue Here (cf. Noise ReadMessage()) - /* e */ + /* Responder: Handshake packet structure + [uint8_t 26] + [Cookie 112 bytes] + [session public key of the peer (32 bytes)] + [24 bytes nonce handshake payload encryption] + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce -> Nonce patched + TODO: authenticate Cookie via AD in XAEAD? + [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + [MAC 16 bytes] + */ + /* e */ + memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); /* es */ - + //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* s */ - + // Nonces contained in packet! + memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + noise_handshake_temp_key, noise_handshake->hash, nonce); /* ss */ + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + /* Payload decryption */ + uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); + noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, + noise_handshake->hash, nonce); - /* old */ - uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, - packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, - HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); - - if (len != sizeof(plain)) { - return false; - } + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - if (!crypto_sha512_eq(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE)) { + if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { return false; } - memcpy(nonce, plain, CRYPTO_NONCE_SIZE); - memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); + // remote_ephemeral + memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); return true; - /* old */ } + /* ReadMessage() if initiator: + <- e, ee, se */ else if(noise_handshake->initiator) { + /* Responder: Handshake packet structure + [uint8_t 26] + [Cookie 112 bytes] + [session public key of the peer (32 bytes)] + [24 bytes nonce handshake payload encryption] + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce -> Nonce patched + TODO: authenticate Cookie via AD in XAEAD? + [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + [MAC 16 bytes] + */ + memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + /* ee */ + //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); + /* se */ + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); + /* Payload decryption */ + uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, + noise_handshake->hash, nonce); + + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { + return false; + } + + memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); + // remote_ephemeral + memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + return true; } else { return false; } @@ -1377,6 +1439,7 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array * @retval 0 on success. */ non_null() +//TODO: adapt for Noise static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE); @@ -1550,6 +1613,7 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce) * @return length of data on success. */ non_null() +//TODO: adapt for Noise static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint8_t *data, const uint8_t *packet, uint16_t length) { @@ -1761,6 +1825,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) * @retval 0 on success. */ non_null() +//TODO: adapt for Noise static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { @@ -2079,6 +2144,7 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con * @retval 0 on success. */ non_null(1, 3) nullable(6) +//TODO: adapt for Noise static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { @@ -2314,6 +2380,7 @@ void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_cal * @retval 0 on success. */ non_null(1, 2, 3) nullable(5) +//TODO: adapt for Noise static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, void *userdata) { @@ -2377,6 +2444,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, * return -1 on failure. * return connection id on success. */ +//TODO: adapt for Noise int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { if (getcryptconnection_id(c, n_c->public_key) != -1) { @@ -2444,13 +2512,14 @@ static int noise_handshake_init //TODO: ? memset(handshake, 0, sizeof(*handshake)); // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h + // Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE uint8_t temp_hash[CRYPTO_SHA512_SIZE]; memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); - // Sets the initiator, s, e, rs, and re variables to the corresponding arguments. => Rest is set afterwards + // Sets the initiator, s, rs (only initiator) => ephemeral keys are set afterwards noise_handshake->initiator = initiator; if (self_secret_key) { memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2458,9 +2527,10 @@ static int noise_handshake_init fprintf(stderr, "Local static private key required, but not provided.\n"); return -1; } - //TODO: only possible if initiator? + /* <- s: pre-message from responder to initiator */ if (initiator) { if (peer_public_key) { + crypto_derive_public_key(noise_handshake->static_public, self_secret_key); memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2468,11 +2538,17 @@ static int noise_handshake_init fprintf(stderr, "Remote peer static public key required, but not provided.\n"); return -1; } + } else if (!initiator) { + crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + // Calls MixHash() once for each public key listed in the pre-messages from Noise IK + noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + } else { + return -1; } //TODO: precompute_static_static ? - //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); + //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility /* Ready to go */ return 0; @@ -2484,6 +2560,7 @@ static int noise_handshake_init * return -1 on failure. * return connection id on success. */ +//TODO: adapt for Noise int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { int crypt_connection_id = getcryptconnection_id(c, real_public_key); @@ -3392,6 +3469,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) clear_temp_packet(c, crypt_connection_id); clear_buffer(&conn->send_array); clear_buffer(&conn->recv_array); + //TODO: adapt for Noise? ret = wipe_crypto_connection(c, crypt_connection_id); } From d0b947708446e9c1e646e923aa5c54e2e756ebac Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 20 Jun 2023 16:37:27 +0200 Subject: [PATCH 007/150] Merged noise_create_crypto_handshake() into create_crypto_handshake() and noise_handle_crypto_handshake() into handle_crypto_handshake() for backwards compatibility. --- toxcore/net_crypto.c | 874 ++++++++++++++++++++++++++++--------------- 1 file changed, 569 insertions(+), 305 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index e68b5bbfa8..1d5d809440 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -537,7 +537,8 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, return 0; } -/** @brief Create a handshake packet and put it in packet. +/** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. + * //TODO: one function for backwards compatiblity * @param cookie must be COOKIE_LENGTH bytes. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. * @@ -545,178 +546,314 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, * @retval HANDSHAKE_PACKET_LENGTH on success. */ non_null() -static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, - const uint8_t *session_pk, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey) +static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, + const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) { - uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - memcpy(plain, nonce, CRYPTO_NONCE_SIZE); - memcpy(plain + CRYPTO_NONCE_SIZE, session_pk, CRYPTO_PUBLIC_KEY_SIZE); - crypto_sha512(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, cookie, COOKIE_LENGTH); - uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - 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->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(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); + // Noise-based handshake + if (noise_handshake != NULL) { + /* Initiator: Handshake packet structure + [uint8_t 26] + [Cookie 112 bytes] + [session public key of the peer (32 bytes)] + [24 bytes nonce static pub key encryption] + [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise + [MAC encrypted static pubkey 16 bytes] + [24 bytes nonce handshake payload encryption] + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce -> Nonce patched + TODO: authenticate Cookie via AD in XAEAD? + [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + [MAC 16 bytes] + */ + /* -> e, es, s, ss */ + if (noise_handshake->initiator) { + // static public set in noise_handshake_init() + // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // set ephemeral private+public + memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + /* e */ + memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + /* es */ + //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); + /* s */ + // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + /* ss */ + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + + /* Noise Handshake Payload */ + uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); + crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + + // OtherCookie is added to payload + if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, + cookie_plain, c->secret_symmetric_key) != 0) { + return -1; + } - if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { - return -1; - } + // Add Handshake payload nonce + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + + packet[0] = NET_PACKET_CRYPTO_HS; + memcpy(packet + 1, cookie, COOKIE_LENGTH); + + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + + return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; + } + /* <- e, ee, se */ + else if (!noise_handshake->initiator) { + /* Responder: Handshake packet structure + [uint8_t 26] + [Cookie 112 bytes] + [session public key of the peer (32 bytes)] + [24 bytes nonce handshake payload encryption] + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce -> Nonce patched + TODO: authenticate Cookie via AD in XAEAD? + [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + [MAC 16 bytes] + */ + // static public set in noise_handshake_init() + // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // set ephemeral private+public + memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + /* e */ + memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + /* ee */ + //TODO: add shared key as param to this function? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); + /* se */ + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + + /* Create Noise Handshake Payload */ + uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); + crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + + // OtherCookie is added to payload + if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, + cookie_plain, c->secret_symmetric_key) != 0) { + return -1; + } - packet[0] = NET_PACKET_CRYPTO_HS; - memcpy(packet + 1, cookie, COOKIE_LENGTH); + // Add Handshake payload nonce + // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - return HANDSHAKE_PACKET_LENGTH; -} + packet[0] = NET_PACKET_CRYPTO_HS; + memcpy(packet + 1, cookie, COOKIE_LENGTH); -/** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. - * @param cookie must be COOKIE_LENGTH bytes. - * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. - * - * @retval -1 on failure. - * @retval HANDSHAKE_PACKET_LENGTH on success. - */ -non_null() -static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, - const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) -{ - /* Initiator: Handshake packet structure - [uint8_t 26] - [Cookie 112 bytes] - [session public key of the peer (32 bytes)] - [24 bytes nonce static pub key encryption] - [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise - [MAC encrypted static pubkey 16 bytes] - [24 bytes nonce handshake payload encryption] - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce -> Nonce patched - TODO: authenticate Cookie via AD in XAEAD? - [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] - [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - [MAC 16 bytes] - */ - /* -> e, es, s, ss */ - if (noise_handshake->initiator) { - // static public set in noise_handshake_init() - // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - // set ephemeral private+public - memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - - /* e */ - memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - /* es */ - //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? - uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); - /* s */ - // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? - random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - /* ss */ - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); - - /* Noise Handshake Payload */ - uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; + } + else { + return -1; + } + } + // old handshake + else { + uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(plain, nonce, CRYPTO_NONCE_SIZE); + memcpy(plain + CRYPTO_NONCE_SIZE, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + crypto_sha512(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - // OtherCookie is added to payload - if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_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; } - // Add Handshake payload nonce - random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, - handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - - packet[0] = NET_PACKET_CRYPTO_HS; - memcpy(packet + 1, cookie, COOKIE_LENGTH); - - crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - - return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; - } - /* <- e, ee, se */ - else if (!noise_handshake->initiator) { - /* Responder: Handshake packet structure - [uint8_t 26] - [Cookie 112 bytes] - [session public key of the peer (32 bytes)] - [24 bytes nonce handshake payload encryption] - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce -> Nonce patched - TODO: authenticate Cookie via AD in XAEAD? - [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] - [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - [MAC 16 bytes] - */ - // static public set in noise_handshake_init() - // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - // set ephemeral private+public - memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - - /* e */ - memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - /* ee */ - //TODO: add shared key as param to this function? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? - uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); - /* se */ - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); - - /* Create Noise Handshake Payload */ - uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - - uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + 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); - // OtherCookie is added to payload - if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, - cookie_plain, c->secret_symmetric_key) != 0) { + if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { return -1; } - // Add Handshake payload nonce - // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? - random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, - handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - packet[0] = NET_PACKET_CRYPTO_HS; memcpy(packet + 1, cookie, COOKIE_LENGTH); - crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - - return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; - } - else { - return -1; + return HANDSHAKE_PACKET_LENGTH; } + + } -/** @brief Handle a crypto handshake packet of length. +// /** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. +// * @param cookie must be COOKIE_LENGTH bytes. +// * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. +// * +// * @retval -1 on failure. +// * @retval HANDSHAKE_PACKET_LENGTH on success. +// */ +// non_null() +// static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, +// const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) +// { +// /* Initiator: Handshake packet structure +// [uint8_t 26] +// [Cookie 112 bytes] +// [session public key of the peer (32 bytes)] +// [24 bytes nonce static pub key encryption] +// [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise +// [MAC encrypted static pubkey 16 bytes] +// [24 bytes nonce handshake payload encryption] +// [Encrypted message containing: +// [24 bytes base nonce] => WITH base Nonce -> Nonce patched +// TODO: authenticate Cookie via AD in XAEAD? +// [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] +// [112 bytes Other Cookie (used by the other to respond to the handshake packet)] +// [MAC 16 bytes] +// */ +// /* -> e, es, s, ss */ +// if (noise_handshake->initiator) { +// // static public set in noise_handshake_init() +// // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); +// // set ephemeral private+public +// memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + +// /* e */ +// memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); +// noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); +// /* es */ +// //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? +// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; +// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); +// /* s */ +// // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? +// random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); +// noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, +// noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); +// /* ss */ +// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + +// /* Noise Handshake Payload */ +// uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; +// memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); +// crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + +// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; +// memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + +// // OtherCookie is added to payload +// if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, +// cookie_plain, c->secret_symmetric_key) != 0) { +// return -1; +// } + +// // Add Handshake payload nonce +// random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); +// noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, +// handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, +// noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + +// packet[0] = NET_PACKET_CRYPTO_HS; +// memcpy(packet + 1, cookie, COOKIE_LENGTH); + +// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + +// return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; +// } +// /* <- e, ee, se */ +// else if (!noise_handshake->initiator) { +// /* Responder: Handshake packet structure +// [uint8_t 26] +// [Cookie 112 bytes] +// [session public key of the peer (32 bytes)] +// [24 bytes nonce handshake payload encryption] +// [Encrypted message containing: +// [24 bytes base nonce] => WITH base Nonce -> Nonce patched +// TODO: authenticate Cookie via AD in XAEAD? +// [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] +// [112 bytes Other Cookie (used by the other to respond to the handshake packet)] +// [MAC 16 bytes] +// */ +// // static public set in noise_handshake_init() +// // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); +// // set ephemeral private+public +// memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + +// /* e */ +// memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); +// noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); +// /* ee */ +// //TODO: add shared key as param to this function? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? +// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; +// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); +// /* se */ +// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + +// /* Create Noise Handshake Payload */ +// uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; +// memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); +// crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + +// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; +// memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + +// // OtherCookie is added to payload +// if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, +// cookie_plain, c->secret_symmetric_key) != 0) { +// return -1; +// } + +// // Add Handshake payload nonce +// // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? +// random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); +// noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, +// handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, +// noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + +// packet[0] = NET_PACKET_CRYPTO_HS; +// memcpy(packet + 1, cookie, COOKIE_LENGTH); + +// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + +// return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; +// } +// else { +// return -1; +// } +// } + +/** TODO: adapt, cf. Noise ReadMessage() @brief Handle a crypto handshake packet of length. * put the nonce contained in the packet in nonce, * the session public key in session_pk * the real public key of the peer in peer_real_pk @@ -736,44 +873,171 @@ static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, c */ non_null(1, 2, 3, 4, 5, 6, 7) nullable(9) static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, - uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk) + uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, + noise_handshake *noise_handshake) { - if (length != HANDSHAKE_PACKET_LENGTH) { - return false; - } + if (noise_handshake != NULL) { + if (!noise_handshake->initiator) { + if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + return false; + } + } else if (noise_handshake->initiator) { + if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + return false; + } + } else { + return false; + } - uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { - return false; - } + if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + return false; + } - if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { - return false; - } + if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { + return false; + } - uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; - crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); + uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; + crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); + + /* -> e, es, s, ss */ + if(!noise_handshake->initiator) { + /* Responder: Handshake packet structure + [uint8_t 26] + [Cookie 112 bytes] + [session public key of the peer (32 bytes)] + [24 bytes nonce handshake payload encryption] + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce -> Nonce patched + TODO: authenticate Cookie via AD in XAEAD? + [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + [MAC 16 bytes] + */ + + /* e */ + memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + /* es */ + //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); + /* s */ + // Nonces contained in packet! + memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + noise_handshake_temp_key, noise_handshake->hash, nonce); + /* ss */ + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + /* Payload decryption */ + uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); + noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, + noise_handshake->hash, nonce); + + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + + if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { + return false; + } - uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, - packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, - HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); + memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); + // remote_ephemeral + memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + return true; + } + /* ReadMessage() if initiator: + <- e, ee, se */ + else if(noise_handshake->initiator) { + /* Responder: Handshake packet structure + [uint8_t 26] + [Cookie 112 bytes] + [session public key of the peer (32 bytes)] + [24 bytes nonce handshake payload encryption] + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce -> Nonce patched + TODO: authenticate Cookie via AD in XAEAD? + [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + [MAC 16 bytes] + */ + memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + /* ee */ + //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); + /* se */ + noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); + /* Payload decryption */ + uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, + noise_handshake->hash, nonce); + + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + + if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { + return false; + } - if (len != sizeof(plain)) { - return false; + memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); + // remote_ephemeral + memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + return true; + } else { + return false; + } } - if (!crypto_sha512_eq(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE)) { - return false; - } + else { + if (length != HANDSHAKE_PACKET_LENGTH) { + return false; + } - memcpy(nonce, plain, CRYPTO_NONCE_SIZE); - memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); - memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - return true; + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + + if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + return false; + } + + if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { + return false; + } + + uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; + crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); + + uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, + packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, + HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); + + if (len != sizeof(plain)) { + return false; + } + + if (!crypto_sha512_eq(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE)) { + return false; + } + + memcpy(nonce, plain, CRYPTO_NONCE_SIZE); + memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + return true; + } } /** TODO: adapt, cf. Noise ReadMessage() @brief Handle a crypto handshake packet of length. @@ -794,133 +1058,133 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t * @retval false on failure. * @retval true on success. */ -non_null(1, 2, 3, 4, 5, 6, 7) nullable(9) -static bool noise_handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, - uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, - noise_handshake *noise_handshake) -{ - if (!noise_handshake->initiator) { - if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - return false; - } - } else if (noise_handshake->initiator) { - if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { - return false; - } - } else { - return false; - } - - uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - - if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { - return false; - } - - if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { - return false; - } - - uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; - crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); - - /* -> e, es, s, ss */ - if(!noise_handshake->initiator) { - /* Responder: Handshake packet structure - [uint8_t 26] - [Cookie 112 bytes] - [session public key of the peer (32 bytes)] - [24 bytes nonce handshake payload encryption] - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce -> Nonce patched - TODO: authenticate Cookie via AD in XAEAD? - [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] - [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - [MAC 16 bytes] - */ - - /* e */ - memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - /* es */ - //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? - uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); - /* s */ - // Nonces contained in packet! - memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - noise_handshake_temp_key, noise_handshake->hash, nonce); - /* ss */ - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); - /* Payload decryption */ - uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); - noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, - sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - noise_handshake->hash, nonce); - - crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - - if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { - return false; - } - - memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); - // remote_ephemeral - memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); - memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - return true; - } - /* ReadMessage() if initiator: - <- e, ee, se */ - else if(noise_handshake->initiator) { - /* Responder: Handshake packet structure - [uint8_t 26] - [Cookie 112 bytes] - [session public key of the peer (32 bytes)] - [24 bytes nonce handshake payload encryption] - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce -> Nonce patched - TODO: authenticate Cookie via AD in XAEAD? - [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] - [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - [MAC 16 bytes] - */ - memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - /* ee */ - //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? - uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); - /* se */ - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); - /* Payload decryption */ - uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, - sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - noise_handshake->hash, nonce); - - crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - - if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { - return false; - } - - memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); - // remote_ephemeral - memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); - memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - return true; - } else { - return false; - } -} +// non_null(1, 2, 3, 4, 5, 6, 7) nullable(9) +// static bool noise_handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, +// uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, +// noise_handshake *noise_handshake) +// { +// if (!noise_handshake->initiator) { +// if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { +// return false; +// } +// } else if (noise_handshake->initiator) { +// if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { +// return false; +// } +// } else { +// return false; +// } + +// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + +// if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { +// return false; +// } + +// if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { +// return false; +// } + +// uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; +// crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); + +// /* -> e, es, s, ss */ +// if(!noise_handshake->initiator) { +// /* Responder: Handshake packet structure +// [uint8_t 26] +// [Cookie 112 bytes] +// [session public key of the peer (32 bytes)] +// [24 bytes nonce handshake payload encryption] +// [Encrypted message containing: +// [24 bytes base nonce] => WITH base Nonce -> Nonce patched +// TODO: authenticate Cookie via AD in XAEAD? +// [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] +// [112 bytes Other Cookie (used by the other to respond to the handshake packet)] +// [MAC 16 bytes] +// */ + +// /* e */ +// memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); +// noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); +// /* es */ +// //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? +// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; +// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); +// /* s */ +// // Nonces contained in packet! +// memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); +// noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, +// noise_handshake_temp_key, noise_handshake->hash, nonce); +// /* ss */ +// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); +// /* Payload decryption */ +// uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; +// memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); +// noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, +// sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, +// noise_handshake->hash, nonce); + +// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + +// if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { +// return false; +// } + +// memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); +// // remote_ephemeral +// memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); +// memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); +// return true; +// } +// /* ReadMessage() if initiator: +// <- e, ee, se */ +// else if(noise_handshake->initiator) { +// /* Responder: Handshake packet structure +// [uint8_t 26] +// [Cookie 112 bytes] +// [session public key of the peer (32 bytes)] +// [24 bytes nonce handshake payload encryption] +// [Encrypted message containing: +// [24 bytes base nonce] => WITH base Nonce -> Nonce patched +// TODO: authenticate Cookie via AD in XAEAD? +// [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] +// [112 bytes Other Cookie (used by the other to respond to the handshake packet)] +// [MAC 16 bytes] +// */ +// memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); +// noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); +// /* ee */ +// //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? +// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; +// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); +// /* se */ +// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); +// /* Payload decryption */ +// uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; +// memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); +// noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, +// sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, +// noise_handshake->hash, nonce); + +// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + +// if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { +// return false; +// } + +// memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); +// // remote_ephemeral +// memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); +// memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); +// return true; +// } else { +// return false; +// } +// } non_null() @@ -1837,7 +2101,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; - if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionpublic_key, + if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, conn->public_key, dht_public_key) != sizeof(handshake_packet)) { return -1; } From 4e25288b6d2d7c27791edae21206a7aff7cb0f6d Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 23 Jun 2023 16:26:34 +0200 Subject: [PATCH 008/150] Adapted rest of necessary functions for Noise-based handshake. --- toxcore/net_crypto.c | 372 +++++++++++++++++++++++++++++++------------ toxcore/net_crypto.h | 6 +- 2 files changed, 274 insertions(+), 104 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1d5d809440..0190f90f5d 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -63,7 +63,9 @@ typedef struct Crypto_Connection { // For Noise //TODO: necessary? - noise_handshake *handshake; + noise_handshake *noise_handshake; + uint8_t send_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t recv_key[CRYPTO_PUBLIC_KEY_SIZE]; // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -232,6 +234,7 @@ non_null() static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uint8_t *dht_public_key, uint64_t number, uint8_t *shared_key) { + fprintf(stderr, "ENTERING: create_cookie_request()\n"); uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t padding[CRYPTO_PUBLIC_KEY_SIZE] = {0}; @@ -320,6 +323,7 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui const uint8_t *shared_key, const uint8_t *dht_public_key) { uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + fprintf(stderr, "ENTERING: create_cookie_response()\n"); memcpy(cookie_plain, request_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; @@ -351,6 +355,7 @@ non_null() static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { + fprintf(stderr, "ENTERING: handle_cookie_request()\n"); if (length != COOKIE_REQUEST_LENGTH) { return -1; } @@ -459,6 +464,8 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8_t *packet, uint16_t length, const uint8_t *shared_key) { + fprintf(stderr, "ENTERING: handle_cookie_response()\n"); + if (length != COOKIE_RESPONSE_LENGTH) { return -1; } @@ -491,11 +498,9 @@ static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], // X25519 - returns plain DH result, afterwards hashed with HKDF encrypt_precompute(public, private, shared_key); // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! - crypto_hkdf(chaining_key, shared_key, NULL, dh_calculation, CRYPTO_SHA512_SIZE, + crypto_hkdf(chaining_key, shared_key, nullptr, dh_calculation, CRYPTO_SHA512_SIZE, CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); //If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() - //TODO: where to InitializeKey(temp_k)? here? need to provide key if I want to set here - crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); return true; } @@ -538,7 +543,6 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, } /** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. - * //TODO: one function for backwards compatiblity * @param cookie must be COOKIE_LENGTH bytes. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. * @@ -549,8 +553,9 @@ non_null() static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) { + fprintf(stderr, "ENTERING: create_crypto_handshake()\n"); // Noise-based handshake - if (noise_handshake != NULL) { + if (noise_handshake != nullptr) { /* Initiator: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] @@ -876,7 +881,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, noise_handshake *noise_handshake) { - if (noise_handshake != NULL) { + fprintf(stderr, "ENTERING: handle_crypto_handshake()\n"); + if (noise_handshake != nullptr) { if (!noise_handshake->initiator) { if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { return false; @@ -1697,13 +1703,13 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array #define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE)) +//TODO: adapt for Noise /** @brief Creates and sends a data packet to the peer using the fastest route. * * @retval -1 on failure. * @retval 0 on success. */ non_null() -//TODO: adapt for Noise static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE); @@ -1725,7 +1731,11 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ VLA(uint8_t, packet, packet_size); packet[0] = NET_PACKET_CRYPTO_DATA; memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); - const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + //TODO: need information in crypto conn if this is a Noise connection! + //TODO: enable backwards compatiblity + // const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + //TODO: add ad? + const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), length + CRYPTO_MAC_SIZE, nullptr, 0); if (len + 1 + sizeof(uint16_t) != packet_size) { LOGGER_ERROR(c->log, "encryption failed: %d", len); @@ -1869,6 +1879,7 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce) #define DATA_NUM_THRESHOLD 21845 +//TODO: adapt for Noise /** @brief Handle a data packet. * Decrypt packet of length and put it into data. * data must be at least MAX_DATA_DATA_PACKET_SIZE big. @@ -1877,7 +1888,6 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce) * @return length of data on success. */ non_null() -//TODO: adapt for Noise static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint8_t *data, const uint8_t *packet, uint16_t length) { @@ -1900,8 +1910,13 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint net_unpack_u16(packet + 1, &num); const uint16_t diff = num - num_cur_nonce; increment_nonce_number(nonce, diff); - const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), - length - (1 + sizeof(uint16_t)), data); + //TODO: need information in crypto conn if this is a Noise connection! + //TODO: enable backwards compatiblity + // const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), + // length - (1 + sizeof(uint16_t)), data); + //TODO: add ad? + const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, + length - length - (1 + sizeof(uint16_t)) - CRYPTO_MAC_SIZE, nullptr, 0); if ((unsigned int)len != length - crypto_packet_overhead) { return -1; @@ -2082,6 +2097,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) return 0; } +//TODO: adapt for Noise /** @brief Create a handshake packet and set it as a temp packet. * @param cookie must be COOKIE_LENGTH. * @@ -2089,7 +2105,6 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) * @retval 0 on success. */ non_null() -//TODO: adapt for Noise static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { @@ -2099,15 +2114,47 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u return -1; } - uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; + if (conn->noise_handshake != nullptr) { + if (conn->noise_handshake->initiator) { + uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; - if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key) != sizeof(handshake_packet)) { - return -1; - } + if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, + conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + return -1; + } - if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) { - return -1; + if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) { + return -1; + } + } + else if (!conn->noise_handshake->initiator) { + uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER]; + + if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, + conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + return -1; + } + + if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) { + return -1; + } + } else { + return -1; + } + } + // old handshake + else { + uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; + + // ephemeral_private and noise_handshake not necessary for old handshake + if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, nullptr, conn->sessionpublic_key, + conn->public_key, dht_public_key, nullptr) != sizeof(handshake_packet)) { + return -1; + } + + if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) { + return -1; + } } send_temp_packet(c, crypt_connection_id); @@ -2310,6 +2357,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } non_null() +//TODO: adapt for Noise static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2333,8 +2381,19 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } - if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { - return -1; + if (conn->noise_handshake != nullptr) { + if (conn->noise_handshake->initiator) { + if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { + return -1; + } + } else { + return -1; + } + } else { + // old handshake + if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { + return -1; + } } conn->status = CRYPTO_CONN_HANDSHAKE_SENT; @@ -2342,6 +2401,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } non_null(1, 3) nullable(5) +//TODO: adapt for Noise static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, void *userdata) { @@ -2361,11 +2421,28 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t cookie[COOKIE_LENGTH]; - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, - packet, length, conn->public_key)) { - return -1; - } + if (conn->noise_handshake != nullptr) { + if (conn->noise_handshake->initiator) { + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + packet, length, conn->public_key, conn->noise_handshake)) { + return -1; + } + // Noise Split(), nonces already set + crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + } else { + return -1; + } + } + // old handshake + else { + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + packet, length, conn->public_key, nullptr)) { + return -1; + } + } + //TODO: adapt? if (pk_equal(dht_public_key, conn->dht_public_key)) { encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); @@ -2408,7 +2485,6 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con * @retval 0 on success. */ non_null(1, 3) nullable(6) -//TODO: adapt for Noise static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { @@ -2624,6 +2700,59 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, return -1; } +/* + * Initializes a Noise HandshakeState with TODO: + * + * return -1 on failure + * return 0 on success + */ +static int noise_handshake_init +(struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +{ + //TODO: ? memset(handshake, 0, sizeof(*handshake)); + + // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h + // Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE + uint8_t temp_hash[CRYPTO_SHA512_SIZE]; + memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); + memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + + // Sets the initiator, s, rs (only initiator) => ephemeral keys are set afterwards + noise_handshake->initiator = initiator; + if (self_secret_key) { + memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); + } else { + fprintf(stderr, "Local static private key required, but not provided.\n"); + return -1; + } + /* <- s: pre-message from responder to initiator */ + if (initiator) { + if (peer_public_key != nullptr) { + crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // Calls MixHash() once for each public key listed in the pre-messages from Noise IK + noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + } else { + fprintf(stderr, "Remote peer static public key required, but not provided.\n"); + return -1; + } + } else if (!initiator) { + crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + // Calls MixHash() once for each public key listed in the pre-messages from Noise IK + noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + } else { + return -1; + } + + //TODO: precompute_static_static ? + + //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility + + /* Ready to go */ + return 0; +} /** @brief Set function to be called when someone requests a new connection to us. * @@ -2644,7 +2773,6 @@ void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_cal * @retval 0 on success. */ non_null(1, 2, 3) nullable(5) -//TODO: adapt for Noise static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, void *userdata) { @@ -2658,12 +2786,26 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, n_c.source = *source; n_c.cookie_length = COOKIE_LENGTH; + //TODO: Differention between old and handshake needs to be checked here! + + if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { + crypto_memzero(n_c.noise_handshake, sizeof(n_c.noise_handshake)); + return -1; + } + if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr)) { + n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { free(n_c.cookie); return -1; } + //TODO: case old handshake + // if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, + // n_c.cookie, data, length, nullptr, nullptr)) { + // free(n_c.cookie); + // return -1; + // } + const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); if (crypt_connection_id != -1) { @@ -2681,9 +2823,11 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } + conn->noise_handshake = n_c.noise_handshake; + memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + // encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); crypto_connection_add_source(c, crypt_connection_id, source); @@ -2691,6 +2835,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, free(n_c.cookie); return -1; } + // responder: vice-verse keys in comparison to initiator + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); conn->status = CRYPTO_CONN_NOT_CONFIRMED; free(n_c.cookie); @@ -2698,17 +2845,50 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } } + //TODO: case old handshake + // if (crypt_connection_id != -1) { + // Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + + // if (conn == nullptr) { + // return -1; + // } + + // if (!pk_equal(n_c.dht_public_key, conn->dht_public_key)) { + // connection_kill(c, crypt_connection_id, userdata); + // } else { + // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { + // free(n_c.cookie); + // return -1; + // } + + // memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); + // memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); + // encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + + // crypto_connection_add_source(c, crypt_connection_id, source); + + // if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { + // free(n_c.cookie); + // return -1; + // } + + // conn->status = CRYPTO_CONN_NOT_CONFIRMED; + // free(n_c.cookie); + // return 0; + // } + // } + const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); free(n_c.cookie); return ret; } +//TODO: adapt for Noise /** @brief Accept a crypto connection. * * return -1 on failure. * return connection id on success. */ -//TODO: adapt for Noise int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { if (getcryptconnection_id(c, n_c->public_key) != -1) { @@ -2739,20 +2919,59 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } conn->connection_number_tcp = connection_number_tcp; - 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(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; - if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { - pthread_mutex_lock(&c->tcp_mutex); - kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - pthread_mutex_unlock(&c->tcp_mutex); - wipe_crypto_connection(c, crypt_connection_id); - return -1; + if (n_c->noise_handshake != nullptr) { + if (!n_c->noise_handshake->initiator) { + conn->noise_handshake = n_c->noise_handshake; + // necessary -> TODO: duplicated code necessary? + 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(c->rng, conn->sent_nonce); + crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); + // happens in create_crypto_handshake() + // memcpy(conn->noise_handshake->ephemeral_private, conn->sessionsecret_key, CRYPTO_PUBLIC_KEY_SIZE); + // memcpy(conn->noise_handshake->ephemeral_public, conn->sessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + + if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { + pthread_mutex_lock(&c->tcp_mutex); + kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + pthread_mutex_unlock(&c->tcp_mutex); + wipe_crypto_connection(c, crypt_connection_id); + return -1; + } + + // Noise Split(), nonces already set + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + } + else { + pthread_mutex_lock(&c->tcp_mutex); + kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + pthread_mutex_unlock(&c->tcp_mutex); + wipe_crypto_connection(c, crypt_connection_id); + return -1; + } + + } + // old handshake + else { + 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(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; + + if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { + pthread_mutex_lock(&c->tcp_mutex); + kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + pthread_mutex_unlock(&c->tcp_mutex); + wipe_crypto_connection(c, crypt_connection_id); + return -1; + } } memcpy(conn->dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2764,60 +2983,6 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return crypt_connection_id; } -/* - * Initializes a Noise HandshakeState with TODO: - * - * return -1 on failure - * return 0 on success - */ -static int noise_handshake_init -(struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) -{ - //TODO: ? memset(handshake, 0, sizeof(*handshake)); - - // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h - // Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE - uint8_t temp_hash[CRYPTO_SHA512_SIZE]; - memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); - memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); - - // Sets the initiator, s, rs (only initiator) => ephemeral keys are set afterwards - noise_handshake->initiator = initiator; - if (self_secret_key) { - memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); - } else { - fprintf(stderr, "Local static private key required, but not provided.\n"); - return -1; - } - /* <- s: pre-message from responder to initiator */ - if (initiator) { - if (peer_public_key) { - crypto_derive_public_key(noise_handshake->static_public, self_secret_key); - memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - // Calls MixHash() once for each public key listed in the pre-messages from Noise IK - noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - } else { - fprintf(stderr, "Remote peer static public key required, but not provided.\n"); - return -1; - } - } else if (!initiator) { - crypto_derive_public_key(noise_handshake->static_public, self_secret_key); - // Calls MixHash() once for each public key listed in the pre-messages from Noise IK - noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); - } else { - return -1; - } - - //TODO: precompute_static_static ? - - //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility - - /* Ready to go */ - return 0; -} - /** @brief Create a crypto connection. * If one to that real public key already exists, return it. * @@ -2873,6 +3038,13 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u wipe_crypto_connection(c, crypt_connection_id); return -1; } + fprintf(stderr, "START: new_crypto_connection() noise_handshake_init()\n"); + // only necessary if Cookie request was successful + if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + return -1; + } + fprintf(stderr, "END: new_crypto_connection() noise_handshake_init()\n"); return crypt_connection_id; } @@ -3891,15 +4063,13 @@ void do_net_crypto(Net_Crypto *c, void *userdata) send_crypto_packets(c); } -//TODO: adapt and implement +//TODO: use? or just use crypto_memzero()? // static void noise_handshake_zero(struct noise_handshake *handshake) // { // memset(&handshake->ephemeral_private, 0, CRYPTO_PUBLIC_KEY_SIZE); // memset(&handshake->remote_ephemeral, 0, CRYPTO_PUBLIC_KEY_SIZE); // memset(&handshake->hash, 0, CRYPTO_SHA512_SIZE); // memset(&handshake->chaining_key, 0, CRYPTO_SHA512_SIZE); -// handshake->remote_index = 0; -// handshake->state = HANDSHAKE_ZEROED; // } void kill_net_crypto(Net_Crypto *c) diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 2875a78cf6..b78c8e8d6b 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -130,7 +130,7 @@ typedef struct noise_handshake { uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; //TODO: necessary? - uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; + //uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t hash[CRYPTO_SHA512_SIZE]; uint8_t chaining_key[CRYPTO_SHA512_SIZE]; @@ -145,7 +145,7 @@ typedef struct New_Connection { uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ - noise_handshake *handshake; + noise_handshake *noise_handshake; // Necessary for Noise // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; @@ -439,7 +439,7 @@ nullable(1) void kill_net_crypto(Net_Crypto *c); //TODO: comment -static void handshake_zero(struct noise_handshake *handshake); +//static void handshake_zero(struct noise_handshake *handshake); #endif From b653e8b3434e971798c9a0dd31bd3c4ede3be5b5 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 26 Jun 2023 15:47:56 +0200 Subject: [PATCH 009/150] Fixed SegFault because of unallocated noise_handshake memory. Added debugging statements. --- toxcore/net_crypto.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 0190f90f5d..2ea67c93b7 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -255,6 +255,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin return -1; } + fprintf(stderr, "END: create_cookie_request()\n"); return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len; } @@ -322,6 +323,7 @@ non_null() static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain, const uint8_t *shared_key, const uint8_t *dht_public_key) { + fprintf(stderr, "ENTERING: create_cookie_response()\n"); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; fprintf(stderr, "ENTERING: create_cookie_response()\n"); memcpy(cookie_plain, request_plain, CRYPTO_PUBLIC_KEY_SIZE); @@ -1316,6 +1318,8 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t return -1; } + fprintf(stderr, "ENTERING: send_packet_to()"); + bool direct_send_attempt = false; pthread_mutex_lock(conn->mutex); @@ -1336,6 +1340,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t pthread_mutex_unlock(conn->mutex); LOGGER_WARNING(c->log, "sending packet of length %d failed", length); + fprintf(stderr, "send_packet_to(); sending packet of length %d failed", length); return -1; } @@ -2078,22 +2083,27 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id) non_null() static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) { + fprintf(stderr, "ENTERING: send_temp_packet()\n"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { + fprintf(stderr, "send_temp_packet() => conn == nullptr\n"); return -1; } if (conn->temp_packet == nullptr) { + fprintf(stderr, "send_temp_packet() => temp_packet == nullptr\n"); return -1; } if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0) { + fprintf(stderr, "send_temp_packet() => send_packet_to() => Error case\n"); return -1; } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); ++conn->temp_packet_num_sent; + fprintf(stderr, "END: send_temp_packet()\n"); return 0; } @@ -2108,6 +2118,7 @@ non_null() static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { + fprintf(stderr, "ENTERING: create_send_handshake()\n"); const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -2217,6 +2228,8 @@ non_null(1, 3) nullable(6) static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { + fprintf(stderr, "ENTERING: handle_data_packet_core(); PACKET: %d\n", packet[0]); + if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) { return -1; } @@ -2361,6 +2374,9 @@ non_null() static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + fprintf(stderr, "ENTERING: handle_packet_cookie_response(); PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d\n", + packet[0], + conn->status); if (conn == nullptr) { return -1; @@ -2407,6 +2423,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + fprintf(stderr, "ENTERING: handle_packet_crypto_hs(); PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d\n", + packet[0], + conn->status); + if (conn == nullptr) { return -1; } @@ -2468,6 +2488,10 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + fprintf(stderr, "ENTERING: handle_packet_crypto_data(); PACKET: %d => NET_PACKET_CRYPTO_DATA => CRYPTO CONN STATE: %d\n", + packet[0], + conn->status); + if (conn == nullptr) { return -1; } @@ -2488,6 +2512,8 @@ non_null(1, 3) nullable(6) static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { + fprintf(stderr, "ENTERING: handle_packet_connection(); PACKET: %d\n", packet[0]); + if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; } @@ -2588,6 +2614,8 @@ static int create_crypto_connection(Net_Crypto *c) return -1; } + //TODO: calloc noise handshake? or in realloc_cryptoconnection()? + c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; } @@ -2709,6 +2737,7 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, static int noise_handshake_init (struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { + fprintf(stderr, "ENTERING: noise_handshake_init()\n"); //TODO: ? memset(handshake, 0, sizeof(*handshake)); // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h @@ -2734,6 +2763,7 @@ static int noise_handshake_init memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + fprintf(stderr, "oise_handshake_init() => INITIATOR keys set\n"); } else { fprintf(stderr, "Remote peer static public key required, but not provided.\n"); return -1; @@ -2742,6 +2772,7 @@ static int noise_handshake_init crypto_derive_public_key(noise_handshake->static_public, self_secret_key); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + fprintf(stderr, "noise_handshake_init() => RESPONDER keys set\n"); } else { return -1; } @@ -2776,6 +2807,7 @@ non_null(1, 2, 3) nullable(5) static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, void *userdata) { + fprintf(stderr, "ENTERING: handle_new_connection_handshake()\n"); New_Connection n_c; n_c.cookie = (uint8_t *)malloc(COOKIE_LENGTH); @@ -2786,6 +2818,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, n_c.source = *source; n_c.cookie_length = COOKIE_LENGTH; + //TODO: calloc n_c.noise_handshake here? + n_c.noise_handshake = (noise_handshake *)calloc(1, sizeof(noise_handshake)); + //TODO: Differention between old and handshake needs to be checked here! if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { @@ -2891,6 +2926,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, */ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { + fprintf(stderr, "ENTERING: accept_crypto_connection()\n"); + if (getcryptconnection_id(c, n_c->public_key) != -1) { return -1; } @@ -2922,6 +2959,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { + fprintf(stderr, "ENTERING: accept_crypto_connection() => INITIATOR\n"); conn->noise_handshake = n_c->noise_handshake; // necessary -> TODO: duplicated code necessary? memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2957,6 +2995,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } // old handshake else { + fprintf(stderr, "ENTERING: accept_crypto_connection() => old handshake\n"); 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); @@ -2992,6 +3031,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: adapt for Noise int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { + fprintf(stderr, "ENTERING: new_crypto_connection()\n"); + int crypt_connection_id = getcryptconnection_id(c, real_public_key); if (crypt_connection_id != -1) { @@ -3039,12 +3080,19 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u return -1; } fprintf(stderr, "START: new_crypto_connection() noise_handshake_init()\n"); + fprintf(stderr, "Handshake size: %d\n", sizeof(conn->noise_handshake)); + // printf("Handshake size: %d\n", sizeof(conn->noise_handshake)); + + //TODO: calloc conn->noise_handshake here? + conn->noise_handshake = (noise_handshake *)calloc(1, sizeof(noise_handshake)); + fprintf(stderr, "Handshake struct size: %d\n", sizeof(noise_handshake)); // only necessary if Cookie request was successful if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); return -1; } fprintf(stderr, "END: new_crypto_connection() noise_handshake_init()\n"); + fprintf(stderr, "END: new_crypto_connection()\n"); return crypt_connection_id; } From 6a70bfb516706ba57325d25b623de0f6d41aa32f Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 26 Jun 2023 20:19:39 +0200 Subject: [PATCH 010/150] Added debug output. Fixed noise_handshake_init() for Initiator case. --- toxcore/net_crypto.c | 121 ++++++++++++++++++++++++++++++++++++++++--- toxcore/net_crypto.h | 4 +- 2 files changed, 114 insertions(+), 11 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 2ea67c93b7..8fa700bc5e 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -234,6 +234,9 @@ non_null() static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uint8_t *dht_public_key, uint64_t number, uint8_t *shared_key) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: create_cookie_request()\n"); fprintf(stderr, "ENTERING: create_cookie_request()\n"); uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t padding[CRYPTO_PUBLIC_KEY_SIZE] = {0}; @@ -255,7 +258,9 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin return -1; } + fprintf(fp, "END: create_cookie_request()\n"); fprintf(stderr, "END: create_cookie_request()\n"); + fclose(fp); return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len; } @@ -323,9 +328,12 @@ non_null() static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain, const uint8_t *shared_key, const uint8_t *dht_public_key) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: create_cookie_response()\n"); fprintf(stderr, "ENTERING: create_cookie_response()\n"); + fclose(fp); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - fprintf(stderr, "ENTERING: create_cookie_response()\n"); memcpy(cookie_plain, request_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; @@ -357,7 +365,11 @@ non_null() static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_cookie_request()\n"); fprintf(stderr, "ENTERING: handle_cookie_request()\n"); + fclose(fp); if (length != COOKIE_REQUEST_LENGTH) { return -1; } @@ -466,7 +478,11 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8_t *packet, uint16_t length, const uint8_t *shared_key) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_cookie_response()\n"); fprintf(stderr, "ENTERING: handle_cookie_response()\n"); + fclose(fp); if (length != COOKIE_RESPONSE_LENGTH) { return -1; @@ -555,7 +571,11 @@ non_null() static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: create_crypto_handshake()\n"); fprintf(stderr, "ENTERING: create_crypto_handshake()\n"); + fclose(fp); // Noise-based handshake if (noise_handshake != nullptr) { /* Initiator: Handshake packet structure @@ -883,7 +903,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, noise_handshake *noise_handshake) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_crypto_handshake()\n"); fprintf(stderr, "ENTERING: handle_crypto_handshake()\n"); + fclose(fp); if (noise_handshake != nullptr) { if (!noise_handshake->initiator) { if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { @@ -1044,6 +1068,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + + return true; } } @@ -1318,7 +1344,10 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t return -1; } - fprintf(stderr, "ENTERING: send_packet_to()"); + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: send_packet_to()\n"); + fprintf(stderr, "ENTERING: send_packet_to()\n"); bool direct_send_attempt = false; @@ -1340,7 +1369,8 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t pthread_mutex_unlock(conn->mutex); LOGGER_WARNING(c->log, "sending packet of length %d failed", length); - fprintf(stderr, "send_packet_to(); sending packet of length %d failed", length); + fprintf(fp, "send_packet_to(); sending packet of length %d failed\n", length); + fprintf(stderr, "send_packet_to(); sending packet of length %d failed\n", length); return -1; } @@ -2083,27 +2113,35 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id) non_null() static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) { + FILE *fp; + fp = fopen("data.log", "a"); + fprintf(fp, "ENTERING: send_temp_packet()\n"); fprintf(stderr, "ENTERING: send_temp_packet()\n"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { + fprintf(fp, "send_temp_packet() => conn == nullptr\n"); fprintf(stderr, "send_temp_packet() => conn == nullptr\n"); return -1; } if (conn->temp_packet == nullptr) { + fprintf(fp, "send_temp_packet() => temp_packet == nullptr\n"); fprintf(stderr, "send_temp_packet() => temp_packet == nullptr\n"); return -1; } if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0) { + fprintf(fp, "send_temp_packet() => send_packet_to() => Error case\n"); fprintf(stderr, "send_temp_packet() => send_packet_to() => Error case\n"); return -1; } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); ++conn->temp_packet_num_sent; + fprintf(fp, "END: send_temp_packet()\n"); fprintf(stderr, "END: send_temp_packet()\n"); + fclose(fp); return 0; } @@ -2118,7 +2156,11 @@ non_null() static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: create_send_handshake()\n"); fprintf(stderr, "ENTERING: create_send_handshake()\n"); + fclose(fp); const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -2228,7 +2270,11 @@ non_null(1, 3) nullable(6) static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_data_packet_core(); PACKET: %d\n", packet[0]); fprintf(stderr, "ENTERING: handle_data_packet_core(); PACKET: %d\n", packet[0]); + fclose(fp); if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) { return -1; @@ -2374,9 +2420,16 @@ non_null() static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_packet_cookie_response(); PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d\n", + packet[0], + conn->status); fprintf(stderr, "ENTERING: handle_packet_cookie_response(); PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d\n", packet[0], conn->status); + fclose(fp); if (conn == nullptr) { return -1; @@ -2423,9 +2476,15 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_packet_crypto_hs(); PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d\n", + packet[0], + conn->status); fprintf(stderr, "ENTERING: handle_packet_crypto_hs(); PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d\n", packet[0], conn->status); + fclose(fp); if (conn == nullptr) { return -1; @@ -2488,9 +2547,15 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_packet_crypto_data(); PACKET: %d => NET_PACKET_CRYPTO_DATA => CRYPTO CONN STATE: %d\n", + packet[0], + conn->status); fprintf(stderr, "ENTERING: handle_packet_crypto_data(); PACKET: %d => NET_PACKET_CRYPTO_DATA => CRYPTO CONN STATE: %d\n", packet[0], conn->status); + fclose(fp); if (conn == nullptr) { return -1; @@ -2512,7 +2577,11 @@ non_null(1, 3) nullable(6) static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_packet_connection(); PACKET: %d\n", packet[0]); fprintf(stderr, "ENTERING: handle_packet_connection(); PACKET: %d\n", packet[0]); + fclose(fp); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; @@ -2737,6 +2806,9 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, static int noise_handshake_init (struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: noise_handshake_init()\n"); fprintf(stderr, "ENTERING: noise_handshake_init()\n"); //TODO: ? memset(handshake, 0, sizeof(*handshake)); @@ -2752,31 +2824,38 @@ static int noise_handshake_init noise_handshake->initiator = initiator; if (self_secret_key) { memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); + crypto_derive_public_key(noise_handshake->static_public, self_secret_key); } else { fprintf(stderr, "Local static private key required, but not provided.\n"); + fprintf(fp, "Local static private key required, but not provided.\n"); return -1; } /* <- s: pre-message from responder to initiator */ if (initiator) { if (peer_public_key != nullptr) { - crypto_derive_public_key(noise_handshake->static_public, self_secret_key); memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - fprintf(stderr, "oise_handshake_init() => INITIATOR keys set\n"); + fprintf(fp, "Noise_handshake_init() => INITIATOR keys set\n"); + fprintf(stderr, "Noise_handshake_init() => INITIATOR keys set\n"); } else { fprintf(stderr, "Remote peer static public key required, but not provided.\n"); + fprintf(fp, "Remote peer static public key required, but not provided.\n"); return -1; } } else if (!initiator) { - crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + // crypto_derive_public_key() happens for both + // crypto_derive_public_key(noise_handshake->static_public, self_secret_key); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + fprintf(fp, "noise_handshake_init() => RESPONDER keys set\n"); fprintf(stderr, "noise_handshake_init() => RESPONDER keys set\n"); } else { return -1; } + fclose(fp); + //TODO: precompute_static_static ? //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility @@ -2807,7 +2886,11 @@ non_null(1, 2, 3) nullable(5) static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, void *userdata) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_new_connection_handshake()\n"); fprintf(stderr, "ENTERING: handle_new_connection_handshake()\n"); + New_Connection n_c; n_c.cookie = (uint8_t *)malloc(COOKIE_LENGTH); @@ -2828,6 +2911,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } + fprintf(fp, "handle_new_connection_handshake() => After Handshake init\n"); + fprintf(stderr, "handle_new_connection_handshake() => After Handshake init\n"); + if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { free(n_c.cookie); @@ -2915,6 +3001,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); free(n_c.cookie); + + fclose(fp); + return ret; } @@ -2926,6 +3015,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, */ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: accept_crypto_connection()\n"); fprintf(stderr, "ENTERING: accept_crypto_connection()\n"); if (getcryptconnection_id(c, n_c->public_key) != -1) { @@ -2959,6 +3051,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { + fprintf(fp, "ENTERING: accept_crypto_connection() => INITIATOR\n"); fprintf(stderr, "ENTERING: accept_crypto_connection() => INITIATOR\n"); conn->noise_handshake = n_c->noise_handshake; // necessary -> TODO: duplicated code necessary? @@ -2995,6 +3088,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } // old handshake else { + fprintf(fp, "ENTERING: accept_crypto_connection() => old handshake\n"); fprintf(stderr, "ENTERING: accept_crypto_connection() => old handshake\n"); memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE); @@ -3019,6 +3113,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; conn->rtt_time = DEFAULT_PING_CONNECTION; crypto_connection_add_source(c, crypt_connection_id, &n_c->source); + + fclose(fp); + return crypt_connection_id; } @@ -3031,6 +3128,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: adapt for Noise int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: new_crypto_connection()\n"); fprintf(stderr, "ENTERING: new_crypto_connection()\n"); int crypt_connection_id = getcryptconnection_id(c, real_public_key); @@ -3079,20 +3179,25 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u wipe_crypto_connection(c, crypt_connection_id); return -1; } + fprintf(fp, "START: new_crypto_connection() noise_handshake_init()\n"); + fprintf(fp, "Handshake size: %d\n", sizeof(conn->noise_handshake)); fprintf(stderr, "START: new_crypto_connection() noise_handshake_init()\n"); fprintf(stderr, "Handshake size: %d\n", sizeof(conn->noise_handshake)); // printf("Handshake size: %d\n", sizeof(conn->noise_handshake)); //TODO: calloc conn->noise_handshake here? conn->noise_handshake = (noise_handshake *)calloc(1, sizeof(noise_handshake)); - fprintf(stderr, "Handshake struct size: %d\n", sizeof(noise_handshake)); + fprintf(fp, "Handshake struct size: %d\n", sizeof(noise_handshake)); // only necessary if Cookie request was successful - if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { + if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); return -1; } + fprintf(fp, "END: new_crypto_connection() noise_handshake_init()\n"); + fprintf(fp, "END: new_crypto_connection()\n"); fprintf(stderr, "END: new_crypto_connection() noise_handshake_init()\n"); fprintf(stderr, "END: new_crypto_connection()\n"); + fclose(fp); return crypt_connection_id; } diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index b78c8e8d6b..6228edd399 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -85,7 +85,7 @@ #define MAX_CRYPTO_DATA_SIZE (uint16_t)(MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE) /** Interval in ms between sending cookie request/handshake packets. */ -#define CRYPTO_SEND_PACKET_INTERVAL 1000 +#define CRYPTO_SEND_PACKET_INTERVAL 2000 /** * The maximum number of times we try to send the cookie request and handshake @@ -129,8 +129,6 @@ typedef struct noise_handshake { uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; - //TODO: necessary? - //uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t hash[CRYPTO_SHA512_SIZE]; uint8_t chaining_key[CRYPTO_SHA512_SIZE]; From f02b8a5e2c66e47819c27e1030cb5552e9bf2c1d Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 28 Jun 2023 18:59:34 +0200 Subject: [PATCH 011/150] Added debugging code to log behavior, fixed bug in . Currently decryption #2 fails on the handshake packet from INITIATOR to RESPONDER. Adapted encryption/decryption functions, but not fixed yet. --- toxcore/crypto_core.c | 71 ++++++++++--- toxcore/crypto_core.h | 14 ++- toxcore/net_crypto.c | 230 ++++++++++++++++++++++++++++++++++++++---- toxcore/net_crypto.h | 2 +- 4 files changed, 280 insertions(+), 37 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 7d8d3c513f..ebcec62a49 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -285,14 +285,17 @@ int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, #endif } -int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, +//TODO: without encrypted_length parameter +size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, uint8_t *encrypted, - size_t encrypted_length, const uint8_t *ad, size_t ad_length) + const uint8_t *ad, size_t ad_length) { // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { return -1; } + + size_t encrypted_length = 0; // nsec is not used by this particular construction and should always be NULL. if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, @@ -301,18 +304,41 @@ int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *n } //assert(length < INT32_MAX - crypto_box_MACBYTES); - return (int32_t)(encrypted_length); -} - -int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, + return encrypted_length; +} +//TODO: with encrypted_length parameter +// int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, +// const uint8_t *plain, size_t plain_length, uint8_t *encrypted, +// size_t encrypted_length, const uint8_t *ad, size_t ad_length) +// { +// // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium +// if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { +// return -1; +// } + +// // nsec is not used by this particular construction and should always be NULL. +// if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, +// ad, ad_length, NULL, nonce, shared_key) != 0) { +// return -1; +// } + +// //assert(length < INT32_MAX - crypto_box_MACBYTES); +// return (int32_t)(encrypted_length); +// } + +//TODO: without plain_length parameter +size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, - size_t plain_length, const uint8_t *ad, size_t ad_length) + const uint8_t *ad, size_t ad_length) { // plain_length is calculated by libsodium - if (encrypted_length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr - || plain == nullptr) { - return -1; - } + //TODO: encrypted length is longer than crypto_box_BOXZEROBYTES => Why is this check here? + // if (encrypted_length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr + // || plain == nullptr) { + // return -1; + // } + + size_t plain_length = 0; if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, NULL, encrypted, encrypted_length, ad, ad_length, nonce, shared_key) != 0) { @@ -321,8 +347,27 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *n // assert(length > crypto_box_MACBYTES); // assert(length < INT32_MAX); - return (int32_t)(plain_length); -} + return plain_length; +} +//TODO: with plain_length parameter +// int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, +// const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, +// size_t plain_length, const uint8_t *ad, size_t ad_length) +// { +// // plain_length is calculated by libsodium +// if (encrypted_length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr +// || plain == nullptr) { +// return -1; +// } +// if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, NULL, encrypted, +// encrypted_length, ad, ad_length, nonce, shared_key) != 0) { +// return -1; +// } + +// // assert(length > crypto_box_MACBYTES); +// // assert(length < INT32_MAX); +// return (int32_t)(plain_length); +// } int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t length, uint8_t *encrypted) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 83a6ea911c..af6e45106c 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -418,8 +418,11 @@ int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, * @return length of encrypted data if everything was fine. */ non_null() -int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, - uint8_t *encrypted, size_t encrypted_length, const uint8_t *ad, size_t ad_length); +//TODO: which is the final one? +// int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, + // uint8_t *encrypted, size_t encrypted_length, const uint8_t *ad, size_t ad_length); +size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, + uint8_t *encrypted, const uint8_t *ad, size_t ad_length); /** * @brief Decrypt message with precomputed shared key using XChaCha20-Poly1305. @@ -432,8 +435,11 @@ int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *n * @return length of plain data if everything was fine. */ non_null() -int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, - uint8_t *plain, size_t plain_length, const uint8_t *ad, size_t ad_length); +//TODO: which is the final one? +// int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, +// uint8_t *plain, size_t plain_length, const uint8_t *ad, size_t ad_length); +size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, + uint8_t *plain, const uint8_t *ad, size_t ad_length); /** * @brief Encrypt message with precomputed shared key. diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 8fa700bc5e..30a8c2cb6c 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -393,6 +393,12 @@ non_null(1, 2, 3) nullable(5) static int udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: udp_handle_cookie_request()\n"); + fprintf(stderr, "ENTERING: udp_handle_cookie_request()\n"); + fclose(fp); + const Net_Crypto *c = (const Net_Crypto *)object; uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; @@ -514,7 +520,7 @@ static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; // X25519 - returns plain DH result, afterwards hashed with HKDF - encrypt_precompute(public, private, shared_key); + encrypt_precompute(public, private, dh_calculation); // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! crypto_hkdf(chaining_key, shared_key, nullptr, dh_calculation, CRYPTO_SHA512_SIZE, CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); @@ -526,6 +532,10 @@ static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], // MixHash(data) as defined in Noise spec static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "noise_mix_hash() => NOISE HANDSHAKE\n"); + fclose(fp); uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); @@ -538,25 +548,82 @@ static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { //TODO: Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext. TODO: does that even happen? - int32_t encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); + int i; + fprintf(fp, "Nonce: "); + for (i = 0; i < CRYPTO_NONCE_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", nonce[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "Shared Key: "); + for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", shared_key[i]); + } + fprintf(fp, "\n"); + fprintf(stderr, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); + // size_t encrypted_length = 0; + // encrypt_data_symmetric_xaead(shared_key, nonce, + // plaintext, plain_length, ciphertext, + // encrypted_length, hash, CRYPTO_SHA512_SIZE); + // fprintf(fp, "noise_encrypt_and_hash() => encrypted_length: %d\n", encrypted_length); + size_t encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, plaintext, plain_length, ciphertext, - plain_length + CRYPTO_MAC_SIZE, hash, CRYPTO_SHA512_SIZE); + hash, CRYPTO_SHA512_SIZE); + fprintf(fp, "noise_encrypt_and_hash() => encrypted_length: %d\n", encrypted_length); noise_mix_hash(hash, ciphertext, encrypted_length); + fclose(fp); } static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { + FILE *fp; + fp = fopen ("data.log", "a"); //TODO: Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext - int32_t plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, + fprintf(fp, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); + int i; + fprintf(fp, "Nonce: "); + for (i = 0; i < CRYPTO_NONCE_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", nonce[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "Shared Key: "); + for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", shared_key[i]); + } + fprintf(fp, "\n"); + fprintf(stderr, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); + // size_t plaintext_length = 0; + // decrypt_data_symmetric_xaead(shared_key, nonce, + // ciphertext, encrypted_length, plaintext, + // plaintext_length, hash, CRYPTO_SHA512_SIZE); + // fprintf(fp, "noise_decrypt_and_hash() => plaintext_length: %d\n", plaintext_length); + size_t plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, ciphertext, encrypted_length, plaintext, - encrypted_length - CRYPTO_MAC_SIZE, hash, CRYPTO_SHA512_SIZE); + hash, CRYPTO_SHA512_SIZE); + fprintf(fp, "noise_decrypt_and_hash() => plaintext_length: %d\n", plaintext_length); if (plaintext_length != (encrypted_length - CRYPTO_MAC_SIZE)) - { + { + fprintf(fp, "noise_decrypt_and_hash() => decryption FAILED\n"); + fprintf(stderr, "noise_decrypt_and_hash() => decryption FAILED\n"); + fclose(fp); return -1; } noise_mix_hash(hash, ciphertext, encrypted_length); + fprintf(fp, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); + fprintf(stderr, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); + fclose(fp); return 0; } @@ -578,6 +645,10 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u fclose(fp); // Noise-based handshake if (noise_handshake != nullptr) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: create_crypto_handshake() => NOISE HANDSHAKE\n"); + fprintf(stderr, "ENTERING: create_crypto_handshake() => NOISE HANDSHAKE\n"); /* Initiator: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] @@ -604,6 +675,14 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* e */ memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + int i; + fprintf(fp, "hash1 INITIATOR: "); + for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", noise_handshake->hash[i]); + } + fprintf(fp, "\n"); /* es */ //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; @@ -611,8 +690,18 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* s */ // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + // fprintf(fp, "create_crypto_handshake() => NOISE HANDSHAKE => INITIATOR => NONCE1: %s, Handshake Key1: %s\n", packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key); + // fprintf(stderr, "create_crypto_handshake() => NOISE HANDSHAKE => INITIATOR => NONCE1: %s, Handshake Key1: %s\n", packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key); + //TODO: encryption and decryption ok noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + fprintf(fp, "hash2 INITIATOR: "); + for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", noise_handshake->hash[i]); + } + fprintf(fp, "\n"); /* ss */ noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); @@ -633,6 +722,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // Add Handshake payload nonce random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + // fprintf(fp, "create_crypto_handshake() => NOISE HANDSHAKE => INITIATOR => NONCE2: %s, Handshake Key2: %s\n", packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key); + // fprintf(stderr, "create_crypto_handshake() => NOISE HANDSHAKE => INITIATOR => NONCE2: %s, Handshake Key2: %s\n", packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key); + //TODO: decryption fails => same nonce, key and hash what is the Problem here? noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); @@ -642,6 +734,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + fclose(fp); + return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* <- e, ee, se */ @@ -701,6 +795,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + fclose(fp); + return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } else { @@ -909,6 +1005,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t fprintf(stderr, "ENTERING: handle_crypto_handshake()\n"); fclose(fp); if (noise_handshake != nullptr) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE\n"); + fprintf(stderr, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE\n"); + if (!noise_handshake->initiator) { if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { return false; @@ -931,15 +1032,21 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } + //TODO: is this correct? => should be, if correct set in packet-creating function uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); /* -> e, es, s, ss */ if(!noise_handshake->initiator) { - /* Responder: Handshake packet structure + fprintf(fp, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER\n"); + fprintf(stderr, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER\n"); + /* Initiator: Handshake packet structure => THIS IS HANDLED HERE [uint8_t 26] [Cookie 112 bytes] [session public key of the peer (32 bytes)] + [24 bytes nonce static pub key encryption] + [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise + [MAC encrypted static pubkey 16 bytes] [24 bytes nonce handshake payload encryption] [Encrypted message containing: [24 bytes base nonce] => WITH base Nonce -> Nonce patched @@ -952,6 +1059,14 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + int i; + fprintf(fp, "hash1 RESPONDER: "); + for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", noise_handshake->hash[i]); + } + fprintf(fp, "\n"); /* es */ //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; @@ -959,20 +1074,37 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* s */ // Nonces contained in packet! memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + // fprintf(fp, "handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => NONCE1: %s, Handshake Key1: %s\n", nonce, noise_handshake_temp_key); + // fprintf(stderr, "handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => NONCE1: %s, Handshake Key1: %s\n", nonce, noise_handshake_temp_key); noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce); + fprintf(fp, "hash2 RESPONDER: "); + for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", noise_handshake->hash[i]); + } + fprintf(fp, "\n"); /* ss */ noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); + // fprintf(fp, "handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => NONCE2: %s, Handshake Key2: %s\n", nonce, noise_handshake_temp_key); + // fprintf(stderr, "handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => NONCE2: %s, Handshake Key2: %s\n", nonce, noise_handshake_temp_key); + //TODO: Error handling + //TODO: currently fails, but same key+nonce+hash => decrypt func should be ok (otherwise first dec would fail), so where is the problem here? noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce); crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + //TODO: currently this fails => decryption fails if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { + fprintf(fp, "ERROR: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => COOKIE HASH WRONG\n"); + fprintf(stderr, "ERROR: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => COOKIE HASH WRONG\n"); + fclose(fp); return false; } @@ -982,11 +1114,16 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + fprintf(fp, "END: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER\n"); + fprintf(stderr, "END: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER\n"); + fclose(fp); return true; } /* ReadMessage() if initiator: <- e, ee, se */ else if(noise_handshake->initiator) { + fprintf(fp, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE => INITIATOR\n"); + fprintf(stderr, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE => INITIATOR\n"); /* Responder: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] @@ -1026,13 +1163,23 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + + fprintf(fp, "END: handle_crypto_handshake() => NOISE HANDSHAKE => INITIATOR\n"); + fprintf(stderr, "END: handle_crypto_handshake() => NOISE HANDSHAKE => INITIATOR\n"); + fclose(fp); return true; } else { return false; } } - + // old handshake + //TODO: is this called? else { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: handle_crypto_handshake() => OLD HANDSHAKE\n"); + fprintf(stderr, "ENTERING: handle_crypto_handshake() => OLD HANDSHAKE\n"); + fclose(fp); if (length != HANDSHAKE_PACKET_LENGTH) { return false; } @@ -1770,7 +1917,9 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ //TODO: enable backwards compatiblity // const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); //TODO: add ad? - const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), length + CRYPTO_MAC_SIZE, nullptr, 0); + //TODO: correct call? + // const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), length + CRYPTO_MAC_SIZE, nullptr, 0); + const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); if (len + 1 + sizeof(uint16_t) != packet_size) { LOGGER_ERROR(c->log, "encryption failed: %d", len); @@ -1950,8 +2099,11 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint // const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), // length - (1 + sizeof(uint16_t)), data); //TODO: add ad? + //TODO: correct call? + // const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, + // length - length - (1 + sizeof(uint16_t)) - CRYPTO_MAC_SIZE, nullptr, 0); const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, - length - length - (1 + sizeof(uint16_t)) - CRYPTO_MAC_SIZE, nullptr, 0); + nullptr, 0); if ((unsigned int)len != length - crypto_packet_overhead) { return -1; @@ -2429,7 +2581,6 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, fprintf(stderr, "ENTERING: handle_packet_cookie_response(); PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d\n", packet[0], conn->status); - fclose(fp); if (conn == nullptr) { return -1; @@ -2452,6 +2603,8 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { + fprintf(fp, "handle_packet_cookie_response() => INITIATOR -> NEW Handshake\n"); + fprintf(stderr, "handle_packet_cookie_response() => INITIATOR -> NEW Handshake\n"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } @@ -2460,11 +2613,15 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } } else { // old handshake + fprintf(fp, "handle_packet_cookie_response() => OLD Handshake\n"); + fprintf(stderr, "handle_packet_cookie_response() => OLD Handshake\n"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } } + fclose(fp); + conn->status = CRYPTO_CONN_HANDSHAKE_SENT; return 0; } @@ -2484,7 +2641,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const fprintf(stderr, "ENTERING: handle_packet_crypto_hs(); PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d\n", packet[0], conn->status); - fclose(fp); if (conn == nullptr) { return -1; @@ -2500,7 +2656,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t cookie[COOKIE_LENGTH]; + //TODO: There should also be a case for RESPONDER? if (conn->noise_handshake != nullptr) { + fprintf(fp, "handle_packet_crypto_hs() => NOISE HANDHSHAKE\n"); + fprintf(stderr, "handle_packet_crypto_hs() => NOISE HANDHSHAKE\n"); if (conn->noise_handshake->initiator) { if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, conn->noise_handshake)) { @@ -2515,13 +2674,15 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } // old handshake else { + fprintf(fp, "handle_packet_crypto_hs() => OLD HANDHSHAKE\n"); + fprintf(stderr, "handle_packet_crypto_hs() => OLD HANDHSHAKE\n"); if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, nullptr)) { return -1; } } - //TODO: adapt? + //TODO: adapt? if (pk_equal(dht_public_key, conn->dht_public_key)) { encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); @@ -2538,6 +2699,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } + fclose(fp); + return 0; } @@ -2682,9 +2845,6 @@ static int create_crypto_connection(Net_Crypto *c) pthread_mutex_unlock(&c->connections_mutex); return -1; } - - //TODO: calloc noise handshake? or in realloc_cryptoconnection()? - c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; } @@ -2836,6 +2996,15 @@ static int noise_handshake_init memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + fprintf(fp, "noise_handshake_init() => noise_mix_hash() INITIATOR\n"); + int i; + fprintf(fp, "Handshake hash: "); + for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", noise_handshake->hash[i]); + } + fprintf(fp, "\n"); fprintf(fp, "Noise_handshake_init() => INITIATOR keys set\n"); fprintf(stderr, "Noise_handshake_init() => INITIATOR keys set\n"); } else { @@ -2848,6 +3017,15 @@ static int noise_handshake_init // crypto_derive_public_key(noise_handshake->static_public, self_secret_key); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + fprintf(fp, "noise_handshake_init() => noise_mix_hash() RESPONDER\n"); + int i; + fprintf(fp, "Handshake hash: "); + for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", noise_handshake->hash[i]); + } + fprintf(fp, "\n"); fprintf(fp, "noise_handshake_init() => RESPONDER keys set\n"); fprintf(stderr, "noise_handshake_init() => RESPONDER keys set\n"); } else { @@ -2913,6 +3091,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, fprintf(fp, "handle_new_connection_handshake() => After Handshake init\n"); fprintf(stderr, "handle_new_connection_handshake() => After Handshake init\n"); + fclose(fp); if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { @@ -3002,8 +3181,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); free(n_c.cookie); - fclose(fp); - return ret; } @@ -3129,7 +3306,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { FILE *fp; - fp = fopen ("data.log", "a"); + fp = fopen ("data.log", "a"); fprintf(fp, "ENTERING: new_crypto_connection()\n"); fprintf(stderr, "ENTERING: new_crypto_connection()\n"); @@ -3576,6 +3753,11 @@ non_null(1, 2, 3) nullable(5) static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { + FILE *fp; + fp = fopen ("data.log", "a"); + fprintf(fp, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); + fprintf(stderr, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); + Net_Crypto *c = (Net_Crypto *)object; if (length <= CRYPTO_MIN_PACKET_SIZE || length > MAX_CRYPTO_PACKET_SIZE) { @@ -3584,10 +3766,13 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t const int crypt_connection_id = crypto_id_ip_port(c, source); + // No crypto connection yet = RESPONDER case if (crypt_connection_id == -1) { if (packet[0] != NET_PACKET_CRYPTO_HS) { return 1; } + fprintf(fp, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); + fprintf(stderr, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); if (handle_new_connection_handshake(c, source, packet, length, userdata) != 0) { return 1; @@ -3596,6 +3781,10 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t return 0; } + //TODO: return -1 if RESPONDER? + + fprintf(fp, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); + fprintf(stderr, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); if (handle_packet_connection(c, crypt_connection_id, packet, length, true, userdata) != 0) { return 1; } @@ -3615,6 +3804,9 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t } pthread_mutex_unlock(conn->mutex); + + fclose(fp); + return 0; } diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 6228edd399..1749504cb7 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -85,7 +85,7 @@ #define MAX_CRYPTO_DATA_SIZE (uint16_t)(MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE) /** Interval in ms between sending cookie request/handshake packets. */ -#define CRYPTO_SEND_PACKET_INTERVAL 2000 +#define CRYPTO_SEND_PACKET_INTERVAL 1000 /** * The maximum number of times we try to send the cookie request and handshake From a06a1153e2c92a4823f7eef60d25cd664279893f Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Thu, 29 Jun 2023 18:09:44 +0200 Subject: [PATCH 012/150] NoiseIK handshake and NoiseIK transport encryption working. One CRYPTO_NONCE_SIZE was missing in NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, therefore 24 bytes were missing in actual sent handshake packet => fixed encryption/decryption during handshake. Changed encrypted_length/plaintext_length to unsigned long long to remove compiler warning. Added some logging/debugging code. Fixed a SegFault in send_temp_packet() due to my crappy logging/debugging code. --- toxcore/crypto_core.c | 4 +-- toxcore/net_crypto.c | 84 ++++++++++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index ebcec62a49..c1a6d1cd1e 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -295,7 +295,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no return -1; } - size_t encrypted_length = 0; + unsigned long long encrypted_length = 0; // nsec is not used by this particular construction and should always be NULL. if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, @@ -338,7 +338,7 @@ size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no // return -1; // } - size_t plain_length = 0; + unsigned long long plain_length = 0; if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, NULL, encrypted, encrypted_length, ad, ad_length, nonce, shared_key) != 0) { diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 30a8c2cb6c..6ceeaf5bcf 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -509,7 +509,7 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) // Necessary for Noise -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) // Implements MixKey(input_key_material) static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], @@ -552,14 +552,14 @@ static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext fp = fopen ("data.log", "a"); fprintf(fp, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); int i; - fprintf(fp, "Nonce: "); + fprintf(fp, "noise_encrypt_and_hash() => Nonce: "); for (i = 0; i < CRYPTO_NONCE_SIZE; i++) { if (i > 0) fprintf(fp, ":"); fprintf(fp, "%02X", nonce[i]); } fprintf(fp, "\n"); - fprintf(fp, "Shared Key: "); + fprintf(fp, "noise_encrypt_and_hash() => Shared Key: "); for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) { if (i > 0) fprintf(fp, ":"); @@ -572,10 +572,17 @@ static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext // plaintext, plain_length, ciphertext, // encrypted_length, hash, CRYPTO_SHA512_SIZE); // fprintf(fp, "noise_encrypt_and_hash() => encrypted_length: %d\n", encrypted_length); - size_t encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, + unsigned long long encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, plaintext, plain_length, ciphertext, hash, CRYPTO_SHA512_SIZE); fprintf(fp, "noise_encrypt_and_hash() => encrypted_length: %d\n", encrypted_length); + fprintf(fp, "noise_encrypt_and_hash() => Ciphertext: "); + for (i = 0; i < encrypted_length; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", ciphertext[i]); + } + fprintf(fp, "\n"); noise_mix_hash(hash, ciphertext, encrypted_length); fclose(fp); } @@ -589,27 +596,34 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, //TODO: Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext fprintf(fp, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); int i; - fprintf(fp, "Nonce: "); + fprintf(fp, "noise_decrypt_and_hash() => Nonce: "); for (i = 0; i < CRYPTO_NONCE_SIZE; i++) { if (i > 0) fprintf(fp, ":"); fprintf(fp, "%02X", nonce[i]); } fprintf(fp, "\n"); - fprintf(fp, "Shared Key: "); + fprintf(fp, "noise_decrypt_and_hash() => Shared Key: "); for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) { if (i > 0) fprintf(fp, ":"); fprintf(fp, "%02X", shared_key[i]); } fprintf(fp, "\n"); + fprintf(fp, "noise_decrypt_and_hash() => Ciphertext (length: %d): ", encrypted_length); + for (i = 0; i < encrypted_length; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", ciphertext[i]); + } + fprintf(fp, "\n"); fprintf(stderr, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); // size_t plaintext_length = 0; // decrypt_data_symmetric_xaead(shared_key, nonce, // ciphertext, encrypted_length, plaintext, // plaintext_length, hash, CRYPTO_SHA512_SIZE); // fprintf(fp, "noise_decrypt_and_hash() => plaintext_length: %d\n", plaintext_length); - size_t plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, + unsigned long long plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, ciphertext, encrypted_length, plaintext, hash, CRYPTO_SHA512_SIZE); fprintf(fp, "noise_decrypt_and_hash() => plaintext_length: %d\n", plaintext_length); @@ -690,9 +704,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* s */ // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - // fprintf(fp, "create_crypto_handshake() => NOISE HANDSHAKE => INITIATOR => NONCE1: %s, Handshake Key1: %s\n", packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key); - // fprintf(stderr, "create_crypto_handshake() => NOISE HANDSHAKE => INITIATOR => NONCE1: %s, Handshake Key1: %s\n", packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key); - //TODO: encryption and decryption ok noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); fprintf(fp, "hash2 INITIATOR: "); @@ -722,16 +733,31 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // Add Handshake payload nonce random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - // fprintf(fp, "create_crypto_handshake() => NOISE HANDSHAKE => INITIATOR => NONCE2: %s, Handshake Key2: %s\n", packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key); - // fprintf(stderr, "create_crypto_handshake() => NOISE HANDSHAKE => INITIATOR => NONCE2: %s, Handshake Key2: %s\n", packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key); - //TODO: decryption fails => same nonce, key and hash what is the Problem here? + noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + fprintf(fp, "AFTER noise_encrypt_and_hash()"); + fprintf(fp, "AFTER noise_encrypt_and_hash() => Ciphertext: "); + for (i = 0; i < (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE); i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE)[i]); + } + fprintf(fp, "\n"); + packet[0] = NET_PACKET_CRYPTO_HS; memcpy(packet + 1, cookie, COOKIE_LENGTH); + fprintf(fp, "INITIATOR WHOLE HANDSHAKE PACKET: "); + for (i = 0; i < NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", packet[i]); + } + fprintf(fp, "\n"); + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); fclose(fp); @@ -1032,7 +1058,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - //TODO: is this correct? => should be, if correct set in packet-creating function uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); @@ -1056,10 +1081,18 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [MAC 16 bytes] */ + fprintf(fp, "RESPONDER WHOLE HANDSHAKE PACKET: "); + int i; + for (i = 0; i < NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; i++) + { + if (i > 0) fprintf(fp, ":"); + fprintf(fp, "%02X", packet[i]); + } + fprintf(fp, "\n"); + /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - int i; fprintf(fp, "hash1 RESPONDER: "); for (i = 0; i < CRYPTO_SHA512_SIZE; i++) { @@ -1074,8 +1107,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* s */ // Nonces contained in packet! memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - // fprintf(fp, "handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => NONCE1: %s, Handshake Key1: %s\n", nonce, noise_handshake_temp_key); - // fprintf(stderr, "handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => NONCE1: %s, Handshake Key1: %s\n", nonce, noise_handshake_temp_key); + noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce); fprintf(fp, "hash2 RESPONDER: "); @@ -1089,18 +1121,15 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + // get Handshake payload nonce memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); - // fprintf(fp, "handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => NONCE2: %s, Handshake Key2: %s\n", nonce, noise_handshake_temp_key); - // fprintf(stderr, "handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => NONCE2: %s, Handshake Key2: %s\n", nonce, noise_handshake_temp_key); - //TODO: Error handling - //TODO: currently fails, but same key+nonce+hash => decrypt func should be ok (otherwise first dec would fail), so where is the problem here? + //TODO: Error handling? noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce); crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - //TODO: currently this fails => decryption fails if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { fprintf(fp, "ERROR: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => COOKIE HASH WRONG\n"); fprintf(stderr, "ERROR: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => COOKIE HASH WRONG\n"); @@ -1173,7 +1202,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } } // old handshake - //TODO: is this called? else { FILE *fp; fp = fopen ("data.log", "a"); @@ -1916,9 +1944,8 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ //TODO: need information in crypto conn if this is a Noise connection! //TODO: enable backwards compatiblity // const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + //TODO: add ad? - //TODO: correct call? - // const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), length + CRYPTO_MAC_SIZE, nullptr, 0); const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); if (len + 1 + sizeof(uint16_t) != packet_size) { @@ -2098,10 +2125,8 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint //TODO: enable backwards compatiblity // const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), // length - (1 + sizeof(uint16_t)), data); + //TODO: add ad? - //TODO: correct call? - // const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, - // length - length - (1 + sizeof(uint16_t)) - CRYPTO_MAC_SIZE, nullptr, 0); const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, nullptr, 0); @@ -2274,18 +2299,21 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) if (conn == nullptr) { fprintf(fp, "send_temp_packet() => conn == nullptr\n"); fprintf(stderr, "send_temp_packet() => conn == nullptr\n"); + fclose(fp); return -1; } if (conn->temp_packet == nullptr) { fprintf(fp, "send_temp_packet() => temp_packet == nullptr\n"); fprintf(stderr, "send_temp_packet() => temp_packet == nullptr\n"); + fclose(fp); return -1; } if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0) { fprintf(fp, "send_temp_packet() => send_packet_to() => Error case\n"); fprintf(stderr, "send_temp_packet() => send_packet_to() => Error case\n"); + fclose(fp); return -1; } From d4184c5a026283a2fe1bff177fcf56edad5b34f0 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 30 Jun 2023 17:08:52 +0200 Subject: [PATCH 013/150] Cleaned up logging/debugging code. Switched to Tox logger. --- toxcore/net_crypto.c | 588 ++++++++++++++++++------------------------- 1 file changed, 246 insertions(+), 342 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 6ceeaf5bcf..4645b5e66b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -234,10 +234,7 @@ non_null() static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uint8_t *dht_public_key, uint64_t number, uint8_t *shared_key) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: create_cookie_request()\n"); - fprintf(stderr, "ENTERING: create_cookie_request()\n"); + LOGGER_DEBUG(c->log, "ENTERING: create_cookie_request()"); uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t padding[CRYPTO_PUBLIC_KEY_SIZE] = {0}; @@ -257,10 +254,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) { return -1; } - - fprintf(fp, "END: create_cookie_request()\n"); - fprintf(stderr, "END: create_cookie_request()\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "END: create_cookie_request()"); return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len; } @@ -328,11 +322,7 @@ non_null() static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain, const uint8_t *shared_key, const uint8_t *dht_public_key) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: create_cookie_response()\n"); - fprintf(stderr, "ENTERING: create_cookie_response()\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "ENTERING: create_cookie_response()"); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; memcpy(cookie_plain, request_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -365,11 +355,7 @@ non_null() static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_cookie_request()\n"); - fprintf(stderr, "ENTERING: handle_cookie_request()\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "ENTERING: handle_cookie_request()"); if (length != COOKIE_REQUEST_LENGTH) { return -1; } @@ -393,11 +379,13 @@ non_null(1, 2, 3) nullable(5) static int udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: udp_handle_cookie_request()\n"); - fprintf(stderr, "ENTERING: udp_handle_cookie_request()\n"); - fclose(fp); + //TODO: add logger? + // LOGGER_DEBUG(c->log, "ENTERING: udp_handle_cookie_request()"); + // FILE *fp; + // fp = fopen ("data.log", "a"); + // fprintf(fp, "ENTERING: udp_handle_cookie_request()\n"); + // fprintf(stderr, "ENTERING: udp_handle_cookie_request()\n"); + // fclose(fp); const Net_Crypto *c = (const Net_Crypto *)object; uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; @@ -426,6 +414,7 @@ non_null() static int tcp_handle_cookie_request(const Net_Crypto *c, int connections_number, const uint8_t *packet, uint16_t length) { + LOGGER_DEBUG(c->log, "ENTERING: tcp_handle_cookie_request()"); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -449,6 +438,7 @@ non_null() static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { + LOGGER_DEBUG(c->log, "ENTERING: tcp_oob_handle_cookie_request()"); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t dht_public_key_temp[CRYPTO_PUBLIC_KEY_SIZE]; @@ -484,11 +474,12 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8_t *packet, uint16_t length, const uint8_t *shared_key) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_cookie_response()\n"); - fprintf(stderr, "ENTERING: handle_cookie_response()\n"); - fclose(fp); + //TODO: add logger? + // FILE *fp; + // fp = fopen ("data.log", "a"); + // fprintf(fp, "ENTERING: handle_cookie_response()\n"); + // fprintf(stderr, "ENTERING: handle_cookie_response()\n"); + // fclose(fp); if (length != COOKIE_RESPONSE_LENGTH) { return -1; @@ -532,10 +523,11 @@ static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], // MixHash(data) as defined in Noise spec static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "noise_mix_hash() => NOISE HANDSHAKE\n"); - fclose(fp); + //TODO: add logger? + // FILE *fp; + // fp = fopen ("data.log", "a"); + // fprintf(fp, "noise_mix_hash() => NOISE HANDSHAKE\n"); + // fclose(fp); uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); @@ -548,99 +540,113 @@ static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { //TODO: Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext. TODO: does that even happen? - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); - int i; - fprintf(fp, "noise_encrypt_and_hash() => Nonce: "); - for (i = 0; i < CRYPTO_NONCE_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", nonce[i]); - } - fprintf(fp, "\n"); - fprintf(fp, "noise_encrypt_and_hash() => Shared Key: "); - for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", shared_key[i]); - } - fprintf(fp, "\n"); - fprintf(stderr, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); - // size_t encrypted_length = 0; - // encrypt_data_symmetric_xaead(shared_key, nonce, - // plaintext, plain_length, ciphertext, - // encrypted_length, hash, CRYPTO_SHA512_SIZE); - // fprintf(fp, "noise_encrypt_and_hash() => encrypted_length: %d\n", encrypted_length); + //TODO: add logger as parameter? + // FILE *fp; + // fp = fopen ("data.log", "a"); + // fprintf(fp, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); + // int i; + // fprintf(fp, "noise_encrypt_and_hash() => Nonce: "); + // for (i = 0; i < CRYPTO_NONCE_SIZE; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", nonce[i]); + // } + // fprintf(fp, "\n"); + // fprintf(fp, "noise_encrypt_and_hash() => Shared Key: "); + // for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", shared_key[i]); + // } + // fprintf(fp, "\n"); + // fprintf(stderr, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); unsigned long long encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, plaintext, plain_length, ciphertext, hash, CRYPTO_SHA512_SIZE); - fprintf(fp, "noise_encrypt_and_hash() => encrypted_length: %d\n", encrypted_length); - fprintf(fp, "noise_encrypt_and_hash() => Ciphertext: "); - for (i = 0; i < encrypted_length; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", ciphertext[i]); - } - fprintf(fp, "\n"); + // fprintf(fp, "noise_encrypt_and_hash() => encrypted_length: %d\n", encrypted_length); + // fprintf(fp, "noise_encrypt_and_hash() => Ciphertext: "); + // for (i = 0; i < encrypted_length; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", ciphertext[i]); + // } + // fprintf(fp, "\n"); + // fclose(fp); noise_mix_hash(hash, ciphertext, encrypted_length); - fclose(fp); } static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { - FILE *fp; - fp = fopen ("data.log", "a"); + //TODO: add logger as parameter? + // FILE *fp; + // fp = fopen ("data.log", "a"); + // fprintf(fp, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); + // int i; + // fprintf(fp, "noise_decrypt_and_hash() => Nonce: "); + // for (i = 0; i < CRYPTO_NONCE_SIZE; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", nonce[i]); + // } + // fprintf(fp, "\n"); + // fprintf(fp, "noise_decrypt_and_hash() => Shared Key: "); + // for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", shared_key[i]); + // } + // fprintf(fp, "\n"); + // fprintf(fp, "noise_decrypt_and_hash() => Ciphertext (length: %d): ", encrypted_length); + // for (i = 0; i < encrypted_length; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", ciphertext[i]); + // } + // fprintf(fp, "\n"); + // fprintf(stderr, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); //TODO: Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext - fprintf(fp, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); - int i; - fprintf(fp, "noise_decrypt_and_hash() => Nonce: "); - for (i = 0; i < CRYPTO_NONCE_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", nonce[i]); - } - fprintf(fp, "\n"); - fprintf(fp, "noise_decrypt_and_hash() => Shared Key: "); - for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", shared_key[i]); - } - fprintf(fp, "\n"); - fprintf(fp, "noise_decrypt_and_hash() => Ciphertext (length: %d): ", encrypted_length); - for (i = 0; i < encrypted_length; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", ciphertext[i]); - } - fprintf(fp, "\n"); - fprintf(stderr, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); - // size_t plaintext_length = 0; - // decrypt_data_symmetric_xaead(shared_key, nonce, - // ciphertext, encrypted_length, plaintext, - // plaintext_length, hash, CRYPTO_SHA512_SIZE); - // fprintf(fp, "noise_decrypt_and_hash() => plaintext_length: %d\n", plaintext_length); unsigned long long plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, ciphertext, encrypted_length, plaintext, hash, CRYPTO_SHA512_SIZE); - fprintf(fp, "noise_decrypt_and_hash() => plaintext_length: %d\n", plaintext_length); - if (plaintext_length != (encrypted_length - CRYPTO_MAC_SIZE)) - { - fprintf(fp, "noise_decrypt_and_hash() => decryption FAILED\n"); - fprintf(stderr, "noise_decrypt_and_hash() => decryption FAILED\n"); - fclose(fp); - return -1; - } + // fprintf(fp, "noise_decrypt_and_hash() => plaintext_length: %d\n", plaintext_length); + // if (plaintext_length != (encrypted_length - CRYPTO_MAC_SIZE)) + // { + // fprintf(fp, "noise_decrypt_and_hash() => decryption FAILED\n"); + // fprintf(stderr, "noise_decrypt_and_hash() => decryption FAILED\n"); + // fclose(fp); + // return -1; + // } noise_mix_hash(hash, ciphertext, encrypted_length); - fprintf(fp, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); - fprintf(stderr, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); - fclose(fp); + // fprintf(fp, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); + // fprintf(stderr, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); + // fclose(fp); return 0; } +//TODO: helper function, TODO: remove from production code +static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, size_t bytes_size, const Logger *log) +{ + LOGGER_DEBUG(log, "string_size: %d", string_size); + LOGGER_DEBUG(log, "bytes_size: %d", bytes_size); + int i; + uint8_t *log_buf = string; + uint8_t *log_buf_endofbuf = log_buf + string_size; + for (i = 0; i < bytes_size; i++) { + /* i use 4 here since we are going to add at most + 3 chars, need a space for a null terminator */ + if (log_buf + 4 < log_buf_endofbuf) { + if (i > 0) { + log_buf += sprintf(log_buf, ":"); + } + log_buf += sprintf(log_buf, "%02X", bytes[i]); + } + } + LOGGER_DEBUG(log, "i after for: %d, %d", i); + LOGGER_DEBUG(log, "log_buf after for: %s", log_buf); +} + /** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. * @param cookie must be COOKIE_LENGTH bytes. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. @@ -652,17 +658,10 @@ non_null() static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: create_crypto_handshake()\n"); - fprintf(stderr, "ENTERING: create_crypto_handshake()\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); // Noise-based handshake if (noise_handshake != nullptr) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: create_crypto_handshake() => NOISE HANDSHAKE\n"); - fprintf(stderr, "ENTERING: create_crypto_handshake() => NOISE HANDSHAKE\n"); + LOGGER_DEBUG(c->log, "NOISE HANDSHAKE"); /* Initiator: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] @@ -689,14 +688,12 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* e */ memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - int i; - fprintf(fp, "hash1 INITIATOR: "); - for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", noise_handshake->hash[i]); - } - fprintf(fp, "\n"); + + //TODO: remove from production code + uint8_t log_hash1[CRYPTO_SHA512_SIZE*3+1]; + bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); + /* es */ //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; @@ -706,13 +703,12 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - fprintf(fp, "hash2 INITIATOR: "); - for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", noise_handshake->hash[i]); - } - fprintf(fp, "\n"); + + //TODO: remove from production code + uint8_t log_hash2[CRYPTO_SHA512_SIZE*3+1]; + bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); + /* ss */ noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); @@ -738,30 +734,36 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - fprintf(fp, "AFTER noise_encrypt_and_hash()"); - fprintf(fp, "AFTER noise_encrypt_and_hash() => Ciphertext: "); - for (i = 0; i < (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE); i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE)[i]); - } - fprintf(fp, "\n"); + LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); + //TODO: remove from production code + uint8_t log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*3+1]; + bytes2string(log_ciphertext, sizeof(log_ciphertext), (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE), + (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); + LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); packet[0] = NET_PACKET_CRYPTO_HS; memcpy(packet + 1, cookie, COOKIE_LENGTH); - fprintf(fp, "INITIATOR WHOLE HANDSHAKE PACKET: "); - for (i = 0; i < NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", packet[i]); - } - fprintf(fp, "\n"); + //TODO: remove from production code, TODO: not printing everything -> LOGGER_DEBUG() limited to 749 bytes? + uint8_t log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; + bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); + LOGGER_DEBUG(c->log, "Handshake Packet INITIATOR: %s", log_packet); + //fprintf(stderr, "Handshake Packet INITIATOR: %s", log_packet); + + //TODO: remove + // FILE *fp; + // fp = fopen("data.log", "a"); + // fprintf(fp, "Handshake Packet Initiator: "); + // for (int i = 0; i < NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", packet[i]); + // } + // fprintf(fp, "\n"); + // fclose(fp); crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - fclose(fp); - return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* <- e, ee, se */ @@ -821,8 +823,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - fclose(fp); - return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } else { @@ -1025,16 +1025,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, noise_handshake *noise_handshake) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_crypto_handshake()\n"); - fprintf(stderr, "ENTERING: handle_crypto_handshake()\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "ENTERING: handle_crypto_handshake()"); if (noise_handshake != nullptr) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE\n"); - fprintf(stderr, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE\n"); + LOGGER_DEBUG(c->log, "NOISE handshake"); if (!noise_handshake->initiator) { if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { @@ -1063,8 +1056,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* -> e, es, s, ss */ if(!noise_handshake->initiator) { - fprintf(fp, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER\n"); - fprintf(stderr, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER\n"); + LOGGER_DEBUG(c->log, "NOISE handshake => RESPONDER"); /* Initiator: Handshake packet structure => THIS IS HANDLED HERE [uint8_t 26] [Cookie 112 bytes] @@ -1080,26 +1072,31 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC 16 bytes] */ - - fprintf(fp, "RESPONDER WHOLE HANDSHAKE PACKET: "); - int i; - for (i = 0; i < NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", packet[i]); - } - fprintf(fp, "\n"); + //TODO: remove from production code, TODO: not printing everything -> LOGGER_DEBUG() limited to 1076 bytes? + uint8_t log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; + bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); + LOGGER_DEBUG(c->log, "Handshake Packet Initiator (received by RESPONDER): %s", log_packet); + + //TODO: remove + // FILE *fp; + // fp = fopen("data.log", "a"); + // fprintf(fp, "Handshake Packet Initiator (received by RESPONDER): "); + // for (int i = 0; i < NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", packet[i]); + // } + // fprintf(fp, "\n"); + // fclose(fp); /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - fprintf(fp, "hash1 RESPONDER: "); - for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", noise_handshake->hash[i]); - } - fprintf(fp, "\n"); + //TODO: remove from production code + uint8_t log_hash1[CRYPTO_SHA512_SIZE*3+1]; + bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); + /* es */ //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; @@ -1110,13 +1107,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce); - fprintf(fp, "hash2 RESPONDER: "); - for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", noise_handshake->hash[i]); - } - fprintf(fp, "\n"); + //TODO: remove from production code + uint8_t log_hash2[CRYPTO_SHA512_SIZE*3+1]; + bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); + /* ss */ noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ @@ -1131,9 +1126,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { - fprintf(fp, "ERROR: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => COOKIE HASH WRONG\n"); - fprintf(stderr, "ERROR: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER => COOKIE HASH WRONG\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "NOISE handshake => RESPONDER => COOKIE HASH WRONG"); return false; } @@ -1143,16 +1136,13 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - fprintf(fp, "END: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER\n"); - fprintf(stderr, "END: handle_crypto_handshake() => NOISE HANDSHAKE => RESPONDER\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "END NOISE handshake => RESPONDER"); return true; } /* ReadMessage() if initiator: <- e, ee, se */ else if(noise_handshake->initiator) { - fprintf(fp, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE => INITIATOR\n"); - fprintf(stderr, "ENTERING: handle_crypto_handshake() => NOISE HANDSHAKE => INITIATOR\n"); + LOGGER_DEBUG(c->log, "ENTERING NOISE handshake => INITIATOR"); /* Responder: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] @@ -1193,9 +1183,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - fprintf(fp, "END: handle_crypto_handshake() => NOISE HANDSHAKE => INITIATOR\n"); - fprintf(stderr, "END: handle_crypto_handshake() => NOISE HANDSHAKE => INITIATOR\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "END NOISE handshake => INITIATOR"); return true; } else { return false; @@ -1203,11 +1191,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } // old handshake else { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_crypto_handshake() => OLD HANDSHAKE\n"); - fprintf(stderr, "ENTERING: handle_crypto_handshake() => OLD HANDSHAKE\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "ENTERING: handle_crypto_handshake() => OLD HANDSHAKE"); + if (length != HANDSHAKE_PACKET_LENGTH) { return false; } @@ -1519,10 +1504,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t return -1; } - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: send_packet_to()\n"); - fprintf(stderr, "ENTERING: send_packet_to()\n"); + LOGGER_DEBUG(c->log, "ENTERING: send_packet_to()"); bool direct_send_attempt = false; @@ -1544,8 +1526,6 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t pthread_mutex_unlock(conn->mutex); LOGGER_WARNING(c->log, "sending packet of length %d failed", length); - fprintf(fp, "send_packet_to(); sending packet of length %d failed\n", length); - fprintf(stderr, "send_packet_to(); sending packet of length %d failed\n", length); return -1; } @@ -2290,38 +2270,22 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id) non_null() static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) { - FILE *fp; - fp = fopen("data.log", "a"); - fprintf(fp, "ENTERING: send_temp_packet()\n"); - fprintf(stderr, "ENTERING: send_temp_packet()\n"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { - fprintf(fp, "send_temp_packet() => conn == nullptr\n"); - fprintf(stderr, "send_temp_packet() => conn == nullptr\n"); - fclose(fp); return -1; } if (conn->temp_packet == nullptr) { - fprintf(fp, "send_temp_packet() => temp_packet == nullptr\n"); - fprintf(stderr, "send_temp_packet() => temp_packet == nullptr\n"); - fclose(fp); return -1; } if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0) { - fprintf(fp, "send_temp_packet() => send_packet_to() => Error case\n"); - fprintf(stderr, "send_temp_packet() => send_packet_to() => Error case\n"); - fclose(fp); return -1; } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); ++conn->temp_packet_num_sent; - fprintf(fp, "END: send_temp_packet()\n"); - fprintf(stderr, "END: send_temp_packet()\n"); - fclose(fp); return 0; } @@ -2336,11 +2300,8 @@ non_null() static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: create_send_handshake()\n"); - fprintf(stderr, "ENTERING: create_send_handshake()\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "ENTERING: create_send_handshake()"); + const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -2450,11 +2411,7 @@ non_null(1, 3) nullable(6) static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_data_packet_core(); PACKET: %d\n", packet[0]); - fprintf(stderr, "ENTERING: handle_data_packet_core(); PACKET: %d\n", packet[0]); - fclose(fp); + LOGGER_DEBUG(c->log, "ENTERING: handle_data_packet_core(); PACKET: %d", packet[0]); if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) { return -1; @@ -2601,12 +2558,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_packet_cookie_response(); PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d\n", - packet[0], - conn->status); - fprintf(stderr, "ENTERING: handle_packet_cookie_response(); PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d\n", + LOGGER_DEBUG(c->log, "ENTERING: handle_packet_cookie_response(); PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d", packet[0], conn->status); @@ -2631,8 +2583,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { - fprintf(fp, "handle_packet_cookie_response() => INITIATOR -> NEW Handshake\n"); - fprintf(stderr, "handle_packet_cookie_response() => INITIATOR -> NEW Handshake\n"); + LOGGER_DEBUG(c->log, "handle_packet_cookie_response() => INITIATOR -> NEW Handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } @@ -2641,15 +2592,12 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } } else { // old handshake - fprintf(fp, "handle_packet_cookie_response() => OLD Handshake\n"); - fprintf(stderr, "handle_packet_cookie_response() => OLD Handshake\n"); + LOGGER_DEBUG(c->log, "handle_packet_cookie_response() -> OLD Handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } } - fclose(fp); - conn->status = CRYPTO_CONN_HANDSHAKE_SENT; return 0; } @@ -2660,13 +2608,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const void *userdata) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_packet_crypto_hs(); PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d\n", - packet[0], - conn->status); - fprintf(stderr, "ENTERING: handle_packet_crypto_hs(); PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d\n", + LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_hs(); PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d", packet[0], conn->status); @@ -2686,8 +2628,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: There should also be a case for RESPONDER? if (conn->noise_handshake != nullptr) { - fprintf(fp, "handle_packet_crypto_hs() => NOISE HANDHSHAKE\n"); - fprintf(stderr, "handle_packet_crypto_hs() => NOISE HANDHSHAKE\n"); + LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => NOISE HANDHSHAKE"); if (conn->noise_handshake->initiator) { if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, conn->noise_handshake)) { @@ -2702,8 +2643,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } // old handshake else { - fprintf(fp, "handle_packet_crypto_hs() => OLD HANDHSHAKE\n"); - fprintf(stderr, "handle_packet_crypto_hs() => OLD HANDHSHAKE\n"); + LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => OLD HANDHSHAKE"); if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, nullptr)) { return -1; @@ -2727,8 +2667,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - fclose(fp); - return 0; } @@ -2738,15 +2676,9 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_packet_crypto_data(); PACKET: %d => NET_PACKET_CRYPTO_DATA => CRYPTO CONN STATE: %d\n", + LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_data(); PACKET: %d => NET_PACKET_CRYPTO_DATA => CRYPTO CONN STATE: %d", packet[0], conn->status); - fprintf(stderr, "ENTERING: handle_packet_crypto_data(); PACKET: %d => NET_PACKET_CRYPTO_DATA => CRYPTO CONN STATE: %d\n", - packet[0], - conn->status); - fclose(fp); if (conn == nullptr) { return -1; @@ -2768,11 +2700,7 @@ non_null(1, 3) nullable(6) static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_packet_connection(); PACKET: %d\n", packet[0]); - fprintf(stderr, "ENTERING: handle_packet_connection(); PACKET: %d\n", packet[0]); - fclose(fp); + LOGGER_DEBUG(c->log, "ENTERING: handle_packet_connection(); PACKET: %d", packet[0]); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; @@ -2994,10 +2922,11 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, static int noise_handshake_init (struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: noise_handshake_init()\n"); - fprintf(stderr, "ENTERING: noise_handshake_init()\n"); + //TODO: add Logger? + // FILE *fp; + // fp = fopen ("data.log", "a"); + // fprintf(fp, "ENTERING: noise_handshake_init()\n"); + // fprintf(stderr, "ENTERING: noise_handshake_init()\n"); //TODO: ? memset(handshake, 0, sizeof(*handshake)); // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h @@ -3015,7 +2944,6 @@ static int noise_handshake_init crypto_derive_public_key(noise_handshake->static_public, self_secret_key); } else { fprintf(stderr, "Local static private key required, but not provided.\n"); - fprintf(fp, "Local static private key required, but not provided.\n"); return -1; } /* <- s: pre-message from responder to initiator */ @@ -3024,20 +2952,20 @@ static int noise_handshake_init memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - fprintf(fp, "noise_handshake_init() => noise_mix_hash() INITIATOR\n"); - int i; - fprintf(fp, "Handshake hash: "); - for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", noise_handshake->hash[i]); - } - fprintf(fp, "\n"); - fprintf(fp, "Noise_handshake_init() => INITIATOR keys set\n"); - fprintf(stderr, "Noise_handshake_init() => INITIATOR keys set\n"); + //TODO: add logger? + // fprintf(fp, "noise_handshake_init() => noise_mix_hash() INITIATOR\n"); + // int i; + // fprintf(fp, "Handshake hash: "); + // for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", noise_handshake->hash[i]); + // } + // fprintf(fp, "\n"); + // fprintf(fp, "Noise_handshake_init() => INITIATOR keys set\n"); + // fprintf(stderr, "Noise_handshake_init() => INITIATOR keys set\n"); } else { fprintf(stderr, "Remote peer static public key required, but not provided.\n"); - fprintf(fp, "Remote peer static public key required, but not provided.\n"); return -1; } } else if (!initiator) { @@ -3045,22 +2973,23 @@ static int noise_handshake_init // crypto_derive_public_key(noise_handshake->static_public, self_secret_key); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); - fprintf(fp, "noise_handshake_init() => noise_mix_hash() RESPONDER\n"); - int i; - fprintf(fp, "Handshake hash: "); - for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - { - if (i > 0) fprintf(fp, ":"); - fprintf(fp, "%02X", noise_handshake->hash[i]); - } - fprintf(fp, "\n"); - fprintf(fp, "noise_handshake_init() => RESPONDER keys set\n"); - fprintf(stderr, "noise_handshake_init() => RESPONDER keys set\n"); + //TODO: add logger? + // fprintf(fp, "noise_handshake_init() => noise_mix_hash() RESPONDER\n"); + // int i; + // fprintf(fp, "Handshake hash: "); + // for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", noise_handshake->hash[i]); + // } + // fprintf(fp, "\n"); + // fprintf(fp, "noise_handshake_init() => RESPONDER keys set\n"); + // fprintf(stderr, "noise_handshake_init() => RESPONDER keys set\n"); } else { return -1; } - fclose(fp); + // fclose(fp); //TODO: precompute_static_static ? @@ -3092,10 +3021,7 @@ non_null(1, 2, 3) nullable(5) static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, void *userdata) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: handle_new_connection_handshake()\n"); - fprintf(stderr, "ENTERING: handle_new_connection_handshake()\n"); + LOGGER_DEBUG(c->log, "ENTERING: handle_new_connection_handshake()"); New_Connection n_c; n_c.cookie = (uint8_t *)malloc(COOKIE_LENGTH); @@ -3117,9 +3043,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } - fprintf(fp, "handle_new_connection_handshake() => After Handshake init\n"); - fprintf(stderr, "handle_new_connection_handshake() => After Handshake init\n"); - fclose(fp); + LOGGER_DEBUG(c->log, "handle_new_connection_handshake() => After Handshake init"); if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { @@ -3220,11 +3144,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, */ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: accept_crypto_connection()\n"); - fprintf(stderr, "ENTERING: accept_crypto_connection()\n"); - if (getcryptconnection_id(c, n_c->public_key) != -1) { return -1; } @@ -3236,6 +3155,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } + LOGGER_DEBUG(c->log, "ENTERING: accept_crypto_connection()"); + Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; if (n_c->cookie_length != COOKIE_LENGTH) { @@ -3256,8 +3177,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { - fprintf(fp, "ENTERING: accept_crypto_connection() => INITIATOR\n"); - fprintf(stderr, "ENTERING: accept_crypto_connection() => INITIATOR\n"); + LOGGER_DEBUG(c->log, "accept_crypto_connection() => INITIATOR"); conn->noise_handshake = n_c->noise_handshake; // necessary -> TODO: duplicated code necessary? memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -3293,8 +3213,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } // old handshake else { - fprintf(fp, "ENTERING: accept_crypto_connection() => old handshake\n"); - fprintf(stderr, "ENTERING: accept_crypto_connection() => old handshake\n"); + LOGGER_DEBUG(c->log, "accept_crypto_connection() => old handshake"); 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); @@ -3319,8 +3238,6 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->rtt_time = DEFAULT_PING_CONNECTION; crypto_connection_add_source(c, crypt_connection_id, &n_c->source); - fclose(fp); - return crypt_connection_id; } @@ -3332,12 +3249,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) */ //TODO: adapt for Noise int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) -{ - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: new_crypto_connection()\n"); - fprintf(stderr, "ENTERING: new_crypto_connection()\n"); - +{ int crypt_connection_id = getcryptconnection_id(c, real_public_key); if (crypt_connection_id != -1) { @@ -3346,6 +3258,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u crypt_connection_id = create_crypto_connection(c); + LOGGER_DEBUG(c->log, "ENTERING: new_crypto_connection()"); + if (crypt_connection_id == -1) { return -1; } @@ -3384,25 +3298,14 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u wipe_crypto_connection(c, crypt_connection_id); return -1; } - fprintf(fp, "START: new_crypto_connection() noise_handshake_init()\n"); - fprintf(fp, "Handshake size: %d\n", sizeof(conn->noise_handshake)); - fprintf(stderr, "START: new_crypto_connection() noise_handshake_init()\n"); - fprintf(stderr, "Handshake size: %d\n", sizeof(conn->noise_handshake)); - // printf("Handshake size: %d\n", sizeof(conn->noise_handshake)); //TODO: calloc conn->noise_handshake here? conn->noise_handshake = (noise_handshake *)calloc(1, sizeof(noise_handshake)); - fprintf(fp, "Handshake struct size: %d\n", sizeof(noise_handshake)); // only necessary if Cookie request was successful if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); return -1; } - fprintf(fp, "END: new_crypto_connection() noise_handshake_init()\n"); - fprintf(fp, "END: new_crypto_connection()\n"); - fprintf(stderr, "END: new_crypto_connection() noise_handshake_init()\n"); - fprintf(stderr, "END: new_crypto_connection()\n"); - fclose(fp); return crypt_connection_id; } @@ -3781,10 +3684,11 @@ non_null(1, 2, 3) nullable(5) static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - FILE *fp; - fp = fopen ("data.log", "a"); - fprintf(fp, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); - fprintf(stderr, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); + //TODO: add logger? + // FILE *fp; + // fp = fopen ("data.log", "a"); + // fprintf(fp, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); + // fprintf(stderr, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); Net_Crypto *c = (Net_Crypto *)object; @@ -3799,8 +3703,8 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t if (packet[0] != NET_PACKET_CRYPTO_HS) { return 1; } - fprintf(fp, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); - fprintf(stderr, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); + // fprintf(fp, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); + // fprintf(stderr, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); if (handle_new_connection_handshake(c, source, packet, length, userdata) != 0) { return 1; @@ -3811,8 +3715,8 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t //TODO: return -1 if RESPONDER? - fprintf(fp, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); - fprintf(stderr, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); + // fprintf(fp, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); + // fprintf(stderr, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); if (handle_packet_connection(c, crypt_connection_id, packet, length, true, userdata) != 0) { return 1; } @@ -3833,7 +3737,7 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t pthread_mutex_unlock(conn->mutex); - fclose(fp); + // fclose(fp); return 0; } From e084bdbd5e72d36f6befec0586e9e635ee4dfad9 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 3 Jul 2023 15:03:04 +0200 Subject: [PATCH 014/150] Changed buffer of log message from 1024 to 4096 bytes to be able to log whole handshake packet. --- toxcore/logger.c | 3 ++- toxcore/net_crypto.c | 12 ++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/toxcore/logger.c b/toxcore/logger.c index d281a66085..9530476ec4 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -109,7 +109,8 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l #endif // Format message - char msg[1024]; + //TODO: changed from 1024 to 4096 + char msg[4096]; va_list args; va_start(args, format); vsnprintf(msg, sizeof(msg), format, args); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 4645b5e66b..f31ec5fc60 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -628,8 +628,6 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, //TODO: helper function, TODO: remove from production code static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, size_t bytes_size, const Logger *log) { - LOGGER_DEBUG(log, "string_size: %d", string_size); - LOGGER_DEBUG(log, "bytes_size: %d", bytes_size); int i; uint8_t *log_buf = string; uint8_t *log_buf_endofbuf = log_buf + string_size; @@ -643,8 +641,6 @@ static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, log_buf += sprintf(log_buf, "%02X", bytes[i]); } } - LOGGER_DEBUG(log, "i after for: %d, %d", i); - LOGGER_DEBUG(log, "log_buf after for: %s", log_buf); } /** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. @@ -744,10 +740,10 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u packet[0] = NET_PACKET_CRYPTO_HS; memcpy(packet + 1, cookie, COOKIE_LENGTH); - //TODO: remove from production code, TODO: not printing everything -> LOGGER_DEBUG() limited to 749 bytes? + //TODO: remove from production code uint8_t log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); - LOGGER_DEBUG(c->log, "Handshake Packet INITIATOR: %s", log_packet); + LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); //fprintf(stderr, "Handshake Packet INITIATOR: %s", log_packet); //TODO: remove @@ -1072,10 +1068,10 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC 16 bytes] */ - //TODO: remove from production code, TODO: not printing everything -> LOGGER_DEBUG() limited to 1076 bytes? + //TODO: remove from production code uint8_t log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); - LOGGER_DEBUG(c->log, "Handshake Packet Initiator (received by RESPONDER): %s", log_packet); + LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); //TODO: remove // FILE *fp; From f4ab64ef4966a2fc149592eb8688955632d3a3dc Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 3 Jul 2023 19:31:36 +0200 Subject: [PATCH 015/150] Cleaned up comments/TODOs. --- toxcore/net_crypto.c | 403 +++++++------------------------------------ 1 file changed, 66 insertions(+), 337 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index f31ec5fc60..d38f8ebe4c 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -70,8 +70,8 @@ typedef struct Crypto_Connection { // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; - // bool initiator; //TODO: necessary? + // bool initiator; // uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ @@ -234,6 +234,7 @@ non_null() static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uint8_t *dht_public_key, uint64_t number, uint8_t *shared_key) { + //TODO: remove LOGGER_DEBUG(c->log, "ENTERING: create_cookie_request()"); uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t padding[CRYPTO_PUBLIC_KEY_SIZE] = {0}; @@ -254,6 +255,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) { return -1; } + //TODO: remove LOGGER_DEBUG(c->log, "END: create_cookie_request()"); return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len; } @@ -384,7 +386,6 @@ static int udp_handle_cookie_request(void *object, const IP_Port *source, const // FILE *fp; // fp = fopen ("data.log", "a"); // fprintf(fp, "ENTERING: udp_handle_cookie_request()\n"); - // fprintf(stderr, "ENTERING: udp_handle_cookie_request()\n"); // fclose(fp); const Net_Crypto *c = (const Net_Crypto *)object; @@ -478,7 +479,6 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, // FILE *fp; // fp = fopen ("data.log", "a"); // fprintf(fp, "ENTERING: handle_cookie_response()\n"); - // fprintf(stderr, "ENTERING: handle_cookie_response()\n"); // fclose(fp); if (length != COOKIE_RESPONSE_LENGTH) { @@ -498,12 +498,18 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, return COOKIE_LENGTH; } +// Necessary for backwards compatiblity #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) // Necessary for Noise #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -// Implements MixKey(input_key_material) -static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], + +/* +* TODO: Implements MixKey(input_key_material) +* input_key_material = DH_X25519(private, public) +*/ + +static bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) @@ -520,7 +526,9 @@ static bool noise_mix_key_dh(uint8_t chaining_key[CRYPTO_SHA512_SIZE], return true; } -// MixHash(data) as defined in Noise spec +/* +* TODO: MixHash(data) as defined in Noise spec +*/ static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) { //TODO: add logger? @@ -534,12 +542,15 @@ static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); } -// EncryptAndHash(plaintext) as defined in Noise spec +/* +* TODO: EncryptAndHash(plaintext) as defined in Noise spec besides +* "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." +* because this is not the case in Tox. +*/ static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { - //TODO: Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext. TODO: does that even happen? //TODO: add logger as parameter? // FILE *fp; // fp = fopen ("data.log", "a"); @@ -559,7 +570,6 @@ static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext // fprintf(fp, "%02X", shared_key[i]); // } // fprintf(fp, "\n"); - // fprintf(stderr, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); unsigned long long encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, plaintext, plain_length, ciphertext, hash, CRYPTO_SHA512_SIZE); @@ -575,6 +585,11 @@ static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext noise_mix_hash(hash, ciphertext, encrypted_length); } +/* +* TODO: DecryptAndHash(plaintext) as defined in Noise spec besides +* "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." +* because this is not the case in Tox. +*/ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) @@ -605,8 +620,6 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, // fprintf(fp, "%02X", ciphertext[i]); // } // fprintf(fp, "\n"); - // fprintf(stderr, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); - //TODO: Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext unsigned long long plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, ciphertext, encrypted_length, plaintext, hash, CRYPTO_SHA512_SIZE); @@ -614,18 +627,20 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, // if (plaintext_length != (encrypted_length - CRYPTO_MAC_SIZE)) // { // fprintf(fp, "noise_decrypt_and_hash() => decryption FAILED\n"); - // fprintf(stderr, "noise_decrypt_and_hash() => decryption FAILED\n"); // fclose(fp); // return -1; // } noise_mix_hash(hash, ciphertext, encrypted_length); // fprintf(fp, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); - // fprintf(stderr, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); // fclose(fp); return 0; } -//TODO: helper function, TODO: remove from production code +/* +* TODO: helper function to print hashes, keys, packets, etc. +* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? +*/ + static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, size_t bytes_size, const Logger *log) { int i; @@ -691,9 +706,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); /* es */ - //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); + /* s */ // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); @@ -706,7 +721,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); /* ss */ - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Noise Handshake Payload */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; @@ -730,8 +745,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); //TODO: remove from production code + LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); uint8_t log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*3+1]; bytes2string(log_ciphertext, sizeof(log_ciphertext), (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE), (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); @@ -744,7 +759,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u uint8_t log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); - //fprintf(stderr, "Handshake Packet INITIATOR: %s", log_packet); //TODO: remove // FILE *fp; @@ -785,12 +799,12 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* e */ memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + /* ee */ - //TODO: add shared key as param to this function? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); /* se */ - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; @@ -857,147 +871,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u } -// /** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. -// * @param cookie must be COOKIE_LENGTH bytes. -// * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. -// * -// * @retval -1 on failure. -// * @retval HANDSHAKE_PACKET_LENGTH on success. -// */ -// non_null() -// static int noise_create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, -// const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) -// { -// /* Initiator: Handshake packet structure -// [uint8_t 26] -// [Cookie 112 bytes] -// [session public key of the peer (32 bytes)] -// [24 bytes nonce static pub key encryption] -// [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise -// [MAC encrypted static pubkey 16 bytes] -// [24 bytes nonce handshake payload encryption] -// [Encrypted message containing: -// [24 bytes base nonce] => WITH base Nonce -> Nonce patched -// TODO: authenticate Cookie via AD in XAEAD? -// [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] -// [112 bytes Other Cookie (used by the other to respond to the handshake packet)] -// [MAC 16 bytes] -// */ -// /* -> e, es, s, ss */ -// if (noise_handshake->initiator) { -// // static public set in noise_handshake_init() -// // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); -// // set ephemeral private+public -// memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - -// /* e */ -// memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); -// noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); -// /* es */ -// //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? -// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; -// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); -// /* s */ -// // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? -// random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); -// noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, -// noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); -// /* ss */ -// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); - -// /* Noise Handshake Payload */ -// uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; -// memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); -// crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - -// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; -// memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - -// // OtherCookie is added to payload -// if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, -// cookie_plain, c->secret_symmetric_key) != 0) { -// return -1; -// } - -// // Add Handshake payload nonce -// random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); -// noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, -// handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, -// noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - -// packet[0] = NET_PACKET_CRYPTO_HS; -// memcpy(packet + 1, cookie, COOKIE_LENGTH); - -// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - -// return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; -// } -// /* <- e, ee, se */ -// else if (!noise_handshake->initiator) { -// /* Responder: Handshake packet structure -// [uint8_t 26] -// [Cookie 112 bytes] -// [session public key of the peer (32 bytes)] -// [24 bytes nonce handshake payload encryption] -// [Encrypted message containing: -// [24 bytes base nonce] => WITH base Nonce -> Nonce patched -// TODO: authenticate Cookie via AD in XAEAD? -// [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] -// [112 bytes Other Cookie (used by the other to respond to the handshake packet)] -// [MAC 16 bytes] -// */ -// // static public set in noise_handshake_init() -// // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); -// // set ephemeral private+public -// memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - -// /* e */ -// memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); -// noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); -// /* ee */ -// //TODO: add shared key as param to this function? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? -// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; -// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); -// /* se */ -// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); - -// /* Create Noise Handshake Payload */ -// uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; -// memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); -// crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - -// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; -// memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - -// // OtherCookie is added to payload -// if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, -// cookie_plain, c->secret_symmetric_key) != 0) { -// return -1; -// } - -// // Add Handshake payload nonce -// // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? -// random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); -// noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, -// handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, -// noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - -// packet[0] = NET_PACKET_CRYPTO_HS; -// memcpy(packet + 1, cookie, COOKIE_LENGTH); - -// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - -// return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; -// } -// else { -// return -1; -// } -// } - /** TODO: adapt, cf. Noise ReadMessage() @brief Handle a crypto handshake packet of length. * put the nonce contained in the packet in nonce, * the session public key in session_pk @@ -1094,9 +967,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); /* es */ - //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* s */ // Nonces contained in packet! memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); @@ -1109,7 +981,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); /* ss */ - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; // get Handshake payload nonce @@ -1132,6 +1004,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: memzero packet? LOGGER_DEBUG(c->log, "END NOISE handshake => RESPONDER"); return true; } @@ -1154,11 +1027,10 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); /* ee */ - //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); /* se */ - noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* Payload decryption */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); @@ -1230,152 +1102,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } } -/** TODO: adapt, cf. Noise ReadMessage() @brief Handle a crypto handshake packet of length. - * put the nonce contained in the packet in nonce, - * the session public key in session_pk - * the real public key of the peer in peer_real_pk - * the dht public key of the peer in dht_public_key and - * the cookie inside the encrypted part of the packet in cookie. - * - * if expected_real_pk isn't NULL it denotes the real public key - * the packet should be from. - * - * nonce must be at least CRYPTO_NONCE_SIZE - * session_pk must be at least CRYPTO_PUBLIC_KEY_SIZE - * peer_real_pk must be at least CRYPTO_PUBLIC_KEY_SIZE - * cookie must be at least COOKIE_LENGTH - * - * @retval false on failure. - * @retval true on success. - */ -// non_null(1, 2, 3, 4, 5, 6, 7) nullable(9) -// static bool noise_handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, -// uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, -// noise_handshake *noise_handshake) -// { -// if (!noise_handshake->initiator) { -// if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { -// return false; -// } -// } else if (noise_handshake->initiator) { -// if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { -// return false; -// } -// } else { -// return false; -// } - -// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - -// if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { -// return false; -// } - -// if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { -// return false; -// } - -// uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; -// crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); - -// /* -> e, es, s, ss */ -// if(!noise_handshake->initiator) { -// /* Responder: Handshake packet structure -// [uint8_t 26] -// [Cookie 112 bytes] -// [session public key of the peer (32 bytes)] -// [24 bytes nonce handshake payload encryption] -// [Encrypted message containing: -// [24 bytes base nonce] => WITH base Nonce -> Nonce patched -// TODO: authenticate Cookie via AD in XAEAD? -// [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] -// [112 bytes Other Cookie (used by the other to respond to the handshake packet)] -// [MAC 16 bytes] -// */ - -// /* e */ -// memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); -// noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); -// /* es */ -// //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? -// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; -// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); -// /* s */ -// // Nonces contained in packet! -// memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); -// noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, -// noise_handshake_temp_key, noise_handshake->hash, nonce); -// /* ss */ -// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); -// /* Payload decryption */ -// uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; -// memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); -// noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, -// sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, -// noise_handshake->hash, nonce); - -// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - -// if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { -// return false; -// } - -// memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); -// // remote_ephemeral -// memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); -// memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); -// return true; -// } -// /* ReadMessage() if initiator: -// <- e, ee, se */ -// else if(noise_handshake->initiator) { -// /* Responder: Handshake packet structure -// [uint8_t 26] -// [Cookie 112 bytes] -// [session public key of the peer (32 bytes)] -// [24 bytes nonce handshake payload encryption] -// [Encrypted message containing: -// [24 bytes base nonce] => WITH base Nonce -> Nonce patched -// TODO: authenticate Cookie via AD in XAEAD? -// [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] -// [112 bytes Other Cookie (used by the other to respond to the handshake packet)] -// [MAC 16 bytes] -// */ -// memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); -// noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); -// /* ee */ -// //TODO: add shared key as param to THIS FUNCTION? TODO: need shared_key in noise_handshake struct? TODO: just temporal shared_key? fire and forget here? -// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; -// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); -// /* se */ -// noise_mix_key_dh(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); -// /* Payload decryption */ -// uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; -// memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); -// noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, -// sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, -// noise_handshake->hash, nonce); - -// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - -// if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { -// return false; -// } - -// memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); -// // remote_ephemeral -// memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); -// memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); -// return true; -// } else { -// return false; -// } -// } - non_null() static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_connection_id) @@ -1889,9 +1615,8 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array #define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE)) -//TODO: adapt for Noise /** @brief Creates and sends a data packet to the peer using the fastest route. - * + * TODO: adapt for Noise * @retval -1 on failure. * @retval 0 on success. */ @@ -2066,11 +1791,10 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce) #define DATA_NUM_THRESHOLD 21845 -//TODO: adapt for Noise /** @brief Handle a data packet. * Decrypt packet of length and put it into data. * data must be at least MAX_DATA_DATA_PACKET_SIZE big. - * + * TODO: adapt for Noise * @retval -1 on failure. * @return length of data on success. */ @@ -2285,10 +2009,9 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) return 0; } -//TODO: adapt for Noise /** @brief Create a handshake packet and set it as a temp packet. * @param cookie must be COOKIE_LENGTH. - * + * TODO: adapt for Noise * @retval -1 on failure. * @retval 0 on success. */ @@ -2549,7 +2272,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } non_null() -//TODO: adapt for Noise +//TODO: comment for Noise static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2584,6 +2307,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } } else { + //TODO: wipe crypto conn? return -1; } } else { @@ -2599,7 +2323,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } non_null(1, 3) nullable(5) -//TODO: adapt for Noise +//TODO: comment for Noise static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, void *userdata) { @@ -2646,8 +2370,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - //TODO: adapt? + //TODO: adapt? TODO: what's the case for this? if (pk_equal(dht_public_key, conn->dht_public_key)) { + //TODO: is this called? encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { @@ -2672,6 +2397,7 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + //TODO: remove from prod code LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_data(); PACKET: %d => NET_PACKET_CRYPTO_DATA => CRYPTO CONN STATE: %d", packet[0], conn->status); @@ -2696,6 +2422,7 @@ non_null(1, 3) nullable(6) static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { + //TODO: remove from prod code LOGGER_DEBUG(c->log, "ENTERING: handle_packet_connection(); PACKET: %d", packet[0]); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { @@ -2918,11 +2645,10 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, static int noise_handshake_init (struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { - //TODO: add Logger? + //TODO: add Logger? TODO: remove // FILE *fp; // fp = fopen ("data.log", "a"); // fprintf(fp, "ENTERING: noise_handshake_init()\n"); - // fprintf(stderr, "ENTERING: noise_handshake_init()\n"); //TODO: ? memset(handshake, 0, sizeof(*handshake)); // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h @@ -2959,7 +2685,6 @@ static int noise_handshake_init // } // fprintf(fp, "\n"); // fprintf(fp, "Noise_handshake_init() => INITIATOR keys set\n"); - // fprintf(stderr, "Noise_handshake_init() => INITIATOR keys set\n"); } else { fprintf(stderr, "Remote peer static public key required, but not provided.\n"); return -1; @@ -2980,7 +2705,6 @@ static int noise_handshake_init // } // fprintf(fp, "\n"); // fprintf(fp, "noise_handshake_init() => RESPONDER keys set\n"); - // fprintf(stderr, "noise_handshake_init() => RESPONDER keys set\n"); } else { return -1; } @@ -3017,6 +2741,7 @@ non_null(1, 2, 3) nullable(5) static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, void *userdata) { + //TODO: remove LOGGER_DEBUG(c->log, "ENTERING: handle_new_connection_handshake()"); New_Connection n_c; @@ -3039,6 +2764,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } + //TODO: remove LOGGER_DEBUG(c->log, "handle_new_connection_handshake() => After Handshake init"); if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, @@ -3075,7 +2801,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - // encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); crypto_connection_add_source(c, crypt_connection_id, source); @@ -3087,6 +2812,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + //TODO: memzero stuff from old handshake? conn->status = CRYPTO_CONN_NOT_CONFIRMED; free(n_c.cookie); return 0; @@ -3132,9 +2858,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return ret; } -//TODO: adapt for Noise /** @brief Accept a crypto connection. - * + * TODO: adapt for Noise * return -1 on failure. * return connection id on success. */ @@ -3151,6 +2876,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } + //TODO: remove LOGGER_DEBUG(c->log, "ENTERING: accept_crypto_connection()"); Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; @@ -3173,7 +2899,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "accept_crypto_connection() => INITIATOR"); + //TODO: remove + LOGGER_DEBUG(c->log, "accept_crypto_connection() => RESPONDER"); conn->noise_handshake = n_c->noise_handshake; // necessary -> TODO: duplicated code necessary? memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -3197,6 +2924,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // Noise Split(), nonces already set crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + //TODO: memzero stuff from old handshake, also not necessary anymore } else { pthread_mutex_lock(&c->tcp_mutex); @@ -3209,6 +2937,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } // old handshake else { + //TODO: remove LOGGER_DEBUG(c->log, "accept_crypto_connection() => old handshake"); memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE); @@ -3239,11 +2968,10 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) /** @brief Create a crypto connection. * If one to that real public key already exists, return it. - * + * //TODO: adapt for Noise * return -1 on failure. * return connection id on success. */ -//TODO: adapt for Noise int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { int crypt_connection_id = getcryptconnection_id(c, real_public_key); @@ -3254,6 +2982,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u crypt_connection_id = create_crypto_connection(c); + //TODO: remove LOGGER_DEBUG(c->log, "ENTERING: new_crypto_connection()"); if (crypt_connection_id == -1) { @@ -3684,7 +3413,6 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t // FILE *fp; // fp = fopen ("data.log", "a"); // fprintf(fp, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); - // fprintf(stderr, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); Net_Crypto *c = (Net_Crypto *)object; @@ -3699,8 +3427,8 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t if (packet[0] != NET_PACKET_CRYPTO_HS) { return 1; } + //TODO: remove // fprintf(fp, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); - // fprintf(stderr, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); if (handle_new_connection_handshake(c, source, packet, length, userdata) != 0) { return 1; @@ -3711,8 +3439,8 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t //TODO: return -1 if RESPONDER? + //TODO: remove // fprintf(fp, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); - // fprintf(stderr, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); if (handle_packet_connection(c, crypt_connection_id, packet, length, true, userdata) != 0) { return 1; } @@ -3733,6 +3461,7 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t pthread_mutex_unlock(conn->mutex); + //TODO: remove // fclose(fp); return 0; From 350d515f6783baacb86a02a207bc06cb20a8847e Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Thu, 14 Sep 2023 16:31:58 +0200 Subject: [PATCH 016/150] fix/cleanup: Changed noise_handshake in Crypto_Connection and New_Connection structs from being dynamically allocated to statically allocated to fix memory leaks. Minor cleanup in regard to debug logging. --- .gitignore | 3 + toxcore/net_crypto.c | 130 +++++++++++++++++++++++++++++-------------- toxcore/net_crypto.h | 3 +- 3 files changed, 94 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index fc3cc5f733..95f15df1ae 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,9 @@ build/ # VScode .vscode/ +# Tests via Zoff +.localrun/ + # Netbeans nbproject diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index d38f8ebe4c..ac1e81803b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -63,6 +63,7 @@ typedef struct Crypto_Connection { // For Noise //TODO: necessary? + noise_handshake noise_handshake_data; noise_handshake *noise_handshake; uint8_t send_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t recv_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -240,6 +241,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin uint8_t padding[CRYPTO_PUBLIC_KEY_SIZE] = {0}; memcpy(plain, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: "Padding is used to maintain backwards-compatibility with previous versions of the protocol." => can this be removed by now? memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, padding, CRYPTO_PUBLIC_KEY_SIZE); memcpy(plain + (CRYPTO_PUBLIC_KEY_SIZE * 2), &number, sizeof(uint64_t)); const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key); @@ -633,7 +635,7 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, noise_mix_hash(hash, ciphertext, encrypted_length); // fprintf(fp, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); // fclose(fp); - return 0; + return plaintext_length; } /* @@ -644,8 +646,8 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, size_t bytes_size, const Logger *log) { int i; - uint8_t *log_buf = string; - uint8_t *log_buf_endofbuf = log_buf + string_size; + char *log_buf = string; + char *log_buf_endofbuf = log_buf + string_size; for (i = 0; i < bytes_size; i++) { /* i use 4 here since we are going to add at most 3 chars, need a space for a null terminator */ @@ -701,9 +703,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code - uint8_t log_hash1[CRYPTO_SHA512_SIZE*3+1]; - bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); + // char log_hash1[CRYPTO_SHA512_SIZE*3+1]; + // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; @@ -716,9 +718,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code - uint8_t log_hash2[CRYPTO_SHA512_SIZE*3+1]; - bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); + // char log_hash2[CRYPTO_SHA512_SIZE*3+1]; + // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); /* ss */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); @@ -746,19 +748,19 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); //TODO: remove from production code - LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); - uint8_t log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*3+1]; - bytes2string(log_ciphertext, sizeof(log_ciphertext), (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE), - (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); - LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); + // LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); + // char log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*3+1]; + // bytes2string(log_ciphertext, sizeof(log_ciphertext), (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE), + // (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); + // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); packet[0] = NET_PACKET_CRYPTO_HS; memcpy(packet + 1, cookie, COOKIE_LENGTH); //TODO: remove from production code - uint8_t log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; - bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); - LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); + // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; + // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); + // LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); //TODO: remove // FILE *fp; @@ -942,7 +944,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [MAC 16 bytes] */ //TODO: remove from production code - uint8_t log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; + char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); @@ -962,7 +964,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code - uint8_t log_hash1[CRYPTO_SHA512_SIZE*3+1]; + char log_hash1[CRYPTO_SHA512_SIZE*3+1]; bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); @@ -973,10 +975,13 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // Nonces contained in packet! memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - noise_handshake_temp_key, noise_handshake->hash, nonce); + if(noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { + return false; + } + //TODO: remove from production code - uint8_t log_hash2[CRYPTO_SHA512_SIZE*3+1]; + char log_hash2[CRYPTO_SHA512_SIZE*3+1]; bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); @@ -986,10 +991,12 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; // get Handshake payload nonce memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); - //TODO: Error handling? - noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + + if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - noise_handshake->hash, nonce); + noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + return false; + } crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); @@ -1000,6 +1007,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); // remote_ephemeral + //TODO: necessary? memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); @@ -1034,9 +1042,12 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* Payload decryption */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + + if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - noise_handshake->hash, nonce); + noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + return false; + } crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); @@ -1226,6 +1237,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t return -1; } + //TODO: remove LOGGER_DEBUG(c->log, "ENTERING: send_packet_to()"); bool direct_send_attempt = false; @@ -1263,6 +1275,9 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t } } + //TODO: remove + LOGGER_DEBUG(c->log, "send_packet_to() => TCP"); + pthread_mutex_unlock(conn->mutex); pthread_mutex_lock(&c->tcp_mutex); const int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length); @@ -1623,6 +1638,9 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array non_null() static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING: send_data_packet()"); + const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE); if (length == 0 || length > max_length) { @@ -1990,6 +2008,9 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id) non_null() static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) { + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING: send_temp_packet()"); + Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -2237,7 +2258,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data, dt.length, userdata); } - + /* conn might get killed in callback. */ conn = get_crypto_connection(c, crypt_connection_id); @@ -2277,7 +2298,8 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "ENTERING: handle_packet_cookie_response(); PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d", + LOGGER_DEBUG(c->log, "ENTERING: handle_packet_cookie_response(); crypto_connection_id: %d => PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d", + crypt_connection_id, packet[0], conn->status); @@ -2354,9 +2376,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet, length, conn->public_key, conn->noise_handshake)) { return -1; } - // Noise Split(), nonces already set + // Noise Split(), nonces already set in conn crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + // free(conn->noise_handshake); } else { return -1; } @@ -2524,6 +2547,14 @@ static int create_crypto_connection(Net_Crypto *c) pthread_mutex_unlock(&c->connections_mutex); return -1; } + + //TODO: adapt static allocation? + c->crypto_connections[id].noise_handshake = &c->crypto_connections[id].noise_handshake_data; + + if (c->crypto_connections[id].noise_handshake == nullptr) { + return -1; + } + c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; } @@ -2557,6 +2588,8 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); free(c->crypto_connections[crypt_connection_id].mutex); + // crypto_memzero(&c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(noise_handshake)); + // free(c->crypto_connections[crypt_connection_id].noise_handshake); crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); /* check if we can resize the connections array */ @@ -2754,13 +2787,15 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, n_c.source = *source; n_c.cookie_length = COOKIE_LENGTH; - //TODO: calloc n_c.noise_handshake here? - n_c.noise_handshake = (noise_handshake *)calloc(1, sizeof(noise_handshake)); + //TODO: adapt static allocation? + n_c.noise_handshake = &n_c.noise_handshake_data; //TODO: Differention between old and handshake needs to be checked here! if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { - crypto_memzero(n_c.noise_handshake, sizeof(n_c.noise_handshake)); + crypto_memzero(n_c.noise_handshake, sizeof(n_c.noise_handshake_data)); + // free(n_c.noise_handshake); + free(n_c.cookie); return -1; } @@ -2769,6 +2804,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { + crypto_memzero(n_c.noise_handshake, sizeof(n_c.noise_handshake_data)); free(n_c.cookie); return -1; } @@ -2782,6 +2818,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); + //TODO: Unsure which case this is.. if already called new_crypto_connection() as responder before? + //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! if (crypt_connection_id != -1) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2797,6 +2835,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } + //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! + //TODO: there is already something in conn->noise_handshake - need to free in this case! + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + // free(conn->noise_handshake); conn->noise_handshake = n_c.noise_handshake; memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); @@ -2808,9 +2850,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, free(n_c.cookie); return -1; } - // responder: vice-verse keys in comparison to initiator + // responder Noise Split(): vice-verse keys in comparison to initiator crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + // free(conn->noise_handshake); //TODO: memzero stuff from old handshake? conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -2897,6 +2940,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->connection_number_tcp = connection_number_tcp; + //TODO: is this zeroed and freeded memory after handle_new_connection_handshake()?! if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { //TODO: remove @@ -2923,7 +2967,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // Noise Split(), nonces already set crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); //TODO: memzero stuff from old handshake, also not necessary anymore } else { @@ -2983,7 +3027,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u crypt_connection_id = create_crypto_connection(c); //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: new_crypto_connection()"); + LOGGER_DEBUG(c->log, "ENTERING: new_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { return -1; @@ -3024,14 +3068,16 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u return -1; } - //TODO: calloc conn->noise_handshake here? - conn->noise_handshake = (noise_handshake *)calloc(1, sizeof(noise_handshake)); // only necessary if Cookie request was successful if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake)); + crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + // free(conn->noise_handshake); return -1; } + //TODO: remove + LOGGER_DEBUG(c->log, "END: new_crypto_connection()"); + return crypt_connection_id; } @@ -3502,6 +3548,8 @@ static void send_crypto_packets(Net_Crypto *c) } if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING: send_crypto_packets() => call send_temp_packet()"); send_temp_packet(c, i); } diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 1749504cb7..feb9263009 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -143,8 +143,9 @@ typedef struct New_Connection { uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ - noise_handshake *noise_handshake; // Necessary for Noise + noise_handshake noise_handshake_data; + noise_handshake *noise_handshake; // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; From 0d5b81af41a926f2888eb51afe708333eb8e493b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Thu, 14 Sep 2023 16:38:24 +0200 Subject: [PATCH 017/150] cleanup: reduced log amount by removing packet debug logging. --- toxcore/net_crypto.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index ac1e81803b..26dc362972 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -944,9 +944,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [MAC 16 bytes] */ //TODO: remove from production code - char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; - bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); - LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); + // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; + // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); + // LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); //TODO: remove // FILE *fp; @@ -964,9 +964,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code - char log_hash1[CRYPTO_SHA512_SIZE*3+1]; - bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); + // char log_hash1[CRYPTO_SHA512_SIZE*3+1]; + // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; @@ -981,9 +981,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } //TODO: remove from production code - char log_hash2[CRYPTO_SHA512_SIZE*3+1]; - bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); + // char log_hash2[CRYPTO_SHA512_SIZE*3+1]; + // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); /* ss */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); @@ -1238,7 +1238,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t } //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: send_packet_to()"); + // LOGGER_DEBUG(c->log, "ENTERING: send_packet_to()"); bool direct_send_attempt = false; @@ -1276,7 +1276,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t } //TODO: remove - LOGGER_DEBUG(c->log, "send_packet_to() => TCP"); + // LOGGER_DEBUG(c->log, "send_packet_to() => TCP"); pthread_mutex_unlock(conn->mutex); pthread_mutex_lock(&c->tcp_mutex); @@ -1639,7 +1639,7 @@ non_null() static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: send_data_packet()"); + // LOGGER_DEBUG(c->log, "ENTERING: send_data_packet()"); const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE); @@ -2009,7 +2009,7 @@ non_null() static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: send_temp_packet()"); + // LOGGER_DEBUG(c->log, "ENTERING: send_temp_packet()"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2350,7 +2350,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const void *userdata) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_hs(); PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d", + LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_hs(); crypt_connection_id: %D => PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d", + crypt_connection_id, packet[0], conn->status); @@ -3549,7 +3550,7 @@ static void send_crypto_packets(Net_Crypto *c) if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: send_crypto_packets() => call send_temp_packet()"); + // LOGGER_DEBUG(c->log, "ENTERING: send_crypto_packets() => call send_temp_packet()"); send_temp_packet(c, i); } From 8462f0cd31ab4076e272d2c94396314a4cc09fe4 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Thu, 14 Sep 2023 19:06:29 +0200 Subject: [PATCH 018/150] debug: added debug output to identify UAF issue root cause. --- toxcore/net_crypto.c | 57 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 26dc362972..59ac59ed75 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2350,7 +2350,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const void *userdata) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_hs(); crypt_connection_id: %D => PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d", + LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_hs(); crypt_connection_id: %d => PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d", crypt_connection_id, packet[0], conn->status); @@ -2476,9 +2476,14 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons non_null() static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) { + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING: realloc_cryptoconnection() => NUM: %d", num); + if (num == 0) { free(c->crypto_connections); c->crypto_connections = nullptr; + //TODO: remove + LOGGER_DEBUG(c->log, "realloc_cryptoconnection() => FREE crypto_connections"); return 0; } @@ -2490,6 +2495,9 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) } c->crypto_connections = newcrypto_connections; + + //TODO: remove + LOGGER_DEBUG(c->log, "END: realloc_cryptoconnection() => realloc done"); return 0; } @@ -2502,6 +2510,9 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) non_null() static int create_crypto_connection(Net_Crypto *c) { + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING: create_crypto_connection()"); + while (true) { /* TODO(irungentoo): is this really the best way to do this? */ pthread_mutex_lock(&c->connections_mutex); @@ -2517,6 +2528,8 @@ static int create_crypto_connection(Net_Crypto *c) for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { if (c->crypto_connections[i].status == CRYPTO_CONN_FREE) { id = i; + //TODO: remove + LOGGER_DEBUG(c->log, "create_crypto_connection(): NO realloc"); break; } } @@ -2526,6 +2539,8 @@ static int create_crypto_connection(Net_Crypto *c) id = c->crypto_connections_length; ++c->crypto_connections_length; c->crypto_connections[id] = empty_crypto_connection; + //TODO: remove + LOGGER_DEBUG(c->log, "create_crypto_connection(): DONE realloc"); } } @@ -2551,10 +2566,11 @@ static int create_crypto_connection(Net_Crypto *c) //TODO: adapt static allocation? c->crypto_connections[id].noise_handshake = &c->crypto_connections[id].noise_handshake_data; - - if (c->crypto_connections[id].noise_handshake == nullptr) { - return -1; - } + //TODO: remove + LOGGER_DEBUG(c->log, "create_crypto_connection() => NEW noise_handshake set"); + // if (c->crypto_connections[id].noise_handshake == nullptr) { + // return -1; + // } c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; } @@ -2571,6 +2587,9 @@ static int create_crypto_connection(Net_Crypto *c) non_null() static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) { + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING: wipe_crypto_connection()"); + if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) { return -1; } @@ -2602,6 +2621,8 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) if (c->crypto_connections_length != i) { c->crypto_connections_length = i; + //TODO: remove + LOGGER_DEBUG(c->log, "wipe_crypto_connection(): REALLOC"); realloc_cryptoconnection(c, c->crypto_connections_length); } @@ -2909,20 +2930,27 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, */ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { + + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING: accept_crypto_connection()"); + if (getcryptconnection_id(c, n_c->public_key) != -1) { + //TODO: remove + LOGGER_DEBUG(c->log, "accept_crypto_connection() => Crypto Connection already exists"); return -1; } const int crypt_connection_id = create_crypto_connection(c); + //TODO: remove + //TODO: Print pub key of peer? + LOGGER_DEBUG(c->log, "AFTER: accept_crypto_connection():create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + if (crypt_connection_id == -1) { LOGGER_ERROR(c->log, "Could not create new crypto connection"); return -1; } - //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: accept_crypto_connection()"); - Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; if (n_c->cookie_length != COOKIE_LENGTH) { @@ -3019,16 +3047,23 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) */ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { + //TODO: remove + //TODO: Print pub key? + LOGGER_DEBUG(c->log, "ENTERING()"); + int crypt_connection_id = getcryptconnection_id(c, real_public_key); if (crypt_connection_id != -1) { + //TODO: remove + //TODO: Print pub key? + LOGGER_DEBUG(c->log, "new_crypto_connection() => Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); return crypt_connection_id; } crypt_connection_id = create_crypto_connection(c); //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: new_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "AFTER: new_crypto_connection():create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { return -1; @@ -3059,6 +3094,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u conn->cookie_request_number = random_u64(c->rng); uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; + //TODO: remove + LOGGER_DEBUG(c->log, "BEFORE: new_crypto_connection():create_cookie_request() => crypt_connection_id: %d", crypt_connection_id); if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, conn->shared_key) != sizeof(cookie_request) || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { @@ -3068,6 +3105,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u wipe_crypto_connection(c, crypt_connection_id); return -1; } + //TODO: remove + LOGGER_DEBUG(c->log, "AFTER: new_crypto_connection():create_cookie_request() => crypt_connection_id: %d", crypt_connection_id); // only necessary if Cookie request was successful if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { From 3d59d4357a2ca76ea4793a2361e3a7c1653339ad Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 15 Sep 2023 12:29:45 +0200 Subject: [PATCH 019/150] Changed noise_handshake to dynamic alloc again in Crypto_Connection. --- toxcore/net_crypto.c | 81 ++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 59ac59ed75..7f7a3e45d3 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -62,13 +62,11 @@ typedef struct Crypto_Connection { uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ // For Noise - //TODO: necessary? - noise_handshake noise_handshake_data; noise_handshake *noise_handshake; uint8_t send_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t recv_key[CRYPTO_PUBLIC_KEY_SIZE]; // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; - // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; + // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; //TODO: necessary? @@ -2379,7 +2377,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } // Noise Split(), nonces already set in conn crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // free(conn->noise_handshake); } else { return -1; @@ -2541,40 +2539,46 @@ static int create_crypto_connection(Net_Crypto *c) c->crypto_connections[id] = empty_crypto_connection; //TODO: remove LOGGER_DEBUG(c->log, "create_crypto_connection(): DONE realloc"); - } - } - - if (id != -1) { - // Memsetting float/double to 0 is non-portable, so we explicitly set them to 0 - c->crypto_connections[id].packet_recv_rate = 0; - c->crypto_connections[id].packet_send_rate = 0; - c->crypto_connections[id].last_packets_left_rem = 0; - c->crypto_connections[id].packet_send_rate_requested = 0; - c->crypto_connections[id].last_packets_left_requested_rem = 0; - c->crypto_connections[id].mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); - - if (c->crypto_connections[id].mutex == nullptr) { + } else { + LOGGER_ERROR(c->log, "create_crypto_connection(): FAILED to realloc connections"); pthread_mutex_unlock(&c->connections_mutex); return -1; } + } - if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { - free(c->crypto_connections[id].mutex); - pthread_mutex_unlock(&c->connections_mutex); - return -1; - } + // Memsetting float/double to 0 is non-portable, so we explicitly set them to 0 + c->crypto_connections[id].packet_recv_rate = 0; + c->crypto_connections[id].packet_send_rate = 0; + c->crypto_connections[id].last_packets_left_rem = 0; + c->crypto_connections[id].packet_send_rate_requested = 0; + c->crypto_connections[id].last_packets_left_requested_rem = 0; + c->crypto_connections[id].mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); - //TODO: adapt static allocation? - c->crypto_connections[id].noise_handshake = &c->crypto_connections[id].noise_handshake_data; - //TODO: remove - LOGGER_DEBUG(c->log, "create_crypto_connection() => NEW noise_handshake set"); - // if (c->crypto_connections[id].noise_handshake == nullptr) { - // return -1; - // } + if (c->crypto_connections[id].mutex == nullptr) { + LOGGER_ERROR(c->log, "create_crypto_connection(): FAILED to alloc mutex"); + pthread_mutex_unlock(&c->connections_mutex); + return -1; + } + + if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { + LOGGER_ERROR(c->log, "create_crypto_connection(): FAILED to init mutex"); + free(c->crypto_connections[id].mutex); + pthread_mutex_unlock(&c->connections_mutex); + return -1; + } - c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; + c->crypto_connections[id].noise_handshake = calloc(1, sizeof(struct noise_handshake)); + //TODO: remove + LOGGER_DEBUG(c->log, "create_crypto_connection() => NEW noise_handshake set"); + if (c->crypto_connections[id].noise_handshake == nullptr) { + LOGGER_ERROR(c->log, "create_crypto_connection(): FAILED to alloc noise_handshake"); + free(c->crypto_connections[id].mutex); + pthread_mutex_unlock(&c->connections_mutex); + return -1; } + c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; + pthread_mutex_unlock(&c->connections_mutex); return id; } @@ -2604,12 +2608,17 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) return -1; } + LOGGER_DEBUG(c->log, "wipe_crypto_connection(): valid id provided, free()'ing"); + uint32_t i; pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); free(c->crypto_connections[crypt_connection_id].mutex); - // crypto_memzero(&c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(noise_handshake)); - // free(c->crypto_connections[crypt_connection_id].noise_handshake); + + crypto_memzero(&c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(struct noise_handshake)); + free(c->crypto_connections[crypt_connection_id].noise_handshake); + c->crypto_connections[crypt_connection_id].noise_handshake = nullptr; + crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); /* check if we can resize the connections array */ @@ -2859,7 +2868,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! //TODO: there is already something in conn->noise_handshake - need to free in this case! - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // free(conn->noise_handshake); conn->noise_handshake = n_c.noise_handshake; @@ -2874,7 +2883,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } // responder Noise Split(): vice-verse keys in comparison to initiator crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // free(conn->noise_handshake); //TODO: memzero stuff from old handshake? @@ -2996,7 +3005,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // Noise Split(), nonces already set crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); //TODO: memzero stuff from old handshake, also not necessary anymore } else { @@ -3110,7 +3119,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // only necessary if Cookie request was successful if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { - crypto_memzero(conn->noise_handshake, sizeof(conn->noise_handshake_data)); + crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // free(conn->noise_handshake); return -1; } From 0f3c2b4535f0229dfb551e8b503e2ab7917d6ca3 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Sep 2023 16:41:55 +0200 Subject: [PATCH 020/150] fix: fixed ASAN memleaks after noise_handshake calloc in create_crypto_connection() via correct free in wipe_crypto_connection(). --- toxcore/net_crypto.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 7f7a3e45d3..f3f88bba37 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2615,7 +2615,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); free(c->crypto_connections[crypt_connection_id].mutex); - crypto_memzero(&c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(struct noise_handshake)); + crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(struct noise_handshake)); free(c->crypto_connections[crypt_connection_id].noise_handshake); c->crypto_connections[crypt_connection_id].noise_handshake = nullptr; @@ -2824,8 +2824,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: Differention between old and handshake needs to be checked here! if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { - crypto_memzero(n_c.noise_handshake, sizeof(n_c.noise_handshake_data)); - // free(n_c.noise_handshake); + crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); + n_c.noise_handshake = nullptr; free(n_c.cookie); return -1; } @@ -2835,7 +2835,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { - crypto_memzero(n_c.noise_handshake, sizeof(n_c.noise_handshake_data)); + crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); + n_c.noise_handshake = nullptr; free(n_c.cookie); return -1; } @@ -2850,8 +2851,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); //TODO: Unsure which case this is.. if already called new_crypto_connection() as responder before? - //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! + //TODO: IMPORTANT!! if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! if (crypt_connection_id != -1) { + LOGGER_DEBUG(c->log, "handle_new_connection_handshake() => CRYPTO CONN EXISTING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -2869,8 +2871,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! //TODO: there is already something in conn->noise_handshake - need to free in this case! crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); - conn->noise_handshake = n_c.noise_handshake; + memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(struct noise_handshake)); + + crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); + n_c.noise_handshake = nullptr; memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2884,7 +2888,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // responder Noise Split(): vice-verse keys in comparison to initiator crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); //TODO: memzero stuff from old handshake? conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -2983,7 +2986,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (!n_c->noise_handshake->initiator) { //TODO: remove LOGGER_DEBUG(c->log, "accept_crypto_connection() => RESPONDER"); - conn->noise_handshake = n_c->noise_handshake; + memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct noise_handshake)); + crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); + // necessary -> TODO: duplicated code necessary? memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE); @@ -3119,8 +3124,13 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // only necessary if Cookie request was successful if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { - crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + //TODO: + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // free(conn->noise_handshake); + pthread_mutex_lock(&c->tcp_mutex); + kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + pthread_mutex_unlock(&c->tcp_mutex); + wipe_crypto_connection(c, crypt_connection_id); return -1; } From f175976ecc4f7bae8b220f0bc24091920bd86369 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 25 Sep 2023 17:47:54 +0200 Subject: [PATCH 021/150] Improvements and added debugging due to test timeouts. Buggy, but most tests working. --- toxcore/net_crypto.c | 213 ++++++++++++++++++++++++++----------------- 1 file changed, 127 insertions(+), 86 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index f3f88bba37..6709589578 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -15,6 +15,7 @@ #include //TODO: remove #include +#include "../testing/misc_tools.h" #include "ccompat.h" #include "list.h" @@ -70,6 +71,7 @@ typedef struct Crypto_Connection { // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; //TODO: necessary? + uint32_t handshake_send_interval; // bool initiator; // uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; @@ -640,7 +642,6 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, * TODO: helper function to print hashes, keys, packets, etc. * TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? */ - static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, size_t bytes_size, const Logger *log) { int i; @@ -658,6 +659,89 @@ static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, } } +/* + * Initializes a Noise HandshakeState with TODO: + * + * return -1 on failure + * return 0 on success + */ +static int noise_handshake_init +(struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +{ + //TODO: add Logger? TODO: remove + // FILE *fp; + // fp = fopen ("data.log", "a"); + // fprintf(fp, "ENTERING: noise_handshake_init()\n"); + //TODO: ? memset(handshake, 0, sizeof(*handshake)); + + // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h + // Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE + uint8_t temp_hash[CRYPTO_SHA512_SIZE]; + memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); + memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + + // Sets the initiator, s, rs (only initiator) => ephemeral keys are set afterwards + noise_handshake->initiator = initiator; + if (self_secret_key) { + memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); + crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + } else { + fprintf(stderr, "Local static private key required, but not provided.\n"); + return -1; + } + /* <- s: pre-message from responder to initiator */ + if (initiator) { + if (peer_public_key != nullptr) { + memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // Calls MixHash() once for each public key listed in the pre-messages from Noise IK + noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: add logger? + // fprintf(fp, "noise_handshake_init() => noise_mix_hash() INITIATOR\n"); + // int i; + // fprintf(fp, "Handshake hash: "); + // for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", noise_handshake->hash[i]); + // } + // fprintf(fp, "\n"); + // fprintf(fp, "Noise_handshake_init() => INITIATOR keys set\n"); + } else { + fprintf(stderr, "Remote peer static public key required, but not provided.\n"); + return -1; + } + } else if (!initiator) { + // crypto_derive_public_key() happens for both + // crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + // Calls MixHash() once for each public key listed in the pre-messages from Noise IK + noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: add logger? + // fprintf(fp, "noise_handshake_init() => noise_mix_hash() RESPONDER\n"); + // int i; + // fprintf(fp, "Handshake hash: "); + // for (i = 0; i < CRYPTO_SHA512_SIZE; i++) + // { + // if (i > 0) fprintf(fp, ":"); + // fprintf(fp, "%02X", noise_handshake->hash[i]); + // } + // fprintf(fp, "\n"); + // fprintf(fp, "noise_handshake_init() => RESPONDER keys set\n"); + } else { + return -1; + } + + // fclose(fp); + + //TODO: precompute_static_static ? + + //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility + + /* Ready to go */ + return 0; +} + /** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. * @param cookie must be COOKIE_LENGTH bytes. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. @@ -896,14 +980,30 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t { LOGGER_DEBUG(c->log, "ENTERING: handle_crypto_handshake()"); if (noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "NOISE handshake"); + LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); if (!noise_handshake->initiator) { if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + LOGGER_DEBUG(c->log, "NOISE handshake => RESPONDER: length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); return false; } } else if (noise_handshake->initiator) { if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR: length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); + //TODO: initialize here as responder? + crypto_memzero(noise_handshake, sizeof(struct noise_handshake)); + if (noise_handshake_init(noise_handshake, c->self_secret_key, nullptr, false) != 0) { + //TODO: + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // free(conn->noise_handshake); + //TODO: necessary? have no crypt_connection_id here + // pthread_mutex_lock(&c->tcp_mutex); + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // pthread_mutex_unlock(&c->tcp_mutex); + // wipe_crypto_connection(c, crypt_connection_id); + return false; + } + //TODO: add again? TODO: IMPORTANT With this false a lot more tests were working? return false; } } else { @@ -2371,6 +2471,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => NOISE HANDHSHAKE"); if (conn->noise_handshake->initiator) { + LOGGER_DEBUG(c->log, "INITIATOR"); if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, conn->noise_handshake)) { return -1; @@ -2379,6 +2480,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // free(conn->noise_handshake); + } else if(!conn->noise_handshake->initiator) { + LOGGER_DEBUG(c->log, "RESPONDER"); + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + packet, length, nullptr, conn->noise_handshake)) { + return -1; + } + // responder Noise Split(): vice-verse keys in comparison to initiator + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // free(conn->noise_handshake); } else { return -1; } @@ -2577,6 +2688,8 @@ static int create_crypto_connection(Net_Crypto *c) return -1; } + c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 3000); + c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; pthread_mutex_unlock(&c->connections_mutex); @@ -2700,89 +2813,6 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, return -1; } -/* - * Initializes a Noise HandshakeState with TODO: - * - * return -1 on failure - * return 0 on success - */ -static int noise_handshake_init -(struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) -{ - //TODO: add Logger? TODO: remove - // FILE *fp; - // fp = fopen ("data.log", "a"); - // fprintf(fp, "ENTERING: noise_handshake_init()\n"); - //TODO: ? memset(handshake, 0, sizeof(*handshake)); - - // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h - // Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE - uint8_t temp_hash[CRYPTO_SHA512_SIZE]; - memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); - memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); - - // Sets the initiator, s, rs (only initiator) => ephemeral keys are set afterwards - noise_handshake->initiator = initiator; - if (self_secret_key) { - memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); - crypto_derive_public_key(noise_handshake->static_public, self_secret_key); - } else { - fprintf(stderr, "Local static private key required, but not provided.\n"); - return -1; - } - /* <- s: pre-message from responder to initiator */ - if (initiator) { - if (peer_public_key != nullptr) { - memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - // Calls MixHash() once for each public key listed in the pre-messages from Noise IK - noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: add logger? - // fprintf(fp, "noise_handshake_init() => noise_mix_hash() INITIATOR\n"); - // int i; - // fprintf(fp, "Handshake hash: "); - // for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", noise_handshake->hash[i]); - // } - // fprintf(fp, "\n"); - // fprintf(fp, "Noise_handshake_init() => INITIATOR keys set\n"); - } else { - fprintf(stderr, "Remote peer static public key required, but not provided.\n"); - return -1; - } - } else if (!initiator) { - // crypto_derive_public_key() happens for both - // crypto_derive_public_key(noise_handshake->static_public, self_secret_key); - // Calls MixHash() once for each public key listed in the pre-messages from Noise IK - noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: add logger? - // fprintf(fp, "noise_handshake_init() => noise_mix_hash() RESPONDER\n"); - // int i; - // fprintf(fp, "Handshake hash: "); - // for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", noise_handshake->hash[i]); - // } - // fprintf(fp, "\n"); - // fprintf(fp, "noise_handshake_init() => RESPONDER keys set\n"); - } else { - return -1; - } - - // fclose(fp); - - //TODO: precompute_static_static ? - - //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility - - /* Ready to go */ - return 0; -} - /** @brief Set function to be called when someone requests a new connection to us. * * The set function should return -1 on failure and 0 on success. @@ -3606,12 +3636,21 @@ static void send_crypto_packets(Net_Crypto *c) continue; } + //TODO: Use again? if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { + //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING: send_crypto_packets() => call send_temp_packet()"); + //LOGGER_DEBUG(c->log, "=> call send_temp_packet() => random_backoff: %d", random_backoff); + // c_sleep(random_backoff); send_temp_packet(c, i); } + //TODO: remove? where to add? + //uint32_t random_backoff = rand() % 1000; + // if ((conn->handshake_send_interval + conn->temp_packet_sent_time) < temp_time) { + // send_temp_packet(c, i); + // } + if ((conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) && (CRYPTO_SEND_PACKET_INTERVAL + conn->last_request_packet_sent) < temp_time) { if (send_request_packet(c, i) == 0) { @@ -3998,6 +4037,8 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + LOGGER_DEBUG(c->log, "ENTERING: crypto conn: %d", crypt_connection_id); + int ret = -1; if (conn != nullptr) { From fdd964d7bbe493cf16548d7521bb186482586737 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 26 Sep 2023 17:15:08 +0200 Subject: [PATCH 022/150] Fix: Fixed issues when two peers initiate a handshake at the same time via new_crypto_connection(). --- toxcore/net_crypto.c | 206 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 167 insertions(+), 39 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 6709589578..cd97bfdc2e 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -16,6 +16,7 @@ //TODO: remove #include #include "../testing/misc_tools.h" +#include "logger.h" #include "ccompat.h" #include "list.h" @@ -665,14 +666,18 @@ static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, * return -1 on failure * return 0 on success */ +//TODO: remove Logger Param static int noise_handshake_init -(struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +(const Logger *log, struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { //TODO: add Logger? TODO: remove // FILE *fp; // fp = fopen ("data.log", "a"); // fprintf(fp, "ENTERING: noise_handshake_init()\n"); //TODO: ? memset(handshake, 0, sizeof(*handshake)); + if (log != nullptr) { + LOGGER_DEBUG(log, "ENTERING"); + } // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h // Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE @@ -682,11 +687,26 @@ static int noise_handshake_init memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + //TODO: remove + char log_ck[CRYPTO_SHA512_SIZE*3+1]; + if (log != nullptr) { + bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); + LOGGER_DEBUG(log, "ck: %s", log_ck); + } + // Sets the initiator, s, rs (only initiator) => ephemeral keys are set afterwards noise_handshake->initiator = initiator; if (self_secret_key) { memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + + //TODO: remove + if (log != nullptr) { + char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); + LOGGER_DEBUG(log, "static pub: %s", log_spub); + } + } else { fprintf(stderr, "Local static private key required, but not provided.\n"); return -1; @@ -695,19 +715,22 @@ static int noise_handshake_init if (initiator) { if (peer_public_key != nullptr) { memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: Remove + if (log != nullptr) { + char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); + LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); + } + // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: add logger? - // fprintf(fp, "noise_handshake_init() => noise_mix_hash() INITIATOR\n"); - // int i; - // fprintf(fp, "Handshake hash: "); - // for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", noise_handshake->hash[i]); + + //TODO: remove + // if (log != nullptr) { + // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "INITIATOR hash: %s", log_hash); // } - // fprintf(fp, "\n"); - // fprintf(fp, "Noise_handshake_init() => INITIATOR keys set\n"); } else { fprintf(stderr, "Remote peer static public key required, but not provided.\n"); return -1; @@ -717,17 +740,12 @@ static int noise_handshake_init // crypto_derive_public_key(noise_handshake->static_public, self_secret_key); // Calls MixHash() once for each public key listed in the pre-messages from Noise IK noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: add logger? - // fprintf(fp, "noise_handshake_init() => noise_mix_hash() RESPONDER\n"); - // int i; - // fprintf(fp, "Handshake hash: "); - // for (i = 0; i < CRYPTO_SHA512_SIZE; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", noise_handshake->hash[i]); - // } - // fprintf(fp, "\n"); - // fprintf(fp, "noise_handshake_init() => RESPONDER keys set\n"); + + //TODO: remove + // if (log != nullptr) { + // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); + // } } else { return -1; } @@ -883,13 +901,28 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* e */ memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: Remove + char log_ck[CRYPTO_SHA512_SIZE*3+1]; + bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + LOGGER_DEBUG(c->log, "RESPONDER pre ee ck: %s", log_ck); /* ee */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); + + //TODO: Remove + char log_temp_key[CRYPTO_SHARED_KEY_SIZE*3+1]; + bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "RESPONDER ee temp_key: %s", log_temp_key); + /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + //TODO: Remove + bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); + /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); @@ -992,7 +1025,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR: length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: initialize here as responder? crypto_memzero(noise_handshake, sizeof(struct noise_handshake)); - if (noise_handshake_init(noise_handshake, c->self_secret_key, nullptr, false) != 0) { + if (noise_handshake_init(c->log, noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // free(conn->noise_handshake); @@ -1004,7 +1037,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } //TODO: add again? TODO: IMPORTANT With this false a lot more tests were working? - return false; + //return false; } } else { return false; @@ -1132,24 +1165,42 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t */ memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: Remove + char log_ck[CRYPTO_SHA512_SIZE*3+1]; + bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + LOGGER_DEBUG(c->log, "INITIATOR pre ee ck: %s", log_ck); + /* ee */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); + + //TODO: Remove + char log_temp_key[CRYPTO_SHARED_KEY_SIZE*3+1]; + bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "INITIATOR ee temp_key: %s", log_temp_key); + /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* Payload decryption */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + //TODO: Remove + bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); + if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake decryption failed"); return false; } crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { + LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake cookie verification failed"); return false; } @@ -1762,6 +1813,14 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ //TODO: enable backwards compatiblity // const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + //TODO: remove + char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "send_key: %s", key); + char nonce_print[CRYPTO_NONCE_SIZE*3+1]; + bytes2string(nonce_print, sizeof(nonce_print), conn->sent_nonce, CRYPTO_NONCE_SIZE, c->log); + LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); + //TODO: add ad? const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); @@ -1942,10 +2001,20 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint // const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), // length - (1 + sizeof(uint16_t)), data); + //TODO: remove + char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "recv_key: %s", key); + char nonce_print[CRYPTO_NONCE_SIZE*3+1]; + bytes2string(nonce_print, sizeof(nonce_print), nonce, CRYPTO_NONCE_SIZE, c->log); + LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); + //TODO: add ad? const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, nullptr, 0); + LOGGER_DEBUG(c->log, "len: %d", len); + if ((unsigned int)len != length - crypto_packet_overhead) { return -1; } @@ -2264,6 +2333,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t data[MAX_DATA_DATA_PACKET_SIZE]; const int len = handle_data_packet(c, crypt_connection_id, data, packet, length); + LOGGER_DEBUG(c->log, "len: %d", len); + if (len <= (int)(sizeof(uint32_t) * 2)) { return -1; } @@ -2309,6 +2380,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { clear_temp_packet(c, crypt_connection_id); conn->status = CRYPTO_CONN_ESTABLISHED; + //TODO: noise_handshake not necessary anymore => memzero! TODO: and free also? + LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); if (conn->connection_status_callback != nullptr) { conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, @@ -2466,7 +2539,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t cookie[COOKIE_LENGTH]; - + + bool initiator_change = false; //TODO: There should also be a case for RESPONDER? if (conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => NOISE HANDHSHAKE"); @@ -2476,20 +2550,64 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet, length, conn->public_key, conn->noise_handshake)) { return -1; } - // Noise Split(), nonces already set in conn - crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); - } else if(!conn->noise_handshake->initiator) { + // TODO: Check if still INITIATOR after handle_crypto_handshake() + if (conn->noise_handshake->initiator) { + LOGGER_DEBUG(c->log, "STILL INITIATOR"); + + //TODO: remove + char ck_print[CRYPTO_SHA512_SIZE*3+1]; + bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + LOGGER_DEBUG(c->log, "ck: %s", ck_print); + + // Noise Split(), nonces already set in conn + crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + + //TODO: remove + char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "send_key: %s", key); + bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "recv_key: %s", key); + //TODO: wrong here? + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + } else if (!conn->noise_handshake->initiator) { + LOGGER_DEBUG(c->log, "INITIATOR CHANGED TO RESPONDER"); + + //TODO: remove + char ck_print[CRYPTO_SHA512_SIZE*3+1]; + bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + LOGGER_DEBUG(c->log, "ck: %s", ck_print); + + //TODO: wrong here, RESPONDER still needs to send handshake packet + // responder Noise Split(): vice-verse keys in comparison to initiator + // crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + + //TODO: remove + char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "send_key: %s", key); + bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "recv_key: %s", key); + + //TODO: wrong here? + //crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + initiator_change = true; + } else { + return -1; + } + } + // Case where RESPONDER without change from INITIATOR + else if(!conn->noise_handshake->initiator && initiator_change) { + //TODO: IMPORTANT currently this is called twice if I'm changing from INITIATOR to RESPONDER LOGGER_DEBUG(c->log, "RESPONDER"); if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; } // responder Noise Split(): vice-verse keys in comparison to initiator - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); + // TODO: here: crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + //TODO: wrong here? + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); } else { return -1; } @@ -2505,7 +2623,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: adapt? TODO: what's the case for this? if (pk_equal(dht_public_key, conn->dht_public_key)) { - //TODO: is this called? + LOGGER_DEBUG(c->log, "pk_equal TRUE case"); + //TODO: is this called? => yes encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { @@ -2514,8 +2633,15 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } + if (initiator_change) { + // responder Noise Split(): vice-verse keys in comparison to initiator + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + } + + //TODO:This should not be the problem why the handshake fails conn->status = CRYPTO_CONN_NOT_CONFIRMED; } else { + LOGGER_DEBUG(c->log, "pk_equal FALSE case"); if (conn->dht_pk_callback != nullptr) { conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key, userdata); } @@ -2688,7 +2814,8 @@ static int create_crypto_connection(Net_Crypto *c) return -1; } - c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 3000); + //TODO: Remove + c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 3000); c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; @@ -2853,7 +2980,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: Differention between old and handshake needs to be checked here! - if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { + if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); n_c.noise_handshake = nullptr; free(n_c.cookie); @@ -3040,8 +3167,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // Noise Split(), nonces already set crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - //TODO: memzero stuff from old handshake, also not necessary anymore + //TODO: wrong here? + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + //TODO: memzero stuff from old handshake, also not necessary anymore => TODO: or after established crypto conn? } else { pthread_mutex_lock(&c->tcp_mutex); @@ -3153,7 +3281,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u LOGGER_DEBUG(c->log, "AFTER: new_crypto_connection():create_cookie_request() => crypt_connection_id: %d", crypt_connection_id); // only necessary if Cookie request was successful - if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { + if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { //TODO: // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // free(conn->noise_handshake); From f6c6830c92f28a467c65831eeb0ce0bb4def0ad9 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 27 Sep 2023 17:40:05 +0200 Subject: [PATCH 023/150] Fix: Added further debug logging and fixed issue in special case of initiator to responder change case (relevant for reconnect test). --- toxcore/net_crypto.c | 106 +++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 28 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index cd97bfdc2e..43fd3beb48 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -384,14 +384,11 @@ non_null(1, 2, 3) nullable(5) static int udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - //TODO: add logger? - // LOGGER_DEBUG(c->log, "ENTERING: udp_handle_cookie_request()"); - // FILE *fp; - // fp = fopen ("data.log", "a"); - // fprintf(fp, "ENTERING: udp_handle_cookie_request()\n"); - // fclose(fp); - const Net_Crypto *c = (const Net_Crypto *)object; + + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING: udp_handle_cookie_request()"); + uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -671,9 +668,6 @@ static int noise_handshake_init (const Logger *log, struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { //TODO: add Logger? TODO: remove - // FILE *fp; - // fp = fopen ("data.log", "a"); - // fprintf(fp, "ENTERING: noise_handshake_init()\n"); //TODO: ? memset(handshake, 0, sizeof(*handshake)); if (log != nullptr) { LOGGER_DEBUG(log, "ENTERING"); @@ -750,8 +744,6 @@ static int noise_handshake_init return -1; } - // fclose(fp); - //TODO: precompute_static_static ? //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility @@ -1091,6 +1083,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // fprintf(fp, "\n"); // fclose(fp); + //TODO: Check here if remote_ephemeral is already the same ephemeral key? + /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -2277,6 +2271,10 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id) } uint8_t kill_packet = PACKET_ID_KILL; + + //TODO: remove + LOGGER_DEBUG(c->log, "KILL PACKET"); + return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end, &kill_packet, sizeof(kill_packet)); } @@ -2286,6 +2284,9 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + //TODO: remove + LOGGER_DEBUG(c->log, "CONNECTION KILL"); + if (conn == nullptr) { return; } @@ -2363,6 +2364,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const uint8_t *real_data = data + (sizeof(uint32_t) * 2); uint16_t real_length = len - (sizeof(uint32_t) * 2); + LOGGER_DEBUG(c->log, "DATA ID: %d", real_data[0]); + while (real_data[0] == PACKET_ID_PADDING) { /* Remove Padding */ ++real_data; --real_length; @@ -2372,7 +2375,10 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } } + LOGGER_DEBUG(c->log, "DATA ID after PADDING: %d", real_data[0]); + if (real_data[0] == PACKET_ID_KILL) { + LOGGER_DEBUG(c->log, "KILL PACKET RECEIVED"); connection_kill(c, crypt_connection_id, userdata); return 0; } @@ -2380,7 +2386,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { clear_temp_packet(c, crypt_connection_id); conn->status = CRYPTO_CONN_ESTABLISHED; - //TODO: noise_handshake not necessary anymore => memzero! TODO: and free also? + //TODO: noise_handshake not necessary anymore => memzero! TODO: and free also? TODO: write function for both! LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); if (conn->connection_status_callback != nullptr) { @@ -2596,19 +2602,36 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } } - // Case where RESPONDER without change from INITIATOR - else if(!conn->noise_handshake->initiator && initiator_change) { - //TODO: IMPORTANT currently this is called twice if I'm changing from INITIATOR to RESPONDER + // Case where RESPONDER with and without change from INITIATOR + else if(!conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER"); + crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { + //TODO: + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // free(conn->noise_handshake); + //TODO: necessary? have no crypt_connection_id here + // pthread_mutex_lock(&c->tcp_mutex); + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // pthread_mutex_unlock(&c->tcp_mutex); + // wipe_crypto_connection(c, crypt_connection_id); + return false; + } if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; } + //TODO: create_send_handshake() here? TODO: condition necessary? + if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { + return -1; + } // responder Noise Split(): vice-verse keys in comparison to initiator - // TODO: here: crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: wrong here? // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); } else { + //TODO: remove + LOGGER_DEBUG(c->log, "NOT initiator or responder => !conn->noise_handshake->initiator: %d, initiator_change: %d", !conn->noise_handshake->initiator, initiator_change); return -1; } } @@ -2627,6 +2650,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: is this called? => yes encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); + if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; @@ -3025,7 +3050,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } - //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! + //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! => nope, are set in create_crypto_handshake() //TODO: there is already something in conn->noise_handshake - need to free in this case! crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(struct noise_handshake)); @@ -3043,8 +3068,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } // responder Noise Split(): vice-verse keys in comparison to initiator + //TODO: remove here? crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + //TODO: wrong here? + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); //TODO: memzero stuff from old handshake? conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -3139,6 +3166,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->connection_number_tcp = connection_number_tcp; //TODO: is this zeroed and freeded memory after handle_new_connection_handshake()?! + //TODO: only happening for RESPONDER? if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { //TODO: remove @@ -3335,6 +3363,9 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ { Net_Crypto *c = (Net_Crypto *)object; + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", data[0]); + if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; } @@ -3369,6 +3400,9 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in { Net_Crypto *c = (Net_Crypto *)object; + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", data[0]); + if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; } @@ -3588,6 +3622,9 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING"); + if (conn == nullptr) { return -1; } @@ -3612,6 +3649,9 @@ int connection_lossy_data_handler(const Net_Crypto *c, int crypt_connection_id, { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING"); + if (conn == nullptr) { return -1; } @@ -3637,6 +3677,9 @@ int nc_dht_pk_callback(const Net_Crypto *c, int crypt_connection_id, dht_pk_cb * { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING"); + if (conn == nullptr) { return -1; } @@ -3671,14 +3714,12 @@ static int crypto_id_ip_port(const Net_Crypto *c, const IP_Port *ip_port) non_null(1, 2, 3) nullable(5) static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) -{ - //TODO: add logger? - // FILE *fp; - // fp = fopen ("data.log", "a"); - // fprintf(fp, "ENTERING: udp_handle_packet() => PACKET %d\n", packet[0]); - +{ Net_Crypto *c = (Net_Crypto *)object; + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", packet[0]); + if (length <= CRYPTO_MIN_PACKET_SIZE || length > MAX_CRYPTO_PACKET_SIZE) { return 1; } @@ -3724,9 +3765,6 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t pthread_mutex_unlock(conn->mutex); - //TODO: remove - // fclose(fp); - return 0; } @@ -4102,6 +4140,9 @@ int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING"); + if (conn == nullptr) { return -1; } @@ -4220,6 +4261,8 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool void new_keys(Net_Crypto *c) { + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING"); crypto_new_keypair(c->rng, c->self_public_key, c->self_secret_key); } @@ -4294,6 +4337,8 @@ Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network * bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8); + LOGGER_DEBUG(temp->log, "DONE"); + return temp; } @@ -4313,6 +4358,8 @@ static void kill_timedout(Net_Crypto *c, void *userdata) continue; } + //TODO: remove + LOGGER_DEBUG(c->log, "connection_kill"); connection_kill(c, i, userdata); } @@ -4356,6 +4403,9 @@ void kill_net_crypto(Net_Crypto *c) return; } + //TODO: remove + LOGGER_DEBUG(c->log, "ENTERING"); + for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { crypto_kill(c, i); } From e2cf7ff668ac6e868bba27d13278225db9be5d6e Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 2 Oct 2023 13:28:21 +0200 Subject: [PATCH 024/150] cleanup: small cleanup of debug/logging code. --- toxcore/net_crypto.c | 206 ++++++++++--------------------------------- 1 file changed, 49 insertions(+), 157 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 43fd3beb48..de10a05bda 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -15,8 +15,6 @@ #include //TODO: remove #include -#include "../testing/misc_tools.h" -#include "logger.h" #include "ccompat.h" #include "list.h" @@ -237,7 +235,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin uint64_t number, uint8_t *shared_key) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: create_cookie_request()"); + LOGGER_DEBUG(c->log, "ENTERING"); uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t padding[CRYPTO_PUBLIC_KEY_SIZE] = {0}; @@ -258,8 +256,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) { return -1; } - //TODO: remove - LOGGER_DEBUG(c->log, "END: create_cookie_request()"); + return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len; } @@ -327,7 +324,7 @@ non_null() static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain, const uint8_t *shared_key, const uint8_t *dht_public_key) { - LOGGER_DEBUG(c->log, "ENTERING: create_cookie_response()"); + LOGGER_DEBUG(c->log, "ENTERING"); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; memcpy(cookie_plain, request_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -360,7 +357,7 @@ non_null() static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { - LOGGER_DEBUG(c->log, "ENTERING: handle_cookie_request()"); + LOGGER_DEBUG(c->log, "ENTERING"); if (length != COOKIE_REQUEST_LENGTH) { return -1; } @@ -387,7 +384,7 @@ static int udp_handle_cookie_request(void *object, const IP_Port *source, const const Net_Crypto *c = (const Net_Crypto *)object; //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: udp_handle_cookie_request()"); + LOGGER_DEBUG(c->log, "ENTERING"); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; @@ -415,7 +412,7 @@ non_null() static int tcp_handle_cookie_request(const Net_Crypto *c, int connections_number, const uint8_t *packet, uint16_t length) { - LOGGER_DEBUG(c->log, "ENTERING: tcp_handle_cookie_request()"); + LOGGER_DEBUG(c->log, "ENTERING"); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -439,7 +436,7 @@ non_null() static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { - LOGGER_DEBUG(c->log, "ENTERING: tcp_oob_handle_cookie_request()"); + LOGGER_DEBUG(c->log, "ENTERING"); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t dht_public_key_temp[CRYPTO_PUBLIC_KEY_SIZE]; @@ -475,12 +472,6 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8_t *packet, uint16_t length, const uint8_t *shared_key) { - //TODO: add logger? - // FILE *fp; - // fp = fopen ("data.log", "a"); - // fprintf(fp, "ENTERING: handle_cookie_response()\n"); - // fclose(fp); - if (length != COOKIE_RESPONSE_LENGTH) { return -1; } @@ -531,11 +522,6 @@ static bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], */ static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) { - //TODO: add logger? - // FILE *fp; - // fp = fopen ("data.log", "a"); - // fprintf(fp, "noise_mix_hash() => NOISE HANDSHAKE\n"); - // fclose(fp); uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); @@ -551,37 +537,10 @@ static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { - //TODO: add logger as parameter? - // FILE *fp; - // fp = fopen ("data.log", "a"); - // fprintf(fp, "noise_encrypt_and_hash() => NOISE HANDSHAKE\n"); - // int i; - // fprintf(fp, "noise_encrypt_and_hash() => Nonce: "); - // for (i = 0; i < CRYPTO_NONCE_SIZE; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", nonce[i]); - // } - // fprintf(fp, "\n"); - // fprintf(fp, "noise_encrypt_and_hash() => Shared Key: "); - // for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", shared_key[i]); - // } - // fprintf(fp, "\n"); unsigned long long encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, plaintext, plain_length, ciphertext, hash, CRYPTO_SHA512_SIZE); - // fprintf(fp, "noise_encrypt_and_hash() => encrypted_length: %d\n", encrypted_length); - // fprintf(fp, "noise_encrypt_and_hash() => Ciphertext: "); - // for (i = 0; i < encrypted_length; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", ciphertext[i]); - // } - // fprintf(fp, "\n"); - // fclose(fp); + noise_mix_hash(hash, ciphertext, encrypted_length); } @@ -594,45 +553,12 @@ static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { - //TODO: add logger as parameter? - // FILE *fp; - // fp = fopen ("data.log", "a"); - // fprintf(fp, "noise_decrypt_and_hash() => NOISE HANDSHAKE\n"); - // int i; - // fprintf(fp, "noise_decrypt_and_hash() => Nonce: "); - // for (i = 0; i < CRYPTO_NONCE_SIZE; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", nonce[i]); - // } - // fprintf(fp, "\n"); - // fprintf(fp, "noise_decrypt_and_hash() => Shared Key: "); - // for (i = 0; i < CRYPTO_SHARED_KEY_SIZE; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", shared_key[i]); - // } - // fprintf(fp, "\n"); - // fprintf(fp, "noise_decrypt_and_hash() => Ciphertext (length: %d): ", encrypted_length); - // for (i = 0; i < encrypted_length; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", ciphertext[i]); - // } - // fprintf(fp, "\n"); unsigned long long plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, ciphertext, encrypted_length, plaintext, hash, CRYPTO_SHA512_SIZE); - // fprintf(fp, "noise_decrypt_and_hash() => plaintext_length: %d\n", plaintext_length); - // if (plaintext_length != (encrypted_length - CRYPTO_MAC_SIZE)) - // { - // fprintf(fp, "noise_decrypt_and_hash() => decryption FAILED\n"); - // fclose(fp); - // return -1; - // } + noise_mix_hash(hash, ciphertext, encrypted_length); - // fprintf(fp, "noise_decrypt_and_hash() => decryption SUCESSFUL\n"); - // fclose(fp); + return plaintext_length; } @@ -667,7 +593,7 @@ static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, static int noise_handshake_init (const Logger *log, struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { - //TODO: add Logger? TODO: remove + //TODO: remove //TODO: ? memset(handshake, 0, sizeof(*handshake)); if (log != nullptr) { LOGGER_DEBUG(log, "ENTERING"); @@ -854,18 +780,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); // LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); - //TODO: remove - // FILE *fp; - // fp = fopen("data.log", "a"); - // fprintf(fp, "Handshake Packet Initiator: "); - // for (int i = 0; i < NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", packet[i]); - // } - // fprintf(fp, "\n"); - // fclose(fp); - crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; @@ -1003,7 +917,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, noise_handshake *noise_handshake) { - LOGGER_DEBUG(c->log, "ENTERING: handle_crypto_handshake()"); + LOGGER_DEBUG(c->log, "ENTERING"); if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); @@ -1028,8 +942,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // wipe_crypto_connection(c, crypt_connection_id); return false; } - //TODO: add again? TODO: IMPORTANT With this false a lot more tests were working? - //return false; } } else { return false; @@ -1071,23 +983,12 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); // LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); - //TODO: remove - // FILE *fp; - // fp = fopen("data.log", "a"); - // fprintf(fp, "Handshake Packet Initiator (received by RESPONDER): "); - // for (int i = 0; i < NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; i++) - // { - // if (i > 0) fprintf(fp, ":"); - // fprintf(fp, "%02X", packet[i]); - // } - // fprintf(fp, "\n"); - // fclose(fp); - //TODO: Check here if remote_ephemeral is already the same ephemeral key? /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: remove from production code // char log_hash1[CRYPTO_SHA512_SIZE*3+1]; // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); @@ -1782,7 +1683,7 @@ non_null() static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING: send_data_packet()"); + // LOGGER_DEBUG(c->log, "ENTERING"); const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE); @@ -2170,7 +2071,7 @@ non_null() static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) { //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING: send_temp_packet()"); + // LOGGER_DEBUG(c->log, "ENTERING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2201,7 +2102,7 @@ non_null() static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { - LOGGER_DEBUG(c->log, "ENTERING: create_send_handshake()"); + LOGGER_DEBUG(c->log, "ENTERING"); const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2319,7 +2220,7 @@ non_null(1, 3) nullable(6) static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { - LOGGER_DEBUG(c->log, "ENTERING: handle_data_packet_core(); PACKET: %d", packet[0]); + LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d", packet[0]); if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) { return -1; @@ -2475,7 +2376,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "ENTERING: handle_packet_cookie_response(); crypto_connection_id: %d => PACKET: %d => NET_PACKET_COOKIE_RESPONSE => CRYPTO CONN STATE: %d", + LOGGER_DEBUG(c->log, "ENTERING: crypto_connection_id: %d => PACKET: %d => CRYPTO CONN STATE: %d", crypt_connection_id, packet[0], conn->status); @@ -2501,7 +2402,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "handle_packet_cookie_response() => INITIATOR -> NEW Handshake"); + LOGGER_DEBUG(c->log, "INITIATOR -> NOISE Handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } @@ -2511,7 +2412,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } } else { // old handshake - LOGGER_DEBUG(c->log, "handle_packet_cookie_response() -> OLD Handshake"); + LOGGER_DEBUG(c->log, "OLD Handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } @@ -2663,7 +2564,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); } - //TODO:This should not be the problem why the handshake fails conn->status = CRYPTO_CONN_NOT_CONFIRMED; } else { LOGGER_DEBUG(c->log, "pk_equal FALSE case"); @@ -2682,7 +2582,7 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); //TODO: remove from prod code - LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_data(); PACKET: %d => NET_PACKET_CRYPTO_DATA => CRYPTO CONN STATE: %d", + LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d => CRYPTO CONN STATE: %d", packet[0], conn->status); @@ -2707,7 +2607,7 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons bool udp, void *userdata) { //TODO: remove from prod code - LOGGER_DEBUG(c->log, "ENTERING: handle_packet_connection(); PACKET: %d", packet[0]); + LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d", packet[0]); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; @@ -2737,13 +2637,13 @@ non_null() static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: realloc_cryptoconnection() => NUM: %d", num); + LOGGER_DEBUG(c->log, "ENTERING: NUM: %d", num); if (num == 0) { free(c->crypto_connections); c->crypto_connections = nullptr; //TODO: remove - LOGGER_DEBUG(c->log, "realloc_cryptoconnection() => FREE crypto_connections"); + LOGGER_DEBUG(c->log, "FREE crypto_connections"); return 0; } @@ -2757,7 +2657,7 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) c->crypto_connections = newcrypto_connections; //TODO: remove - LOGGER_DEBUG(c->log, "END: realloc_cryptoconnection() => realloc done"); + LOGGER_DEBUG(c->log, "END: realloc done"); return 0; } @@ -2771,7 +2671,7 @@ non_null() static int create_crypto_connection(Net_Crypto *c) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: create_crypto_connection()"); + LOGGER_DEBUG(c->log, "ENTERING"); while (true) { /* TODO(irungentoo): is this really the best way to do this? */ pthread_mutex_lock(&c->connections_mutex); @@ -2789,7 +2689,7 @@ static int create_crypto_connection(Net_Crypto *c) if (c->crypto_connections[i].status == CRYPTO_CONN_FREE) { id = i; //TODO: remove - LOGGER_DEBUG(c->log, "create_crypto_connection(): NO realloc"); + LOGGER_DEBUG(c->log, "NO realloc"); break; } } @@ -2800,9 +2700,9 @@ static int create_crypto_connection(Net_Crypto *c) ++c->crypto_connections_length; c->crypto_connections[id] = empty_crypto_connection; //TODO: remove - LOGGER_DEBUG(c->log, "create_crypto_connection(): DONE realloc"); + LOGGER_DEBUG(c->log, "DONE realloc"); } else { - LOGGER_ERROR(c->log, "create_crypto_connection(): FAILED to realloc connections"); + LOGGER_ERROR(c->log, "FAILED to realloc connections"); pthread_mutex_unlock(&c->connections_mutex); return -1; } @@ -2817,30 +2717,29 @@ static int create_crypto_connection(Net_Crypto *c) c->crypto_connections[id].mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); if (c->crypto_connections[id].mutex == nullptr) { - LOGGER_ERROR(c->log, "create_crypto_connection(): FAILED to alloc mutex"); + LOGGER_ERROR(c->log, "failed to alloc mutex"); pthread_mutex_unlock(&c->connections_mutex); return -1; } if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { - LOGGER_ERROR(c->log, "create_crypto_connection(): FAILED to init mutex"); + LOGGER_ERROR(c->log, "failed to init mutex"); free(c->crypto_connections[id].mutex); pthread_mutex_unlock(&c->connections_mutex); return -1; } c->crypto_connections[id].noise_handshake = calloc(1, sizeof(struct noise_handshake)); - //TODO: remove - LOGGER_DEBUG(c->log, "create_crypto_connection() => NEW noise_handshake set"); + if (c->crypto_connections[id].noise_handshake == nullptr) { - LOGGER_ERROR(c->log, "create_crypto_connection(): FAILED to alloc noise_handshake"); + LOGGER_ERROR(c->log, "failed to alloc noise_handshake"); free(c->crypto_connections[id].mutex); pthread_mutex_unlock(&c->connections_mutex); return -1; } //TODO: Remove - c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 3000); + //c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 3000); c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; @@ -2857,7 +2756,7 @@ non_null() static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: wipe_crypto_connection()"); + LOGGER_DEBUG(c->log, "ENTERING"); if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) { return -1; @@ -2873,7 +2772,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) return -1; } - LOGGER_DEBUG(c->log, "wipe_crypto_connection(): valid id provided, free()'ing"); + LOGGER_DEBUG(c->log, "valid id provided, free()'ing"); uint32_t i; @@ -2895,8 +2794,6 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) if (c->crypto_connections_length != i) { c->crypto_connections_length = i; - //TODO: remove - LOGGER_DEBUG(c->log, "wipe_crypto_connection(): REALLOC"); realloc_cryptoconnection(c, c->crypto_connections_length); } @@ -2988,7 +2885,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, void *userdata) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: handle_new_connection_handshake()"); + LOGGER_DEBUG(c->log, "ENTERING"); New_Connection n_c; n_c.cookie = (uint8_t *)malloc(COOKIE_LENGTH); @@ -3013,7 +2910,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } //TODO: remove - LOGGER_DEBUG(c->log, "handle_new_connection_handshake() => After Handshake init"); + LOGGER_DEBUG(c->log, "After Handshake init"); if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { @@ -3128,11 +3025,11 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: accept_crypto_connection()"); + LOGGER_DEBUG(c->log, "ENTERING"); if (getcryptconnection_id(c, n_c->public_key) != -1) { //TODO: remove - LOGGER_DEBUG(c->log, "accept_crypto_connection() => Crypto Connection already exists"); + LOGGER_DEBUG(c->log, "Crypto Connection already exists"); return -1; } @@ -3140,7 +3037,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: remove //TODO: Print pub key of peer? - LOGGER_DEBUG(c->log, "AFTER: accept_crypto_connection():create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "AFTER: create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { LOGGER_ERROR(c->log, "Could not create new crypto connection"); @@ -3170,7 +3067,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { //TODO: remove - LOGGER_DEBUG(c->log, "accept_crypto_connection() => RESPONDER"); + LOGGER_DEBUG(c->log, "NOISE Handshake RESPONDER"); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct noise_handshake)); crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); @@ -3211,7 +3108,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // old handshake else { //TODO: remove - LOGGER_DEBUG(c->log, "accept_crypto_connection() => old handshake"); + LOGGER_DEBUG(c->log, "OLD handshake"); 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); @@ -3248,22 +3145,21 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { //TODO: remove - //TODO: Print pub key? - LOGGER_DEBUG(c->log, "ENTERING()"); + LOGGER_DEBUG(c->log, "ENTERING"); int crypt_connection_id = getcryptconnection_id(c, real_public_key); if (crypt_connection_id != -1) { //TODO: remove //TODO: Print pub key? - LOGGER_DEBUG(c->log, "new_crypto_connection() => Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); return crypt_connection_id; } crypt_connection_id = create_crypto_connection(c); //TODO: remove - LOGGER_DEBUG(c->log, "AFTER: new_crypto_connection():create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { return -1; @@ -3295,7 +3191,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; //TODO: remove - LOGGER_DEBUG(c->log, "BEFORE: new_crypto_connection():create_cookie_request() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "BEFORE: create_cookie_request()"); if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, conn->shared_key) != sizeof(cookie_request) || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { @@ -3306,7 +3202,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u return -1; } //TODO: remove - LOGGER_DEBUG(c->log, "AFTER: new_crypto_connection():create_cookie_request() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); // only necessary if Cookie request was successful if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { @@ -3321,7 +3217,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u } //TODO: remove - LOGGER_DEBUG(c->log, "END: new_crypto_connection()"); + LOGGER_DEBUG(c->log, "END"); return crypt_connection_id; } @@ -3731,8 +3627,6 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t if (packet[0] != NET_PACKET_CRYPTO_HS) { return 1; } - //TODO: remove - // fprintf(fp, "ENTERING: udp_handle_packet() => NO CRYPTO CONN YET -> RESPONDER\n"); if (handle_new_connection_handshake(c, source, packet, length, userdata) != 0) { return 1; @@ -3743,8 +3637,6 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t //TODO: return -1 if RESPONDER? - //TODO: remove - // fprintf(fp, "ENTERING: udp_handle_packet() => CRYPTO CONN EXISTING\n"); if (handle_packet_connection(c, crypt_connection_id, packet, length, true, userdata) != 0) { return 1; } From 7e03515b8e045ee10b255f45bb0ec870d1dd01cf Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 2 Oct 2023 20:14:09 +0200 Subject: [PATCH 025/150] change: moved noise_handshake_init() to handle_cookie_response for INITIATOR case. memzero noise_handshake before every init. Further minor adaptions, e.g. Crypto Conn Status changes. Minor logging/debug adaptions. --- toxcore/net_crypto.c | 212 ++++++++++++++++++++++++------------------- 1 file changed, 117 insertions(+), 95 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index de10a05bda..5a5caaab0f 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -594,11 +594,12 @@ static int noise_handshake_init (const Logger *log, struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { //TODO: remove - //TODO: ? memset(handshake, 0, sizeof(*handshake)); if (log != nullptr) { LOGGER_DEBUG(log, "ENTERING"); } + crypto_memzero(noise_handshake, sizeof(struct noise_handshake)); + // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h // Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE uint8_t temp_hash[CRYPTO_SHA512_SIZE]; @@ -608,11 +609,11 @@ static int noise_handshake_init memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); //TODO: remove - char log_ck[CRYPTO_SHA512_SIZE*3+1]; - if (log != nullptr) { - bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); - LOGGER_DEBUG(log, "ck: %s", log_ck); - } + // char log_ck[CRYPTO_SHA512_SIZE*3+1]; + // if (log != nullptr) { + // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "ck: %s", log_ck); + // } // Sets the initiator, s, rs (only initiator) => ephemeral keys are set afterwards noise_handshake->initiator = initiator; @@ -672,7 +673,7 @@ static int noise_handshake_init //TODO: precompute_static_static ? - //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility + //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility, also inefficient /* Ready to go */ return 0; @@ -730,7 +731,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); /* s */ - // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? + // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? or leads to nonce reuse? random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); @@ -809,25 +810,25 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove - char log_ck[CRYPTO_SHA512_SIZE*3+1]; - bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - LOGGER_DEBUG(c->log, "RESPONDER pre ee ck: %s", log_ck); + // char log_ck[CRYPTO_SHA512_SIZE*3+1]; + // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "RESPONDER pre ee ck: %s", log_ck); /* ee */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); //TODO: Remove - char log_temp_key[CRYPTO_SHARED_KEY_SIZE*3+1]; - bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "RESPONDER ee temp_key: %s", log_temp_key); + // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*3+1]; + // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "RESPONDER ee temp_key: %s", log_temp_key); /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); //TODO: Remove - bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); + // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; @@ -845,7 +846,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u } // Add Handshake payload nonce - // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? + // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? or leads to nonce reuse? random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, @@ -924,13 +925,13 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t if (!noise_handshake->initiator) { if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "NOISE handshake => RESPONDER: length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); + //TODO: wipe in this case? //TODO: wipe crypto conn or just noise_handshake? return false; } } else if (noise_handshake->initiator) { if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR: length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: initialize here as responder? - crypto_memzero(noise_handshake, sizeof(struct noise_handshake)); if (noise_handshake_init(c->log, noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); @@ -1005,6 +1006,13 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { return false; } + + //TODO: + char log_static[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "local static pub: %s", log_static); + bytes2string(log_static, sizeof(log_static), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "local remote pub: %s", log_static); //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*3+1]; @@ -1062,18 +1070,18 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove - char log_ck[CRYPTO_SHA512_SIZE*3+1]; - bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - LOGGER_DEBUG(c->log, "INITIATOR pre ee ck: %s", log_ck); + // char log_ck[CRYPTO_SHA512_SIZE*3+1]; + // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "INITIATOR pre ee ck: %s", log_ck); /* ee */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); //TODO: Remove - char log_temp_key[CRYPTO_SHARED_KEY_SIZE*3+1]; - bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "INITIATOR ee temp_key: %s", log_temp_key); + // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*3+1]; + // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "INITIATOR ee temp_key: %s", log_temp_key); /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); @@ -1082,8 +1090,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); //TODO: Remove - bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); + // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, @@ -1709,12 +1717,12 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ // const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); //TODO: remove - char key[CRYPTO_SECRET_KEY_SIZE*3+1]; - bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "send_key: %s", key); - char nonce_print[CRYPTO_NONCE_SIZE*3+1]; - bytes2string(nonce_print, sizeof(nonce_print), conn->sent_nonce, CRYPTO_NONCE_SIZE, c->log); - LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); + // char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + // bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "send_key: %s", key); + // char nonce_print[CRYPTO_NONCE_SIZE*3+1]; + // bytes2string(nonce_print, sizeof(nonce_print), conn->sent_nonce, CRYPTO_NONCE_SIZE, c->log); + // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); //TODO: add ad? const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); @@ -1897,18 +1905,18 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint // length - (1 + sizeof(uint16_t)), data); //TODO: remove - char key[CRYPTO_SECRET_KEY_SIZE*3+1]; - bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "recv_key: %s", key); - char nonce_print[CRYPTO_NONCE_SIZE*3+1]; - bytes2string(nonce_print, sizeof(nonce_print), nonce, CRYPTO_NONCE_SIZE, c->log); - LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); + // char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "recv_key: %s", key); + // char nonce_print[CRYPTO_NONCE_SIZE*3+1]; + // bytes2string(nonce_print, sizeof(nonce_print), nonce, CRYPTO_NONCE_SIZE, c->log); + // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); //TODO: add ad? const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, nullptr, 0); - LOGGER_DEBUG(c->log, "len: %d", len); + LOGGER_DEBUG(c->log, "decrypt len: %d", len); if ((unsigned int)len != length - crypto_packet_overhead) { return -1; @@ -2235,8 +2243,6 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t data[MAX_DATA_DATA_PACKET_SIZE]; const int len = handle_data_packet(c, crypt_connection_id, data, packet, length); - LOGGER_DEBUG(c->log, "len: %d", len); - if (len <= (int)(sizeof(uint32_t) * 2)) { return -1; } @@ -2287,7 +2293,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { clear_temp_packet(c, crypt_connection_id); conn->status = CRYPTO_CONN_ESTABLISHED; - //TODO: noise_handshake not necessary anymore => memzero! TODO: and free also? TODO: write function for both! + //TODO: noise_handshake not necessary anymore => memzero! TODO: and free also? TODO: write function for both! TODO: how this is done for other dynamic allocs? LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); if (conn->connection_status_callback != nullptr) { @@ -2400,6 +2406,17 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } + //TODO: here? + // only necessary if Cookie response was successful + if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, conn->public_key, true) != 0) { + //TODO: + // pthread_mutex_lock(&c->tcp_mutex); + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // pthread_mutex_unlock(&c->tcp_mutex); + // wipe_crypto_connection(c, crypt_connection_id); + return -1; + } + if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR -> NOISE Handshake"); @@ -2407,7 +2424,6 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } } else { - //TODO: wipe crypto conn? return -1; } } else { @@ -2437,6 +2453,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } + //TODO: what if I remove CRYPTO_CONN_NOT_CONFIRMED from here? if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT && conn->status != CRYPTO_CONN_NOT_CONFIRMED) { @@ -2447,8 +2464,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t cookie[COOKIE_LENGTH]; + //TODO: via noise_handshake struct? bool initiator_change = false; - //TODO: There should also be a case for RESPONDER? + if (conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => NOISE HANDHSHAKE"); if (conn->noise_handshake->initiator) { @@ -2457,56 +2475,42 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet, length, conn->public_key, conn->noise_handshake)) { return -1; } - // TODO: Check if still INITIATOR after handle_crypto_handshake() + //TODO: Check if still INITIATOR after handle_crypto_handshake(), can change to RESPONDER if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "STILL INITIATOR"); //TODO: remove - char ck_print[CRYPTO_SHA512_SIZE*3+1]; - bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - LOGGER_DEBUG(c->log, "ck: %s", ck_print); + // char ck_print[CRYPTO_SHA512_SIZE*3+1]; + // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "ck: %s", ck_print); // Noise Split(), nonces already set in conn crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + LOGGER_DEBUG(c->log, "After Noise Split()"); //TODO: remove - char key[CRYPTO_SECRET_KEY_SIZE*3+1]; - bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "send_key: %s", key); - bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "recv_key: %s", key); - //TODO: wrong here? - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + // bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "send_key: %s", key); + // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "recv_key: %s", key); } else if (!conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR CHANGED TO RESPONDER"); //TODO: remove - char ck_print[CRYPTO_SHA512_SIZE*3+1]; - bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - LOGGER_DEBUG(c->log, "ck: %s", ck_print); - - //TODO: wrong here, RESPONDER still needs to send handshake packet - // responder Noise Split(): vice-verse keys in comparison to initiator - // crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + // char ck_print[CRYPTO_SHA512_SIZE*3+1]; + // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "ck: %s", ck_print); - //TODO: remove - char key[CRYPTO_SECRET_KEY_SIZE*3+1]; - bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "send_key: %s", key); - bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "recv_key: %s", key); - - //TODO: wrong here? - //crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); initiator_change = true; } else { return -1; } } + //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary // Case where RESPONDER with and without change from INITIATOR else if(!conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER"); - crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); @@ -2522,14 +2526,17 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet, length, nullptr, conn->noise_handshake)) { return -1; } - //TODO: create_send_handshake() here? TODO: condition necessary? + // RESPONDER needs to send handshake packet, afterwards finished if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } + + conn->status = CRYPTO_CONN_HANDSHAKE_SENT; + // responder Noise Split(): vice-verse keys in comparison to initiator crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - //TODO: wrong here? - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + //TODO: remove + LOGGER_DEBUG(c->log, "After Noise Split()"); } else { //TODO: remove LOGGER_DEBUG(c->log, "NOT initiator or responder => !conn->noise_handshake->initiator: %d, initiator_change: %d", !conn->noise_handshake->initiator, initiator_change); @@ -2545,14 +2552,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - //TODO: adapt? TODO: what's the case for this? + //TODO: adapt? what's the case for this? if (pk_equal(dht_public_key, conn->dht_public_key)) { LOGGER_DEBUG(c->log, "pk_equal TRUE case"); - //TODO: is this called? => yes - encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + //TODO: this is called + //TODO: necessary for old handshake =>change to OLD handshake condition + //encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); + // OLD handshake case if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; @@ -2561,7 +2570,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (initiator_change) { // responder Noise Split(): vice-verse keys in comparison to initiator + //TODO: currently happens twice for RESPONDER? doesnt change keys, but needless crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + LOGGER_DEBUG(c->log, "After Noise Split()"); } conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -2637,13 +2648,13 @@ non_null() static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING: NUM: %d", num); + // LOGGER_DEBUG(c->log, "ENTERING: NUM: %d", num); if (num == 0) { free(c->crypto_connections); c->crypto_connections = nullptr; //TODO: remove - LOGGER_DEBUG(c->log, "FREE crypto_connections"); + // LOGGER_DEBUG(c->log, "FREE crypto_connections"); return 0; } @@ -2657,7 +2668,7 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) c->crypto_connections = newcrypto_connections; //TODO: remove - LOGGER_DEBUG(c->log, "END: realloc done"); + // LOGGER_DEBUG(c->log, "END: realloc done"); return 0; } @@ -2932,7 +2943,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: Unsure which case this is.. if already called new_crypto_connection() as responder before? //TODO: IMPORTANT!! if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! if (crypt_connection_id != -1) { - LOGGER_DEBUG(c->log, "handle_new_connection_handshake() => CRYPTO CONN EXISTING"); + LOGGER_DEBUG(c->log, "CRYPTO CONN EXISTING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -2948,7 +2959,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! => nope, are set in create_crypto_handshake() - //TODO: there is already something in conn->noise_handshake - need to free in this case! + // there is already something in conn->noise_handshake - need to memzero in this case! crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(struct noise_handshake)); @@ -2967,6 +2978,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // responder Noise Split(): vice-verse keys in comparison to initiator //TODO: remove here? crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + //TODO: remove + LOGGER_DEBUG(c->log, "After Noise Split()"); + //TODO: wrong here? // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); @@ -3068,6 +3082,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (!n_c->noise_handshake->initiator) { //TODO: remove LOGGER_DEBUG(c->log, "NOISE Handshake RESPONDER"); + crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct noise_handshake)); crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); @@ -3080,7 +3095,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // happens in create_crypto_handshake() // memcpy(conn->noise_handshake->ephemeral_private, conn->sessionsecret_key, CRYPTO_PUBLIC_KEY_SIZE); // memcpy(conn->noise_handshake->ephemeral_public, conn->sessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - conn->status = CRYPTO_CONN_NOT_CONFIRMED; + if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { pthread_mutex_lock(&c->tcp_mutex); @@ -3092,6 +3107,12 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // Noise Split(), nonces already set crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + + //TODO: before or after create_send_handshake() (in general) + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + + //TODO: remove + LOGGER_DEBUG(c->log, "After Noise Split()"); //TODO: wrong here? // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); //TODO: memzero stuff from old handshake, also not necessary anymore => TODO: or after established crypto conn? @@ -3204,17 +3225,18 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u //TODO: remove LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); + //TODO: here? // only necessary if Cookie request was successful - if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { - //TODO: - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); - pthread_mutex_lock(&c->tcp_mutex); - kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - pthread_mutex_unlock(&c->tcp_mutex); - wipe_crypto_connection(c, crypt_connection_id); - return -1; - } + // if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { + // //TODO: + // // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // // free(conn->noise_handshake); + // pthread_mutex_lock(&c->tcp_mutex); + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // pthread_mutex_unlock(&c->tcp_mutex); + // wipe_crypto_connection(c, crypt_connection_id); + // return -1; + // } //TODO: remove LOGGER_DEBUG(c->log, "END"); @@ -3694,7 +3716,7 @@ static void send_crypto_packets(Net_Crypto *c) continue; } - //TODO: Use again? + //TODO: Use again? / TODO: adapt? if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { //TODO: remove From 85f4496f80b50e32c6c9b58b4c08707ec59880be Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 3 Oct 2023 17:11:33 +0200 Subject: [PATCH 026/150] fix: fixed current behavior in handle_crypto_hs(). fixed wrong memzero of n_c.noise_handshake. --- toxcore/net_crypto.c | 86 ++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 5a5caaab0f..fa607e6a19 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -70,7 +70,7 @@ typedef struct Crypto_Connection { // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; //TODO: necessary? - uint32_t handshake_send_interval; + uint16_t handshake_send_interval; // bool initiator; // uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; @@ -1007,7 +1007,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - //TODO: + //TODO: remove char log_static[CRYPTO_PUBLIC_KEY_SIZE*3+1]; bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, "local static pub: %s", log_static); @@ -2040,6 +2040,8 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u conn->temp_packet = temp_packet; conn->temp_packet_length = length; conn->temp_packet_sent_time = 0; + //TODO: remove + LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time = 0"); conn->temp_packet_num_sent = 0; return 0; } @@ -2096,6 +2098,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); + LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); ++conn->temp_packet_num_sent; return 0; } @@ -2244,6 +2247,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const int len = handle_data_packet(c, crypt_connection_id, data, packet, length); if (len <= (int)(sizeof(uint32_t) * 2)) { + //TODO: unwanted side effects? + connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2453,12 +2458,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } - //TODO: what if I remove CRYPTO_CONN_NOT_CONFIRMED from here? + //TODO: what if I remove CRYPTO_CONN_NOT_CONFIRMED from here? => doesn't work together with connection_kill() after decrypting failure (after new handshake) if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT && conn->status != CRYPTO_CONN_NOT_CONFIRMED) { return -1; } + // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING + // && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { + // return -1; + // } uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -2475,10 +2484,14 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet, length, conn->public_key, conn->noise_handshake)) { return -1; } + //TODO: Check if still INITIATOR after handle_crypto_handshake(), can change to RESPONDER if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "STILL INITIATOR"); + //TODO: ok here? + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + //TODO: remove // char ck_print[CRYPTO_SHA512_SIZE*3+1]; // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); @@ -2503,11 +2516,26 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // LOGGER_DEBUG(c->log, "ck: %s", ck_print); initiator_change = true; + + //TODO: does this work now? + // RESPONDER needs to send handshake packet, afterwards finished + if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { + return -1; + } + + //TODO: or CRYPTO_HANDSHAKE_SENT? + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + + // responder Noise Split(): vice-verse keys in comparison to initiator + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + //TODO: remove + LOGGER_DEBUG(c->log, "After Noise Split()"); + } else { return -1; } } - //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary + //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary => TODO: need info in conn or noise_handshake // Case where RESPONDER with and without change from INITIATOR else if(!conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER"); @@ -2531,7 +2559,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } - conn->status = CRYPTO_CONN_HANDSHAKE_SENT; + //TODO: or CRYPTO_HANDSHAKE_SENT? + conn->status = CRYPTO_CONN_NOT_CONFIRMED; // responder Noise Split(): vice-verse keys in comparison to initiator crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); @@ -2559,6 +2588,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: necessary for old handshake =>change to OLD handshake condition //encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + //TODO: Noise Split() here? + LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); // OLD handshake case @@ -2568,6 +2599,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } + //TODO: adapt if (initiator_change) { // responder Noise Split(): vice-verse keys in comparison to initiator //TODO: currently happens twice for RESPONDER? doesnt change keys, but needless @@ -2575,7 +2607,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "After Noise Split()"); } - conn->status = CRYPTO_CONN_NOT_CONFIRMED; + //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway + //TODO: necessary for old handshake / backwards compatibility + //conn->status = CRYPTO_CONN_NOT_CONFIRMED; } else { LOGGER_DEBUG(c->log, "pk_equal FALSE case"); if (conn->dht_pk_callback != nullptr) { @@ -2750,7 +2784,8 @@ static int create_crypto_connection(Net_Crypto *c) } //TODO: Remove - //c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 3000); + // c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 800); + // LOGGER_DEBUG(c->log, "handshake_send_interval: %d", c->crypto_connections[id].handshake_send_interval); c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; @@ -2941,7 +2976,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); //TODO: Unsure which case this is.. if already called new_crypto_connection() as responder before? - //TODO: IMPORTANT!! if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! if (crypt_connection_id != -1) { LOGGER_DEBUG(c->log, "CRYPTO CONN EXISTING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2957,24 +2991,23 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, free(n_c.cookie); return -1; } - - //TODO: if this is called as responder and there is already a crypto connection, then the session keys of this peer are lost?! => nope, are set in create_crypto_handshake() // there is already something in conn->noise_handshake - need to memzero in this case! crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(struct noise_handshake)); - - crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); - n_c.noise_handshake = nullptr; memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); crypto_connection_add_source(c, crypt_connection_id, source); + if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { free(n_c.cookie); return -1; } + + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + // responder Noise Split(): vice-verse keys in comparison to initiator //TODO: remove here? crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); @@ -2985,7 +3018,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); //TODO: memzero stuff from old handshake? - conn->status = CRYPTO_CONN_NOT_CONFIRMED; + + crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); + n_c.noise_handshake = nullptr; + free(n_c.cookie); return 0; } @@ -3076,7 +3112,6 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->connection_number_tcp = connection_number_tcp; - //TODO: is this zeroed and freeded memory after handle_new_connection_handshake()?! //TODO: only happening for RESPONDER? if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { @@ -3084,7 +3119,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) LOGGER_DEBUG(c->log, "NOISE Handshake RESPONDER"); crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct noise_handshake)); - crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); + //NOT possible here, need content afterwards! + // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); // necessary -> TODO: duplicated code necessary? memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -3096,7 +3132,6 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // memcpy(conn->noise_handshake->ephemeral_private, conn->sessionsecret_key, CRYPTO_PUBLIC_KEY_SIZE); // memcpy(conn->noise_handshake->ephemeral_public, conn->sessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); @@ -3105,12 +3140,12 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } + //TODO: before or after create_send_handshake() (in general) => AFTER (current status) + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + // Noise Split(), nonces already set crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - //TODO: before or after create_send_handshake() (in general) - conn->status = CRYPTO_CONN_NOT_CONFIRMED; - //TODO: remove LOGGER_DEBUG(c->log, "After Noise Split()"); //TODO: wrong here? @@ -3154,6 +3189,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->rtt_time = DEFAULT_PING_CONNECTION; crypto_connection_add_source(c, crypt_connection_id, &n_c->source); + //TODO: here correct? + crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); + return crypt_connection_id; } @@ -3716,9 +3754,14 @@ static void send_crypto_packets(Net_Crypto *c) continue; } + //TODO: remove + // LOGGER_DEBUG(c->log, "conn->handshake_send_interval: %d", conn->handshake_send_interval); + LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); + // LOGGER_DEBUG(c->log, "(conn->handshake_send_interval + conn->temp_packet_sent_time): %lu", (conn->handshake_send_interval + conn->temp_packet_sent_time)); + LOGGER_DEBUG(c->log, "temp_time: %lu", temp_time); + //TODO: Use again? / TODO: adapt? if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { - //TODO: remove //LOGGER_DEBUG(c->log, "=> call send_temp_packet() => random_backoff: %d", random_backoff); // c_sleep(random_backoff); @@ -3726,7 +3769,6 @@ static void send_crypto_packets(Net_Crypto *c) } //TODO: remove? where to add? - //uint32_t random_backoff = rand() % 1000; // if ((conn->handshake_send_interval + conn->temp_packet_sent_time) < temp_time) { // send_temp_packet(c, i); // } From 46ae442cd15a4f51f135b8fdef870bf5d8de6700 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 4 Oct 2023 14:38:01 +0200 Subject: [PATCH 027/150] cleanup: removed unnecessary code. --- toxcore/net_crypto.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index fa607e6a19..1d67e1d450 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2473,7 +2473,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t cookie[COOKIE_LENGTH]; - //TODO: via noise_handshake struct? + //TODO: via noise_handshake struct? TODO: remove bool initiator_change = false; if (conn->noise_handshake != nullptr) { @@ -2539,17 +2539,18 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // Case where RESPONDER with and without change from INITIATOR else if(!conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER"); - if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { - //TODO: - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); - //TODO: necessary? have no crypt_connection_id here - // pthread_mutex_lock(&c->tcp_mutex); - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // pthread_mutex_unlock(&c->tcp_mutex); - // wipe_crypto_connection(c, crypt_connection_id); - return false; - } + // necessary, otherwise broken after INITIATOR to RESPONDER change + if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { + //TODO: + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // free(conn->noise_handshake); + //TODO: necessary? + // pthread_mutex_lock(&c->tcp_mutex); + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // pthread_mutex_unlock(&c->tcp_mutex); + // wipe_crypto_connection(c, crypt_connection_id); + return false; + } if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; @@ -2599,14 +2600,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - //TODO: adapt - if (initiator_change) { - // responder Noise Split(): vice-verse keys in comparison to initiator - //TODO: currently happens twice for RESPONDER? doesnt change keys, but needless - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - LOGGER_DEBUG(c->log, "After Noise Split()"); - } - //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway //TODO: necessary for old handshake / backwards compatibility //conn->status = CRYPTO_CONN_NOT_CONFIRMED; From be6445aa59297690ff49ffe69c08aaa7458fdf6a Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 4 Oct 2023 16:29:42 +0200 Subject: [PATCH 028/150] Implemented different handshake behavior. Currently fails at create_send_handshake() because of a nullptr. --- toxcore/net_crypto.c | 139 ++++++++++++++++++++++++------------------- 1 file changed, 78 insertions(+), 61 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1d67e1d450..b6b779b761 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -921,32 +921,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t LOGGER_DEBUG(c->log, "ENTERING"); if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); - - if (!noise_handshake->initiator) { - if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - LOGGER_DEBUG(c->log, "NOISE handshake => RESPONDER: length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); - //TODO: wipe in this case? //TODO: wipe crypto conn or just noise_handshake? - return false; - } - } else if (noise_handshake->initiator) { - if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { - LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR: length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); - //TODO: initialize here as responder? - if (noise_handshake_init(c->log, noise_handshake, c->self_secret_key, nullptr, false) != 0) { - //TODO: - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); - //TODO: necessary? have no crypt_connection_id here - // pthread_mutex_lock(&c->tcp_mutex); - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // pthread_mutex_unlock(&c->tcp_mutex); - // wipe_crypto_connection(c, crypt_connection_id); - return false; - } - } - } else { - return false; - } uint8_t cookie_plain[COOKIE_DATA_LENGTH]; @@ -2118,9 +2092,13 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { + //TODO: remove + LOGGER_DEBUG(c->log, "nullptr"); return -1; } + LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); + if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; @@ -2479,15 +2457,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => NOISE HANDHSHAKE"); if (conn->noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "INITIATOR"); - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + LOGGER_DEBUG(c->log, "INITIATOR received RESPONDER HS Packet"); + if(length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, conn->noise_handshake)) { - return -1; - } - - //TODO: Check if still INITIATOR after handle_crypto_handshake(), can change to RESPONDER - if (conn->noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "STILL INITIATOR"); + return -1; + } //TODO: ok here? conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -2507,8 +2482,24 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // LOGGER_DEBUG(c->log, "send_key: %s", key); // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "recv_key: %s", key); - } else if (!conn->noise_handshake->initiator) { + } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "INITIATOR CHANGED TO RESPONDER"); + if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { + //TODO: + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // free(conn->noise_handshake); + //TODO: necessary? + // pthread_mutex_lock(&c->tcp_mutex); + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // pthread_mutex_unlock(&c->tcp_mutex); + // wipe_crypto_connection(c, crypt_connection_id); + return -1; + } + + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + packet, length, conn->public_key, conn->noise_handshake)) { + return -1; + } //TODO: remove // char ck_print[CRYPTO_SHA512_SIZE*3+1]; @@ -2530,7 +2521,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "After Noise Split()"); - } else { return -1; } @@ -2539,34 +2529,41 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // Case where RESPONDER with and without change from INITIATOR else if(!conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER"); - // necessary, otherwise broken after INITIATOR to RESPONDER change - if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { - //TODO: - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); - //TODO: necessary? - // pthread_mutex_lock(&c->tcp_mutex); - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // pthread_mutex_unlock(&c->tcp_mutex); - // wipe_crypto_connection(c, crypt_connection_id); - return false; - } - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + // necessary, otherwise broken after INITIATOR to RESPONDER change + if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { + //TODO: + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // free(conn->noise_handshake); + //TODO: necessary? + // pthread_mutex_lock(&c->tcp_mutex); + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // pthread_mutex_unlock(&c->tcp_mutex); + // wipe_crypto_connection(c, crypt_connection_id); + return false; + } + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { - return -1; + return -1; + } + // RESPONDER needs to send handshake packet, afterwards finished + if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { + return -1; + } + + //TODO: or CRYPTO_HANDSHAKE_SENT? + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + + // responder Noise Split(): vice-verse keys in comparison to initiator + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + //TODO: remove + LOGGER_DEBUG(c->log, "After Noise Split()"); } - // RESPONDER needs to send handshake packet, afterwards finished - if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { + else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + // cannot chagne to INITIATOR here, connection broken + connection_kill(c, crypt_connection_id, userdata); return -1; } - - //TODO: or CRYPTO_HANDSHAKE_SENT? - conn->status = CRYPTO_CONN_NOT_CONFIRMED; - - // responder Noise Split(): vice-verse keys in comparison to initiator - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - //TODO: remove - LOGGER_DEBUG(c->log, "After Noise Split()"); } else { //TODO: remove LOGGER_DEBUG(c->log, "NOT initiator or responder => !conn->noise_handshake->initiator: %d, initiator_change: %d", !conn->noise_handshake->initiator, initiator_change); @@ -2959,6 +2956,14 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } + //TODO: remove + char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + bytes2string(log_spub, sizeof(log_spub), n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "session pub: %s", log_spub); + char log_cookie[COOKIE_LENGTH*3+1]; + bytes2string(log_cookie, sizeof(log_cookie), n_c.cookie, COOKIE_LENGTH, c->log); + LOGGER_DEBUG(c->log, "cookie: %s", log_cookie); + //TODO: case old handshake // if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, // n_c.cookie, data, length, nullptr, nullptr)) { @@ -3110,7 +3115,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (!n_c->noise_handshake->initiator) { //TODO: remove LOGGER_DEBUG(c->log, "NOISE Handshake RESPONDER"); - crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // needless after calloc + //crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct noise_handshake)); //NOT possible here, need content afterwards! // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); @@ -3125,6 +3131,17 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // memcpy(conn->noise_handshake->ephemeral_private, conn->sessionsecret_key, CRYPTO_PUBLIC_KEY_SIZE); // memcpy(conn->noise_handshake->ephemeral_public, conn->sessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: remove + char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + bytes2string(log_spub, sizeof(log_spub), n_c->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "NC session pub: %s", log_spub); + char log_cookie[COOKIE_LENGTH*3+1]; + bytes2string(log_cookie, sizeof(log_cookie), n_c->cookie, COOKIE_LENGTH, c->log); + LOGGER_DEBUG(c->log, "NC cookie: %s", log_cookie); + char log_conn[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + bytes2string(log_conn, sizeof(log_conn), conn->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "CONN session pub: %s", log_conn); + if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); From 721f887e5517f10d74c6f90cb4f9086d04a44ba0 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 4 Oct 2023 19:40:35 +0200 Subject: [PATCH 029/150] fix/cleanup: fixed connection status bug in accept_crypto_connection() - status needs to be set _before_ create_send_handshake(). Cleaned up/adapted debug logging. --- toxcore/net_crypto.c | 104 +++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index b6b779b761..9bcf66bbdc 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -937,7 +937,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* -> e, es, s, ss */ if(!noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "NOISE handshake => RESPONDER"); + LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); /* Initiator: Handshake packet structure => THIS IS HANDLED HERE [uint8_t 26] [Cookie 112 bytes] @@ -978,6 +978,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t if(noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { + LOGGER_DEBUG(c->log, "RESPONDER: Noise ReadMessage remote static decryption failed"); return false; } @@ -1003,13 +1004,14 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + LOGGER_DEBUG(c->log, "RESPONDER: Noise HS payload decryption failed"); return false; } crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { - LOGGER_DEBUG(c->log, "NOISE handshake => RESPONDER => COOKIE HASH WRONG"); + LOGGER_DEBUG(c->log, "RESPONDER: COOKIE HASH WRONG"); return false; } @@ -1021,13 +1023,13 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet? - LOGGER_DEBUG(c->log, "END NOISE handshake => RESPONDER"); + LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); return true; } /* ReadMessage() if initiator: <- e, ee, se */ else if(noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "ENTERING NOISE handshake => INITIATOR"); + LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); /* Responder: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] @@ -1070,7 +1072,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { - LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake decryption failed"); + LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); return false; } @@ -1088,7 +1090,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - LOGGER_DEBUG(c->log, "END NOISE handshake => INITIATOR"); + LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); return true; } else { return false; @@ -1890,7 +1892,8 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, nullptr, 0); - LOGGER_DEBUG(c->log, "decrypt len: %d", len); + //TODO: remove + // LOGGER_DEBUG(c->log, "data packet decrypt len: %d", len); if ((unsigned int)len != length - crypto_packet_overhead) { return -1; @@ -2226,6 +2229,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (len <= (int)(sizeof(uint32_t) * 2)) { //TODO: unwanted side effects? + LOGGER_DEBUG(c->log, "connection_kill() because data packet decryption failure, len: %d", len); connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2427,7 +2431,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const void *userdata) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "ENTERING: handle_packet_crypto_hs(); crypt_connection_id: %d => PACKET: %d => NET_PACKET_CRYPTO_HS => CRYPTO CONN STATE: %d", + LOGGER_DEBUG(c->log, "ENTERING: crypt_connection_id: %d | PACKET: %d | CRYPTO CONN STATE: %d", crypt_connection_id, packet[0], conn->status); @@ -2442,6 +2446,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const && conn->status != CRYPTO_CONN_NOT_CONFIRMED) { return -1; } + //TODO: unwanted side effects? => yes, see above // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING // && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { // return -1; @@ -2455,10 +2460,11 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const bool initiator_change = false; if (conn->noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => NOISE HANDHSHAKE"); + LOGGER_DEBUG(c->log, "NOISE HANDHSHAKE"); if (conn->noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "INITIATOR received RESPONDER HS Packet"); if(length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + LOGGER_DEBUG(c->log, "INITIATOR: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); + //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, conn->noise_handshake)) { return -1; @@ -2474,7 +2480,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // Noise Split(), nonces already set in conn crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); - LOGGER_DEBUG(c->log, "After Noise Split()"); + LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); //TODO: remove // char key[CRYPTO_SECRET_KEY_SIZE*3+1]; @@ -2483,7 +2489,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "recv_key: %s", key); } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - LOGGER_DEBUG(c->log, "INITIATOR CHANGED TO RESPONDER"); + LOGGER_DEBUG(c->log, "INITIATOR: CHANGED TO RESPONDER"); if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); @@ -2520,7 +2526,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // responder Noise Split(): vice-verse keys in comparison to initiator crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove - LOGGER_DEBUG(c->log, "After Noise Split()"); + LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } else { return -1; } @@ -2528,8 +2534,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary => TODO: need info in conn or noise_handshake // Case where RESPONDER with and without change from INITIATOR else if(!conn->noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "RESPONDER"); if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); // necessary, otherwise broken after INITIATOR to RESPONDER change if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: @@ -2557,9 +2563,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // responder Noise Split(): vice-verse keys in comparison to initiator crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove - LOGGER_DEBUG(c->log, "After Noise Split()"); + LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); // cannot chagne to INITIATOR here, connection broken connection_kill(c, crypt_connection_id, userdata); return -1; @@ -2617,7 +2624,7 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); //TODO: remove from prod code - LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d => CRYPTO CONN STATE: %d", + LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d | CRYPTO CONN STATE: %d", packet[0], conn->status); @@ -2946,7 +2953,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } //TODO: remove - LOGGER_DEBUG(c->log, "After Handshake init"); + LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { @@ -2957,12 +2964,12 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } //TODO: remove - char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; - bytes2string(log_spub, sizeof(log_spub), n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "session pub: %s", log_spub); - char log_cookie[COOKIE_LENGTH*3+1]; - bytes2string(log_cookie, sizeof(log_cookie), n_c.cookie, COOKIE_LENGTH, c->log); - LOGGER_DEBUG(c->log, "cookie: %s", log_cookie); + // char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + // bytes2string(log_spub, sizeof(log_spub), n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "RESPONDER: session pub: %s", log_spub); + // char log_cookie[COOKIE_LENGTH*3+1]; + // bytes2string(log_cookie, sizeof(log_cookie), n_c.cookie, COOKIE_LENGTH, c->log); + // LOGGER_DEBUG(c->log, "RESPONDER: cookie: %s", log_cookie); //TODO: case old handshake // if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, @@ -2975,7 +2982,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: Unsure which case this is.. if already called new_crypto_connection() as responder before? if (crypt_connection_id != -1) { - LOGGER_DEBUG(c->log, "CRYPTO CONN EXISTING"); + LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -3010,7 +3017,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: remove here? crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove - LOGGER_DEBUG(c->log, "After Noise Split()"); + LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); //TODO: wrong here? // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); @@ -3077,7 +3084,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (getcryptconnection_id(c, n_c->public_key) != -1) { //TODO: remove - LOGGER_DEBUG(c->log, "Crypto Connection already exists"); + LOGGER_DEBUG(c->log, "RESPONDER: Crypto Connection already exists"); return -1; } @@ -3085,7 +3092,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: remove //TODO: Print pub key of peer? - LOGGER_DEBUG(c->log, "AFTER: create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "RESPONDER: AFTER: create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { LOGGER_ERROR(c->log, "Could not create new crypto connection"); @@ -3114,7 +3121,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { //TODO: remove - LOGGER_DEBUG(c->log, "NOISE Handshake RESPONDER"); + LOGGER_DEBUG(c->log, "Responder: Noise WriteMessage"); // needless after calloc //crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct noise_handshake)); @@ -3131,16 +3138,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // memcpy(conn->noise_handshake->ephemeral_private, conn->sessionsecret_key, CRYPTO_PUBLIC_KEY_SIZE); // memcpy(conn->noise_handshake->ephemeral_public, conn->sessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: remove - char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; - bytes2string(log_spub, sizeof(log_spub), n_c->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "NC session pub: %s", log_spub); - char log_cookie[COOKIE_LENGTH*3+1]; - bytes2string(log_cookie, sizeof(log_cookie), n_c->cookie, COOKIE_LENGTH, c->log); - LOGGER_DEBUG(c->log, "NC cookie: %s", log_cookie); - char log_conn[CRYPTO_PUBLIC_KEY_SIZE*3+1]; - bytes2string(log_conn, sizeof(log_conn), conn->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "CONN session pub: %s", log_conn); + //TODO: before or after create_send_handshake() (in general) => IMPORTANT: in this case here, otherwise get_crypto_connection() in create_send_handshake() returns a nullptr + conn->status = CRYPTO_CONN_NOT_CONFIRMED; if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { pthread_mutex_lock(&c->tcp_mutex); @@ -3150,14 +3149,11 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - //TODO: before or after create_send_handshake() (in general) => AFTER (current status) - conn->status = CRYPTO_CONN_NOT_CONFIRMED; - // Noise Split(), nonces already set crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove - LOGGER_DEBUG(c->log, "After Noise Split()"); + LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); //TODO: wrong here? // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); //TODO: memzero stuff from old handshake, also not necessary anymore => TODO: or after established crypto conn? @@ -3221,14 +3217,14 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u if (crypt_connection_id != -1) { //TODO: remove //TODO: Print pub key? - LOGGER_DEBUG(c->log, "Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "INITIATOR: Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); return crypt_connection_id; } crypt_connection_id = create_crypto_connection(c); //TODO: remove - LOGGER_DEBUG(c->log, "AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "INITIATOR: AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { return -1; @@ -3260,7 +3256,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; //TODO: remove - LOGGER_DEBUG(c->log, "BEFORE: create_cookie_request()"); + // LOGGER_DEBUG(c->log, "INITIATOR: BEFORE: create_cookie_request()"); + if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, conn->shared_key) != sizeof(cookie_request) || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { @@ -3270,8 +3267,9 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u wipe_crypto_connection(c, crypt_connection_id); return -1; } + //TODO: remove - LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); + // LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); //TODO: here? // only necessary if Cookie request was successful @@ -3287,7 +3285,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // } //TODO: remove - LOGGER_DEBUG(c->log, "END"); + LOGGER_DEBUG(c->log, "INITIATOR: END"); return crypt_connection_id; } @@ -3764,13 +3762,13 @@ static void send_crypto_packets(Net_Crypto *c) continue; } - //TODO: remove + //TODO: remove TODO: interesting if want to adapt interval // LOGGER_DEBUG(c->log, "conn->handshake_send_interval: %d", conn->handshake_send_interval); - LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); + // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); // LOGGER_DEBUG(c->log, "(conn->handshake_send_interval + conn->temp_packet_sent_time): %lu", (conn->handshake_send_interval + conn->temp_packet_sent_time)); - LOGGER_DEBUG(c->log, "temp_time: %lu", temp_time); + // LOGGER_DEBUG(c->log, "temp_time: %lu", temp_time); - //TODO: Use again? / TODO: adapt? + //TODO: Use again? / TODO: adapt interval? if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { //TODO: remove //LOGGER_DEBUG(c->log, "=> call send_temp_packet() => random_backoff: %d", random_backoff); @@ -4107,7 +4105,7 @@ int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + // LOGGER_DEBUG(c->log, "ENTERING"); if (conn == nullptr) { return -1; @@ -4324,7 +4322,7 @@ static void kill_timedout(Net_Crypto *c, void *userdata) continue; } - //TODO: remove + //TODO: remove LOGGER_DEBUG(c->log, "connection_kill"); connection_kill(c, i, userdata); } From ecd7312cf42e05fc34cbb664792fc997f08d0f26 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Thu, 30 Nov 2023 20:25:48 +0100 Subject: [PATCH 030/150] cleanup: Removed unused crypto_hmac512_verify(). Moved generic noise_* functions to crypto_core. Use function based on libsodium bin2hex() to print bytes for debugging (instead of custom func). --- toxcore/crypto_core.c | 74 ++++++++++++++++++++++++++++++++++--- toxcore/crypto_core.h | 46 +++++++++++++++++++---- toxcore/net_crypto.c | 86 ++----------------------------------------- toxcore/net_crypto.h | 1 + 4 files changed, 111 insertions(+), 96 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index c1a6d1cd1e..8307bc8a65 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -605,12 +605,6 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S { crypto_auth_hmacsha512(auth, data, length, key); } -//TODO: verify needed? TODO: key size correct? -bool crypto_hmac512_verify(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], - const uint8_t *data, size_t length) -{ - return crypto_auth_hmacsha512_verify(auth, data, length, key) == 0; -} /* This is Hugo Krawczyk's HKDF: * - https://eprint.iacr.org/2010/264.pdf @@ -733,3 +727,71 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length) { rng->funcs->random_bytes(rng->obj, bytes, length); } + +/* Noise part */ + +/* +* TODO: Implements MixKey(input_key_material) +* input_key_material = DH_X25519(private, public) +*/ +bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) +{ + uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; + + // X25519 - returns plain DH result, afterwards hashed with HKDF + encrypt_precompute(public, private, dh_calculation); + // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! + crypto_hkdf(chaining_key, shared_key, nullptr, dh_calculation, CRYPTO_SHA512_SIZE, + CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); + //If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() + crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); + return true; +} + +/* +* TODO: MixHash(data) as defined in Noise spec +*/ +void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) +{ + uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; + memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); + memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); + crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); +} + +/* +* TODO: EncryptAndHash(plaintext) as defined in Noise spec besides +* "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." +* because this is not the case in Tox. +*/ +void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, + size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) +{ + unsigned long long encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, + plaintext, plain_length, ciphertext, + hash, CRYPTO_SHA512_SIZE); + + noise_mix_hash(hash, ciphertext, encrypted_length); +} + +/* +* TODO: DecryptAndHash(plaintext) as defined in Noise spec besides +* "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." +* because this is not the case in Tox. +*/ +int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, + size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) +{ + unsigned long long plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, + ciphertext, encrypted_length, plaintext, + hash, CRYPTO_SHA512_SIZE); + + noise_mix_hash(hash, ciphertext, encrypted_length); + + return plaintext_length; +} diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index af6e45106c..4560d15524 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -184,14 +184,6 @@ non_null() void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t length); -/** - * @brief Verify an HMAC authenticator. - * TODO: verify needed? - */ -non_null() -bool crypto_hmac512_verify(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], - const uint8_t *data, size_t length); - /* This is Hugo Krawczyk's HKDF: * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 @@ -521,6 +513,44 @@ bool crypto_memunlock(void *data, size_t length); non_null() void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); +/* Noise Part */ + +/* +* TODO: Implements MixKey(input_key_material) +* input_key_material = DH_X25519(private, public) +*/ +non_null() +bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]); + +/* +* TODO: MixHash(data) as defined in Noise spec +*/ +non_null() +void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len); + +/* +* TODO: EncryptAndHash(plaintext) as defined in Noise spec besides +* "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." +* because this is not the case in Tox. +*/ +non_null() +void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, + size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); + +/* +* TODO: DecryptAndHash(plaintext) as defined in Noise spec besides +* "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." +* because this is not the case in Tox. +*/ +non_null() +int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, + size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); + #ifdef __cplusplus } // extern "C" #endif diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 9bcf66bbdc..28b68dcbd4 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -13,8 +13,8 @@ #include #include #include -//TODO: remove -#include +//TODO: remove, used to for bin2hex_toupper() function to print/log bytes +#include "../other/fun/create_common.h" #include "ccompat.h" #include "list.h" @@ -495,92 +495,14 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -/* -* TODO: Implements MixKey(input_key_material) -* input_key_material = DH_X25519(private, public) -*/ - -static bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], - const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) -{ - uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; - - // X25519 - returns plain DH result, afterwards hashed with HKDF - encrypt_precompute(public, private, dh_calculation); - // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! - crypto_hkdf(chaining_key, shared_key, nullptr, dh_calculation, CRYPTO_SHA512_SIZE, - CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); - //If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() - crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); - return true; -} - -/* -* TODO: MixHash(data) as defined in Noise spec -*/ -static void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) -{ - uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; - memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); - memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); - crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); -} - -/* -* TODO: EncryptAndHash(plaintext) as defined in Noise spec besides -* "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." -* because this is not the case in Tox. -*/ -static void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, - size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) -{ - unsigned long long encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, - plaintext, plain_length, ciphertext, - hash, CRYPTO_SHA512_SIZE); - - noise_mix_hash(hash, ciphertext, encrypted_length); -} - -/* -* TODO: DecryptAndHash(plaintext) as defined in Noise spec besides -* "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." -* because this is not the case in Tox. -*/ -static int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, - size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) -{ - unsigned long long plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, - ciphertext, encrypted_length, plaintext, - hash, CRYPTO_SHA512_SIZE); - - noise_mix_hash(hash, ciphertext, encrypted_length); - - return plaintext_length; -} - /* * TODO: helper function to print hashes, keys, packets, etc. * TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? +* uses sodium_bin2hex() via bin2hex_toupper() function from `../other/fun/create_common.h` */ static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, size_t bytes_size, const Logger *log) { - int i; - char *log_buf = string; - char *log_buf_endofbuf = log_buf + string_size; - for (i = 0; i < bytes_size; i++) { - /* i use 4 here since we are going to add at most - 3 chars, need a space for a null terminator */ - if (log_buf + 4 < log_buf_endofbuf) { - if (i > 0) { - log_buf += sprintf(log_buf, ":"); - } - log_buf += sprintf(log_buf, "%02X", bytes[i]); - } - } + bin2hex_toupper(string, string_size, bytes, bytes_size); } /* diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index feb9263009..3c27c80390 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -121,6 +121,7 @@ non_null() TCP_Connections *nc_get_tcp_c(const Net_Crypto *c); non_null() DHT *nc_get_dht(const Net_Crypto *c); //TODO: struct necessary? +//TODO: move to crypto_core.h? typedef struct noise_handshake { //TODO: static_private? uint8_t static_private[CRYPTO_PUBLIC_KEY_SIZE]; From c80bbb303c95ce1f58b4d58751c2799b9a964af8 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 1 Dec 2023 13:46:08 +0100 Subject: [PATCH 031/150] fix: fix compiler error due to usage of public/private. --- toxcore/crypto_core.c | 6 +++--- toxcore/crypto_core.h | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 8307bc8a65..596e7b6e83 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -736,13 +736,13 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length) */ bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], - const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]) + const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; // X25519 - returns plain DH result, afterwards hashed with HKDF - encrypt_precompute(public, private, dh_calculation); + encrypt_precompute(public_key, private_key, dh_calculation); // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! crypto_hkdf(chaining_key, shared_key, nullptr, dh_calculation, CRYPTO_SHA512_SIZE, CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 4560d15524..c81d955e26 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -520,10 +520,9 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); * input_key_material = DH_X25519(private, public) */ non_null() -bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - const uint8_t private[CRYPTO_PUBLIC_KEY_SIZE], - const uint8_t public[CRYPTO_PUBLIC_KEY_SIZE]); +bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); /* * TODO: MixHash(data) as defined in Noise spec From e052b5d4687d495aa4a041f72c8310e34e5810a6 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 1 Dec 2023 17:34:00 +0100 Subject: [PATCH 032/150] cleanup/doc: Cleaned up Noise related code in crypto_core. Added Noise functions to end of crypto_core files. Added documentation and comments. --- toxcore/crypto_core.c | 294 +++++++++++++++++++----------------------- toxcore/crypto_core.h | 235 ++++++++++++++++++++------------- 2 files changed, 278 insertions(+), 251 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 596e7b6e83..b7897797f2 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -285,90 +285,6 @@ int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, #endif } -//TODO: without encrypted_length parameter -size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, - const uint8_t *plain, size_t plain_length, uint8_t *encrypted, - const uint8_t *ad, size_t ad_length) -{ - // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium - if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { - return -1; - } - - unsigned long long encrypted_length = 0; - - // nsec is not used by this particular construction and should always be NULL. - if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, - ad, ad_length, NULL, nonce, shared_key) != 0) { - return -1; - } - - //assert(length < INT32_MAX - crypto_box_MACBYTES); - return encrypted_length; -} -//TODO: with encrypted_length parameter -// int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, -// const uint8_t *plain, size_t plain_length, uint8_t *encrypted, -// size_t encrypted_length, const uint8_t *ad, size_t ad_length) -// { -// // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium -// if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { -// return -1; -// } - -// // nsec is not used by this particular construction and should always be NULL. -// if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, -// ad, ad_length, NULL, nonce, shared_key) != 0) { -// return -1; -// } - -// //assert(length < INT32_MAX - crypto_box_MACBYTES); -// return (int32_t)(encrypted_length); -// } - -//TODO: without plain_length parameter -size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, - const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, - const uint8_t *ad, size_t ad_length) -{ - // plain_length is calculated by libsodium - //TODO: encrypted length is longer than crypto_box_BOXZEROBYTES => Why is this check here? - // if (encrypted_length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr - // || plain == nullptr) { - // return -1; - // } - - unsigned long long plain_length = 0; - - if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, NULL, encrypted, - encrypted_length, ad, ad_length, nonce, shared_key) != 0) { - return -1; - } - - // assert(length > crypto_box_MACBYTES); - // assert(length < INT32_MAX); - return plain_length; -} -//TODO: with plain_length parameter -// int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, -// const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, -// size_t plain_length, const uint8_t *ad, size_t ad_length) -// { -// // plain_length is calculated by libsodium -// if (encrypted_length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr -// || plain == nullptr) { -// return -1; -// } -// if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, NULL, encrypted, -// encrypted_length, ad, ad_length, nonce, shared_key) != 0) { -// return -1; -// } - -// // assert(length > crypto_box_MACBYTES); -// // assert(length < INT32_MAX); -// return (int32_t)(plain_length); -// } - int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t length, uint8_t *encrypted) { @@ -594,69 +510,6 @@ bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[ #endif } -/* -* HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of -* `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of -* of 32 bytes (SHA512-256 HASHLEN). -* TODO: key size correct? -*/ -void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, - size_t length) -{ - crypto_auth_hmacsha512(auth, data, length, key); -} - -/* This is Hugo Krawczyk's HKDF: - * - https://eprint.iacr.org/2010/264.pdf - * - https://tools.ietf.org/html/rfc5869 - * HKDF(chaining_key, input_key_material, num_outputs): Takes a -chaining_key byte sequence of length HASHLEN, and an input_key_material -byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes. -Returns a pair or triple of byte sequences each of length HASHLEN, -depending on whether num_outputs is two or three: -– Sets temp_key = HMAC-HASH(chaining_key, input_key_material). -– Sets output1 = HMAC-HASH(temp_key, byte(0x01)). -– Sets output2 = HMAC-HASH(temp_key, output1 || byte(0x02)). -– If num_outputs == 2 then returns the pair (output1, output2). -– Sets output3 = HMAC-HASH(temp_key, output2 || byte(0x03)). -– Returns the triple (output1, output2, output3). - -Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in -length. Also note that the HKDF() function is simply HKDF from [4] with the -chaining_key as HKDF salt, and zero-length HKDF info. - */ -void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, - size_t first_len, size_t second_len, size_t third_len, - size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) -{ - uint8_t output[CRYPTO_SHA512_SIZE + 1]; - // temp_key = secret in WG - uint8_t temp_key[CRYPTO_SHA512_SIZE]; - - /* Extract entropy from data into temp_key */ - // data => input_key_material => DH result in Noise - crypto_hmac512(temp_key, chaining_key, data, data_len); - - /* Expand first key: key = temp_key, data = 0x1 */ - output[0] = 1; - crypto_hmac512(output, temp_key, output, 1); - memcpy(output1, output, first_len); - - /* Expand second key: key = secret, data = first-key || 0x2 */ - output[CRYPTO_SHA512_SIZE] = 2; - crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); - memcpy(output2, output, second_len); - - /* Expand third key: key = temp_key, data = second-key || 0x3 */ - output[CRYPTO_SHA512_SIZE] = 3; - crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); - memcpy(output3, output, third_len); - - /* Clear sensitive data from stack */ - crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); - crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); -} - void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION @@ -728,13 +581,127 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length) rng->funcs->random_bytes(rng->obj, bytes, length); } -/* Noise part */ +/* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ + +size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, + const uint8_t *plain, size_t plain_length, uint8_t *encrypted, + const uint8_t *ad, size_t ad_length) +{ + // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium + if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { + return -1; + } + + unsigned long long encrypted_length = 0; + + // nsec is not used by this particular construction and should always be NULL. + if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, + ad, ad_length, NULL, nonce, shared_key) != 0) { + return -1; + } + + //assert(length < INT32_MAX - crypto_box_MACBYTES); + return encrypted_length; +} + +size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, + const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, + const uint8_t *ad, size_t ad_length) +{ + // Additional data ad can be a NULL pointer with ad_length equal to 0; plain_length is calculated by libsodium + if (encrypted_length <= CRYPTO_MAC_SIZE || shared_key == nullptr || nonce == nullptr || encrypted == nullptr + || plain == nullptr) { + return -1; + } + + unsigned long long plain_length = 0; + + if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, NULL, encrypted, + encrypted_length, ad, ad_length, nonce, shared_key) != 0) { + return -1; + } + + // assert(length > crypto_box_MACBYTES); + // assert(length < INT32_MAX); + return plain_length; +} /* -* TODO: Implements MixKey(input_key_material) -* input_key_material = DH_X25519(private, public) +* cf. Noise sections 4.3 and 5.1 +* Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. +* This function is only called via `crypto_hkdf()`. +* HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of +* `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of +* of 32 bytes (SHA512-256 HASHLEN). Cf. https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512 +* key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) +* is always HASHLEN bytes. */ -bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], +void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, + size_t data_length) +{ + crypto_auth_hmacsha512(auth, data, data_length, key); +} + +/* This is Hugo Krawczyk's HKDF: + * - https://eprint.iacr.org/2010/264.pdf + * - https://tools.ietf.org/html/rfc5869 + * HKDF(chaining_key, input_key_material, num_outputs): Takes a + * chaining_key byte sequence of length HASHLEN, and an input_key_material + * byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes. + * Returns a pair or triple of byte sequences each of length HASHLEN, + * depending on whether num_outputs is two or three: + * – Sets temp_key = HMAC-HASH(chaining_key, input_key_material). + * – Sets output1 = HMAC-HASH(temp_key, byte(0x01)). + * – Sets output2 = HMAC-HASH(temp_key, output1 || byte(0x02)). + * – If num_outputs == 2 then returns the pair (output1, output2). + * – Sets output3 = HMAC-HASH(temp_key, output2 || byte(0x03)). + * – Returns the triple (output1, output2, output3). + * Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in + * length. Also note that the HKDF() function is simply HKDF with the + * chaining_key as HKDF salt, and zero-length HKDF info. + */ +void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, + size_t first_len, size_t second_len, size_t third_len, + size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) +{ + uint8_t output[CRYPTO_SHA512_SIZE + 1]; + // temp_key = secret in WG + uint8_t temp_key[CRYPTO_SHA512_SIZE]; + + /* Extract entropy from data into temp_key */ + // data => input_key_material => DH result in Noise + crypto_hmac512(temp_key, chaining_key, data, data_len); + + /* Expand first key: key = temp_key, data = 0x1 */ + output[0] = 1; + crypto_hmac512(output, temp_key, output, 1); + memcpy(output1, output, first_len); + + /* Expand second key: key = secret, data = first-key || 0x2 */ + output[CRYPTO_SHA512_SIZE] = 2; + crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); + memcpy(output2, output, second_len); + + /* Expand third key: key = temp_key, data = second-key || 0x3 */ + /* Currently not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ + output[CRYPTO_SHA512_SIZE] = 3; + crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); + memcpy(output3, output, third_len); + + /* Clear sensitive data from stack */ + crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); + crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); +} + +/* + * cf. Noise section 5.2 + * Executes the following steps: + * - Sets ck, temp_k = HKDF(ck, input_key_material, 2). + * - If HASHLEN is 64, then truncates temp_k to 32 bytes + * - Calls InitializeKey(temp_k). + * input_key_material = DH_X25519(private, public) + */ +void noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) @@ -746,14 +713,15 @@ bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! crypto_hkdf(chaining_key, shared_key, nullptr, dh_calculation, CRYPTO_SHA512_SIZE, CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); - //If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() + // If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); - return true; } /* -* TODO: MixHash(data) as defined in Noise spec -*/ + * Noise MixHash(data): Sets h = HASH(h || data). + * + * cf. Noise section 5.2 + */ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) { uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; @@ -763,10 +731,10 @@ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_ } /* -* TODO: EncryptAndHash(plaintext) as defined in Noise spec besides -* "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." -* because this is not the case in Tox. -*/ + * cf. Noise section 5.2 + * "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." + * This is not the case in Tox. + */ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) @@ -779,10 +747,10 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, } /* -* TODO: DecryptAndHash(plaintext) as defined in Noise spec besides -* "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." -* because this is not the case in Tox. -*/ + * cf. Noise section 5.2 + * "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." + * This is not the case in Tox. + */ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index c81d955e26..98721d8a61 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -159,7 +159,7 @@ void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length); /** * @brief Compute an HMAC authenticator (32 bytes). - * + * * @param auth Resulting authenticator. * @param key Secret key, as generated by `new_hmac_key()`. */ @@ -174,39 +174,6 @@ non_null() bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[CRYPTO_HMAC_KEY_SIZE], const uint8_t *data, size_t length); -/** - * @brief Compute an HMAC authenticator (32 bytes). - * - * @param auth Resulting authenticator. - * @param key Secret key - */ -non_null() -void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, - size_t length); - -/* This is Hugo Krawczyk's HKDF: - * - https://eprint.iacr.org/2010/264.pdf - * - https://tools.ietf.org/html/rfc5869 - * HKDF(chaining_key, input_key_material, num_outputs): Takes a -chaining_key byte sequence of length HASHLEN, and an input_key_material -byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes. -Returns a pair or triple of byte sequences each of length HASHLEN, -depending on whether num_outputs is two or three: -– Sets temp_key = HMAC-HASH(chaining_key, input_key_material). -– Sets output1 = HMAC-HASH(temp_key, byte(0x01)). -– Sets output2 = HMAC-HASH(temp_key, output1 || byte(0x02)). -– If num_outputs == 2 then returns the pair (output1, output2). -– Sets output3 = HMAC-HASH(temp_key, output2 || byte(0x03)). -– Returns the triple (output1, output2, output3). - -Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in -length. Also note that the HKDF() function is simply HKDF from [4] with the -chaining_key as HKDF salt, and zero-length HKDF info. - */ -void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, - size_t first_len, size_t second_len, size_t third_len, - size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); - /** * @brief Compare 2 public keys of length @ref CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to * timing attacks. @@ -398,41 +365,6 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const non_null() int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *shared_key); -/** - * @brief Encrypt message with precomputed shared key using XChaCha20-Poly1305. - * - * Encrypts plain of length length to encrypted of length + @ref CRYPTO_MAC_SIZE - * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NONCE_SIZE - * byte nonce. The encrypted message, as well as a tag authenticating both the confidential - * message m and adlen bytes of non-confidential data ad, are put into encrypted. - * - * @retval -1 if there was a problem. - * @return length of encrypted data if everything was fine. - */ -non_null() -//TODO: which is the final one? -// int32_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, - // uint8_t *encrypted, size_t encrypted_length, const uint8_t *ad, size_t ad_length); -size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, - uint8_t *encrypted, const uint8_t *ad, size_t ad_length); - -/** - * @brief Decrypt message with precomputed shared key using XChaCha20-Poly1305. - * - * Decrypts encrypted of length encrypted_length to plain of plain_length - * `length - CRYPTO_MAC_SIZE` using a shared key @ref CRYPTO_SHARED_KEY_SIZE - * big and a @ref CRYPTO_NONCE_SIZE byte nonce. - * - * @retval -1 if there was a problem (decryption failed). - * @return length of plain data if everything was fine. - */ -non_null() -//TODO: which is the final one? -// int32_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, -// uint8_t *plain, size_t plain_length, const uint8_t *ad, size_t ad_length); -size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, - uint8_t *plain, const uint8_t *ad, size_t ad_length); - /** * @brief Encrypt message with precomputed shared key. * @@ -513,38 +445,165 @@ bool crypto_memunlock(void *data, size_t length); non_null() void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); -/* Noise Part */ +/* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ -/* -* TODO: Implements MixKey(input_key_material) -* input_key_material = DH_X25519(private, public) -*/ +/** + * @brief Encrypt message with precomputed shared key using XChaCha20-Poly1305. + * + * Encrypts plain of plain_length to encrypted of plain_length + @ref CRYPTO_MAC_SIZE + * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NONCE_SIZE + * byte nonce. The encrypted message, as well as a tag authenticating both the confidential + * message m and adlen bytes of non-confidential data ad, are put into encrypted. + * + * @retval -1 if there was a problem. + * @return length of encrypted data if everything was fine. + */ +non_null() +size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, + uint8_t *encrypted, const uint8_t *ad, size_t ad_length); + +/** + * @brief Decrypt message with precomputed shared key using XChaCha20-Poly1305. + * + * Decrypts encrypted of encrypted_length to plain of length + * `length - CRYPTO_MAC_SIZE` using a shared key @ref CRYPTO_SHARED_KEY_SIZE + * big and a @ref CRYPTO_NONCE_SIZE byte nonce. + * + * @retval -1 if there was a problem (decryption failed). + * @return length of plain data if everything was fine. + */ non_null() -bool noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], +size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, + uint8_t *plain, const uint8_t *ad, size_t ad_length); + +/** + * @brief Compute an HMAC-SHA512 authenticator (64 bytes). + * + * cf. Noise sections 4.3 and 5.1 + * Applies HMAC from RFC2104 (https://tools.ietf.org/html/rfc2104) using the HASH() (=SHA512) function. + * This function is only called via `crypto_hkdf()`. + * HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of + * `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of + * of 32 bytes (SHA512-256 HASHLEN). Cf. https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512 + * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) + * is always HASHLEN bytes. + * + * @param auth Resulting authenticator. + * @param key Secret key + */ +non_null() +void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, + size_t data_length); + +/** + * @brief Computes the number of provides outputs (=keys) with HKDF. + * + * cf. Noise sections 4.3 and 5.1 + * + * This is Hugo Krawczyk's HKDF: + * - https://eprint.iacr.org/2010/264.pdf + * - https://tools.ietf.org/html/rfc5869 + * HKDF(chaining_key, input_key_material, num_outputs): Takes a + * chaining_key byte sequence of length HASHLEN, and an input_key_material + * byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes. + * Returns a pair or triple of byte sequences each of length HASHLEN, + * depending on whether num_outputs is two or three: + * – Sets temp_key = HMAC-HASH(chaining_key, input_key_material). + * – Sets output1 = HMAC-HASH(temp_key, byte(0x01)). + * – Sets output2 = HMAC-HASH(temp_key, output1 || byte(0x02)). + * – If num_outputs == 2 then returns the pair (output1, output2). + * – Sets output3 = HMAC-HASH(temp_key, output2 || byte(0x03)). + * – Returns the triple (output1, output2, output3). + * Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in + * length. Also note that the HKDF() function is simply HKDF with the + * chaining_key as HKDF salt, and zero-length HKDF info. + * + * @param output1 First key to compute + * @param first_len Length of output1/key + * @param output2 Second key to compute + * @param second_len Length of output2/key + * @param output3 Third key to compute + * @param third_len Length of output3/key + * @param data HKDF input_key_material byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes + * @param data_len length of either zero bytes, 32 bytes, or DHLEN bytes + * @param Noise 64 byte chaining key as HKDF salt + */ +void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, + size_t first_len, size_t second_len, size_t third_len, + size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); + +/** + * @brief Noise MixKey(input_key_material) + * + * cf. Noise section 5.2 + * Executes the following steps: + * - Sets ck, temp_k = HKDF(ck, input_key_material, 2). + * - If HASHLEN is 64, then truncates temp_k to 32 bytes + * - Calls InitializeKey(temp_k). + * input_key_material = DH_X25519(private, public) + * + * @param 64 byte Noise ck + * @param shared_key 32 byte key to be calculated + * @param private_key X25519 private key + * @param public_key X25519 public key + */ +non_null() +void noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); -/* -* TODO: MixHash(data) as defined in Noise spec -*/ +/** + * @brief Noise MixHash(data): Sets h = HASH(h || data). + * + * cf. Noise section 5.2 + * + * @param hash Contains current hash, is updated with new hash + * @param data to add to hash + * @param data_len length of data to hash + * + */ non_null() void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len); -/* -* TODO: EncryptAndHash(plaintext) as defined in Noise spec besides -* "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." -* because this is not the case in Tox. -*/ +/** + * @brief Noise EncryptAndHash(plaintext): Sets ciphertext = EncryptWithAd(h, + * plaintext), calls MixHash(ciphertext), and returns ciphertext. Note + * that if k is empty, the EncryptWithAd() call will set ciphertext equal + * to plaintext. + * + * cf. Noise section 5.2 + * "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." + * This is not the case in Tox. + * + * @param ciphertext stores encrypted plaintext + * @param plaintext to be encrypted + * @param plain_lenth length of plaintext + * @param shared_key used for XAEAD encryption + * @param hash stores hash value, used as associated data in XAEAD + * @param nonce used for XEAD encryption + */ non_null() void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); -/* -* TODO: DecryptAndHash(plaintext) as defined in Noise spec besides -* "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." -* because this is not the case in Tox. -*/ +/** + * @brief DecryptAndHash(ciphertext): Sets plaintext = DecryptWithAd(h, + * ciphertext), calls MixHash(ciphertext), and returns plaintext. Note + * that if k is empty, the DecryptWithAd() call will set plaintext equal to + * ciphertext. + * + * cf. Noise section 5.2 + * "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." + * This is not the case in Tox. + * + * @param ciphertext contains ciphertext to decrypt + * @param plaintext stores decrypted ciphertext + * @param encrypted_lenth length of ciphertext+MAC + * @param shared_key used for XAEAD decryption + * @param hash stores hash value, used as associated data in XAEAD + * @param nonce used for XEAD decryption + */ non_null() int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], From 9d861a8fc4cb06bb75e00e1cfd0590770d9e932f Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 1 Dec 2023 17:40:44 +0100 Subject: [PATCH 033/150] fix: Fixed typos in documentation. --- toxcore/crypto_core.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 98721d8a61..b8e2ab444d 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -526,7 +526,7 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * @param third_len Length of output3/key * @param data HKDF input_key_material byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes * @param data_len length of either zero bytes, 32 bytes, or DHLEN bytes - * @param Noise 64 byte chaining key as HKDF salt + * @param chaining_key Noise 64 byte chaining key as HKDF salt */ void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, size_t first_len, size_t second_len, size_t third_len, @@ -542,7 +542,7 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uin * - Calls InitializeKey(temp_k). * input_key_material = DH_X25519(private, public) * - * @param 64 byte Noise ck + * @param chaining_key 64 byte Noise ck * @param shared_key 32 byte key to be calculated * @param private_key X25519 private key * @param public_key X25519 public key @@ -577,7 +577,7 @@ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_ * * @param ciphertext stores encrypted plaintext * @param plaintext to be encrypted - * @param plain_lenth length of plaintext + * @param plain_length length of plaintext * @param shared_key used for XAEAD encryption * @param hash stores hash value, used as associated data in XAEAD * @param nonce used for XEAD encryption @@ -599,7 +599,7 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, * * @param ciphertext contains ciphertext to decrypt * @param plaintext stores decrypted ciphertext - * @param encrypted_lenth length of ciphertext+MAC + * @param encrypted_length length of ciphertext+MAC * @param shared_key used for XAEAD decryption * @param hash stores hash value, used as associated data in XAEAD * @param nonce used for XEAD decryption From fb4d415e117b1a087d0dcfb1c7b269785f763d41 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 1 Dec 2023 20:21:15 +0100 Subject: [PATCH 034/150] cleanup/doc: cleaned up comments and added documentation to net_crypto. Adapted logging with bytes2string(). --- toxcore/net_crypto.c | 279 ++++++++++++++++++++++++------------------- toxcore/net_crypto.h | 5 +- 2 files changed, 163 insertions(+), 121 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 28b68dcbd4..63d798afd7 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -65,6 +65,7 @@ typedef struct Crypto_Connection { noise_handshake *noise_handshake; uint8_t send_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t recv_key[CRYPTO_PUBLIC_KEY_SIZE]; + //TODO: remove // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -489,14 +490,14 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, return COOKIE_LENGTH; } -// Necessary for backwards compatiblity +/* Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -// Necessary for Noise +/* Necessary for Noise-based handshake */ #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /* -* TODO: helper function to print hashes, keys, packets, etc. +* TODO: Helper function to print hashes, keys, packets, etc. * TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? * uses sodium_bin2hex() via bin2hex_toupper() function from `../other/fun/create_common.h` */ @@ -505,13 +506,26 @@ static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, bin2hex_toupper(string, string_size, bytes, bytes_size); } -/* - * Initializes a Noise HandshakeState with TODO: - * - * return -1 on failure - * return 0 on success +/** + * @brief Initializes a Noise Handshake State with provided static X25519 ID key pair, X25519 static ID public key from peer + * and sets if initiator or not. + * + * cf. Noise section 5.3 + * Calls InitializeSymmetric(protocol_name). + * Calls MixHash(prologue). + * Sets the initiator, s, e, rs, and re variables to the corresponding arguments. + * Calls MixHash() once for each public key listed in the pre-messages. + * + * //TODO: remove Logger Param + * @param log Tox logger + * @param noise_handshake handshake struct to save the necessary values to + * @param self_secret_key static private ID X25519 key of this Tox instance + * @param peer_public_key X25519 static ID public key from peer to connect to + * @param initiator specifies if this Tox instance is the initiator of this crypto connection + * + * @return -1 on failure + * @return 0 on success */ -//TODO: remove Logger Param static int noise_handshake_init (const Logger *log, struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { @@ -522,8 +536,8 @@ static int noise_handshake_init crypto_memzero(noise_handshake, sizeof(struct noise_handshake)); - // IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h - // Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE + /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h + Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ uint8_t temp_hash[CRYPTO_SHA512_SIZE]; memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); @@ -531,13 +545,13 @@ static int noise_handshake_init memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); //TODO: remove - // char log_ck[CRYPTO_SHA512_SIZE*3+1]; + // char log_ck[CRYPTO_SHA512_SIZE*2+1]; // if (log != nullptr) { // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); // LOGGER_DEBUG(log, "ck: %s", log_ck); // } - // Sets the initiator, s, rs (only initiator) => ephemeral keys are set afterwards + /* Sets the initiator, s => ephemeral keys are set afterwards */ noise_handshake->initiator = initiator; if (self_secret_key) { memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -545,7 +559,7 @@ static int noise_handshake_init //TODO: remove if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + char log_spub[CRYPTO_PUBLIC_KEY_SIZE*2+1]; bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); LOGGER_DEBUG(log, "static pub: %s", log_spub); } @@ -554,19 +568,19 @@ static int noise_handshake_init fprintf(stderr, "Local static private key required, but not provided.\n"); return -1; } - /* <- s: pre-message from responder to initiator */ + /* <- s: pre-message from responder to initiator => sets rs (only initiator) */ if (initiator) { if (peer_public_key != nullptr) { memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + char log_spub[CRYPTO_PUBLIC_KEY_SIZE*2+1]; bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); } - // Calls MixHash() once for each public key listed in the pre-messages from Noise IK + /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove @@ -579,9 +593,7 @@ static int noise_handshake_init return -1; } } else if (!initiator) { - // crypto_derive_public_key() happens for both - // crypto_derive_public_key(noise_handshake->static_public, self_secret_key); - // Calls MixHash() once for each public key listed in the pre-messages from Noise IK + /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove @@ -601,41 +613,51 @@ static int noise_handshake_init return 0; } -/** TODO: adapt, cf. Noise WriteMessage() @brief Create a handshake packet and put it in packet. +/** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. + * + * cf. Noise section 5.3 -> WriteMessage(payload, message_buffer) + * * @param cookie must be COOKIE_LENGTH bytes. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. - * + * @param nonce base nonce for this Tox instance, to be used for transport message encryption after handshake + * @param ephemeral_private Ephemeral private X25519 key of this Tox instance for this handshake + * @param ephemeral_public Ephemeral public X25519 key of this Tox instance for this handshake + * @param peer_real_pk X25519 static ID public key from peer to connect to + * @param peer_dht_pubkey X25519 DHT public key from peer to connect to + * @param noise_handshake struct containing Noise information/values + * * @retval -1 on failure. - * @retval HANDSHAKE_PACKET_LENGTH on success. + * @retval HANDSHAKE_PACKET_LENGTH on success (non-Noise handshake). + * @retval NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR if Noise handshake initiator + * @retval NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER if Noise handshake responder + * */ non_null() static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) { LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); - // Noise-based handshake + /* Noise-based handshake */ if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE HANDSHAKE"); /* Initiator: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] - [session public key of the peer (32 bytes)] - [24 bytes nonce static pub key encryption] - [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise + [session public key of the peer (32 bytes)] => currently in plain + [24 bytes nonce for static pub key encryption] + [encrypted static public key of the INITIATOR (32 bytes)] [MAC encrypted static pubkey 16 bytes] [24 bytes nonce handshake payload encryption] [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce -> Nonce patched + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake TODO: authenticate Cookie via AD in XAEAD? [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] - [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - [MAC 16 bytes] + [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] + [MAC encrypted payload 16 bytes] */ /* -> e, es, s, ss */ if (noise_handshake->initiator) { - // static public set in noise_handshake_init() - // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - // set ephemeral private+public + /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -644,7 +666,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code - // char log_hash1[CRYPTO_SHA512_SIZE*3+1]; + // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); @@ -653,13 +675,14 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); /* s */ - // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? or leads to nonce reuse? + /*Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet + || TODO: or use 0? or leads to nonce reuse? */ random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code - // char log_hash2[CRYPTO_SHA512_SIZE*3+1]; + // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); @@ -675,13 +698,13 @@ 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); - // OtherCookie is added to payload + /* OtherCookie is added to payload */ if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } - // Add Handshake payload nonce + /* Add Handshake payload nonce */ random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, @@ -690,7 +713,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u //TODO: remove from production code // LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); - // char log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*3+1]; + // char log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*2+1]; // bytes2string(log_ciphertext, sizeof(log_ciphertext), (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE), // (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); @@ -699,7 +722,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(packet + 1, cookie, COOKIE_LENGTH); //TODO: remove from production code - // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; + // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); // LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); @@ -712,18 +735,16 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Responder: Handshake packet structure [uint8_t 26] [Cookie 112 bytes] - [session public key of the peer (32 bytes)] - [24 bytes nonce handshake payload encryption] + [session public key of the peer (32 bytes)] => currently in plain + [24 bytes nonce for handshake payload encryption] [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce -> Nonce patched + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake TODO: authenticate Cookie via AD in XAEAD? [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - [MAC 16 bytes] + [MAC encrypted payload 16 bytes] */ - // static public set in noise_handshake_init() - // memcpy(noise_handshake->static_public, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - // set ephemeral private+public + /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -732,7 +753,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove - // char log_ck[CRYPTO_SHA512_SIZE*3+1]; + // char log_ck[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "RESPONDER pre ee ck: %s", log_ck); @@ -741,7 +762,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); //TODO: Remove - // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*3+1]; + // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "RESPONDER ee temp_key: %s", log_temp_key); @@ -761,14 +782,15 @@ 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); - // OtherCookie is added to payload + /* OtherCookie is added to payload */ if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } - // Add Handshake payload nonce - // Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? or leads to nonce reuse? + /* Add Handshake payload nonce + Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet + || TODO: or use 0? or leads to nonce reuse? */ random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, @@ -785,7 +807,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return -1; } } - // old handshake + /* non-Noise handshake */ else { uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(plain, nonce, CRYPTO_NONCE_SIZE); @@ -813,16 +835,15 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return HANDSHAKE_PACKET_LENGTH; } - - } -/** TODO: adapt, cf. Noise ReadMessage() @brief Handle a crypto handshake packet of length. - * put the nonce contained in the packet in nonce, +/** @brief Handle a crypto handshake packet of length. + * put the base nonce contained in the packet in nonce, * the session public key in session_pk * the real public key of the peer in peer_real_pk * the dht public key of the peer in dht_public_key and * the cookie inside the encrypted part of the packet in cookie. + * Currently supports noise-Noise and Noise handshake * * if expected_real_pk isn't NULL it denotes the real public key * the packet should be from. @@ -832,6 +853,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u * peer_real_pk must be at least CRYPTO_PUBLIC_KEY_SIZE * cookie must be at least COOKIE_LENGTH * + * cf. Noise section 5.3 -> ReadMessage(payload, message_buffer) + * * @retval false on failure. * @retval true on success. */ @@ -841,6 +864,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_handshake *noise_handshake) { LOGGER_DEBUG(c->log, "ENTERING"); + /* Noise-based handshake */ if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); @@ -860,23 +884,23 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* -> e, es, s, ss */ if(!noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); - /* Initiator: Handshake packet structure => THIS IS HANDLED HERE + /* Initiator: Handshake packet structure handled here [uint8_t 26] [Cookie 112 bytes] - [session public key of the peer (32 bytes)] + [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce static pub key encryption] [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise [MAC encrypted static pubkey 16 bytes] [24 bytes nonce handshake payload encryption] [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce -> Nonce patched + [24 bytes base nonce] => WITH base Nonce, to be used for transport message decryption after handshake TODO: authenticate Cookie via AD in XAEAD? [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC 16 bytes] */ //TODO: remove from production code - // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*3+1]; + // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); // LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); @@ -887,7 +911,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code - // char log_hash1[CRYPTO_SHA512_SIZE*3+1]; + // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); @@ -895,7 +919,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* s */ - // Nonces contained in packet! + /* Nonces contained in packet! */ memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); if(noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, @@ -905,14 +929,14 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } //TODO: remove - char log_static[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + char log_static[CRYPTO_PUBLIC_KEY_SIZE*2+1]; bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, "local static pub: %s", log_static); bytes2string(log_static, sizeof(log_static), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, "local remote pub: %s", log_static); //TODO: remove from production code - // char log_hash2[CRYPTO_SHA512_SIZE*3+1]; + // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); @@ -920,7 +944,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - // get Handshake payload nonce + /* get Handshake payload base nonce */ memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, @@ -968,7 +992,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove - // char log_ck[CRYPTO_SHA512_SIZE*3+1]; + // char log_ck[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "INITIATOR pre ee ck: %s", log_ck); @@ -977,7 +1001,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); //TODO: Remove - // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*3+1]; + // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "INITIATOR ee temp_key: %s", log_temp_key); @@ -1018,7 +1042,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } } - // old handshake + /* non-Noise handshake */ else { LOGGER_DEBUG(c->log, "ENTERING: handle_crypto_handshake() => OLD HANDSHAKE"); @@ -1580,8 +1604,11 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array #define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE)) -/** @brief Creates and sends a data packet to the peer using the fastest route. - * TODO: adapt for Noise +/** @brief Creates and sends a data packet to the peer using the fastest route. Currently only supports Noise (XChaCha20-Poly1305) + * transport encryption. + * + * TODO: adapt for backwards compatibility + * * @retval -1 on failure. * @retval 0 on success. */ @@ -1615,10 +1642,10 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ // const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); //TODO: remove - // char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; // bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "send_key: %s", key); - // char nonce_print[CRYPTO_NONCE_SIZE*3+1]; + // char nonce_print[CRYPTO_NONCE_SIZE*2+1]; // bytes2string(nonce_print, sizeof(nonce_print), conn->sent_nonce, CRYPTO_NONCE_SIZE, c->log); // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); @@ -1770,7 +1797,11 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce) /** @brief Handle a data packet. * Decrypt packet of length and put it into data. * data must be at least MAX_DATA_DATA_PACKET_SIZE big. - * TODO: adapt for Noise + * Currently only supports Noise (XChaCha20-Poly1305) + * transport decryption. + * + * TODO: adapt for backwards compatibility + * * @retval -1 on failure. * @return length of data on success. */ @@ -1803,10 +1834,10 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint // length - (1 + sizeof(uint16_t)), data); //TODO: remove - // char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "recv_key: %s", key); - // char nonce_print[CRYPTO_NONCE_SIZE*3+1]; + // char nonce_print[CRYPTO_NONCE_SIZE*2+1]; // bytes2string(nonce_print, sizeof(nonce_print), nonce, CRYPTO_NONCE_SIZE, c->log); // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); @@ -1940,7 +1971,7 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u conn->temp_packet_length = length; conn->temp_packet_sent_time = 0; //TODO: remove - LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time = 0"); + // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time = 0"); conn->temp_packet_num_sent = 0; return 0; } @@ -2002,9 +2033,10 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) return 0; } -/** @brief Create a handshake packet and set it as a temp packet. +/** @brief Create a handshake packet and set it as a temp packet. Currently supports non-Noise and + * Noise-based handshake. * @param cookie must be COOKIE_LENGTH. - * TODO: adapt for Noise + * * @retval -1 on failure. * @retval 0 on success. */ @@ -2018,12 +2050,13 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u if (conn == nullptr) { //TODO: remove - LOGGER_DEBUG(c->log, "nullptr"); + // LOGGER_DEBUG(c->log, "nullptr"); return -1; } LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); + /* Noise-based handshake */ if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; @@ -2052,11 +2085,11 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u return -1; } } - // old handshake + /* non-Noise handshake*/ else { uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; - // ephemeral_private and noise_handshake not necessary for old handshake + /* ephemeral_private and noise_handshake not necessary for old handshake */ if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, nullptr, conn->sessionpublic_key, conn->public_key, dht_public_key, nullptr) != sizeof(handshake_packet)) { return -1; @@ -2286,7 +2319,12 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } non_null() -//TODO: comment for Noise +/** + * @brief Handles a cookie response packet. Currently supports non-Noise and Noise-bashed handshake. + * + * @return -1 in case of failure + * @return 0 if cookie response handled successfully + */ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2336,8 +2374,8 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } } else { - // old handshake - LOGGER_DEBUG(c->log, "OLD Handshake"); + /* non-Noise handshake */ + LOGGER_DEBUG(c->log, "non-Noise Handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } @@ -2348,7 +2386,12 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } non_null(1, 3) nullable(5) -//TODO: comment for Noise +/** + * @brief Handles receive handshake packets. Currently supports non-Noise and Noise-based handshake. + * + * @return -1 in case of failure + * @return 0 if successful + */ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, void *userdata) { @@ -2396,16 +2439,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const conn->status = CRYPTO_CONN_NOT_CONFIRMED; //TODO: remove - // char ck_print[CRYPTO_SHA512_SIZE*3+1]; + // char ck_print[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "ck: %s", ck_print); - // Noise Split(), nonces already set in conn + /* Noise Split(), nonces already set in crypto connection */ crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); //TODO: remove - // char key[CRYPTO_SECRET_KEY_SIZE*3+1]; + // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; // bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "send_key: %s", key); // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); @@ -2430,14 +2473,14 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } //TODO: remove - // char ck_print[CRYPTO_SHA512_SIZE*3+1]; + // char ck_print[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "ck: %s", ck_print); initiator_change = true; //TODO: does this work now? - // RESPONDER needs to send handshake packet, afterwards finished + /* RESPONDER needs to send handshake packet, afterwards finished */ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } @@ -2445,7 +2488,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: or CRYPTO_HANDSHAKE_SENT? conn->status = CRYPTO_CONN_NOT_CONFIRMED; - // responder Noise Split(): vice-verse keys in comparison to initiator + /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); @@ -2454,11 +2497,11 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary => TODO: need info in conn or noise_handshake - // Case where RESPONDER with and without change from INITIATOR + /* Case where RESPONDER with and without change from INITIATOR */ else if(!conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); - // necessary, otherwise broken after INITIATOR to RESPONDER change + /* necessary, otherwise broken after INITIATOR to RESPONDER change */ if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); @@ -2474,7 +2517,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet, length, nullptr, conn->noise_handshake)) { return -1; } - // RESPONDER needs to send handshake packet, afterwards finished + /* RESPONDER needs to send handshake packet, afterwards finished */ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } @@ -2482,14 +2525,14 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: or CRYPTO_HANDSHAKE_SENT? conn->status = CRYPTO_CONN_NOT_CONFIRMED; - // responder Noise Split(): vice-verse keys in comparison to initiator + /* responder Noise Split(): vice-verse keys in comparison to initiator */ crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); - // cannot chagne to INITIATOR here, connection broken + /* cannot chagne to INITIATOR here, connection broken */ connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2499,7 +2542,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } } - // old handshake + /* non-Noise handshake */ else { LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => OLD HANDHSHAKE"); if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, @@ -2508,7 +2551,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - //TODO: adapt? what's the case for this? if (pk_equal(dht_public_key, conn->dht_public_key)) { LOGGER_DEBUG(c->log, "pk_equal TRUE case"); //TODO: this is called @@ -2519,7 +2561,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); - // OLD handshake case + // non-Noise handshake case if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; @@ -2865,7 +2907,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; - //TODO: Differention between old and handshake needs to be checked here! + //TODO: Differention between non-Noise and Noise-based handshake needs to be checked here! if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); @@ -2886,14 +2928,14 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } //TODO: remove - // char log_spub[CRYPTO_PUBLIC_KEY_SIZE*3+1]; + // char log_spub[CRYPTO_PUBLIC_KEY_SIZE*2+1]; // bytes2string(log_spub, sizeof(log_spub), n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "RESPONDER: session pub: %s", log_spub); - // char log_cookie[COOKIE_LENGTH*3+1]; + // char log_cookie[COOKIE_LENGTH*2+1]; // bytes2string(log_cookie, sizeof(log_cookie), n_c.cookie, COOKIE_LENGTH, c->log); // LOGGER_DEBUG(c->log, "RESPONDER: cookie: %s", log_cookie); - //TODO: case old handshake + //TODO: case non-Noise handshake // if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, // n_c.cookie, data, length, nullptr, nullptr)) { // free(n_c.cookie); @@ -2918,7 +2960,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, free(n_c.cookie); return -1; } - // there is already something in conn->noise_handshake - need to memzero in this case! + /* there is already something in conn->noise_handshake -> necessary to memzero in this case! */ crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(struct noise_handshake)); @@ -2935,7 +2977,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, conn->status = CRYPTO_CONN_NOT_CONFIRMED; - // responder Noise Split(): vice-verse keys in comparison to initiator + /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ //TODO: remove here? crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove @@ -2954,7 +2996,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } } - //TODO: case old handshake + //TODO: case non-Noise handshake // if (crypt_connection_id != -1) { // Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2993,8 +3035,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return ret; } -/** @brief Accept a crypto connection. - * TODO: adapt for Noise +/** @brief Accept a crypto connection. Currently supports non-Noise and Noise-based handshake. + * * return -1 on failure. * return connection id on success. */ @@ -3044,9 +3086,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (!n_c->noise_handshake->initiator) { //TODO: remove LOGGER_DEBUG(c->log, "Responder: Noise WriteMessage"); - // needless after calloc - //crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct noise_handshake)); + //NOT possible here, need content afterwards! // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); @@ -3056,11 +3097,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(c->rng, conn->sent_nonce); crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); - // happens in create_crypto_handshake() - // memcpy(conn->noise_handshake->ephemeral_private, conn->sessionsecret_key, CRYPTO_PUBLIC_KEY_SIZE); - // memcpy(conn->noise_handshake->ephemeral_public, conn->sessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: before or after create_send_handshake() (in general) => IMPORTANT: in this case here, otherwise get_crypto_connection() in create_send_handshake() returns a nullptr + /* IMPORTANT: in this case here/before create_send_handshake(), otherwise get_crypto_connection() in + create_send_handshake() returns a nullptr */ conn->status = CRYPTO_CONN_NOT_CONFIRMED; if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { @@ -3071,7 +3110,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - // Noise Split(), nonces already set + /* Noise Split(), base nonces already set */ crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); //TODO: remove @@ -3089,10 +3128,10 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } } - // old handshake + /* non-Noise handshake */ else { //TODO: remove - LOGGER_DEBUG(c->log, "OLD handshake"); + LOGGER_DEBUG(c->log, "non-Noise handshake"); 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); @@ -3123,9 +3162,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return crypt_connection_id; } -/** @brief Create a crypto connection. +/** @brief Create a crypto connection. Currently independent of non-Noise/Noise handshake. * If one to that real public key already exists, return it. - * //TODO: adapt for Noise + * * return -1 on failure. * return connection id on success. */ diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 3c27c80390..6a7009f5fa 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -122,6 +122,8 @@ non_null() DHT *nc_get_dht(const Net_Crypto *c); //TODO: struct necessary? //TODO: move to crypto_core.h? +/** @brief Necessary Noise handshake state information/values. + */ typedef struct noise_handshake { //TODO: static_private? uint8_t static_private[CRYPTO_PUBLIC_KEY_SIZE]; @@ -147,6 +149,7 @@ typedef struct New_Connection { // Necessary for Noise noise_handshake noise_handshake_data; noise_handshake *noise_handshake; + //TODO: if no struct necessary // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -438,7 +441,7 @@ void do_net_crypto(Net_Crypto *c, void *userdata); nullable(1) void kill_net_crypto(Net_Crypto *c); -//TODO: comment +//TODO: necessary? //static void handshake_zero(struct noise_handshake *handshake); From e8edb9fda369c26c88748ef07ba81c3e4ee262ac Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 4 Dec 2023 20:23:53 +0100 Subject: [PATCH 035/150] fix: missed one curly bracket. --- toxcore/net_crypto.c | 1 + 1 file changed, 1 insertion(+) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 72bd3a26de..54e9eec55b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2717,6 +2717,7 @@ static int create_crypto_connection(Net_Crypto *c) c->crypto_connections[id].packet_send_rate_requested = 0; c->crypto_connections[id].last_packets_left_requested_rem = 0; c->crypto_connections[id].mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t)); + } if (c->crypto_connections[id].mutex == nullptr) { LOGGER_ERROR(c->log, "failed to alloc mutex"); From e0cfc392dc1466a3f1fee1303d0805900012b24d Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 4 Dec 2023 20:50:07 +0100 Subject: [PATCH 036/150] fix: fix double free after merge. --- toxcore/net_crypto.c | 1 - 1 file changed, 1 deletion(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 54e9eec55b..73f6bc1d03 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2781,7 +2781,6 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex); - free(c->crypto_connections[crypt_connection_id].mutex); crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(struct noise_handshake)); free(c->crypto_connections[crypt_connection_id].noise_handshake); From 58d0df46928292955f3ec45b134df75364a49e0b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 13:58:16 +0100 Subject: [PATCH 037/150] fix/cleanup: Changed NULL to nullptr, free() to mem_delete(), calloc() to mem_alloc(). Renamed Noise_Handshake struct. --- toxcore/crypto_core.c | 4 ++-- toxcore/net_crypto.c | 48 +++++++++++++++++++++---------------------- toxcore/net_crypto.h | 8 ++++---- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index b7897797f2..60a6179e9e 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -596,7 +596,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no // nsec is not used by this particular construction and should always be NULL. if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, - ad, ad_length, NULL, nonce, shared_key) != 0) { + ad, ad_length, nullptr, nonce, shared_key) != 0) { return -1; } @@ -616,7 +616,7 @@ size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no unsigned long long plain_length = 0; - if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, NULL, encrypted, + if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, nullptr, encrypted, encrypted_length, ad, ad_length, nonce, shared_key) != 0) { return -1; } diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 73f6bc1d03..b8737933dd 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -62,7 +62,7 @@ typedef struct Crypto_Connection { uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ // For Noise - noise_handshake *noise_handshake; + Noise_Handshake *noise_handshake; uint8_t send_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t recv_key[CRYPTO_PUBLIC_KEY_SIZE]; //TODO: remove @@ -528,14 +528,14 @@ static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, * @return 0 on success */ static int noise_handshake_init -(const Logger *log, struct noise_handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) { //TODO: remove if (log != nullptr) { LOGGER_DEBUG(log, "ENTERING"); } - crypto_memzero(noise_handshake, sizeof(struct noise_handshake)); + crypto_memzero(noise_handshake, sizeof(struct Noise_Handshake)); /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ @@ -635,7 +635,7 @@ static int noise_handshake_init */ non_null() static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, - const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, noise_handshake *noise_handshake) + const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake) { LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); /* Noise-based handshake */ @@ -862,7 +862,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u non_null(1, 2, 3, 4, 5, 6, 7) nullable(9) static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, - noise_handshake *noise_handshake) + Noise_Handshake *noise_handshake) { LOGGER_DEBUG(c->log, "ENTERING"); /* Noise-based handshake */ @@ -2457,7 +2457,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); + // mem_delete(c->mem, conn->noise_handshake); //TODO: necessary? // pthread_mutex_lock(&c->tcp_mutex); // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); @@ -2504,7 +2504,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // free(conn->noise_handshake); + // mem_delete(c->mem, conn->noise_handshake); //TODO: necessary? // pthread_mutex_lock(&c->tcp_mutex); // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); @@ -2731,11 +2731,11 @@ static int create_crypto_connection(Net_Crypto *c) return -1; } - c->crypto_connections[id].noise_handshake = calloc(1, sizeof(struct noise_handshake)); + c->crypto_connections[id].noise_handshake = (Noise_Handshake *) mem_alloc(c->mem, sizeof(struct Noise_Handshake)); if (c->crypto_connections[id].noise_handshake == nullptr) { LOGGER_ERROR(c->log, "failed to alloc noise_handshake"); - free(c->crypto_connections[id].mutex); + mem_delete(c->mem, c->crypto_connections[id].mutex); pthread_mutex_unlock(&c->connections_mutex); return -1; } @@ -2782,8 +2782,8 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex); - crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(struct noise_handshake)); - free(c->crypto_connections[crypt_connection_id].noise_handshake); + crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(struct Noise_Handshake)); + mem_delete(c->mem, c->crypto_connections[crypt_connection_id].noise_handshake); c->crypto_connections[crypt_connection_id].noise_handshake = nullptr; crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); @@ -2906,9 +2906,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: Differention between non-Noise and Noise-based handshake needs to be checked here! if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { - crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); + crypto_memzero(n_c.noise_handshake, sizeof(struct Noise_Handshake)); n_c.noise_handshake = nullptr; - free(n_c.cookie); + mem_delete(c->mem, n_c.cookie); return -1; } @@ -2917,7 +2917,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { - crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); + crypto_memzero(n_c.noise_handshake, sizeof(struct Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); return -1; @@ -2934,7 +2934,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: case non-Noise handshake // if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, // n_c.cookie, data, length, nullptr, nullptr)) { - // free(n_c.cookie); + // mem_delete(c->mem, n_c.cookie); // return -1; // } @@ -2957,8 +2957,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } /* there is already something in conn->noise_handshake -> necessary to memzero in this case! */ - crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(struct noise_handshake)); + crypto_memzero(conn->noise_handshake, sizeof(struct Noise_Handshake)); + memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(struct Noise_Handshake)); memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2984,7 +2984,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: memzero stuff from old handshake? - crypto_memzero(n_c.noise_handshake, sizeof(struct noise_handshake)); + crypto_memzero(n_c.noise_handshake, sizeof(struct Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); @@ -3004,7 +3004,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // connection_kill(c, crypt_connection_id, userdata); // } else { // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - // free(n_c.cookie); + // mem_delete(c->mem, n_c.cookie); // return -1; // } @@ -3015,12 +3015,12 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // crypto_connection_add_source(c, crypt_connection_id, source); // if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { - // free(n_c.cookie); + // mem_delete(c->mem, n_c.cookie); // return -1; // } // conn->status = CRYPTO_CONN_NOT_CONFIRMED; - // free(n_c.cookie); + // mem_delete(c->mem, n_c.cookie); // return 0; // } // } @@ -3081,7 +3081,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (!n_c->noise_handshake->initiator) { //TODO: remove LOGGER_DEBUG(c->log, "Responder: Noise WriteMessage"); - memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct noise_handshake)); + memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct Noise_Handshake)); //NOT possible here, need content afterwards! // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); @@ -3152,7 +3152,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) crypto_connection_add_source(c, crypt_connection_id, &n_c->source); //TODO: here correct? - crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); + crypto_memzero(n_c->noise_handshake, sizeof(struct Noise_Handshake)); return crypt_connection_id; } @@ -3232,7 +3232,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { // //TODO: // // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // // free(conn->noise_handshake); + // mem_delete(c->mem, conn->noise_handshake); // pthread_mutex_lock(&c->tcp_mutex); // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); // pthread_mutex_unlock(&c->tcp_mutex); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 2a745c5daa..14e60c099e 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -124,7 +124,7 @@ non_null() DHT *nc_get_dht(const Net_Crypto *c); //TODO: move to crypto_core.h? /** @brief Necessary Noise handshake state information/values. */ -typedef struct noise_handshake { +typedef struct Noise_Handshake { //TODO: static_private? uint8_t static_private[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t static_public[CRYPTO_PUBLIC_KEY_SIZE]; @@ -137,7 +137,7 @@ typedef struct noise_handshake { uint8_t chaining_key[CRYPTO_SHA512_SIZE]; bool initiator; -} noise_handshake; +} Noise_Handshake; typedef struct New_Connection { IP_Port source; @@ -147,8 +147,8 @@ typedef struct New_Connection { uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ // Necessary for Noise - noise_handshake noise_handshake_data; - noise_handshake *noise_handshake; + Noise_Handshake noise_handshake_data; + Noise_Handshake *noise_handshake; //TODO: if no struct necessary // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; From e4dbc391a9d7f204c959dce606084f2d1cd8efaf Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 15:00:13 +0100 Subject: [PATCH 038/150] fix: removed dependency for bin2hex_toupper() from create_common.h. Added generic bytes_to_string() function to util.c (based on id_to_string() from Messenger.c). --- toxcore/net_crypto.c | 32 ++++++++++++++++---------------- toxcore/util.c | 14 ++++++++++++++ toxcore/util.h | 11 +++++++++++ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index b8737933dd..801b664da6 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -13,8 +13,6 @@ #include #include #include -//TODO: remove, used to for bin2hex_toupper() function to print/log bytes -#include "../other/fun/create_common.h" #include "ccompat.h" #include "list.h" @@ -500,11 +498,11 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, /* * TODO: Helper function to print hashes, keys, packets, etc. * TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? -* uses sodium_bin2hex() via bin2hex_toupper() function from `../other/fun/create_common.h` +* bytes_to_string() from util.h */ -static void bytes2string(char *string, size_t string_size, const uint8_t *bytes, size_t bytes_size, const Logger *log) +static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) { - bin2hex_toupper(string, string_size, bytes, bytes_size); + bytes_to_string(bytes, bytes_length, string, string_length); } /** @@ -2328,15 +2326,15 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + if (conn == nullptr) { + return -1; + } + LOGGER_DEBUG(c->log, "ENTERING: crypto_connection_id: %d => PACKET: %d => CRYPTO CONN STATE: %d", crypt_connection_id, packet[0], conn->status); - if (conn == nullptr) { - return -1; - } - if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING) { return -1; } @@ -2395,15 +2393,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const void *userdata) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "ENTERING: crypt_connection_id: %d | PACKET: %d | CRYPTO CONN STATE: %d", - crypt_connection_id, - packet[0], - conn->status); if (conn == nullptr) { return -1; } + LOGGER_DEBUG(c->log, "ENTERING: crypt_connection_id: %d | PACKET: %d | CRYPTO CONN STATE: %d", + crypt_connection_id, + packet[0], + conn->status); + //TODO: what if I remove CRYPTO_CONN_NOT_CONFIRMED from here? => doesn't work together with connection_kill() after decrypting failure (after new handshake) if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT @@ -2586,14 +2585,15 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); + if (conn == nullptr) { + return -1; + } + //TODO: remove from prod code LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d | CRYPTO CONN STATE: %d", packet[0], conn->status); - if (conn == nullptr) { - return -1; - } if (conn->status != CRYPTO_CONN_NOT_CONFIRMED && conn->status != CRYPTO_CONN_ESTABLISHED) { return -1; diff --git a/toxcore/util.c b/toxcore/util.c index 3b3779bd7c..8aad2c9ef5 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -148,3 +148,17 @@ uint32_t jenkins_one_at_a_time_hash(const uint8_t *key, size_t len) hash += (uint32_t)((uint64_t)hash << 15); return hash; } + +/** generic function to print bytes as String; based on id_to_string() from Messenger.c */ +void bytes_to_string(const uint8_t *bytes, size_t bytes_length, char *str, size_t str_length) +{ + if (str_length < (bytes_length * 2 + 1)) { + snprintf(str, str_length, "Bad buf length"); + } + + for (uint32_t i = 0; i < bytes_length; ++i) { + snprintf(&str[i * 2], str_length - i * 2, "%02X", bytes[i]); + } + + str[bytes_length * 2] = '\0'; +} diff --git a/toxcore/util.h b/toxcore/util.h index 44091b3622..517e7a1aab 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "attributes.h" #include "mem.h" @@ -75,6 +76,16 @@ uint32_t jenkins_one_at_a_time_hash(const uint8_t *key, size_t len); non_null() uint16_t data_checksum(const uint8_t *data, uint32_t length); +/** + * @brief Generic function to print bytes as String; based on id_to_string() from Messenger.c + * + * @param bytes Bytes to be printed as String. + * @param bytes_length The length in bytes + * @param str The string to save the result to. + * @param str_length Length of the string + */ +void bytes_to_string(const uint8_t *bytes, size_t bytes_length, char *str, size_t str_length); + #ifdef __cplusplus } // extern "C" #endif From 973317539afc6e2d5eacf1268071625fd2cbf472 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 15:54:56 +0100 Subject: [PATCH 039/150] fix: minor fixes for CI. --- toxcore/crypto_core.c | 2 +- toxcore/crypto_core.h | 1 - toxcore/net_crypto.c | 24 ++++++++++++------------ toxcore/util.h | 1 + 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 60a6179e9e..ebecbdee97 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -600,7 +600,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no return -1; } - //assert(length < INT32_MAX - crypto_box_MACBYTES); + // assert(length < INT32_MAX - crypto_box_MACBYTES); return encrypted_length; } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index cadece9fe6..06942dc3f3 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -491,7 +491,6 @@ size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no * @param auth Resulting authenticator. * @param key Secret key */ -non_null() void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_length); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 801b664da6..857ff5fb48 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -533,7 +533,7 @@ static int noise_handshake_init LOGGER_DEBUG(log, "ENTERING"); } - crypto_memzero(noise_handshake, sizeof(struct Noise_Handshake)); + crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ @@ -2027,7 +2027,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); - LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); + LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %llu", conn->temp_packet_sent_time); ++conn->temp_packet_num_sent; return 0; } @@ -2455,7 +2455,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "INITIATOR: CHANGED TO RESPONDER"); if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { //TODO: - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); // mem_delete(c->mem, conn->noise_handshake); //TODO: necessary? // pthread_mutex_lock(&c->tcp_mutex); @@ -2731,7 +2731,7 @@ static int create_crypto_connection(Net_Crypto *c) return -1; } - c->crypto_connections[id].noise_handshake = (Noise_Handshake *) mem_alloc(c->mem, sizeof(struct Noise_Handshake)); + c->crypto_connections[id].noise_handshake = (Noise_Handshake *) mem_alloc(c->mem, sizeof(Noise_Handshake)); if (c->crypto_connections[id].noise_handshake == nullptr) { LOGGER_ERROR(c->log, "failed to alloc noise_handshake"); @@ -2782,7 +2782,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex); - crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(struct Noise_Handshake)); + crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].noise_handshake); c->crypto_connections[crypt_connection_id].noise_handshake = nullptr; @@ -2906,7 +2906,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: Differention between non-Noise and Noise-based handshake needs to be checked here! if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { - crypto_memzero(n_c.noise_handshake, sizeof(struct Noise_Handshake)); + crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); return -1; @@ -2917,7 +2917,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { - crypto_memzero(n_c.noise_handshake, sizeof(struct Noise_Handshake)); + crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); return -1; @@ -2957,8 +2957,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } /* there is already something in conn->noise_handshake -> necessary to memzero in this case! */ - crypto_memzero(conn->noise_handshake, sizeof(struct Noise_Handshake)); - memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(struct Noise_Handshake)); + crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(Noise_Handshake)); memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2984,7 +2984,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: memzero stuff from old handshake? - crypto_memzero(n_c.noise_handshake, sizeof(struct Noise_Handshake)); + crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); @@ -3081,7 +3081,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (!n_c->noise_handshake->initiator) { //TODO: remove LOGGER_DEBUG(c->log, "Responder: Noise WriteMessage"); - memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(struct Noise_Handshake)); + memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(Noise_Handshake)); //NOT possible here, need content afterwards! // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); @@ -3152,7 +3152,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) crypto_connection_add_source(c, crypt_connection_id, &n_c->source); //TODO: here correct? - crypto_memzero(n_c->noise_handshake, sizeof(struct Noise_Handshake)); + crypto_memzero(n_c->noise_handshake, sizeof(Noise_Handshake)); return crypt_connection_id; } diff --git a/toxcore/util.h b/toxcore/util.h index 517e7a1aab..ffd6d401fa 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -84,6 +84,7 @@ uint16_t data_checksum(const uint8_t *data, uint32_t length); * @param str The string to save the result to. * @param str_length Length of the string */ +non_null() void bytes_to_string(const uint8_t *bytes, size_t bytes_length, char *str, size_t str_length); #ifdef __cplusplus From dc65e97cbe1ce99c17c0b6210d65eb5d71f1a8be Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 16:10:13 +0100 Subject: [PATCH 040/150] fix: minor fixes for CI. --- toxcore/crypto_core.c | 22 +++++++++++----------- toxcore/net_crypto.c | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index ebecbdee97..3fd61b8dd2 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -626,16 +626,16 @@ size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no return plain_length; } -/* -* cf. Noise sections 4.3 and 5.1 -* Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. -* This function is only called via `crypto_hkdf()`. -* HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of -* `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of -* of 32 bytes (SHA512-256 HASHLEN). Cf. https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512 -* key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) -* is always HASHLEN bytes. -*/ +/** + * cf. Noise sections 4.3 and 5.1 + * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. + * This function is only called via `crypto_hkdf()`. + * HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of + * `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of + * of 32 bytes (SHA512-256 HASHLEN). Cf. https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512 + * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) + * is always HASHLEN bytes. + */ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_length) { @@ -724,7 +724,7 @@ void noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], */ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) { - uint8_t to_hash[CRYPTO_SHA512_SIZE + data_len]; + VLA(uint8_t, to_hash, CRYPTO_SHA512_SIZE + data_len); memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 857ff5fb48..d57c589458 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2027,7 +2027,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); - LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %llu", conn->temp_packet_sent_time); + // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); ++conn->temp_packet_num_sent; return 0; } From 6a030f01137efd5a2b996f0b67320ecc87564bfa Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 16:19:37 +0100 Subject: [PATCH 041/150] fix: minor fixes for CI. --- toxcore/crypto_core.h | 1 - toxcore/util.c | 1 + toxcore/util.h | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 06942dc3f3..381dbdb267 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -546,7 +546,6 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uin * @param private_key X25519 private key * @param public_key X25519 public key */ -non_null() void noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); diff --git a/toxcore/util.c b/toxcore/util.c index 8aad2c9ef5..eda98faf7d 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "ccompat.h" diff --git a/toxcore/util.h b/toxcore/util.h index ffd6d401fa..dbbae97448 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -14,7 +14,6 @@ #include #include #include -#include #include "attributes.h" #include "mem.h" From af18b085ec6831e8221c7b9182062ce7306b8118 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 16:45:35 +0100 Subject: [PATCH 042/150] fix: minor fixes for CI. --- toxcore/net_crypto.c | 6 ++++-- toxcore/net_crypto.h | 2 ++ toxcore/util.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index d57c589458..1f0dd55216 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -564,7 +564,8 @@ static int noise_handshake_init } } else { - fprintf(stderr, "Local static private key required, but not provided.\n"); + // fprintf(stderr, "Local static private key required, but not provided.\n"); + LOGGER_DEBUG(log, "Local static private key required, but not provided."); return -1; } /* <- s: pre-message from responder to initiator => sets rs (only initiator) */ @@ -588,7 +589,8 @@ static int noise_handshake_init // LOGGER_DEBUG(log, "INITIATOR hash: %s", log_hash); // } } else { - fprintf(stderr, "Remote peer static public key required, but not provided.\n"); + // fprintf(stderr, "Remote peer static public key required, but not provided.\n"); + LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); return -1; } } else if (!initiator) { diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 14e60c099e..636f4971b3 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -113,6 +113,8 @@ #define DEFAULT_PING_CONNECTION 1000 #define DEFAULT_TCP_PING_CONNECTION 500 +#define NOISE_PROTOCOL_NAME Noise_IK_25519_XChaChaPoly_SHA512 + typedef struct Net_Crypto Net_Crypto; non_null() const uint8_t *nc_get_self_public_key(const Net_Crypto *c); diff --git a/toxcore/util.c b/toxcore/util.c index eda98faf7d..bb1b1fc70b 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -13,10 +13,10 @@ #include "util.h" +#include #include #include #include -#include #include "ccompat.h" From 91128c6ce09c939e21176c040897653382a4d8a5 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 16:58:42 +0100 Subject: [PATCH 043/150] fix/cleanup: changed crypto_hkdf() to two outputs because output3 is currently not needed (maybe necessary in the future for PSKs). --- toxcore/crypto_core.c | 16 ++++++++-------- toxcore/crypto_core.h | 4 ++-- toxcore/net_crypto.c | 12 +++++------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 3fd61b8dd2..78d9b25793 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -660,8 +660,8 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * length. Also note that the HKDF() function is simply HKDF with the * chaining_key as HKDF salt, and zero-length HKDF info. */ -void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, - size_t first_len, size_t second_len, size_t third_len, +void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, + size_t first_len, size_t second_len, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) { uint8_t output[CRYPTO_SHA512_SIZE + 1]; @@ -683,10 +683,10 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uin memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ - /* Currently not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ - output[CRYPTO_SHA512_SIZE] = 3; - crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); - memcpy(output3, output, third_len); + /* Currently output3 not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ + // output[CRYPTO_SHA512_SIZE] = 3; + // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); + // memcpy(output3, output, third_len); /* Clear sensitive data from stack */ crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); @@ -711,8 +711,8 @@ void noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], // X25519 - returns plain DH result, afterwards hashed with HKDF encrypt_precompute(public_key, private_key, dh_calculation); // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! - crypto_hkdf(chaining_key, shared_key, nullptr, dh_calculation, CRYPTO_SHA512_SIZE, - CRYPTO_SHARED_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); + crypto_hkdf(chaining_key, shared_key, dh_calculation, CRYPTO_SHA512_SIZE, + CRYPTO_SHARED_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); // If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 381dbdb267..e6280aeace 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -527,8 +527,8 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * @param data_len length of either zero bytes, 32 bytes, or DHLEN bytes * @param chaining_key Noise 64 byte chaining key as HKDF salt */ -void crypto_hkdf(uint8_t *output1, uint8_t *output2, uint8_t *output3, const uint8_t *data, - size_t first_len, size_t second_len, size_t third_len, +void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, + size_t first_len, size_t second_len, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); /** diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1f0dd55216..0920c87b36 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -18,8 +18,6 @@ #include "list.h" #include "mono_time.h" #include "util.h" - -static const uint8_t NOISE_PROTOCOL_NAME[34] = "Noise_IK_25519_XChaChaPoly_SHA512"; typedef struct Packet_Data { uint64_t sent_time; uint16_t length; @@ -2444,7 +2442,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // LOGGER_DEBUG(c->log, "ck: %s", ck_print); /* Noise Split(), nonces already set in crypto connection */ - crypto_hkdf(conn->send_key, conn->recv_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->send_key, conn->recv_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); //TODO: remove @@ -2489,7 +2487,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const conn->status = CRYPTO_CONN_NOT_CONFIRMED; /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } else { @@ -2526,7 +2524,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const conn->status = CRYPTO_CONN_NOT_CONFIRMED; /* responder Noise Split(): vice-verse keys in comparison to initiator */ - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } @@ -2977,7 +2975,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ //TODO: remove here? - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); @@ -3108,7 +3106,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } /* Noise Split(), base nonces already set */ - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); From e9dfc41b3143728254a768574fe86afabcaa2c3d Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 17:14:54 +0100 Subject: [PATCH 044/150] fix: minor fixes for CI. --- toxcore/crypto_core.h | 2 -- toxcore/net_crypto.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index e6280aeace..9170c8c764 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -521,8 +521,6 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * @param first_len Length of output1/key * @param output2 Second key to compute * @param second_len Length of output2/key - * @param output3 Third key to compute - * @param third_len Length of output3/key * @param data HKDF input_key_material byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes * @param data_len length of either zero bytes, 32 bytes, or DHLEN bytes * @param chaining_key Noise 64 byte chaining key as HKDF salt diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 636f4971b3..d7b5bcee87 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -113,7 +113,7 @@ #define DEFAULT_PING_CONNECTION 1000 #define DEFAULT_TCP_PING_CONNECTION 500 -#define NOISE_PROTOCOL_NAME Noise_IK_25519_XChaChaPoly_SHA512 +#define NOISE_PROTOCOL_NAME "Noise_IK_25519_XChaChaPoly_SHA512" typedef struct Net_Crypto Net_Crypto; From 04f87eddcad1448c4b0fb96de89417ff92163e4c Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 19:16:26 +0100 Subject: [PATCH 045/150] fix: changed noise_mix_key() to use crypto_scalarmult_curve25519() instead enrypt_precompute() - otherwise HSalsa20 is performed before HKDF. --- toxcore/crypto_core.c | 8 ++++++-- toxcore/crypto_core.h | 2 +- toxcore/net_crypto.c | 6 +----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 78d9b25793..f62d61e103 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -701,7 +701,7 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, * - Calls InitializeKey(temp_k). * input_key_material = DH_X25519(private, public) */ -void noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], +int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) @@ -709,12 +709,16 @@ void noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; // X25519 - returns plain DH result, afterwards hashed with HKDF - encrypt_precompute(public_key, private_key, dh_calculation); + if(crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { + return -1; + } // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! crypto_hkdf(chaining_key, shared_key, dh_calculation, CRYPTO_SHA512_SIZE, CRYPTO_SHARED_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); // If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); + + return 0; } /* diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 9170c8c764..dd8653a451 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -544,7 +544,7 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, * @param private_key X25519 private key * @param public_key X25519 public key */ -void noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], +int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 0920c87b36..7516e15456 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -550,7 +550,7 @@ static int noise_handshake_init /* Sets the initiator, s => ephemeral keys are set afterwards */ noise_handshake->initiator = initiator; - if (self_secret_key) { + if (self_secret_key != nullptr) { memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); crypto_derive_public_key(noise_handshake->static_public, self_secret_key); @@ -604,10 +604,6 @@ static int noise_handshake_init return -1; } - //TODO: precompute_static_static ? - - //TODO: crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); -> here? currently not possible due to backwards compatibility, also inefficient - /* Ready to go */ return 0; } From f22d07442118893d2036fbe0ef2851531c9e08f4 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 5 Dec 2023 21:12:30 +0100 Subject: [PATCH 046/150] cleanup: removed unnecessary memcpys and related parameters from handle_crypto_handshake(). Memzero/free of noise_handshake after crypto connection is established. --- toxcore/net_crypto.c | 61 ++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 7516e15456..03e5b9cd61 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -956,14 +956,18 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } + // received base nonce memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); - // remote_ephemeral - //TODO: necessary? - memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + // not necessary for Noise (=remote ephemeral) + // memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + // cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); - memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + // not necessary for Noise (=remote static) + // memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + // necessary memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: memzero packet? + //TODO: memzero packet, unwatend side effects? + // crypto_memzero(packet, length); LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); return true; } @@ -1024,13 +1028,20 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } + // neccessary, base nonce memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); - // remote_ephemeral - memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); - memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + // not necessary for Noise (=remote ephemeral) + // memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + // not necessary for Noise INITIATOR + //memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + // not necessary for Noise (=remote static) + // memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + // necessary memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: memzero packet, unwatend side effects? + // crypto_memzero(packet, length); + LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); return true; } else { @@ -1077,6 +1088,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: memzero packet, unwatend side effects? + // crypto_memzero(packet, length); return true; } @@ -2230,9 +2243,14 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { clear_temp_packet(c, crypt_connection_id); conn->status = CRYPTO_CONN_ESTABLISHED; - //TODO: noise_handshake not necessary anymore => memzero! TODO: and free also? TODO: write function for both! TODO: how this is done for other dynamic allocs? + LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); + //TODO: noise_handshake not necessary anymore => memzero and free + crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + mem_delete(c->mem, conn->noise_handshake); + conn->noise_handshake = nullptr; + if (conn->connection_status_callback != nullptr) { conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, true, userdata); @@ -2411,8 +2429,11 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // return -1; // } + // necessary only for non-Noise uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; + // necessary for Noise and non-Noise uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + // necessary for Noise RESPONDER and non-Noise uint8_t cookie[COOKIE_LENGTH]; //TODO: via noise_handshake struct? TODO: remove @@ -2424,7 +2445,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if(length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, nullptr, packet, length, conn->public_key, conn->noise_handshake)) { return -1; } @@ -2461,7 +2482,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, cookie, packet, length, conn->public_key, conn->noise_handshake)) { return -1; } @@ -2507,7 +2528,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // wipe_crypto_connection(c, crypt_connection_id); return false; } - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; } @@ -2778,9 +2799,12 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex); - crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(Noise_Handshake)); - mem_delete(c->mem, c->crypto_connections[crypt_connection_id].noise_handshake); - c->crypto_connections[crypt_connection_id].noise_handshake = nullptr; + // necessary for backwards compatibility and because after ESTABLISHED noise_handshake is already memzeroed/freed + if (c->crypto_connections[crypt_connection_id].noise_handshake != nullptr) { + crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(Noise_Handshake)); + mem_delete(c->mem, c->crypto_connections[crypt_connection_id].noise_handshake); + c->crypto_connections[crypt_connection_id].noise_handshake = nullptr; + } crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); @@ -2911,6 +2935,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); + //TODO: remove n_c.peersessionpublic_key and n_c.public_key for Noise call if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); @@ -2957,6 +2982,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(Noise_Handshake)); memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); + //TODO: remove, unnecessary for Noise memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); crypto_connection_add_source(c, crypt_connection_id, source); @@ -3085,7 +3111,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // necessary -> TODO: duplicated code necessary? 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); + // not necessary for Noise + // memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(c->rng, conn->sent_nonce); crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); From ce7bb036f79d1081fa57ef1e4533e0d9ffef8c73 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 13 Dec 2023 18:21:12 +0100 Subject: [PATCH 047/150] feat: Encrypt cookies in Noise handshake packets and authenticate via XAEAD. --- toxcore/net_crypto.c | 142 ++++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 68 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 03e5b9cd61..b150674cfb 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -487,11 +487,12 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, return COOKIE_LENGTH; } -/* Necessary for backwards compatiblity to non-Noise handshake */ +/* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -/* Necessary for Noise-based handshake */ -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +/* Noise: Necessary for Noise-based handshake */ +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) /* * TODO: Helper function to print hashes, keys, packets, etc. @@ -637,7 +638,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u LOGGER_DEBUG(c->log, "NOISE HANDSHAKE"); /* Initiator: Handshake packet structure [uint8_t 26] - [Cookie 112 bytes] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce for static pub key encryption] [encrypted static public key of the INITIATOR (32 bytes)] @@ -645,8 +645,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [24 bytes nonce handshake payload encryption] [Encrypted message containing: [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - TODO: authenticate Cookie via AD in XAEAD? - [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] [MAC encrypted payload 16 bytes] */ @@ -657,7 +656,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* e */ - memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(packet + 1, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code @@ -672,9 +671,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* s */ /*Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? or leads to nonce reuse? */ - random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; @@ -685,26 +684,30 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Noise Handshake Payload */ - uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + // Noise: Cookie authenticated via ciphertext MAC + // crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + + // Noise: Cookie from RESPONDER + memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); /* OtherCookie is added to payload */ - if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, + if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } /* Add Handshake payload nonce */ - random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); //TODO: remove from production code // LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); @@ -714,13 +717,15 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); packet[0] = NET_PACKET_CRYPTO_HS; - memcpy(packet + 1, cookie, COOKIE_LENGTH); + // Noise: cookie (from other peer/RESPONDER) is encrypted and included in ciphertext + // memcpy(packet + 1, cookie, COOKIE_LENGTH); //TODO: remove from production code // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); // LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); + //TODO: memzero handshake_payload_plain crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; @@ -729,13 +734,11 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u else if (!noise_handshake->initiator) { /* Responder: Handshake packet structure [uint8_t 26] - [Cookie 112 bytes] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce for handshake payload encryption] [Encrypted message containing: [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - TODO: authenticate Cookie via AD in XAEAD? - [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [Cookie 112 bytes] => Cookie encrypted and authenticate via XAEAD [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC encrypted payload 16 bytes] */ @@ -744,7 +747,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* e */ - memcpy(packet + 1 + COOKIE_LENGTH, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(packet + 1, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove @@ -769,16 +772,20 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); /* Create Noise Handshake Payload */ - uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + // Noise: Cookie authenticated via ciphertext MAC + // crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + + // Noise: Cookie from INITIATOR + memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); /* OtherCookie is added to payload */ - if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, + if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } @@ -786,14 +793,16 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Add Handshake payload nonce Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet || TODO: or use 0? or leads to nonce reuse? */ - random_nonce(c->rng, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); - noise_encrypt_and_hash(packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE); + noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); packet[0] = NET_PACKET_CRYPTO_HS; - memcpy(packet + 1, cookie, COOKIE_LENGTH); + // Noise: cookie (from other peer/INITIATOR) is encrypted and included in ciphertext + // memcpy(packet + 1, cookie, COOKIE_LENGTH); + //TODO: memzero handshake_payload_plain crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; @@ -865,23 +874,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { - return false; - } - - if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { - return false; - } - - uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; - crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); - /* -> e, es, s, ss */ if(!noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); /* Initiator: Handshake packet structure handled here [uint8_t 26] - [Cookie 112 bytes] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce static pub key encryption] [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise @@ -889,11 +886,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [24 bytes nonce handshake payload encryption] [Encrypted message containing: [24 bytes base nonce] => WITH base Nonce, to be used for transport message decryption after handshake - TODO: authenticate Cookie via AD in XAEAD? - [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC 16 bytes] */ + //TODO: remove from production code // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); @@ -902,7 +899,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t //TODO: Check here if remote_ephemeral is already the same ephemeral key? /* e */ - memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code @@ -915,9 +912,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* s */ /* Nonces contained in packet! */ - memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - if(noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + if(noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { LOGGER_DEBUG(c->log, "RESPONDER: Noise ReadMessage remote static decryption failed"); return false; @@ -938,11 +935,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* ss */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ - uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH]; /* get Handshake payload base nonce */ - memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); + memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); - if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS payload decryption failed"); @@ -951,8 +948,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { - LOGGER_DEBUG(c->log, "RESPONDER: COOKIE HASH WRONG"); + if (open_cookie(c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { + return false; + } + + if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { return false; } @@ -961,13 +961,16 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // not necessary for Noise (=remote ephemeral) // memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); // cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() - memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); // not necessary for Noise (=remote static) // memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); // necessary memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? // crypto_memzero(packet, length); + + //TODO: memzero handshake_payload_plain + LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); return true; } @@ -977,17 +980,15 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); /* Responder: Handshake packet structure [uint8_t 26] - [Cookie 112 bytes] [session public key of the peer (32 bytes)] [24 bytes nonce handshake payload encryption] [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce -> Nonce patched - TODO: authenticate Cookie via AD in XAEAD? - [64 bytes sha512 hash of the entire Cookie sitting outside the encrypted part] + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC 16 bytes] */ - memcpy(noise_handshake->remote_ephemeral, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove @@ -1007,14 +1008,14 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* Payload decryption */ - uint8_t handshake_payload_plain[CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - memcpy(nonce, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH]; + memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); //TODO: Remove // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); - if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); @@ -1023,8 +1024,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - if (!crypto_sha512_eq(cookie_hash, handshake_payload_plain + CRYPTO_NONCE_SIZE)) { - LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake cookie verification failed"); + if (open_cookie(c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { + return false; + } + + if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { return false; } @@ -1042,6 +1046,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t //TODO: memzero packet, unwatend side effects? // crypto_memzero(packet, length); + //TODO: memzero handshake_payload_plain + LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); return true; } else { @@ -1657,7 +1663,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ // bytes2string(nonce_print, sizeof(nonce_print), conn->sent_nonce, CRYPTO_NONCE_SIZE, c->log); // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); - //TODO: add ad? + //TODO: add ad? only packet ID and last two bytes of nonce sent in plain const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); if (len + 1 + sizeof(uint16_t) != packet_size) { @@ -1849,7 +1855,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint // bytes2string(nonce_print, sizeof(nonce_print), nonce, CRYPTO_NONCE_SIZE, c->log); // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); - //TODO: add ad? + //TODO: add ad? only packet ID and last two bytes of nonce sent in plain const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, nullptr, 0); @@ -2246,10 +2252,11 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); - //TODO: noise_handshake not necessary anymore => memzero and free + //Noise: noise_handshake not necessary anymore => memzero and free crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, conn->noise_handshake); conn->noise_handshake = nullptr; + //TODO: non-Noise: also delete values from conn? if (conn->connection_status_callback != nullptr) { conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, @@ -2364,10 +2371,9 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } - //TODO: here? - // only necessary if Cookie response was successful + // Noise: only necessary if Cookie response was successful if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, conn->public_key, true) != 0) { - //TODO: + //TODO: cleanup // pthread_mutex_lock(&c->tcp_mutex); // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); // pthread_mutex_unlock(&c->tcp_mutex); From 063d0c25a07c396ef54e5db186af881428491621 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Thu, 14 Dec 2023 17:29:41 +0100 Subject: [PATCH 048/150] cleanup: removed unnecessary TODOs. --- toxcore/net_crypto.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index b150674cfb..6e6bd8c30b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2373,11 +2373,6 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, // Noise: only necessary if Cookie response was successful if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, conn->public_key, true) != 0) { - //TODO: cleanup - // pthread_mutex_lock(&c->tcp_mutex); - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // pthread_mutex_unlock(&c->tcp_mutex); - // wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -2477,14 +2472,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "INITIATOR: CHANGED TO RESPONDER"); if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { - //TODO: - // crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); - // mem_delete(c->mem, conn->noise_handshake); - //TODO: necessary? - // pthread_mutex_lock(&c->tcp_mutex); - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // pthread_mutex_unlock(&c->tcp_mutex); - // wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -2524,14 +2511,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change */ if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { - //TODO: - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // mem_delete(c->mem, conn->noise_handshake); - //TODO: necessary? - // pthread_mutex_lock(&c->tcp_mutex); - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // pthread_mutex_unlock(&c->tcp_mutex); - // wipe_crypto_connection(c, crypt_connection_id); return false; } if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, cookie, @@ -2554,7 +2533,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); /* cannot chagne to INITIATOR here, connection broken */ - connection_kill(c, crypt_connection_id, userdata); return -1; } } else { From 8d96364e4110bedba3f27e57b8199f513a72e525 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Thu, 14 Dec 2023 18:48:40 +0100 Subject: [PATCH 049/150] cleanup: moved Noise Split (symmetric key derivation). --- toxcore/net_crypto.c | 108 ++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 64 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 6e6bd8c30b..83864b0d9b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2450,25 +2450,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet, length, conn->public_key, conn->noise_handshake)) { return -1; } - - //TODO: ok here? - conn->status = CRYPTO_CONN_NOT_CONFIRMED; - - //TODO: remove - // char ck_print[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "ck: %s", ck_print); - - /* Noise Split(), nonces already set in crypto connection */ - crypto_hkdf(conn->send_key, conn->recv_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); - LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); - - //TODO: remove - // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; - // bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "send_key: %s", key); - // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "recv_key: %s", key); } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "INITIATOR: CHANGED TO RESPONDER"); if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { @@ -2487,19 +2468,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const initiator_change = true; - //TODO: does this work now? /* RESPONDER needs to send handshake packet, afterwards finished */ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } - - //TODO: or CRYPTO_HANDSHAKE_SENT? - conn->status = CRYPTO_CONN_NOT_CONFIRMED; - - /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); - //TODO: remove - LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } else { return -1; } @@ -2521,14 +2493,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } - - //TODO: or CRYPTO_HANDSHAKE_SENT? - conn->status = CRYPTO_CONN_NOT_CONFIRMED; - - /* responder Noise Split(): vice-verse keys in comparison to initiator */ - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); - //TODO: remove - LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); @@ -2551,27 +2515,53 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } if (pk_equal(dht_public_key, conn->dht_public_key)) { - LOGGER_DEBUG(c->log, "pk_equal TRUE case"); - //TODO: this is called - //TODO: necessary for old handshake =>change to OLD handshake condition - //encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); - - //TODO: Noise Split() here? LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); - // non-Noise handshake case - if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { - if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { + if (conn->noise_handshake != nullptr) { + LOGGER_DEBUG(c->log, "NOISE HANDHSHAKE"); + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + if (conn->noise_handshake->initiator) { + //TODO: remove + // char ck_print[CRYPTO_SHA512_SIZE*2+1]; + // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "ck: %s", ck_print); + + /* INITIATOR Noise Split(), nonces already set in crypto connection */ + crypto_hkdf(conn->send_key, conn->recv_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); + LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); + + //TODO: remove + // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; + // bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "send_key: %s", key); + // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "recv_key: %s", key); + } + else if(!conn->noise_handshake->initiator) { + /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ + crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); + //TODO: remove + LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); + } + else { return -1; } } - - //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway - //TODO: necessary for old handshake / backwards compatibility - //conn->status = CRYPTO_CONN_NOT_CONFIRMED; + /* non-Noise handshake case */ + else { + if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { + if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { + return -1; + } + } + //TODO: necessary for non-Noise handshake => change to OLD handshake condition + //encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway + //TODO: necessary for old handshake / backwards compatibility + //conn->status = CRYPTO_CONN_NOT_CONFIRMED; + } } else { - LOGGER_DEBUG(c->log, "pk_equal FALSE case"); if (conn->dht_pk_callback != nullptr) { conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key, userdata); } @@ -2919,8 +2909,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); - //TODO: remove n_c.peersessionpublic_key and n_c.public_key for Noise call - if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, + if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, nullptr, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; @@ -2966,8 +2955,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(Noise_Handshake)); memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); - //TODO: remove, unnecessary for Noise - memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); + /* unnecessary for Noise */ + // memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); crypto_connection_add_source(c, crypt_connection_id, source); @@ -2985,11 +2974,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); - //TODO: wrong here? - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - - //TODO: memzero stuff from old handshake? - crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; @@ -3117,9 +3101,6 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); - //TODO: wrong here? - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - //TODO: memzero stuff from old handshake, also not necessary anymore => TODO: or after established crypto conn? } else { pthread_mutex_lock(&c->tcp_mutex); @@ -3237,7 +3218,6 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u //TODO: here? // only necessary if Cookie request was successful // if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { - // //TODO: // // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); // mem_delete(c->mem, conn->noise_handshake); // pthread_mutex_lock(&c->tcp_mutex); @@ -3653,7 +3633,7 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t const int crypt_connection_id = crypto_id_ip_port(c, source); - // No crypto connection yet = RESPONDER case + /* No crypto connection yet = RESPONDER case */ if (crypt_connection_id == -1) { if (packet[0] != NET_PACKET_CRYPTO_HS) { return 1; From 04326d8e4b1d11ffb4ef129ad698c99e4c6cb7ef Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 15 Dec 2023 19:28:01 +0100 Subject: [PATCH 050/150] fix/cleanup: minor changes for CI checks. --- toxcore/net_crypto.c | 55 +++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 83864b0d9b..f0b85c5ec9 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -592,7 +592,9 @@ static int noise_handshake_init LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); return -1; } - } else if (!initiator) { + } + /* Noise RESPONDER */ + else { /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -601,9 +603,7 @@ static int noise_handshake_init // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); // } - } else { - return -1; - } + } /* Ready to go */ return 0; @@ -649,7 +649,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] [MAC encrypted payload 16 bytes] */ - /* -> e, es, s, ss */ + /* Noise INITIATOR: -> e, es, s, ss */ if (noise_handshake->initiator) { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); @@ -730,8 +730,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } - /* <- e, ee, se */ - else if (!noise_handshake->initiator) { + /* Noise RESPONDER: <- e, ee, se */ + else { /* Responder: Handshake packet structure [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain @@ -807,9 +807,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } - else { - return -1; - } } /* non-Noise handshake */ else { @@ -974,9 +971,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); return true; } - /* ReadMessage() if initiator: - <- e, ee, se */ - else if(noise_handshake->initiator) { + /* Noiise ReadMessage() if initiator: <- e, ee, se */ + else { LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); /* Responder: Handshake packet structure [uint8_t 26] @@ -1050,9 +1046,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); return true; - } else { - return false; - } + } } /* non-Noise handshake */ else { @@ -2084,7 +2078,8 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u return -1; } } - else if (!conn->noise_handshake->initiator) { + /* Noise RESPONDER */ + else { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER]; if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, @@ -2095,9 +2090,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) { return -1; } - } else { - return -1; - } + } } /* non-Noise handshake*/ else { @@ -2430,15 +2423,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // return -1; // } - // necessary only for non-Noise - uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; // necessary for Noise and non-Noise uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; // necessary for Noise RESPONDER and non-Noise uint8_t cookie[COOKIE_LENGTH]; //TODO: via noise_handshake struct? TODO: remove - bool initiator_change = false; + // bool initiator_change = false; if (conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE HANDHSHAKE"); @@ -2466,7 +2457,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "ck: %s", ck_print); - initiator_change = true; + // initiator_change = true; /* RESPONDER needs to send handshake packet, afterwards finished */ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { @@ -2478,7 +2469,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary => TODO: need info in conn or noise_handshake /* Case where RESPONDER with and without change from INITIATOR */ - else if(!conn->noise_handshake->initiator) { + else { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change */ @@ -2499,15 +2490,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* cannot chagne to INITIATOR here, connection broken */ return -1; } - } else { - //TODO: remove - LOGGER_DEBUG(c->log, "NOT initiator or responder => !conn->noise_handshake->initiator: %d, initiator_change: %d", !conn->noise_handshake->initiator, initiator_change); - return -1; - } + } } /* non-Noise handshake */ else { LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => OLD HANDHSHAKE"); + // necessary only for non-Noise + uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, nullptr)) { return -1; @@ -2538,15 +2527,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "recv_key: %s", key); } - else if(!conn->noise_handshake->initiator) { + /* Noise RESPONDER */ + else { /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } - else { - return -1; - } } /* non-Noise handshake case */ else { From 862770d47f4065f571cf628ba7108a40e2f0278b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 18 Dec 2023 15:21:12 +0100 Subject: [PATCH 051/150] fix: fix for cimple and MSAN uninitialized value. --- toxcore/crypto_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index f62d61e103..12296d02ea 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -631,7 +631,7 @@ size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. * This function is only called via `crypto_hkdf()`. * HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of - * `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of + * `crypto_hmac*()` in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of * of 32 bytes (SHA512-256 HASHLEN). Cf. https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512 * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. @@ -707,6 +707,7 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; + crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); // X25519 - returns plain DH result, afterwards hashed with HKDF if(crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { From d6a4338e567aeeae07b2b0c44b88fc67b3094fe6 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 18 Dec 2023 15:42:15 +0100 Subject: [PATCH 052/150] fix: MSAN uninitialized value. --- toxcore/crypto_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 12296d02ea..3925061d61 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -707,7 +707,8 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; - crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); + // crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); + memset(dh_calculation, 0, CRYPTO_PUBLIC_KEY_SIZE); // X25519 - returns plain DH result, afterwards hashed with HKDF if(crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { From 663f8cc52cbc485ad2bbe3c351ab0462969d505d Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 18 Dec 2023 16:42:01 +0100 Subject: [PATCH 053/150] fix: for TSAN. --- toxcore/crypto_core.c | 1 - toxcore/net_crypto.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 3925061d61..b47ddcb64f 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -707,7 +707,6 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; - // crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); memset(dh_calculation, 0, CRYPTO_PUBLIC_KEY_SIZE); // X25519 - returns plain DH result, afterwards hashed with HKDF diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index f0b85c5ec9..368a04a082 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2192,7 +2192,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (len <= (int)(sizeof(uint32_t) * 2)) { //TODO: unwanted side effects? LOGGER_DEBUG(c->log, "connection_kill() because data packet decryption failure, len: %d", len); - connection_kill(c, crypt_connection_id, userdata); + // connection_kill(c, crypt_connection_id, userdata); return -1; } From 7485b1485eb917899499cb4ea11901f40fb38f4c Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 18 Dec 2023 17:56:47 +0100 Subject: [PATCH 054/150] test: testing changed connection_kill() behavior. --- toxcore/net_crypto.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 368a04a082..ea1e46a0e2 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2190,9 +2190,9 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const int len = handle_data_packet(c, crypt_connection_id, data, packet, length); if (len <= (int)(sizeof(uint32_t) * 2)) { - //TODO: unwanted side effects? - LOGGER_DEBUG(c->log, "connection_kill() because data packet decryption failure, len: %d", len); - // connection_kill(c, crypt_connection_id, userdata); + LOGGER_DEBUG(c->log, "connection_kill() because data packet decryption failure, crypt_connection_id: %d", crypt_connection_id); + //TODO: unwanted side effects? TODO: leave here? + connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2488,6 +2488,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); /* cannot chagne to INITIATOR here, connection broken */ + //TODO: leave here? + connection_kill(c, crypt_connection_id, userdata); return -1; } } From 73d3ddf6f0a7ba381ecd16e12d4b9b107aedc55c Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 18 Dec 2023 19:33:54 +0100 Subject: [PATCH 055/150] fix: fixed handle_crypto_handshake() and calls because public_key (=remote static) is necessary for friend_connection.c->handle_new_connections() --- toxcore/net_crypto.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index ea1e46a0e2..bfd0bb3d48 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -959,8 +959,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); // cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); - // not necessary for Noise (=remote static) - // memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + // not necessary for Noise (=remote static) => TODO: necessary for friend_connection.c->handle_new_connections() + memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); // necessary memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? @@ -2447,7 +2447,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } - if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, cookie, + if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, packet, length, conn->public_key, conn->noise_handshake)) { return -1; } @@ -2463,6 +2463,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } + //TODO: here? + conn->status = CRYPTO_CONN_HANDSHAKE_SENT; } else { return -1; } @@ -2476,7 +2478,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { return false; } - if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, cookie, + if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; } @@ -2484,6 +2486,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } + //TODO: here? + conn->status = CRYPTO_CONN_HANDSHAKE_SENT; } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); @@ -2898,7 +2902,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); - if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, nullptr, n_c.dht_public_key, + //TODO: need to add peer_real_pk (=n_c.public_key) -> otherwise not working (call via friend_connection.c) + if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; @@ -3006,6 +3011,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); mem_delete(c->mem, n_c.cookie); + LOGGER_DEBUG(c->log, "ret (!= 0?): %d", ret); return ret; } From 60fb6ae4f81a270f51d1fa0a958766416cc8a115 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 18 Dec 2023 20:57:53 +0100 Subject: [PATCH 056/150] fix: fixed call to handle_crypto_handshake(). --- toxcore/net_crypto.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index bfd0bb3d48..b8d4990fbb 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -532,6 +532,7 @@ static int noise_handshake_init LOGGER_DEBUG(log, "ENTERING"); } + //TODO: move to handle_packet_crypto_hs()? crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h @@ -679,6 +680,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); + char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); /* ss */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); @@ -903,6 +907,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); + char log_static[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "local static pub: %s", log_static); + bytes2string(log_static, sizeof(log_static), noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "remote ephemeral: %s", log_static); /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; @@ -918,9 +927,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } //TODO: remove - char log_static[CRYPTO_PUBLIC_KEY_SIZE*2+1]; - bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "local static pub: %s", log_static); bytes2string(log_static, sizeof(log_static), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, "local remote pub: %s", log_static); @@ -2448,7 +2454,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, - packet, length, conn->public_key, conn->noise_handshake)) { + packet, length, nullptr, conn->noise_handshake)) { return -1; } From a7eccb6c5df8146b07b59d1b21758ca8f8794c7b Mon Sep 17 00:00:00 2001 From: zoff99 Date: Tue, 19 Dec 2023 15:51:54 +0100 Subject: [PATCH 057/150] add handshake compatiblilty option --- toxcore/Messenger.h | 1 + toxcore/tox.c | 1 + toxcore/tox.h | 13 +++++++++++++ toxcore/tox_api.c | 3 +++ 4 files changed, 18 insertions(+) diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index cabb2af89d..54693429df 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -61,6 +61,7 @@ typedef struct Messenger_State_Plugin { typedef struct Messenger_Options { bool ipv6enabled; + bool noisecompatibilityenabled; bool udp_disabled; TCP_Proxy_Info proxy_info; uint16_t port_range[2]; diff --git a/toxcore/tox.c b/toxcore/tox.c index 768d5f9efd..cce2bfcdec 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -699,6 +699,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) } m_options.ipv6enabled = tox_options_get_ipv6_enabled(opts); + m_options.noisecompatibilityenabled = tox_options_get_noise_compatibility_enabled(opts); m_options.udp_disabled = !tox_options_get_udp_enabled(opts); m_options.port_range[0] = tox_options_get_start_port(opts); m_options.port_range[1] = tox_options_get_end_port(opts); diff --git a/toxcore/tox.h b/toxcore/tox.h index 8d816618c3..a3f727ad09 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -689,6 +689,15 @@ struct Tox_Options { */ const Tox_System *operating_system; + /** + * compatibility for old non-NOISE handshake. + * + * If this is set to false, non-NOISE handshake + * will not work anymore. + * + * Default: true. + */ + bool noise_compatibility_enabled; }; @@ -764,6 +773,10 @@ const Tox_System *tox_options_get_operating_system(const struct Tox_Options *opt void tox_options_set_operating_system(struct Tox_Options *options, const Tox_System *operating_system); +bool tox_options_get_noise_compatibility_enabled(const struct Tox_Options *options); + +void tox_options_set_noise_compatibility_enabled(struct Tox_Options *options, bool noise_compatibility_enabled); + /** * @brief Initialises a Tox_Options object with the default options. * diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c index 61c248c30d..724afb45d5 100644 --- a/toxcore/tox_api.c +++ b/toxcore/tox_api.c @@ -162,6 +162,8 @@ ACCESSORS(bool,, local_discovery_enabled) ACCESSORS(bool,, dht_announcements_enabled) ACCESSORS(bool,, experimental_thread_safety) ACCESSORS(const Tox_System *,, operating_system) +ACCESSORS(bool,, noise_compatibility_enabled) + //!TOKSTYLE+ @@ -188,6 +190,7 @@ void tox_options_default(struct Tox_Options *options) tox_options_set_local_discovery_enabled(options, true); tox_options_set_dht_announcements_enabled(options, true); tox_options_set_experimental_thread_safety(options, false); + tox_options_set_noise_compatibility_enabled(options, true); } } From dc4492c9c0c97fe6903bf479de1189f1d47b45a6 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Dec 2023 16:28:50 +0100 Subject: [PATCH 058/150] cleanup: minor cleanup --- toxcore/net_crypto.c | 58 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index b8d4990fbb..770f62dc81 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -67,7 +67,7 @@ typedef struct Crypto_Connection { // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; //TODO: necessary? - uint16_t handshake_send_interval; + // uint16_t handshake_send_interval; // bool initiator; // uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; @@ -637,7 +637,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Noise-based handshake */ if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE HANDSHAKE"); - /* Initiator: Handshake packet structure + /* Noise INITIATOR: -> e, es, s, ss */ + /* Initiator: Handshake packet structure [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce for static pub key encryption] @@ -649,8 +650,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] [MAC encrypted payload 16 bytes] + => 393 bytes in total */ - /* Noise INITIATOR: -> e, es, s, ss */ if (noise_handshake->initiator) { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); @@ -735,8 +736,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* Noise RESPONDER: <- e, ee, se */ - else { - /* Responder: Handshake packet structure + /* Responder: Handshake packet structure [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce for handshake payload encryption] @@ -745,7 +745,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [Cookie 112 bytes] => Cookie encrypted and authenticate via XAEAD [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC encrypted payload 16 bytes] + => 321 bytes in total */ + else { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -876,9 +878,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - if(!noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); - /* Initiator: Handshake packet structure handled here + /* Initiator: Handshake packet structure handled here [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce static pub key encryption] @@ -890,7 +890,10 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC 16 bytes] + => 393 bytes in total */ + if(!noise_handshake->initiator) { + LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); //TODO: remove from production code // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; @@ -965,11 +968,12 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); // cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); - // not necessary for Noise (=remote static) => TODO: necessary for friend_connection.c->handle_new_connections() + /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ + //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); // necessary memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: memzero packet, unwatend side effects? + //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); //TODO: memzero handshake_payload_plain @@ -978,9 +982,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } /* Noiise ReadMessage() if initiator: <- e, ee, se */ - else { - LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); - /* Responder: Handshake packet structure + /* Responder: Handshake packet structure [uint8_t 26] [session public key of the peer (32 bytes)] [24 bytes nonce handshake payload encryption] @@ -989,7 +991,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD [112 bytes Other Cookie (used by the other to respond to the handshake packet)] [MAC 16 bytes] + => 321 bytes in total */ + else { + LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); + memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -1045,7 +1051,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // necessary memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: memzero packet, unwatend side effects? + //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); //TODO: memzero handshake_payload_plain @@ -2197,7 +2203,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (len <= (int)(sizeof(uint32_t) * 2)) { LOGGER_DEBUG(c->log, "connection_kill() because data packet decryption failure, crypt_connection_id: %d", crypt_connection_id); - //TODO: unwanted side effects? TODO: leave here? + //TODO: unwanted side effects? leave here? connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2255,7 +2261,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, conn->noise_handshake); conn->noise_handshake = nullptr; - //TODO: non-Noise: also delete values from conn? + //TODO: non-Noise: also crypto_memzero() values from conn? if (conn->connection_status_callback != nullptr) { conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, @@ -2453,6 +2459,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } + /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() + -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; @@ -2484,6 +2492,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { return false; } + /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() + -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; @@ -2772,7 +2782,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex); - // necessary for backwards compatibility and because after ESTABLISHED noise_handshake is already memzeroed/freed + /* Noise: necessary for backwards compatibility and because after CRYPTO_CONN_ESTABLISHED noise_handshake is already memzeroed/freed */ if (c->crypto_connections[crypt_connection_id].noise_handshake != nullptr) { crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].noise_handshake); @@ -2908,7 +2918,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); - //TODO: need to add peer_real_pk (=n_c.public_key) -> otherwise not working (call via friend_connection.c) + /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); @@ -3067,7 +3077,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->connection_number_tcp = connection_number_tcp; - //TODO: only happening for RESPONDER? + //Noise: only happening for RESPONDER if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { //TODO: remove @@ -4132,7 +4142,6 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) clear_temp_packet(c, crypt_connection_id); clear_buffer(c->mem, &conn->send_array); clear_buffer(c->mem, &conn->recv_array); - //TODO: adapt for Noise? ret = wipe_crypto_connection(c, crypt_connection_id); } @@ -4297,15 +4306,6 @@ void do_net_crypto(Net_Crypto *c, void *userdata) send_crypto_packets(c); } -//TODO: use? or just use crypto_memzero()? -// static void noise_handshake_zero(struct noise_handshake *handshake) -// { -// memset(&handshake->ephemeral_private, 0, CRYPTO_PUBLIC_KEY_SIZE); -// memset(&handshake->remote_ephemeral, 0, CRYPTO_PUBLIC_KEY_SIZE); -// memset(&handshake->hash, 0, CRYPTO_SHA512_SIZE); -// memset(&handshake->chaining_key, 0, CRYPTO_SHA512_SIZE); -// } - void kill_net_crypto(Net_Crypto *c) { if (c == nullptr) { From 3c16f65fe5c84eea95f96064b22a99eb404d1ae6 Mon Sep 17 00:00:00 2001 From: "Tobias Buchberger (goldroom)" Date: Sat, 6 Jan 2024 21:25:50 +0100 Subject: [PATCH 059/150] fix: fix for ubsan. --- toxcore/crypto_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 2e8047de6b..eb1b94b515 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -457,7 +457,7 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); * @retval -1 if there was a problem. * @return length of encrypted data if everything was fine. */ -non_null() +non_null(1, 2, 3, 4, 5, 7) nullable(6) size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length); @@ -471,7 +471,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no * @retval -1 if there was a problem (decryption failed). * @return length of plain data if everything was fine. */ -non_null() +non_null(1, 2, 3, 4, 5, 7) nullable(6) size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); From 781828a96f00fb0e7c6bc7fd5c320210233c4200 Mon Sep 17 00:00:00 2001 From: "Tobias Buchberger (goldroom)" Date: Sat, 6 Jan 2024 21:34:25 +0100 Subject: [PATCH 060/150] fix: fix for ubsan. --- toxcore/crypto_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index eb1b94b515..e6ae4ea25c 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -457,7 +457,7 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); * @retval -1 if there was a problem. * @return length of encrypted data if everything was fine. */ -non_null(1, 2, 3, 4, 5, 7) nullable(6) +non_null(1, 2, 3, 5) nullable(6) size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length); @@ -471,7 +471,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no * @retval -1 if there was a problem (decryption failed). * @return length of plain data if everything was fine. */ -non_null(1, 2, 3, 4, 5, 7) nullable(6) +non_null(1, 2, 3, 5) nullable(6) size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); From 654f26a2be52d96fe3ec274828b64619efa02307 Mon Sep 17 00:00:00 2001 From: "Tobias Buchberger (goldroom)" Date: Sat, 6 Jan 2024 21:47:11 +0100 Subject: [PATCH 061/150] fix: fix for ubsan. --- toxcore/net_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1f555ce61a..1b99c759e0 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -634,7 +634,7 @@ static int noise_handshake_init * @retval NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER if Noise handshake responder * */ -non_null() +non_null(1, 2, 3, 4, 6, 7, 8) nullable(5, 9) static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake) { @@ -870,7 +870,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u * @retval false on failure. * @retval true on success. */ -non_null(1, 2, 3, 4, 5, 6, 7) nullable(9) +non_null(1, 2, 5, 7) nullable(3, 4, 6, 9, 10) static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, Noise_Handshake *noise_handshake) From 61695d4d950d06907c14e519e87d9c6d05179ed6 Mon Sep 17 00:00:00 2001 From: "Tobias Buchberger (goldroom)" Date: Sun, 7 Jan 2024 00:08:05 +0100 Subject: [PATCH 062/150] fix: fixed noise backwards compatibility option. --- toxcore/Messenger.h | 2 +- toxcore/tox.c | 2 +- toxcore/tox.h | 4 ++-- toxcore/tox_api.c | 36 ++++++++++++++++++------------------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 7d582a5d16..b5956c0871 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -61,7 +61,7 @@ typedef struct Messenger_State_Plugin { typedef struct Messenger_Options { bool ipv6enabled; - bool noisecompatibilityenabled; + bool noise_compatibility_enabled; bool udp_disabled; TCP_Proxy_Info proxy_info; uint16_t port_range[2]; diff --git a/toxcore/tox.c b/toxcore/tox.c index 1fa84d1e9e..3a42edd08d 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -707,7 +707,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) } m_options.ipv6enabled = tox_options_get_ipv6_enabled(opts); - m_options.noisecompatibilityenabled = tox_options_get_noise_compatibility_enabled(opts); + m_options.noise_compatibility_enabled = tox_options_get_noise_compatibility_enabled(opts); m_options.udp_disabled = !tox_options_get_udp_enabled(opts); m_options.port_range[0] = tox_options_get_start_port(opts); m_options.port_range[1] = tox_options_get_end_port(opts); diff --git a/toxcore/tox.h b/toxcore/tox.h index 2dee5bcdec..faf5003483 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -700,9 +700,9 @@ struct Tox_Options { const Tox_System *operating_system; /** - * compatibility for old non-NOISE handshake. + * Compatibility for old non-Noise handshake. * - * If this is set to false, non-NOISE handshake + * If this is set to false, non-Noise handshake * will not work anymore. * * Default: true. diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c index 6c3defcafe..122c2ef319 100644 --- a/toxcore/tox_api.c +++ b/toxcore/tox_api.c @@ -148,24 +148,24 @@ void tox_options_set_##name(struct Tox_Options *options, type name) \ options->name = name; \ } -ACCESSORS(bool,, ipv6_enabled) -ACCESSORS(bool,, udp_enabled) -ACCESSORS(Tox_Proxy_Type, proxy_, type) -ACCESSORS(const char *, proxy_, host) -ACCESSORS(uint16_t, proxy_, port) -ACCESSORS(uint16_t,, start_port) -ACCESSORS(uint16_t,, end_port) -ACCESSORS(uint16_t,, tcp_port) -ACCESSORS(bool,, hole_punching_enabled) -ACCESSORS(Tox_Savedata_Type, savedata_, type) -ACCESSORS(size_t, savedata_, length) -ACCESSORS(tox_log_cb *, log_, callback) -ACCESSORS(void *, log_, user_data) -ACCESSORS(bool,, local_discovery_enabled) -ACCESSORS(bool,, dht_announcements_enabled) -ACCESSORS(bool,, experimental_thread_safety) -ACCESSORS(const Tox_System *,, operating_system) -ACCESSORS(bool,, noise_compatibility_enabled) +ACCESSORS(bool, ipv6_enabled) +ACCESSORS(bool, udp_enabled) +ACCESSORS(Tox_Proxy_Type, proxy_type) +ACCESSORS(const char *, proxy_host) +ACCESSORS(uint16_t, proxy_port) +ACCESSORS(uint16_t, start_port) +ACCESSORS(uint16_t, end_port) +ACCESSORS(uint16_t, tcp_port) +ACCESSORS(bool, hole_punching_enabled) +ACCESSORS(Tox_Savedata_Type, savedata_type) +ACCESSORS(size_t, savedata_length) +ACCESSORS(tox_log_cb *, log_callback) +ACCESSORS(void *, log_user_data) +ACCESSORS(bool, local_discovery_enabled) +ACCESSORS(bool, dht_announcements_enabled) +ACCESSORS(bool, experimental_thread_safety) +ACCESSORS(const Tox_System *, operating_system) +ACCESSORS(bool, noise_compatibility_enabled) //!TOKSTYLE+ From ffa677efa772d525e084222388ffe68ec55e5128 Mon Sep 17 00:00:00 2001 From: "Tobias Buchberger (goldroom)" Date: Sun, 7 Jan 2024 01:35:30 +0100 Subject: [PATCH 063/150] feat: backwards compatibility to non-Noise handshake. --- toxcore/net_crypto.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1b99c759e0..a79b938fbd 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -64,9 +64,10 @@ typedef struct Crypto_Connection { uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ // For Noise + bool noise_handshake_enabled; Noise_Handshake *noise_handshake; - uint8_t send_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t recv_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; + uint8_t recv_key[CRYPTO_SHARED_KEY_SIZE]; //TODO: remove // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; @@ -2082,7 +2083,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); /* Noise-based handshake */ - if (conn->noise_handshake != nullptr) { + if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; @@ -2237,7 +2238,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const uint8_t *real_data = data + (sizeof(uint32_t) * 2); uint16_t real_length = len - (sizeof(uint32_t) * 2); - LOGGER_DEBUG(c->log, "DATA ID: %d", real_data[0]); + //TODO: remove + // LOGGER_DEBUG(c->log, "DATA ID: %d", real_data[0]); while (real_data[0] == PACKET_ID_PADDING) { /* Remove Padding */ ++real_data; @@ -2248,7 +2250,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } } - LOGGER_DEBUG(c->log, "DATA ID after PADDING: %d", real_data[0]); + //TODO: remove + // LOGGER_DEBUG(c->log, "DATA ID after PADDING: %d", real_data[0]); if (real_data[0] == PACKET_ID_KILL) { LOGGER_DEBUG(c->log, "KILL PACKET RECEIVED"); @@ -2382,7 +2385,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } // Noise: only necessary if Cookie response was successful - if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, conn->public_key, true) != 0) { + if (conn->noise_handshake_enabled && noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, conn->public_key, true) != 0) { return -1; } @@ -2448,7 +2451,11 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: via noise_handshake struct? TODO: remove // bool initiator_change = false; - if (conn->noise_handshake != nullptr) { + if (length == HANDSHAKE_PACKET_LENGTH) { + conn->noise_handshake_enabled = false; + } + + if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE HANDHSHAKE"); if (conn->noise_handshake->initiator) { if(length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { @@ -2521,7 +2528,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } /* non-Noise handshake */ else { - LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => OLD HANDHSHAKE"); + LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => non-Noise HANDHSHAKE"); // necessary only for non-Noise uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, @@ -3212,6 +3219,8 @@ 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->noise_handshake_enabled = true; + conn->cookie_request_number = random_u64(c->rng); uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; From b78376c13f3a57853af4f39db762ca6578ed645d Mon Sep 17 00:00:00 2001 From: "Tobias Buchberger (goldroom)" Date: Sun, 7 Jan 2024 02:00:09 +0100 Subject: [PATCH 064/150] feat: backwards compatibility to non-Noise handshake. --- toxcore/net_crypto.c | 58 ++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index a79b938fbd..5931b367f8 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -900,6 +900,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t */ if(!noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); + if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + return false; + } //TODO: remove from production code // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; @@ -987,7 +990,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); return true; } - /* Noiise ReadMessage() if initiator: <- e, ee, se */ + /* Noise ReadMessage() if initiator: <- e, ee, se */ /* Responder: Handshake packet structure [uint8_t 26] [session public key of the peer (32 bytes)] @@ -1001,6 +1004,10 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t */ else { LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); + + if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + return false; + } memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -2919,24 +2926,33 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, n_c.noise_handshake = &n_c.noise_handshake_data; //TODO: Differention between non-Noise and Noise-based handshake needs to be checked here! + //TODO: e.g. based on length? - if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { - crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); - n_c.noise_handshake = nullptr; - mem_delete(c->mem, n_c.cookie); - return -1; - } + if (length != HANDSHAKE_PACKET_LENGTH) { + if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { + crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); + n_c.noise_handshake = nullptr; + mem_delete(c->mem, n_c.cookie); + return -1; + } - //TODO: remove - LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); - - /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ - if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { - crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); - n_c.noise_handshake = nullptr; - mem_delete(c->mem, n_c.cookie); - return -1; + //TODO: remove + LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); + + /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ + if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, + n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { + crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); + n_c.noise_handshake = nullptr; + mem_delete(c->mem, n_c.cookie); + return -1; + } + } else { /* case non-Noise handshake */ + if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, + n_c.cookie, data, length, nullptr, nullptr)) { + mem_delete(c->mem, n_c.cookie); + return -1; + } } //TODO: remove @@ -2947,16 +2963,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // bytes2string(log_cookie, sizeof(log_cookie), n_c.cookie, COOKIE_LENGTH, c->log); // LOGGER_DEBUG(c->log, "RESPONDER: cookie: %s", log_cookie); - //TODO: case non-Noise handshake - // if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, - // n_c.cookie, data, length, nullptr, nullptr)) { - // mem_delete(c->mem, n_c.cookie); - // return -1; - // } - const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); //TODO: Unsure which case this is.. if already called new_crypto_connection() as responder before? + //TODO: add compatibility to non-Noise handshake if (crypt_connection_id != -1) { LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); From d38f6e826dd08dd3511d347848001eb3821d0f4c Mon Sep 17 00:00:00 2001 From: iphydf Date: Mon, 19 Feb 2024 17:45:44 +0000 Subject: [PATCH 065/150] fix merge issue --- toxcore/net_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 55bf1ee6c9..d13fa8508f 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -3315,7 +3315,7 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ Net_Crypto *c = (Net_Crypto *)object; //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", data[0]); + LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", packet[0]); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; @@ -3352,7 +3352,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in Net_Crypto *c = (Net_Crypto *)object; //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", data[0]); + LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", packet[0]); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; From 4f16bb2d0ace0bd890b4a7553b3986b742625297 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 19 Feb 2024 17:46:00 +0000 Subject: [PATCH 066/150] Restyled by astyle --- toxcore/crypto_core.c | 106 ++++++++++++++++++++--------------------- toxcore/crypto_core.h | 22 ++++----- toxcore/net_crypto.c | 108 +++++++++++++++++++++--------------------- toxcore/net_crypto.h | 12 ++--- toxcore/util.h | 2 +- 5 files changed, 124 insertions(+), 126 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 48ab406833..1e6a160c06 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -532,8 +532,8 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length) /* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, - const uint8_t *plain, size_t plain_length, uint8_t *encrypted, - const uint8_t *ad, size_t ad_length) + const uint8_t *plain, size_t plain_length, uint8_t *encrypted, + const uint8_t *ad, size_t ad_length) { // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { @@ -541,10 +541,10 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no } unsigned long long encrypted_length = 0; - + // nsec is not used by this particular construction and should always be NULL. if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, - ad, ad_length, nullptr, nonce, shared_key) != 0) { + ad, ad_length, nullptr, nonce, shared_key) != 0) { return -1; } @@ -553,8 +553,8 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no } size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, - const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, - const uint8_t *ad, size_t ad_length) + const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, + const uint8_t *ad, size_t ad_length) { // Additional data ad can be a NULL pointer with ad_length equal to 0; plain_length is calculated by libsodium if (encrypted_length <= CRYPTO_MAC_SIZE || shared_key == nullptr || nonce == nullptr || encrypted == nullptr @@ -565,7 +565,7 @@ size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no unsigned long long plain_length = 0; if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, nullptr, encrypted, - encrypted_length, ad, ad_length, nonce, shared_key) != 0) { + encrypted_length, ad, ad_length, nonce, shared_key) != 0) { return -1; } @@ -579,13 +579,13 @@ size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. * This function is only called via `crypto_hkdf()`. * HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of - * `crypto_hmac*()` in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of + * `crypto_hmac*()` in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of * of 32 bytes (SHA512-256 HASHLEN). Cf. https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512 - * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) + * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, - size_t data_length) + size_t data_length) { crypto_auth_hmacsha512(auth, data, data_length, key); } @@ -609,36 +609,36 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * chaining_key as HKDF salt, and zero-length HKDF info. */ void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, - size_t first_len, size_t second_len, - size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) + size_t first_len, size_t second_len, + size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) { - uint8_t output[CRYPTO_SHA512_SIZE + 1]; + uint8_t output[CRYPTO_SHA512_SIZE + 1]; // temp_key = secret in WG uint8_t temp_key[CRYPTO_SHA512_SIZE]; - /* Extract entropy from data into temp_key */ + /* Extract entropy from data into temp_key */ // data => input_key_material => DH result in Noise - crypto_hmac512(temp_key, chaining_key, data, data_len); + crypto_hmac512(temp_key, chaining_key, data, data_len); - /* Expand first key: key = temp_key, data = 0x1 */ - output[0] = 1; - crypto_hmac512(output, temp_key, output, 1); - memcpy(output1, output, first_len); + /* Expand first key: key = temp_key, data = 0x1 */ + output[0] = 1; + crypto_hmac512(output, temp_key, output, 1); + memcpy(output1, output, first_len); - /* Expand second key: key = secret, data = first-key || 0x2 */ - output[CRYPTO_SHA512_SIZE] = 2; - crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); - memcpy(output2, output, second_len); + /* Expand second key: key = secret, data = first-key || 0x2 */ + output[CRYPTO_SHA512_SIZE] = 2; + crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); + memcpy(output2, output, second_len); - /* Expand third key: key = temp_key, data = second-key || 0x3 */ + /* Expand third key: key = temp_key, data = second-key || 0x3 */ /* Currently output3 not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ - // output[CRYPTO_SHA512_SIZE] = 3; - // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); - // memcpy(output3, output, third_len); + // output[CRYPTO_SHA512_SIZE] = 3; + // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); + // memcpy(output3, output, third_len); - /* Clear sensitive data from stack */ - crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); - crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); + /* Clear sensitive data from stack */ + crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); + crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); } /* @@ -650,34 +650,34 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, * input_key_material = DH_X25519(private, public) */ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], - const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { - uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; memset(dh_calculation, 0, CRYPTO_PUBLIC_KEY_SIZE); // X25519 - returns plain DH result, afterwards hashed with HKDF - if(crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { + if (crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { return -1; } // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! - crypto_hkdf(chaining_key, shared_key, dh_calculation, CRYPTO_SHA512_SIZE, - CRYPTO_SHARED_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); + crypto_hkdf(chaining_key, shared_key, dh_calculation, CRYPTO_SHA512_SIZE, + CRYPTO_SHARED_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); // If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() - crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); + crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); return 0; } /* * Noise MixHash(data): Sets h = HASH(h || data). - * + * * cf. Noise section 5.2 */ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) { - VLA(uint8_t, to_hash, CRYPTO_SHA512_SIZE + data_len); + VLA(uint8_t, to_hash, CRYPTO_SHA512_SIZE + data_len); memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); @@ -687,32 +687,32 @@ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_ * cf. Noise section 5.2 * "Noise spec: Note that if k is empty, the EncryptWithAd() call will set ciphertext equal to plaintext." * This is not the case in Tox. - */ + */ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, - size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) + size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { unsigned long long encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, - plaintext, plain_length, ciphertext, - hash, CRYPTO_SHA512_SIZE); + plaintext, plain_length, ciphertext, + hash, CRYPTO_SHA512_SIZE); - noise_mix_hash(hash, ciphertext, encrypted_length); + noise_mix_hash(hash, ciphertext, encrypted_length); } /* * cf. Noise section 5.2 * "Note that if k is empty, the DecryptWithAd() call will set plaintext equal to ciphertext." * This is not the case in Tox. - */ + */ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, - size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) + size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) { unsigned long long plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, - ciphertext, encrypted_length, plaintext, - hash, CRYPTO_SHA512_SIZE); + ciphertext, encrypted_length, plaintext, + hash, CRYPTO_SHA512_SIZE); - noise_mix_hash(hash, ciphertext, encrypted_length); + noise_mix_hash(hash, ciphertext, encrypted_length); - return plaintext_length; + return plaintext_length; } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index e95917a06e..e81a553ab8 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -516,7 +516,7 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); */ non_null(1, 2, 3, 5) nullable(6) size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, - uint8_t *encrypted, const uint8_t *ad, size_t ad_length); + uint8_t *encrypted, const uint8_t *ad, size_t ad_length); /** * @brief Decrypt message with precomputed shared key using XChaCha20-Poly1305. @@ -530,7 +530,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no */ non_null(1, 2, 3, 5) nullable(6) size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, - uint8_t *plain, const uint8_t *ad, size_t ad_length); + uint8_t *plain, const uint8_t *ad, size_t ad_length); /** * @brief Compute an HMAC-SHA512 authenticator (64 bytes). @@ -548,7 +548,7 @@ size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no * @param key Secret key */ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, - size_t data_length); + size_t data_length); /** * @brief Computes the number of provides outputs (=keys) with HKDF. @@ -582,8 +582,8 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * @param chaining_key Noise 64 byte chaining key as HKDF salt */ void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, - size_t first_len, size_t second_len, - size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); + size_t first_len, size_t second_len, + size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); /** * @brief Noise MixKey(input_key_material) @@ -601,8 +601,8 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, * @param public_key X25519 public key */ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], - const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); + const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); /** * @brief Noise MixHash(data): Sets h = HASH(h || data). @@ -636,8 +636,8 @@ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_ */ non_null() void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, - size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); + size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); /** * @brief DecryptAndHash(ciphertext): Sets plaintext = DecryptWithAd(h, @@ -658,8 +658,8 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, */ non_null() int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, - size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); + size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); #ifdef __cplusplus } /* extern "C" */ diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index d13fa8508f..2faa946a84 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -564,7 +564,7 @@ static int noise_handshake_init //TODO: remove if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); LOGGER_DEBUG(log, "static pub: %s", log_spub); } @@ -581,7 +581,7 @@ static int noise_handshake_init //TODO: Remove if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); } @@ -606,10 +606,10 @@ static int noise_handshake_init noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove - // if (log != nullptr) { - // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); - // } + // if (log != nullptr) { + // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); + // } } /* Ready to go */ @@ -681,13 +681,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u || TODO: or use 0? or leads to nonce reuse? */ random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); - char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); @@ -709,7 +709,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* OtherCookie is added to payload */ if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, - cookie_plain, c->secret_symmetric_key) != 0) { + cookie_plain, c->secret_symmetric_key) != 0) { return -1; } @@ -717,8 +717,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, - handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); //TODO: remove from production code // LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); @@ -798,7 +798,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* OtherCookie is added to payload */ if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, - cookie_plain, c->secret_symmetric_key) != 0) { + cookie_plain, c->secret_symmetric_key) != 0) { return -1; } @@ -807,8 +807,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u || TODO: or use 0? or leads to nonce reuse? */ random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, - handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); packet[0] = NET_PACKET_CRYPTO_HS; // Noise: cookie (from other peer/INITIATOR) is encrypted and included in ciphertext @@ -831,13 +831,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_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) { + cookie_plain, c->secret_symmetric_key) != 0) { return -1; } 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); + packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { return -1; @@ -898,7 +898,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [MAC 16 bytes] => 393 bytes in total */ - if(!noise_handshake->initiator) { + if (!noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { return false; @@ -919,7 +919,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); - char log_static[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + char log_static[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, "local static pub: %s", log_static); bytes2string(log_static, sizeof(log_static), noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE, c->log); @@ -932,8 +932,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* Nonces contained in packet! */ memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - if(noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { + if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { LOGGER_DEBUG(c->log, "RESPONDER: Noise ReadMessage remote static decryption failed"); return false; } @@ -954,9 +954,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* get Handshake payload base nonce */ memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); - if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, - sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, + noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS payload decryption failed"); return false; } @@ -1036,9 +1036,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); - if(noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, - sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, + noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); return false; } @@ -1096,8 +1096,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, - packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, - HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); + packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, + HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); if (len != sizeof(plain)) { return false; @@ -1874,7 +1874,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint //TODO: add ad? only packet ID and last two bytes of nonce sent in plain const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, - nullptr, 0); + nullptr, 0); //TODO: remove // LOGGER_DEBUG(c->log, "data packet decrypt len: %d", len); @@ -2091,7 +2091,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { return -1; } @@ -2104,7 +2104,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER]; if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { return -1; } @@ -2368,9 +2368,9 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } LOGGER_DEBUG(c->log, "ENTERING: crypto_connection_id: %d => PACKET: %d => CRYPTO CONN STATE: %d", - crypt_connection_id, - packet[0], - conn->status); + crypt_connection_id, + packet[0], + conn->status); if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING) { return -1; @@ -2430,9 +2430,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } LOGGER_DEBUG(c->log, "ENTERING: crypt_connection_id: %d | PACKET: %d | CRYPTO CONN STATE: %d", - crypt_connection_id, - packet[0], - conn->status); + crypt_connection_id, + packet[0], + conn->status); //TODO: what if I remove CRYPTO_CONN_NOT_CONFIRMED from here? => doesn't work together with connection_kill() after decrypting failure (after new handshake) if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING @@ -2461,11 +2461,11 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE HANDHSHAKE"); if (conn->noise_handshake->initiator) { - if(length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, nullptr, - packet, length, conn->public_key, conn->noise_handshake)) { + packet, length, conn->public_key, conn->noise_handshake)) { return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { @@ -2477,7 +2477,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, - packet, length, nullptr, conn->noise_handshake)) { + packet, length, nullptr, conn->noise_handshake)) { return -1; } @@ -2510,7 +2510,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, - packet, length, nullptr, conn->noise_handshake)) { + packet, length, nullptr, conn->noise_handshake)) { return -1; } /* RESPONDER needs to send handshake packet, afterwards finished */ @@ -2519,8 +2519,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } //TODO: here? conn->status = CRYPTO_CONN_HANDSHAKE_SENT; - } - else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); /* cannot chagne to INITIATOR here, connection broken */ //TODO: leave here? @@ -2535,7 +2534,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // necessary only for non-Noise uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, - packet, length, conn->public_key, nullptr)) { + packet, length, conn->public_key, nullptr)) { return -1; } } @@ -2606,8 +2605,8 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con //TODO: remove from prod code LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d | CRYPTO CONN STATE: %d", - packet[0], - conn->status); + packet[0], + conn->status); if (conn->status != CRYPTO_CONN_NOT_CONFIRMED && conn->status != CRYPTO_CONN_ESTABLISHED) { @@ -2753,11 +2752,11 @@ static int create_crypto_connection(Net_Crypto *c) return -1; } - if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { - mem_delete(c->mem, c->crypto_connections[id].mutex); - pthread_mutex_unlock(&c->connections_mutex); - return -1; - } + if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { + mem_delete(c->mem, c->crypto_connections[id].mutex); + pthread_mutex_unlock(&c->connections_mutex); + return -1; + } c->crypto_connections[id].noise_handshake = (Noise_Handshake *) mem_alloc(c->mem, sizeof(Noise_Handshake)); @@ -2951,7 +2950,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { + n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); @@ -3144,8 +3143,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); - } - else { + } else { pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); pthread_mutex_unlock(&c->tcp_mutex); @@ -3264,7 +3262,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // only necessary if Cookie request was successful // if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { // // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // mem_delete(c->mem, conn->noise_handshake); + // mem_delete(c->mem, conn->noise_handshake); // pthread_mutex_lock(&c->tcp_mutex); // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); // pthread_mutex_unlock(&c->tcp_mutex); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index c700d82fb5..2ab0d6e2bc 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -137,13 +137,13 @@ typedef struct Noise_Handshake { //TODO: static_private? uint8_t static_private[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t static_public[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t ephemeral_private[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t ephemeral_private[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t hash[CRYPTO_SHA512_SIZE]; - uint8_t chaining_key[CRYPTO_SHA512_SIZE]; + uint8_t hash[CRYPTO_SHA512_SIZE]; + uint8_t chaining_key[CRYPTO_SHA512_SIZE]; bool initiator; } Noise_Handshake; @@ -160,7 +160,7 @@ typedef struct New_Connection { Noise_Handshake *noise_handshake; //TODO: if no struct necessary // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; - // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; + // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; // bool initiator; diff --git a/toxcore/util.h b/toxcore/util.h index 9f51105879..40f7b75854 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -98,7 +98,7 @@ uint16_t data_checksum(const uint8_t *data, uint32_t length); /** * @brief Generic function to print bytes as String; based on id_to_string() from Messenger.c - * + * * @param bytes Bytes to be printed as String. * @param bytes_length The length in bytes * @param str The string to save the result to. From 190c0384a57a7369904a6a9e5621a88b6e37c095 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 15 Mar 2024 12:41:39 +0100 Subject: [PATCH 067/150] fix: removed unused OtherCookie from RESPONDER handshake packet. --- toxcore/net_crypto.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 2faa946a84..4d57c2dd0f 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -497,8 +497,9 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /* Noise: Necessary for Noise-based handshake */ #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) /* * TODO: Helper function to print hashes, keys, packets, etc. @@ -695,7 +696,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Noise Handshake Payload */ - uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH]; + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); // Noise: Cookie authenticated via ciphertext MAC // crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); @@ -748,10 +749,10 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [24 bytes nonce for handshake payload encryption] [Encrypted message containing: [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => Cookie encrypted and authenticate via XAEAD - [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD + ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK [MAC encrypted payload 16 bytes] - => 321 bytes in total + => ~~321~~ 209 bytes in total */ else { /* set ephemeral private+public */ @@ -784,7 +785,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); /* Create Noise Handshake Payload */ - uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH]; + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); // Noise: Cookie authenticated via ciphertext MAC // crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); @@ -792,15 +793,14 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // Noise: Cookie from INITIATOR memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - - /* OtherCookie is added to payload */ - if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, - cookie_plain, c->secret_symmetric_key) != 0) { - return -1; - } + /* OtherCookie is added to payload => NOT necessary for RESPONDER HS Packet */ + // uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + // 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->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, + // cookie_plain, c->secret_symmetric_key) != 0) { + // return -1; + // } /* Add Handshake payload nonce Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet @@ -950,7 +950,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* ss */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ - uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH]; + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; /* get Handshake payload base nonce */ memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); @@ -998,9 +998,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [Encrypted message containing: [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD - [112 bytes Other Cookie (used by the other to respond to the handshake packet)] + ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK [MAC 16 bytes] - => 321 bytes in total + => ~~321~~ 209 bytes in total */ else { LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); @@ -1029,7 +1029,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* Payload decryption */ - uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH]; + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); //TODO: Remove From 2201b8c0384ff5dfa69b9577bf9e870f20b181ee Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 18 Mar 2024 18:32:54 +0100 Subject: [PATCH 068/150] Fix: fixed wrong usages of CRYPTO_PUBLIC_KEY_SIZE to CRYPTO_SECRET_KEY_SIZE. --- toxcore/crypto_core.c | 2 +- toxcore/crypto_core.h | 2 +- toxcore/net_crypto.c | 6 +++--- toxcore/net_crypto.h | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 1e6a160c06..daf0a9a4b7 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -651,7 +651,7 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, */ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index e81a553ab8..1bb8a916bc 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -601,7 +601,7 @@ void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, * @param public_key X25519 public key */ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - const uint8_t private_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); /** diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 4d57c2dd0f..c31ca9e43b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -560,7 +560,7 @@ static int noise_handshake_init /* Sets the initiator, s => ephemeral keys are set afterwards */ noise_handshake->initiator = initiator; if (self_secret_key != nullptr) { - memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(noise_handshake->static_public, self_secret_key); //TODO: remove @@ -661,7 +661,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u */ if (noise_handshake->initiator) { /* set ephemeral private+public */ - memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* e */ @@ -756,7 +756,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u */ else { /* set ephemeral private+public */ - memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); /* e */ diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 2ab0d6e2bc..484df950c8 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -135,9 +135,9 @@ non_null() DHT *nc_get_dht(const Net_Crypto *c); */ typedef struct Noise_Handshake { //TODO: static_private? - uint8_t static_private[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t static_private[CRYPTO_SECRET_KEY_SIZE]; uint8_t static_public[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t ephemeral_private[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t ephemeral_private[CRYPTO_SECRET_KEY_SIZE]; uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; @@ -161,8 +161,8 @@ typedef struct New_Connection { //TODO: if no struct necessary // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; - // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; - // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; + // uint8_t niose_send_key[CRYPTO_SHARED_KEY_SIZE]; + // uint8_t noise_recv_key[CRYPTO_SHARED_KEY_SIZE]; // bool initiator; uint8_t *cookie; From a52f2fd311dc136bc5311bc7946730eca8838d03 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 18 Mar 2024 20:56:36 +0100 Subject: [PATCH 069/150] feat: backwards compatibility to non-Noise handshake. --- toxcore/net_crypto.c | 117 +++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index c31ca9e43b..c06cbb06e7 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1637,7 +1637,6 @@ static int handle_request_packet(const Memory *mem, Mono_Time *mono_time, Packet /** @brief Creates and sends a data packet to the peer using the fastest route. Currently only supports Noise (XChaCha20-Poly1305) * transport encryption. * - * TODO: adapt for backwards compatibility * * @retval -1 on failure. * @retval 0 on success. @@ -1667,9 +1666,6 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ VLA(uint8_t, packet, packet_size); packet[0] = NET_PACKET_CRYPTO_DATA; memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); - //TODO: need information in crypto conn if this is a Noise connection! - //TODO: enable backwards compatiblity - // const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); //TODO: remove // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; @@ -1679,8 +1675,15 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ // bytes2string(nonce_print, sizeof(nonce_print), conn->sent_nonce, CRYPTO_NONCE_SIZE, c->log); // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); - //TODO: add ad? only packet ID and last two bytes of nonce sent in plain - const int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); + //TODO: len was const + int len; + if (conn->noise_handshake_enabled) { /* Case NoiseIK handshake */ + //TODO: add ad? only packet ID and last two bytes of nonce sent in plain + int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); + } else { /* Case non-Noise handshake */ + int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + } + if (len + 1 + sizeof(uint16_t) != packet_size) { LOGGER_ERROR(c->log, "encryption failed: %d", len); @@ -1831,7 +1834,6 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce) * Currently only supports Noise (XChaCha20-Poly1305) * transport decryption. * - * TODO: adapt for backwards compatibility * * @retval -1 on failure. * @return length of data on success. @@ -1859,10 +1861,6 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint net_unpack_u16(packet + 1, &num); const uint16_t diff = num - num_cur_nonce; increment_nonce_number(nonce, diff); - //TODO: need information in crypto conn if this is a Noise connection! - //TODO: enable backwards compatiblity - // const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), - // length - (1 + sizeof(uint16_t)), data); //TODO: remove // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; @@ -1872,9 +1870,18 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint // bytes2string(nonce_print, sizeof(nonce_print), nonce, CRYPTO_NONCE_SIZE, c->log); // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); - //TODO: add ad? only packet ID and last two bytes of nonce sent in plain - const int len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, + //TODO: len was const + int len; + if (conn->noise_handshake_enabled) { /* case NoiseIK handshake */ + //TODO: add ad? only packet ID and last two bytes of nonce sent in plain + len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, nullptr, 0); + } else { /* case non-Noise handshake */ + len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), + length - (1 + sizeof(uint16_t)), data); + } + + //TODO: remove // LOGGER_DEBUG(c->log, "data packet decrypt len: %d", len); @@ -2456,6 +2463,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (length == HANDSHAKE_PACKET_LENGTH) { conn->noise_handshake_enabled = false; + //TODO: Wipe noise_handshake etc. in this case? } if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { @@ -2543,7 +2551,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); - if (conn->noise_handshake != nullptr) { + if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE HANDHSHAKE"); conn->status = CRYPTO_CONN_NOT_CONFIRMED; if (conn->noise_handshake->initiator) { @@ -2571,18 +2579,18 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } } - /* non-Noise handshake case */ + /* Backwards compatibility: non-Noise handshake case */ else { if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } } - //TODO: necessary for non-Noise handshake => change to OLD handshake condition - //encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + /* Backwards compatibility: necessary for non-Noise handshake */ + encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway - //TODO: necessary for old handshake / backwards compatibility - //conn->status = CRYPTO_CONN_NOT_CONFIRMED; + /* Backwards compatibility: necessary for non-Noise handshake */ + conn->status = CRYPTO_CONN_NOT_CONFIRMED; } } else { if (conn->dht_pk_callback != nullptr) { @@ -2931,13 +2939,11 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, n_c.source = *source; n_c.cookie_length = COOKIE_LENGTH; - //TODO: adapt static allocation? - n_c.noise_handshake = &n_c.noise_handshake_data; - - //TODO: Differention between non-Noise and Noise-based handshake needs to be checked here! - //TODO: e.g. based on length? + /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { + //TODO: adapt static allocation? + n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; @@ -2957,6 +2963,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } } else { /* case non-Noise handshake */ + // Necessary for backwards compatibility + n_c.noise_handshake = nullptr; if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, nullptr)) { mem_delete(c->mem, n_c.cookie); @@ -2974,8 +2982,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); - //TODO: Unsure which case this is.. if already called new_crypto_connection() as responder before? - //TODO: add compatibility to non-Noise handshake + //TODO: This is only called if new_crypto_connection() was already called in the meantime! Now RESPONDER! + //TODO: Does it make sense to handle this case for NoiseIK handshake? if (crypt_connection_id != -1) { LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2986,7 +2994,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!pk_equal(n_c.dht_public_key, conn->dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); - } else { + } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ + conn->noise_handshake_enabled = true; if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { mem_delete(c->mem, n_c.cookie); return -1; @@ -3020,41 +3029,29 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, mem_delete(c->mem, n_c.cookie); return 0; - } - } - - //TODO: case non-Noise handshake - // if (crypt_connection_id != -1) { - // Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - - // if (conn == nullptr) { - // return -1; - // } - - // if (!pk_equal(n_c.dht_public_key, conn->dht_public_key)) { - // connection_kill(c, crypt_connection_id, userdata); - // } else { - // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - // mem_delete(c->mem, n_c.cookie); - // return -1; - // } + } else { /* case non-Noise handshake */ + conn->noise_handshake_enabled = false; + if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { + mem_delete(c->mem, n_c.cookie); + return -1; + } - // memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); - // memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - // encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); + memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); + encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); - // crypto_connection_add_source(c, crypt_connection_id, source); + crypto_connection_add_source(c, crypt_connection_id, source); - // if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { - // mem_delete(c->mem, n_c.cookie); - // return -1; - // } + if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { + mem_delete(c->mem, n_c.cookie); + return -1; + } - // conn->status = CRYPTO_CONN_NOT_CONFIRMED; - // mem_delete(c->mem, n_c.cookie); - // return 0; - // } - // } + conn->status = CRYPTO_CONN_NOT_CONFIRMED; + mem_delete(c->mem, n_c.cookie); + return 0; + } + } const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); mem_delete(c->mem, n_c.cookie); @@ -3108,7 +3105,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->connection_number_tcp = connection_number_tcp; - //Noise: only happening for RESPONDER + // NoiseIK: only happening for RESPONDER if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { //TODO: remove @@ -3237,6 +3234,8 @@ 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); + // Necessary for backwards compatibility to non-Noise handshake + conn->noise_handshake = nullptr; conn->noise_handshake_enabled = true; conn->cookie_request_number = random_u64(c->rng); From 075d88804f2cea595b07e99dbfc05d260d6f51c6 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Mar 2024 10:11:54 +0100 Subject: [PATCH 070/150] fix: fixed uninitialized variable. --- toxcore/net_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index c06cbb06e7..97a30232e3 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1676,7 +1676,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); //TODO: len was const - int len; + int len = 0; if (conn->noise_handshake_enabled) { /* Case NoiseIK handshake */ //TODO: add ad? only packet ID and last two bytes of nonce sent in plain int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); @@ -1871,7 +1871,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); //TODO: len was const - int len; + int len = 0; if (conn->noise_handshake_enabled) { /* case NoiseIK handshake */ //TODO: add ad? only packet ID and last two bytes of nonce sent in plain len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, From 688635a6b00c38cf3b806ca58c44cacdd9eb1539 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Mar 2024 10:15:59 +0100 Subject: [PATCH 071/150] fix: fixed uninitialized variable. --- toxcore/net_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 97a30232e3..cadcd70447 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1679,9 +1679,9 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ int len = 0; if (conn->noise_handshake_enabled) { /* Case NoiseIK handshake */ //TODO: add ad? only packet ID and last two bytes of nonce sent in plain - int len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); + len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); } else { /* Case non-Noise handshake */ - int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); } From c16643dceaff0f6fc935b3678a487d7438b73ec7 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Mar 2024 10:31:33 +0100 Subject: [PATCH 072/150] fix: fixed reference to nullptr. --- toxcore/net_crypto.c | 1 - 1 file changed, 1 deletion(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index cadcd70447..6d2eb23213 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -3235,7 +3235,6 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u memcpy(conn->dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); // Necessary for backwards compatibility to non-Noise handshake - conn->noise_handshake = nullptr; conn->noise_handshake_enabled = true; conn->cookie_request_number = random_u64(c->rng); From 01d175abf91c29a55670959c1635b967bc471b61 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Mar 2024 10:54:48 +0100 Subject: [PATCH 073/150] debug: added debug output. --- toxcore/net_crypto.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 6d2eb23213..0c37101209 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2401,7 +2401,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "INITIATOR -> NOISE Handshake"); + LOGGER_DEBUG(c->log, "INITIATOR -> Noise handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } @@ -2410,7 +2410,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } } else { /* non-Noise handshake */ - LOGGER_DEBUG(c->log, "non-Noise Handshake"); + LOGGER_DEBUG(c->log, "non-Noise handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } @@ -2477,7 +2477,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - LOGGER_DEBUG(c->log, "INITIATOR: CHANGED TO RESPONDER"); + LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { return -1; } @@ -2510,7 +2510,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Case where RESPONDER with and without change from INITIATOR */ else { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); + LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change */ if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { return false; @@ -2538,7 +2538,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } /* non-Noise handshake */ else { - LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => non-Noise HANDHSHAKE"); + LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => non-Noise handshake"); // necessary only for non-Noise uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, @@ -2552,7 +2552,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "NOISE HANDHSHAKE"); + LOGGER_DEBUG(c->log, "Noise handshake"); conn->status = CRYPTO_CONN_NOT_CONFIRMED; if (conn->noise_handshake->initiator) { //TODO: remove @@ -2581,6 +2581,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } /* Backwards compatibility: non-Noise handshake case */ else { + LOGGER_DEBUG(c->log, "non-Noise handshake"); if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; @@ -2995,6 +2996,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!pk_equal(n_c.dht_public_key, conn->dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ + LOGGER_DEBUG(c->log, "Noise handshake"); conn->noise_handshake_enabled = true; if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { mem_delete(c->mem, n_c.cookie); @@ -3030,6 +3032,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, mem_delete(c->mem, n_c.cookie); return 0; } else { /* case non-Noise handshake */ + LOGGER_DEBUG(c->log, "non-Noise handshake"); conn->noise_handshake_enabled = false; if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { mem_delete(c->mem, n_c.cookie); @@ -3109,7 +3112,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { //TODO: remove - LOGGER_DEBUG(c->log, "Responder: Noise WriteMessage"); + LOGGER_DEBUG(c->log, "Responder: Noise handshake -> Noise WriteMessage"); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(Noise_Handshake)); //NOT possible here, need content afterwards! From 2325cc1d0008b13042f68cb6e49fb0abb7323a5b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Mar 2024 11:01:43 +0100 Subject: [PATCH 074/150] fix: possible fix for wrong non-Noise handshake. --- toxcore/net_crypto.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 0c37101209..bb8df5bc70 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2461,16 +2461,18 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: via noise_handshake struct? TODO: remove // bool initiator_change = false; - if (length == HANDSHAKE_PACKET_LENGTH) { - conn->noise_handshake_enabled = false; + if (length != HANDSHAKE_PACKET_LENGTH) { + conn->noise_handshake_enabled = true; //TODO: Wipe noise_handshake etc. in this case? + } else { + conn->noise_handshake_enabled = false; } if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "NOISE HANDHSHAKE"); + LOGGER_DEBUG(c->log, "Noise handshake"); if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { - LOGGER_DEBUG(c->log, "INITIATOR: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); + LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, nullptr, packet, length, conn->public_key, conn->noise_handshake)) { From c64f676509164353f78f3efa092ee4506e2ff0ef Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Mar 2024 15:57:44 +0100 Subject: [PATCH 075/150] feat: backwards compatibility to non-Noise handshake. Successfully tested with minitox and current toktok/toxic master branch (+goldroom c-toxcore master). --- toxcore/net_crypto.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index bb8df5bc70..6ba85ae541 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -643,7 +643,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); /* Noise-based handshake */ if (noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "NOISE HANDSHAKE"); + LOGGER_DEBUG(c->log, "Noise Handshake"); /* Noise INITIATOR: -> e, es, s, ss */ /* Initiator: Handshake packet structure [uint8_t 26] @@ -822,6 +822,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u } /* non-Noise handshake */ else { + LOGGER_DEBUG(c->log, "non-Noise handshake"); uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(plain, nonce, CRYPTO_NONCE_SIZE); memcpy(plain + CRYPTO_NONCE_SIZE, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -2584,11 +2585,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Backwards compatibility: non-Noise handshake case */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { + //TODO: doesn't work if Noise handshake packet was sent before + // if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } - } + // } /* Backwards compatibility: necessary for non-Noise handshake */ encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway @@ -3145,6 +3147,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); + //TODO: here correct? + crypto_memzero(n_c->noise_handshake, sizeof(Noise_Handshake)); } else { pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); @@ -3182,8 +3186,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->rtt_time = DEFAULT_PING_CONNECTION; crypto_connection_add_source(c, crypt_connection_id, &n_c->source); - //TODO: here correct? - crypto_memzero(n_c->noise_handshake, sizeof(Noise_Handshake)); + //TODO: here correct? => nope, crashes backwards compatbility + // crypto_memzero(n_c->noise_handshake, sizeof(Noise_Handshake)); return crypt_connection_id; } From 4286d4b31fc87fabcc3571a9bee3cd2fc97848af Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 19 Mar 2024 16:42:14 +0100 Subject: [PATCH 076/150] fix: fix for backwards compatibility to non-Noise handshake. --- toxcore/net_crypto.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 6ba85ae541..14b0f12e57 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1076,7 +1076,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } /* non-Noise handshake */ else { - LOGGER_DEBUG(c->log, "ENTERING: handle_crypto_handshake() => OLD HANDSHAKE"); + LOGGER_DEBUG(c->log, "non-Noise handshake"); if (length != HANDSHAKE_PACKET_LENGTH) { return false; @@ -2095,6 +2095,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u /* Noise-based handshake */ if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { + LOGGER_DEBUG(c->log, "NoiseIK handshake"); if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; @@ -2123,6 +2124,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u } /* non-Noise handshake*/ else { + LOGGER_DEBUG(c->log, "non-Noise handshake"); uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; /* ephemeral_private and noise_handshake not necessary for old handshake */ @@ -2541,7 +2543,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } /* non-Noise handshake */ else { - LOGGER_DEBUG(c->log, "handle_packet_crypto_hs() => non-Noise handshake"); + LOGGER_DEBUG(c->log, "non-Noise handshake"); // necessary only for non-Noise uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, @@ -2968,6 +2970,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } } else { /* case non-Noise handshake */ + LOGGER_DEBUG(c->log, "non-Noise handshake"); // Necessary for backwards compatibility n_c.noise_handshake = nullptr; if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, @@ -3115,6 +3118,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // NoiseIK: only happening for RESPONDER if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { + conn->noise_handshake_enabled = true; //TODO: remove LOGGER_DEBUG(c->log, "Responder: Noise handshake -> Noise WriteMessage"); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(Noise_Handshake)); From 21b9126626d652df30e770ffbdb6f0309a36a04a Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 22 Mar 2024 14:47:55 +0100 Subject: [PATCH 077/150] cleanup: stated explicit lengths for Noise function parameters (where possible) in crypto_core. --- toxcore/crypto_core.c | 6 +++--- toxcore/crypto_core.h | 4 ++-- toxcore/net_crypto.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index daf0a9a4b7..eff931ac77 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -531,7 +531,7 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length) /* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ -size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, +size_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) { @@ -552,7 +552,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no return encrypted_length; } -size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, +size_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length) { @@ -657,7 +657,7 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; memset(dh_calculation, 0, CRYPTO_PUBLIC_KEY_SIZE); - // X25519 - returns plain DH result, afterwards hashed with HKDF + // X25519: returns plain DH result, afterwards hashed with HKDF if (crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { return -1; } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 1bb8a916bc..c4b9e1b608 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -515,7 +515,7 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); * @return length of encrypted data if everything was fine. */ non_null(1, 2, 3, 5) nullable(6) -size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t plain_length, +size_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length); /** @@ -529,7 +529,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *no * @return length of plain data if everything was fine. */ non_null(1, 2, 3, 5) nullable(6) -size_t decrypt_data_symmetric_xaead(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t encrypted_length, +size_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); /** diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 14b0f12e57..acfd01af36 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -3196,7 +3196,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return crypt_connection_id; } -/** @brief Create a crypto connection. Currently independent of non-Noise/Noise handshake. +/** @brief Create a crypto connection. Currently supports both non-Noise and NoiseIK handshake. * If one to that real public key already exists, return it. * * return -1 on failure. From 760b4a351f89f0ab08617264fe3f778b6dce33d2 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 22 Mar 2024 16:10:19 +0100 Subject: [PATCH 078/150] fix: fixed merge issue found by coverage-linux check. --- toxcore/net_crypto.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index acfd01af36..f674a3e154 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2751,6 +2751,15 @@ static int create_crypto_connection(Net_Crypto *c) return -1; } + c->crypto_connections[id].noise_handshake = (Noise_Handshake *) mem_alloc(c->mem, sizeof(Noise_Handshake)); + + if (c->crypto_connections[id].noise_handshake == nullptr) { + LOGGER_ERROR(c->log, "failed to alloc noise_handshake"); + mem_delete(c->mem, c->crypto_connections[id].mutex); + pthread_mutex_unlock(&c->connections_mutex); + return -1; + } + // Memsetting float/double to 0 is non-portable, so we explicitly set them to 0 c->crypto_connections[id].packet_recv_rate = 0.0; c->crypto_connections[id].packet_send_rate = 0.0; @@ -2761,33 +2770,10 @@ static int create_crypto_connection(Net_Crypto *c) c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; } - if (c->crypto_connections[id].mutex == nullptr) { - LOGGER_ERROR(c->log, "failed to alloc mutex"); - pthread_mutex_unlock(&c->connections_mutex); - return -1; - } - - if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { - mem_delete(c->mem, c->crypto_connections[id].mutex); - pthread_mutex_unlock(&c->connections_mutex); - return -1; - } - - c->crypto_connections[id].noise_handshake = (Noise_Handshake *) mem_alloc(c->mem, sizeof(Noise_Handshake)); - - if (c->crypto_connections[id].noise_handshake == nullptr) { - LOGGER_ERROR(c->log, "failed to alloc noise_handshake"); - mem_delete(c->mem, c->crypto_connections[id].mutex); - pthread_mutex_unlock(&c->connections_mutex); - return -1; - } - //TODO: Remove // c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 800); // LOGGER_DEBUG(c->log, "handshake_send_interval: %d", c->crypto_connections[id].handshake_send_interval); - c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; - pthread_mutex_unlock(&c->connections_mutex); return id; } From a467d454d8bd441c757dba083f13ee9e8d64455b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 22 Mar 2024 17:33:12 +0100 Subject: [PATCH 079/150] cleanup/fix: changed parameter ordering of crypto_hkdf() to make tokstyle happy. --- toxcore/crypto_core.c | 14 +++++++------- toxcore/crypto_core.h | 4 ++-- toxcore/net_crypto.c | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index eff931ac77..8f696cca01 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -608,8 +608,8 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * length. Also note that the HKDF() function is simply HKDF with the * chaining_key as HKDF salt, and zero-length HKDF info. */ -void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, - size_t first_len, size_t second_len, +void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, + size_t second_len, const uint8_t *data, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) { uint8_t output[CRYPTO_SHA512_SIZE + 1]; @@ -654,18 +654,18 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { - uint8_t dh_calculation[CRYPTO_PUBLIC_KEY_SIZE]; - memset(dh_calculation, 0, CRYPTO_PUBLIC_KEY_SIZE); + uint8_t dh_calculation[CRYPTO_SHARED_KEY_SIZE]; + memset(dh_calculation, 0, CRYPTO_SHARED_KEY_SIZE); // X25519: returns plain DH result, afterwards hashed with HKDF if (crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { return -1; } // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! - crypto_hkdf(chaining_key, shared_key, dh_calculation, CRYPTO_SHA512_SIZE, - CRYPTO_SHARED_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, chaining_key); + crypto_hkdf(chaining_key, CRYPTO_SHA512_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, + CRYPTO_SHARED_KEY_SIZE, chaining_key); // If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() - crypto_memzero(dh_calculation, CRYPTO_PUBLIC_KEY_SIZE); + crypto_memzero(dh_calculation, CRYPTO_SHARED_KEY_SIZE); return 0; } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index c4b9e1b608..dcb4ec6c5c 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -581,8 +581,8 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * @param data_len length of either zero bytes, 32 bytes, or DHLEN bytes * @param chaining_key Noise 64 byte chaining key as HKDF salt */ -void crypto_hkdf(uint8_t *output1, uint8_t *output2, const uint8_t *data, - size_t first_len, size_t second_len, +void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, + size_t second_len, const uint8_t *data, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); /** diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index f674a3e154..5688d5484b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2566,7 +2566,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // LOGGER_DEBUG(c->log, "ck: %s", ck_print); /* INITIATOR Noise Split(), nonces already set in crypto connection */ - crypto_hkdf(conn->send_key, conn->recv_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); //TODO: remove @@ -2579,7 +2579,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise RESPONDER */ else { /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } @@ -3015,7 +3015,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ //TODO: remove here? - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); @@ -3133,7 +3133,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } /* Noise Split(), base nonces already set */ - crypto_hkdf(conn->recv_key, conn->send_key, nullptr, CRYPTO_SYMMETRIC_KEY_SIZE, CRYPTO_SYMMETRIC_KEY_SIZE, 0, conn->noise_handshake->chaining_key); + crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); From 78472458016b098c8d94872a43f3e06823b31e7c Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 22 Mar 2024 17:52:58 +0100 Subject: [PATCH 080/150] fix: fixes for CI. --- toxcore/logger.c | 2 +- toxcore/net_crypto.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/logger.c b/toxcore/logger.c index 4092ec41f9..7593508411 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -109,7 +109,7 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l #endif /* WIN32 */ // Format message - //TODO: changed from 1024 to 4096 + // TODO: changed from 1024 to 4096 char msg[4096]; va_list args; va_start(args, format); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 5688d5484b..a87bd8c3c4 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2518,7 +2518,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change */ if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { - return false; + return -1; } /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ From 85d12b67f648b77757c38a29ac08948b55722b2b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Wed, 3 Apr 2024 15:29:17 +0200 Subject: [PATCH 081/150] fix: added missing non_null()/nullable() statements to . --- toxcore/crypto_core.h | 3 +++ toxcore/net_crypto.c | 6 +++--- toxcore/net_crypto.h | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index dcb4ec6c5c..1c8e2e3966 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -547,6 +547,7 @@ size_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S * @param auth Resulting authenticator. * @param key Secret key */ +non_null(1, 2) nullable(3) void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_length); @@ -581,6 +582,7 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * @param data_len length of either zero bytes, 32 bytes, or DHLEN bytes * @param chaining_key Noise 64 byte chaining key as HKDF salt */ + non_null(1, 3, 7) nullable(5) void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, size_t second_len, const uint8_t *data, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); @@ -600,6 +602,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * @param private_key X25519 private key * @param public_key X25519 public key */ + non_null() int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index a87bd8c3c4..7c6df04715 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -52,19 +52,19 @@ typedef enum Crypto_Conn_State { } Crypto_Conn_State; typedef struct Crypto_Connection { - // Necessary for non-Noise handshake + // (Currently) used for both non-Noise and Noise handshakes/connections uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ uint8_t sessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public key for this session. */ uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private key for this session. */ - uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ + uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. Not used in Noise handshake. */ uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. */ Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ - // For Noise + // Necessary for Noise handshake bool noise_handshake_enabled; Noise_Handshake *noise_handshake; uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 484df950c8..9d510689df 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -129,12 +129,12 @@ non_null() const uint8_t *nc_get_self_secret_key(const Net_Crypto *c); non_null() TCP_Connections *nc_get_tcp_c(const Net_Crypto *c); non_null() DHT *nc_get_dht(const Net_Crypto *c); -//TODO: struct necessary? -//TODO: move to crypto_core.h? +// TODO: struct necessary? +// TODO: move to crypto_core.h? /** @brief Necessary Noise handshake state information/values. */ typedef struct Noise_Handshake { - //TODO: static_private? + // TODO: static_private? uint8_t static_private[CRYPTO_SECRET_KEY_SIZE]; uint8_t static_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t ephemeral_private[CRYPTO_SECRET_KEY_SIZE]; From d87f9c10942353bf108af483207c8b9cba60f90b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 12 Apr 2024 18:13:11 +0200 Subject: [PATCH 082/150] feat: Implemented Noise_IK_25519_ChaChaPoly_SHA512 instead of Noise_IK_25519_XChaChaPoly_SHA512 to be compliant with Noise specification/framework. Therefore added functions for IETF ChaCha20-Poly1305 construction to crypto_core (this uses 12 byte nonces). Adapted the handshake functions to use ChaCha20-Poly1305 instead of XChaCha20-Poly1305. NoiseIK based crypto connections still use XChaCha20-Poly1305 for transport message encryption. --- toxcore/crypto_core.c | 55 +++++++++++++- toxcore/crypto_core.h | 40 +++++++++- toxcore/net_crypto.c | 168 ++++++++++++++++++++++++++++++++---------- 3 files changed, 218 insertions(+), 45 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 8f696cca01..8026c9d549 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -531,6 +531,49 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length) /* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ +size_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], + const uint8_t *plain, size_t plain_length, uint8_t *encrypted, + const uint8_t *ad, size_t ad_length) +{ + // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium + if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { + return -1; + } + + unsigned long long encrypted_length = 0; + + // nsec is not used by this particular construction and should always be NULL. + if (crypto_aead_chacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, + ad, ad_length, nullptr, nonce, shared_key) != 0) { + return -1; + } + + // assert(length < INT32_MAX - crypto_box_MACBYTES); + return encrypted_length; +} + +size_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], + const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, + const uint8_t *ad, size_t ad_length) +{ + // Additional data ad can be a NULL pointer with ad_length equal to 0; plain_length is calculated by libsodium + if (encrypted_length <= CRYPTO_MAC_SIZE || shared_key == nullptr || nonce == nullptr || encrypted == nullptr + || plain == nullptr) { + return -1; + } + + unsigned long long plain_length = 0; + + if (crypto_aead_chacha20poly1305_ietf_decrypt(plain, &plain_length, nullptr, encrypted, + encrypted_length, ad, ad_length, nonce, shared_key) != 0) { + return -1; + } + + // assert(length > crypto_box_MACBYTES); + // assert(length < INT32_MAX); + return plain_length; +} + size_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) @@ -690,9 +733,11 @@ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_ */ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) + uint8_t hash[CRYPTO_SHA512_SIZE]) { - unsigned long long encrypted_length = encrypt_data_symmetric_xaead(shared_key, nonce, + static const uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + + unsigned long long encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, hash, CRYPTO_SHA512_SIZE); @@ -706,9 +751,11 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, */ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]) + uint8_t hash[CRYPTO_SHA512_SIZE]) { - unsigned long long plaintext_length = decrypt_data_symmetric_xaead(shared_key, nonce, + static const uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + + unsigned long long plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, hash, CRYPTO_SHA512_SIZE); diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 1c8e2e3966..525822e715 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -67,6 +67,11 @@ extern "C" { */ #define CRYPTO_NONCE_SIZE 24 +/** + * @brief NoiseIK: The number of bytes in a nonce used for encryption/decryption (ChaChaPoly-1305-IETF). + */ +#define CRYPTO_NOISEIK_NONCE_SIZE 12 + /** * @brief The number of bytes in a SHA256 hash. */ @@ -503,6 +508,35 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); /* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ +/** + * @brief Encrypt message with precomputed shared key using ChaCha20-Poly1305. + * + * Encrypts plain of plain_length to encrypted of plain_length + @ref CRYPTO_MAC_SIZE + * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NONCE_SIZE + * byte nonce. The encrypted message, as well as a tag authenticating both the confidential + * message m and adlen bytes of non-confidential data ad, are put into encrypted. + * + * @retval -1 if there was a problem. + * @return length of encrypted data if everything was fine. + */ +non_null(1, 2, 3, 5) nullable(6) +size_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *plain, size_t plain_length, + uint8_t *encrypted, const uint8_t *ad, size_t ad_length); + +/** + * @brief Decrypt message with precomputed shared key using ChaCha20-Poly1305. + * + * Decrypts encrypted of encrypted_length to plain of length + * `length - CRYPTO_MAC_SIZE` using a shared key @ref CRYPTO_SHARED_KEY_SIZE + * big and a @ref CRYPTO_NONCE_SIZE byte nonce. + * + * @retval -1 if there was a problem (decryption failed). + * @return length of plain data if everything was fine. + */ +non_null(1, 2, 3, 5) nullable(6) +size_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, + uint8_t *plain, const uint8_t *ad, size_t ad_length); + /** * @brief Encrypt message with precomputed shared key using XChaCha20-Poly1305. * @@ -640,7 +674,7 @@ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_ non_null() void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); + uint8_t hash[CRYPTO_SHA512_SIZE]); /** * @brief DecryptAndHash(ciphertext): Sets plaintext = DecryptWithAd(h, @@ -660,9 +694,9 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, * @param nonce used for XEAD decryption */ non_null() -int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, +int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE], uint8_t nonce[CRYPTO_NONCE_SIZE]); + uint8_t hash[CRYPTO_SHA512_SIZE]); #ifdef __cplusplus } /* extern "C" */ diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 7c6df04715..8ac9b157ee 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -496,8 +496,12 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, /* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /* Noise: Necessary for Noise-based handshake */ -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +//TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 +// #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +//TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 +// #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) @@ -645,7 +649,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise Handshake"); /* Noise INITIATOR: -> e, es, s, ss */ - /* Initiator: Handshake packet structure + /* Initiator: Handshake packet structure (Noise_IK_25519_XChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce for static pub key encryption] @@ -659,6 +663,20 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [MAC encrypted payload 16 bytes] => 393 bytes in total */ + /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + [uint8_t 26] + [session public key of the peer (32 bytes)] => currently in plain + ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 + [encrypted static public key of the INITIATOR (32 bytes)] + [MAC encrypted static pubkey 16 bytes] + ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD + [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] + [MAC encrypted payload 16 bytes] + => 345 bytes in total + */ if (noise_handshake->initiator) { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); @@ -678,11 +696,15 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); /* s */ - /*Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet - || TODO: or use 0? or leads to nonce reuse? */ - random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 + /*Nonce provided as parameter is the base nonce! -> This adds nonce for static pub key encryption to packet (XChaCha20-Poly1305) */ + // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + + /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + noise_handshake->hash); //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; @@ -714,12 +736,17 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return -1; } + //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 /* Add Handshake payload nonce */ - random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + // handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + noise_handshake->hash); //TODO: remove from production code // LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); @@ -743,7 +770,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* Noise RESPONDER: <- e, ee, se */ - /* Responder: Handshake packet structure + /* Responder: Handshake packet structure (Noise_IK_25519_XChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce for handshake payload encryption] @@ -754,6 +781,17 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [MAC encrypted payload 16 bytes] => ~~321~~ 209 bytes in total */ + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + [uint8_t 26] + [session public key of the peer (32 bytes)] => currently in plain + ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD + ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK + [MAC encrypted payload 16 bytes] + => ~~321~~ 185 bytes in total + */ else { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); @@ -793,6 +831,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // Noise: Cookie from INITIATOR memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + //TODO: remove /* OtherCookie is added to payload => NOT necessary for RESPONDER HS Packet */ // uint8_t cookie_plain[COOKIE_DATA_LENGTH]; // memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); @@ -802,13 +841,17 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // return -1; // } - /* Add Handshake payload nonce - Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet - || TODO: or use 0? or leads to nonce reuse? */ - random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 + /* Add Handshake payload nonce. Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet */ + // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + // handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + + /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + noise_handshake->hash); packet[0] = NET_PACKET_CRYPTO_HS; // Noise: cookie (from other peer/INITIATOR) is encrypted and included in ciphertext @@ -885,7 +928,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - /* Initiator: Handshake packet structure handled here + /* Initiator: Handshake packet structure handled here (Noise_IK_25519_XChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain [24 bytes nonce static pub key encryption] @@ -899,6 +942,20 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [MAC 16 bytes] => 393 bytes in total */ + /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_SHA512) + [uint8_t 26] + [session public key of the peer (32 bytes)] => currently in plain + ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 + [encrypted static public key of the INITIATOR (32 bytes)] + [MAC encrypted static pubkey 16 bytes] + ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD + [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] + [MAC encrypted payload 16 bytes] + => 345 bytes in total + */ if (!noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { @@ -930,11 +987,17 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); /* s */ - /* Nonces contained in packet! */ - memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + /* TODO: remove; Nonces contained in packet! */ + // memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + // if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + // noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { + // LOGGER_DEBUG(c->log, "RESPONDER: Noise ReadMessage remote static decryption failed"); + // return false; + // } - if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { + /* Nonce for static pub key decryption is _always_ 0 in case of ChaCha20-Poly1305 */ + if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + noise_handshake_temp_key, noise_handshake->hash) != CRYPTO_PUBLIC_KEY_SIZE) { LOGGER_DEBUG(c->log, "RESPONDER: Noise ReadMessage remote static decryption failed"); return false; } @@ -952,12 +1015,19 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; - /* get Handshake payload base nonce */ - memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); + /* TODO: remove; get Handshake payload nonce */ + // memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); + // if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + // sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, + // noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + // LOGGER_DEBUG(c->log, "RESPONDER: Noise HS payload decryption failed"); + // return false; + // } - if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + /* Nonce for payload decryption is _always_ 0 in case of ChaCha20-Poly1305 */ + if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + noise_handshake->hash) != sizeof(handshake_payload_plain)) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS payload decryption failed"); return false; } @@ -992,7 +1062,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* Responder: Handshake packet structure + /* Responder: Handshake packet structure (Noise_IK_X25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] [24 bytes nonce handshake payload encryption] @@ -1003,6 +1073,17 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [MAC 16 bytes] => ~~321~~ 209 bytes in total */ + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + [uint8_t 26] + [session public key of the peer (32 bytes)] => currently in plain + ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD + ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK + [MAC encrypted payload 16 bytes] + => ~~321~~ 185 bytes in total + */ else { LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); @@ -1029,17 +1110,26 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); - /* Payload decryption */ - uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; - memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - //TODO: Remove // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); + + /* Payload decryption */ + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; + + /* TODO: remove; get Handshake payload nonce */ + // memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); + // if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + // sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, + // noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + // LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); + // return false; + // } - if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + /* Nonce for payload decryption is 0 in case of ChaCha20-Poly1305 */ + if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { + noise_handshake->hash) != sizeof(handshake_payload_plain)) { LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); return false; } @@ -2404,7 +2494,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "INITIATOR -> Noise handshake"); + LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } @@ -2512,11 +2602,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary => TODO: need info in conn or noise_handshake + //TODO: Or add new connection state? /* Case where RESPONDER with and without change from INITIATOR */ else { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); - /* necessary, otherwise broken after INITIATOR to RESPONDER change */ + /* necessary, otherwise broken after INITIATOR to RESPONDER change; also necessary without change */ if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { return -1; } @@ -3051,6 +3142,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); mem_delete(c->mem, n_c.cookie); + //TODO: remove; ret value is from friend_connection.c:handle_new_connections() LOGGER_DEBUG(c->log, "ret (!= 0?): %d", ret); return ret; } @@ -3198,14 +3290,14 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u if (crypt_connection_id != -1) { //TODO: remove //TODO: Print pub key? - LOGGER_DEBUG(c->log, "INITIATOR: Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); return crypt_connection_id; } crypt_connection_id = create_crypto_connection(c); //TODO: remove - LOGGER_DEBUG(c->log, "INITIATOR: AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { return -1; From 34a88d43a85df680a5129f73b150893b8fb28502 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 12 Apr 2024 18:16:32 +0200 Subject: [PATCH 083/150] fix: fix param for asan/tsan/ubsan. --- toxcore/crypto_core.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 525822e715..0041b24d14 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -669,7 +669,6 @@ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_ * @param plain_length length of plaintext * @param shared_key used for XAEAD encryption * @param hash stores hash value, used as associated data in XAEAD - * @param nonce used for XEAD encryption */ non_null() void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, @@ -691,7 +690,6 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, * @param encrypted_length length of ciphertext+MAC * @param shared_key used for XAEAD decryption * @param hash stores hash value, used as associated data in XAEAD - * @param nonce used for XEAD decryption */ non_null() int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, From 06404d5728972d18ee36a4f0e615ea540f2a7afe Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 12 Apr 2024 18:24:42 +0200 Subject: [PATCH 084/150] fix: changed Noise protocol name to Noise_IK_25519_ChaChaPoly_SHA512. --- toxcore/crypto_core.h | 8 ++++---- toxcore/net_crypto.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 0041b24d14..9f8e683197 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -509,10 +509,10 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); /* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ /** - * @brief Encrypt message with precomputed shared key using ChaCha20-Poly1305. + * @brief Encrypt message with precomputed shared key using ChaCha20-Poly1305-IETF (RFC7539). * * Encrypts plain of plain_length to encrypted of plain_length + @ref CRYPTO_MAC_SIZE - * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NONCE_SIZE + * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NOISEIK_NONCE_SIZE * byte nonce. The encrypted message, as well as a tag authenticating both the confidential * message m and adlen bytes of non-confidential data ad, are put into encrypted. * @@ -524,11 +524,11 @@ size_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SI uint8_t *encrypted, const uint8_t *ad, size_t ad_length); /** - * @brief Decrypt message with precomputed shared key using ChaCha20-Poly1305. + * @brief Decrypt message with precomputed shared key using ChaCha20-Poly1305-IETF (RFC7539). * * Decrypts encrypted of encrypted_length to plain of length * `length - CRYPTO_MAC_SIZE` using a shared key @ref CRYPTO_SHARED_KEY_SIZE - * big and a @ref CRYPTO_NONCE_SIZE byte nonce. + * big and a @ref CRYPTO_NOISEIK_NONCE_SIZE byte nonce. * * @retval -1 if there was a problem (decryption failed). * @return length of plain data if everything was fine. diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 9d510689df..09fe9ea2c4 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -120,7 +120,7 @@ typedef enum Packet_Id { #define DEFAULT_PING_CONNECTION 1000 #define DEFAULT_TCP_PING_CONNECTION 500 -#define NOISE_PROTOCOL_NAME "Noise_IK_25519_XChaChaPoly_SHA512" +#define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" typedef struct Net_Crypto Net_Crypto; From f5778643dbc6b289be33430ce454a1d81ae1e7c2 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 12 Apr 2024 21:32:25 +0200 Subject: [PATCH 085/150] test: trying test vectors from noise-c --- auto_tests/crypto_test.c | 637 ++++++++++++----- auto_tests/crypto_test.c.real | 372 ++++++++++ auto_tests/crypto_test_NoiseIK_test_vectors.c | 639 ++++++++++++++++++ toxcore/crypto_core.c | 131 +++- toxcore/crypto_core.h | 44 ++ toxcore/net_crypto.c | 126 +--- toxcore/net_crypto.h | 21 - 7 files changed, 1646 insertions(+), 324 deletions(-) create mode 100644 auto_tests/crypto_test.c.real create mode 100644 auto_tests/crypto_test_NoiseIK_test_vectors.c diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 83f8c525a6..90f6c5d59a 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -1,15 +1,20 @@ #include #include #include +#include #include "../testing/misc_tools.h" #include "../toxcore/crypto_core.h" #include "../toxcore/net_crypto.h" #include "check_compat.h" +#include "../other/fun/create_common.h" +#include "../toxcore/mem.h" static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) { - for (size_t i = 0; i < blen; i++) { + size_t i; + + for (i = 0; i < blen; i++) { b[i] = random_u08(rng); } } @@ -82,18 +87,19 @@ static void test_known(void) { uint8_t c[147]; uint8_t m[131]; + uint16_t clen, mlen; ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); @@ -104,6 +110,7 @@ static void test_fast_known(void) uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t c[147]; uint8_t m[131]; + uint16_t clen, mlen; encrypt_precompute(bobpk, alicesk, k); @@ -112,193 +119,450 @@ static void test_fast_known(void) ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); } -static void test_endtoend(void) -{ - const Random *rng = os_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]; - uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; - uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; - uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; - uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; - - uint8_t n[CRYPTO_NONCE_SIZE]; - - enum { M_SIZE = 50 }; - uint8_t m[M_SIZE]; - uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; - uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; - uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; - uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; - uint8_t m1[sizeof(m)]; - uint8_t m2[sizeof(m)]; - uint8_t m3[sizeof(m)]; - uint8_t m4[sizeof(m)]; - - //Generate random message (random length from 10 to 50) - const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; - rand_bytes(rng, m, mlen); - rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - - //Generate keypairs - crypto_new_keypair(rng, pk1, sk1); - crypto_new_keypair(rng, pk2, sk2); - - //Precompute shared keys - encrypt_precompute(pk2, sk1, k1); - encrypt_precompute(pk1, sk2, k2); - - ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); - - //Encrypt all four ways - const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); - const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); - const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); - const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); - - ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); - ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); - ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 - && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); - - //Decrypt all four ways - const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); - const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); - const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); - const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); - - ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); - ck_assert_msg(m1len == mlen, "wrong decrypted text length"); - ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 - && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); - ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); - } -} - -static void test_large_data(void) -{ - const Random *rng = os_random(); - ck_assert(rng != nullptr); - uint8_t k[CRYPTO_SHARED_KEY_SIZE]; - uint8_t n[CRYPTO_NONCE_SIZE]; +static const uint8_t test_nonce_chacha20[8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; - const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; - uint8_t *m1 = (uint8_t *)malloc(m1_size); - uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); - uint8_t *m1prime = (uint8_t *)malloc(m1_size); +static const uint8_t test_nonce_chacha20_ietf[12] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; - const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; - uint8_t *m2 = (uint8_t *)malloc(m2_size); - uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); +static const uint8_t test_nonce_xchacha20[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; - ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); +static const uint8_t test_nonce_one_zero_byte[1] = { + 0x00 +}; - //Generate random messages - rand_bytes(rng, m1, m1_size); - rand_bytes(rng, m2, m2_size); - rand_bytes(rng, n, CRYPTO_NONCE_SIZE); +static const uint8_t prologue[11] = { + 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x31, 0x32, 0x33 +}; - //Generate key - rand_bytes(rng, k, CRYPTO_SHARED_KEY_SIZE); +uint8_t init_static[32] = { + 0xe6, 0x1e, 0xf9, 0x91, 0x9c, 0xde, 0x45, 0xdd, + 0x5f, 0x82, 0x16, 0x64, 0x04, 0xbd, 0x08, 0xe3, + 0x8b, 0xce, 0xb5, 0xdf, 0xdf, 0xde, 0xd0, 0xa3, + 0x4c, 0x8d, 0xf7, 0xed, 0x54, 0x22, 0x14, 0xd1 +}; - 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); +uint8_t init_ephemeral[32] = { + 0x89, 0x3e, 0x28, 0xb9, 0xdc, 0x6c, 0xa8, 0xd6, + 0x11, 0xab, 0x66, 0x47, 0x54, 0xb8, 0xce, 0xb7, + 0xba, 0xc5, 0x11, 0x73, 0x49, 0xa4, 0x43, 0x9a, + 0x6b, 0x05, 0x69, 0xda, 0x97, 0x7c, 0x46, 0x4a +}; - ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); - ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); +uint8_t init_remote_static[32] = { + 0x31, 0xe0, 0x30, 0x3f, 0xd6, 0x41, 0x8d, 0x2f, + 0x8c, 0x0e, 0x78, 0xb9, 0x1f, 0x22, 0xe8, 0xca, + 0xed, 0x0f, 0xbe, 0x48, 0x65, 0x6d, 0xcf, 0x47, + 0x67, 0xe4, 0x83, 0x4f, 0x70, 0x1b, 0x8f, 0x62 +}; - const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); +uint8_t resp_static[32] = { + 0x4a, 0x3a, 0xcb, 0xfd, 0xb1, 0x63, 0xde, 0xc6, + 0x51, 0xdf, 0xa3, 0x19, 0x4d, 0xec, 0xe6, 0x76, + 0xd4, 0x37, 0x02, 0x9c, 0x62, 0xa4, 0x08, 0xb4, + 0xc5, 0xea, 0x91, 0x14, 0x24, 0x6e, 0x48, 0x93 +}; - ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); - ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); +uint8_t resp_ephemeral[32] = { + 0xbb, 0xdb, 0x4c, 0xdb, 0xd3, 0x09, 0xf1, 0xa1, + 0xf2, 0xe1, 0x45, 0x69, 0x67, 0xfe, 0x28, 0x8c, + 0xad, 0xd6, 0xf7, 0x12, 0xd6, 0x5d, 0xc7, 0xb7, + 0x79, 0x3d, 0x5e, 0x63, 0xda, 0x6b, 0x37, 0x5b +}; - free(c2); - free(m2); - free(m1prime); - free(c1); - free(m1); -} +uint8_t payload1[16] = { + 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f, + 0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 + }; -static void test_large_data_symmetric(void) +static void test_fast_known2(void) { - const Random *rng = os_random(); - ck_assert(rng != nullptr); - uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; - - uint8_t n[CRYPTO_NONCE_SIZE]; - - const size_t m1_size = 16 * 16 * 16; - uint8_t *m1 = (uint8_t *)malloc(m1_size); - uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); - uint8_t *m1prime = (uint8_t *)malloc(m1_size); - - ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); - - //Generate random messages - rand_bytes(rng, m1, m1_size); - rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; + uint8_t m1[131]; + uint8_t m2[131]; + uint8_t xm1[131]; + uint8_t xm2[131]; + uint8_t c1[147]; + uint8_t c2[147]; + uint8_t xc1[147]; + uint8_t xc2[147]; + uint16_t xclen2, xmlen2; + unsigned long long mlen1 = 0; + unsigned long long clen1 = 0; + unsigned long long mlen2 = 0; + unsigned long long clen2 = 0; + unsigned long long xclen1 = 0; + unsigned long long xmlen1 = 0; + int result; + + uint8_t hash[CRYPTO_SHA512_SIZE]; + uint8_t send_key1[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t recv_key1[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t send_key2[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t recv_key2[CRYPTO_PUBLIC_KEY_SIZE]; - //Generate key - new_symmetric_key(rng, k); + encrypt_precompute(bobpk, alicesk, 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"); + // ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), + // "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); + // ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); + + // crypto_sha512(hash, k, CRYPTO_PUBLIC_KEY_SIZE); + // crypto_hkdf(send_key1, recv_key1, NULL, k, + // CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, 0, + // CRYPTO_PUBLIC_KEY_SIZE, hash); + + // char send_key1_string[CRYPTO_SHA512_SIZE * 2 + 1]; + // char recv_key1_string[CRYPTO_SHA512_SIZE * 2 + 1]; + // bin2hex_toupper(send_key1_string, sizeof(send_key1_string), send_key1, CRYPTO_PUBLIC_KEY_SIZE); + // bin2hex_toupper(recv_key1_string, sizeof(recv_key1_string), recv_key1, CRYPTO_PUBLIC_KEY_SIZE); + // printf("libsodium-HMAC: %s\n", send_key1_string); + // printf("libsodium-HMAC: %s\n", recv_key1_string); + + // crypto_hkdf_libsodium(send_key2, recv_key2, NULL, k, + // CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, 0, + // CRYPTO_PUBLIC_KEY_SIZE, hash); + + // char send_key2_string[CRYPTO_SHA512_SIZE * 2 + 1]; + // char recv_key2_string[CRYPTO_SHA512_SIZE * 2 + 1]; + // bin2hex_toupper(send_key2_string, sizeof(send_key2_string), send_key2, CRYPTO_PUBLIC_KEY_SIZE); + // bin2hex_toupper(recv_key2_string, sizeof(recv_key2_string), recv_key2, CRYPTO_PUBLIC_KEY_SIZE); + // printf("libsodium-HKDF: %s\n", send_key2_string); + // printf("libsodium-HKDF: %s\n", recv_key2_string); + + char ciphertext_hex[147 * 2 + 1]; + + /* All-zero nonces with matching length (8/12/24 bytes)*/ + /* crypto_aead_chacha20poly1305_encrypt */ + crypto_aead_chacha20poly1305_encrypt(c1, &clen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_chacha20, k); + bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c1, clen1); + printf("crypto_aead_chacha20poly1305_encrypt: %s\n", ciphertext_hex); + /* crypto_aead_chacha20poly1305_ietf_encrypt */ + crypto_aead_chacha20poly1305_ietf_encrypt(c2, &clen2, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_chacha20_ietf, k); + bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c2, clen2); + printf("crypto_aead_chacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); + /* crypto_aead_xchacha20poly1305_ietf_encrypt */ + crypto_aead_xchacha20poly1305_ietf_encrypt(xc1, &xclen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_xchacha20, k); + bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc1, xclen1); + printf("crypto_aead_xchacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); + /* Tox crypto_core XChaCha20 */ + clen2 = encrypt_data_symmetric_xaead(k, test_nonce_xchacha20, test_m, sizeof(test_m) / sizeof(uint8_t), xc2, NULL, 0); + bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc2, xclen2); + printf("encrypt_data_symmetric_xaead(XChaCha20): %s\n", ciphertext_hex); + + /* nonce with only one zero byte => different results! */ + /* crypto_aead_chacha20poly1305_encrypt */ + // crypto_aead_chacha20poly1305_encrypt(c1, &clen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); + // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c1, clen1); + // printf("crypto_aead_chacha20poly1305_encrypt: %s\n", ciphertext_hex); + // /* crypto_aead_chacha20poly1305_ietf_encrypt */ + // crypto_aead_chacha20poly1305_ietf_encrypt(c2, &clen2, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); + // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c2, clen2); + // printf("crypto_aead_chacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); + // /* crypto_aead_xchacha20poly1305_ietf_encrypt */ + // crypto_aead_xchacha20poly1305_ietf_encrypt(xc1, &xclen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); + // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc1, xclen1); + // printf("crypto_aead_xchacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); + // /* Tox crypto_core XChaCha20 */ + // clen2 = encrypt_data_symmetric_xaead(k, test_nonce_one_zero_byte, test_m, sizeof(test_m) / sizeof(uint8_t), xc2, NULL, 0); + // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc2, xclen2); + // printf("encrypt_data_symmetric_xaead(XChaCha20): %s\n", ciphertext_hex); + + + // ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); + // ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); + + // char correct_plain[131 * 2 + 1]; + // char plaintext_hex[147 * 2 + 1]; + // bin2hex_toupper(correct_plain, sizeof(correct_plain), test_m, 131); + // printf("Correct Plaintext: %s\n", correct_plain); + + // /* All-zero nonces with matching length (8/12/24 bytes)*/ + // /* crypto_aead_chacha20poly1305_decrypt */ + // result = crypto_aead_chacha20poly1305_decrypt(m1, &mlen1, NULL, c1, clen1, NULL, 0, test_nonce_chacha20, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m1, mlen1); + // printf("crypto_aead_chacha20poly1305_decrypt: %d, %s\n", result, plaintext_hex); + // /* crypto_aead_chacha20poly1305_ietf_decrypt */ + // result = crypto_aead_chacha20poly1305_ietf_decrypt(m2, &mlen2, NULL, c2, clen2, NULL, 0, test_nonce_chacha20_ietf, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m2, mlen2); + // printf("crypto_aead_chacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); + // /* crypto_aead_xchacha20poly1305_ietf_decrypt */ + // result = crypto_aead_xchacha20poly1305_ietf_decrypt(xm1, &xmlen1, NULL, xc1, xclen1, NULL, 0, test_nonce_xchacha20, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm1, xmlen1); + // printf("crypto_aead_xchacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); + // /* Tox crypto_core XChaCha20 */ + // xmlen2 = decrypt_data_symmetric_xaead(k, test_nonce_xchacha20, xc2, xclen2, xm2, NULL, 0); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm2, xmlen2); + // printf("decrypt_data_symmetric_xaead(XChaCha20): %s\n", plaintext_hex); + + /* nonce with only one zero byte */ + /* crypto_aead_chacha20poly1305_decrypt */ + // result = crypto_aead_chacha20poly1305_decrypt(m1, &mlen1, NULL, c1, clen1, NULL, 0, test_nonce_one_zero_byte, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m1, mlen1); + // printf("crypto_aead_chacha20poly1305_decrypt: %d, %s\n", result, plaintext_hex); + // /* crypto_aead_chacha20poly1305_ietf_decrypt */ + // result = crypto_aead_chacha20poly1305_ietf_decrypt(m2, &mlen2, NULL, c2, clen2, NULL, 0, test_nonce_one_zero_byte, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m2, mlen2); + // printf("crypto_aead_chacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); + // /* crypto_aead_xchacha20poly1305_ietf_decrypt */ + // result = crypto_aead_xchacha20poly1305_ietf_decrypt(xm1, &xmlen1, NULL, xc1, xclen1, NULL, 0, test_nonce_one_zero_byte, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm1, xmlen1); + // printf("crypto_aead_xchacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); + // /* Tox crypto_core XChaCha20 */ + // xmlen2 = decrypt_data_symmetric_xaead(k, test_nonce_one_zero_byte, xc2, xclen2, xm2, NULL, 0); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm2, xmlen2); + // printf("decrypt_data_symmetric_xaead(XChaCha20): %s\n", plaintext_hex); + + // ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); + // ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); + + // INITIATOR: + Noise_Handshake *noise_handshake = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); + noise_handshake_init(nullptr, noise_handshake, init_static, init_remote_static, true); + + memcpy(noise_handshake->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake->ephemeral_public, init_ephemeral); + + char ephemeral_public_print[32 * 2 + 1]; + bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + printf("ephemeral_public_print: %s\n", ephemeral_public_print); + + char resp_static_print[32 * 2 + 1]; + uint8_t resp_static_pub[32]; + crypto_derive_public_key(resp_static_pub, resp_static); + bin2hex_toupper(resp_static_print, sizeof(resp_static_print), resp_static_pub, CRYPTO_PUBLIC_KEY_SIZE); + printf("resp_static_pub: %s\n", resp_static_print); + + /* e */ + noise_mix_hash(noise_handshake->hash, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: remove from production code + // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; + // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); + + /* es */ + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + + /* s */ + //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 + /*Nonce provided as parameter is the base nonce! -> This adds nonce for static pub key encryption to packet (XChaCha20-Poly1305) */ + // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + + /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + uint8_t ciphertext1[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; + noise_encrypt_and_hash(ciphertext1, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + noise_handshake->hash); + + char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; + bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); + printf("ciphertext1_print: %s\n", ciphertext1_print); + + //TODO: remove from production code + // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; + // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); + // char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); + + /* ss */ + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + + /* Noise Handshake Payload */ + // uint8_t handshake_payload_plain[15]; + uint8_t ciphertext2[sizeof(payload1) + CRYPTO_MAC_SIZE]; + + //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 + /* Add Handshake payload nonce */ + // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + // handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + + /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + noise_encrypt_and_hash(ciphertext2, + payload1, sizeof(payload1), noise_handshake_temp_key, + noise_handshake->hash); + + char ciphertext2_print[sizeof(ciphertext2) * 2 + 1]; + bin2hex_toupper(ciphertext2_print, sizeof(ciphertext2_print), ciphertext2, sizeof(ciphertext2)); + printf("ciphertext2_print: %s\n", ciphertext2_print); +} - const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); +// 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]; +// uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; +// uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; +// uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; +// uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; +// uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; + +// uint8_t n[CRYPTO_NONCE_SIZE]; + +// enum { M_SIZE = 50 }; +// uint8_t m[M_SIZE]; +// uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; +// uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; +// uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; +// uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; +// uint8_t m1[sizeof(m)]; +// uint8_t m2[sizeof(m)]; +// uint8_t m3[sizeof(m)]; +// uint8_t m4[sizeof(m)]; + +// //Generate random message (random length from 10 to 50) +// const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; +// rand_bytes(rng, m, mlen); +// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + +// //Generate keypairs +// crypto_new_keypair(rng, pk1, sk1); +// crypto_new_keypair(rng, pk2, sk2); + +// //Precompute shared keys +// encrypt_precompute(pk2, sk1, k1); +// encrypt_precompute(pk1, sk2, k2); + +// ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); + +// //Encrypt all four ways +// const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); +// const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); +// const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); +// const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); + +// ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); +// ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); +// ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 +// && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); + +// //Decrypt all four ways +// const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); +// const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); +// const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); +// const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); + +// ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); +// ck_assert_msg(m1len == mlen, "wrong decrypted text length"); +// ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 +// && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); +// ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); +// } +// } + +// 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]; + +// const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; +// uint8_t *m1 = (uint8_t *)malloc(m1_size); +// uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); +// uint8_t *m1prime = (uint8_t *)malloc(m1_size); + +// const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; +// uint8_t *m2 = (uint8_t *)malloc(m2_size); +// uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); + +// ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); + +// //Generate random messages +// rand_bytes(rng, m1, m1_size); +// rand_bytes(rng, m2, m2_size); +// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + +// //Generate key +// 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); + +// ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); +// ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); + +// const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + +// ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); +// ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); + +// free(c2); +// free(m2); +// free(m1prime); +// free(c1); +// free(m1); +// } + +// 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]; + +// const size_t m1_size = 16 * 16 * 16; +// uint8_t *m1 = (uint8_t *)malloc(m1_size); +// uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); +// uint8_t *m1prime = (uint8_t *)malloc(m1_size); - ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); - ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); +// ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); - free(m1prime); - free(c1); - free(m1); -} +// //Generate random messages +// rand_bytes(rng, m1, m1_size); +// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); -static void test_very_large_data(void) -{ - const Random *rng = os_random(); - ck_assert(rng != nullptr); +// //Generate key +// new_symmetric_key(rng, k); - const uint8_t nonce[CRYPTO_NONCE_SIZE] = {0}; - uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(rng, pk, sk); +// 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"); - // 100 MiB of data (all zeroes, doesn't matter what's inside). - const uint32_t plain_size = 100 * 1024 * 1024; - uint8_t *plain = (uint8_t *)malloc(plain_size); - uint8_t *encrypted = (uint8_t *)malloc(plain_size + CRYPTO_MAC_SIZE); +// const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - ck_assert(plain != nullptr); - ck_assert(encrypted != nullptr); +// ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); +// ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - encrypt_data(pk, sk, nonce, plain, plain_size, encrypted); - - free(encrypted); - free(plain); -} +// free(m1prime); +// free(c1); +// free(m1); +// } static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) { - uint32_t num1 = 0; + uint32_t num1, num2; memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); num1 = net_ntohl(num1); - uint32_t num2 = num + num1; + num2 = num + num1; if (num2 < num1) { for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { @@ -314,34 +578,36 @@ static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); } -static void test_increment_nonce(void) -{ - const Random *rng = os_random(); - ck_assert(rng != nullptr); +// static void test_increment_nonce(void) +// { +// const Random *rng = system_random(); +// ck_assert(rng != nullptr); - uint8_t n[CRYPTO_NONCE_SIZE]; +// uint32_t i; - for (uint32_t i = 0; i < CRYPTO_NONCE_SIZE; ++i) { - n[i] = random_u08(rng); - } +// uint8_t n[CRYPTO_NONCE_SIZE]; - uint8_t n1[CRYPTO_NONCE_SIZE]; +// for (i = 0; i < CRYPTO_NONCE_SIZE; ++i) { +// n[i] = random_u08(rng); +// } - memcpy(n1, n, CRYPTO_NONCE_SIZE); +// uint8_t n1[CRYPTO_NONCE_SIZE]; - for (uint32_t i = 0; i < (1 << 18); ++i) { - increment_nonce_number_cmp(n, 1); - increment_nonce(n1); - ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); - } +// memcpy(n1, n, CRYPTO_NONCE_SIZE); - for (uint32_t i = 0; i < (1 << 18); ++i) { - 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"); - } -} +// for (i = 0; i < (1 << 18); ++i) { +// increment_nonce_number_cmp(n, 1); +// increment_nonce(n1); +// ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); +// } + +// for (i = 0; i < (1 << 18); ++i) { +// 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"); +// } +// } static void test_memzero(void) { @@ -349,8 +615,9 @@ static void test_memzero(void) memcpy(src, test_c, sizeof(test_c)); crypto_memzero(src, sizeof(src)); + size_t i; - for (size_t i = 0; i < sizeof(src); i++) { + for (i = 0; i < sizeof(src); i++) { ck_assert_msg(src[i] == 0, "Memory is not zeroed"); } } @@ -359,14 +626,14 @@ int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); - test_known(); - test_fast_known(); - test_endtoend(); /* waiting up to 15 seconds */ - test_large_data(); - test_large_data_symmetric(); - test_very_large_data(); - test_increment_nonce(); - test_memzero(); + // test_known(); + // test_fast_known(); + test_fast_known2(); + // test_endtoend(); /* waiting up to 15 seconds */ + // test_large_data(); + // test_large_data_symmetric(); + // test_increment_nonce(); + // test_memzero(); return 0; } diff --git a/auto_tests/crypto_test.c.real b/auto_tests/crypto_test.c.real new file mode 100644 index 0000000000..83f8c525a6 --- /dev/null +++ b/auto_tests/crypto_test.c.real @@ -0,0 +1,372 @@ +#include +#include +#include + +#include "../testing/misc_tools.h" +#include "../toxcore/crypto_core.h" +#include "../toxcore/net_crypto.h" +#include "check_compat.h" + +static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) +{ + for (size_t i = 0; i < blen; i++) { + b[i] = random_u08(rng); + } +} + +// These test vectors are from libsodium's test suite + +static const uint8_t alicesk[32] = { + 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, + 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, + 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, + 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a +}; + +static const uint8_t bobpk[32] = { + 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, + 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, + 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, + 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f +}; + +static const uint8_t test_nonce[24] = { + 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, + 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6, + 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 +}; + +static const uint8_t test_m[131] = { + 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, + 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, + 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, + 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc, + 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, + 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, + 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4, + 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, + 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, + 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57, + 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, + 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, + 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd, + 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, + 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, + 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64, + 0x5e, 0x07, 0x05 +}; + +static const uint8_t test_c[147] = { + 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, + 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, + 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, + 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, + 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, + 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, + 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, + 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, + 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, + 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, + 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, + 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, + 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, + 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, + 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, + 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, + 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, + 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, + 0xe3, 0x55, 0xa5 +}; + +static void test_known(void) +{ + uint8_t c[147]; + uint8_t m[131]; + + ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), + "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); + ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); + ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); + + const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + + ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); + ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); + + const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + + ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); + ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); +} + +static void test_fast_known(void) +{ + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; + uint8_t c[147]; + uint8_t m[131]; + + encrypt_precompute(bobpk, alicesk, k); + + ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), + "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); + ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); + ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); + + const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + + ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); + ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); + + const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + + ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); + ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); +} + +static void test_endtoend(void) +{ + const Random *rng = os_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]; + uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; + uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; + uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; + uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; + + uint8_t n[CRYPTO_NONCE_SIZE]; + + enum { M_SIZE = 50 }; + uint8_t m[M_SIZE]; + uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t m1[sizeof(m)]; + uint8_t m2[sizeof(m)]; + uint8_t m3[sizeof(m)]; + uint8_t m4[sizeof(m)]; + + //Generate random message (random length from 10 to 50) + const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; + rand_bytes(rng, m, mlen); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + + //Generate keypairs + crypto_new_keypair(rng, pk1, sk1); + crypto_new_keypair(rng, pk2, sk2); + + //Precompute shared keys + encrypt_precompute(pk2, sk1, k1); + encrypt_precompute(pk1, sk2, k2); + + ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); + + //Encrypt all four ways + const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); + const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); + const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); + const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); + + ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); + ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); + ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 + && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); + + //Decrypt all four ways + const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); + const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); + const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); + const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); + + ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); + ck_assert_msg(m1len == mlen, "wrong decrypted text length"); + ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 + && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); + ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); + } +} + +static void test_large_data(void) +{ + const Random *rng = os_random(); + ck_assert(rng != nullptr); + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; + uint8_t n[CRYPTO_NONCE_SIZE]; + + const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; + uint8_t *m1 = (uint8_t *)malloc(m1_size); + uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); + uint8_t *m1prime = (uint8_t *)malloc(m1_size); + + const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; + uint8_t *m2 = (uint8_t *)malloc(m2_size); + uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); + + ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); + + //Generate random messages + rand_bytes(rng, m1, m1_size); + rand_bytes(rng, m2, m2_size); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + + //Generate key + 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); + + ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); + ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); + + const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + + ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); + ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); + + free(c2); + free(m2); + free(m1prime); + free(c1); + free(m1); +} + +static void test_large_data_symmetric(void) +{ + const Random *rng = os_random(); + ck_assert(rng != nullptr); + uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; + + uint8_t n[CRYPTO_NONCE_SIZE]; + + const size_t m1_size = 16 * 16 * 16; + uint8_t *m1 = (uint8_t *)malloc(m1_size); + uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); + uint8_t *m1prime = (uint8_t *)malloc(m1_size); + + ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); + + //Generate random messages + rand_bytes(rng, m1, m1_size); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + + //Generate key + 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"); + + const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + + ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); + ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); + + free(m1prime); + free(c1); + free(m1); +} + +static void test_very_large_data(void) +{ + const Random *rng = os_random(); + ck_assert(rng != nullptr); + + const uint8_t nonce[CRYPTO_NONCE_SIZE] = {0}; + uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t sk[CRYPTO_SECRET_KEY_SIZE]; + crypto_new_keypair(rng, pk, sk); + + // 100 MiB of data (all zeroes, doesn't matter what's inside). + const uint32_t plain_size = 100 * 1024 * 1024; + uint8_t *plain = (uint8_t *)malloc(plain_size); + uint8_t *encrypted = (uint8_t *)malloc(plain_size + CRYPTO_MAC_SIZE); + + ck_assert(plain != nullptr); + ck_assert(encrypted != nullptr); + + encrypt_data(pk, sk, nonce, plain, plain_size, encrypted); + + free(encrypted); + free(plain); +} + +static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) +{ + uint32_t num1 = 0; + memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); + num1 = net_ntohl(num1); + uint32_t num2 = num + num1; + + if (num2 < num1) { + for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { + ++nonce[i - 1]; + + if (nonce[i - 1] != 0) { + break; + } + } + } + + num2 = net_htonl(num2); + memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); +} + +static void test_increment_nonce(void) +{ + const Random *rng = os_random(); + ck_assert(rng != nullptr); + + uint8_t n[CRYPTO_NONCE_SIZE]; + + for (uint32_t i = 0; i < CRYPTO_NONCE_SIZE; ++i) { + n[i] = random_u08(rng); + } + + uint8_t n1[CRYPTO_NONCE_SIZE]; + + memcpy(n1, n, CRYPTO_NONCE_SIZE); + + for (uint32_t i = 0; i < (1 << 18); ++i) { + increment_nonce_number_cmp(n, 1); + increment_nonce(n1); + ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); + } + + for (uint32_t i = 0; i < (1 << 18); ++i) { + 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"); + } +} + +static void test_memzero(void) +{ + uint8_t src[sizeof(test_c)]; + memcpy(src, test_c, sizeof(test_c)); + + crypto_memzero(src, sizeof(src)); + + for (size_t i = 0; i < sizeof(src); i++) { + ck_assert_msg(src[i] == 0, "Memory is not zeroed"); + } +} + +int main(void) +{ + setvbuf(stdout, nullptr, _IONBF, 0); + + test_known(); + test_fast_known(); + test_endtoend(); /* waiting up to 15 seconds */ + test_large_data(); + test_large_data_symmetric(); + test_very_large_data(); + test_increment_nonce(); + test_memzero(); + + return 0; +} diff --git a/auto_tests/crypto_test_NoiseIK_test_vectors.c b/auto_tests/crypto_test_NoiseIK_test_vectors.c new file mode 100644 index 0000000000..90f6c5d59a --- /dev/null +++ b/auto_tests/crypto_test_NoiseIK_test_vectors.c @@ -0,0 +1,639 @@ +#include +#include +#include +#include + +#include "../testing/misc_tools.h" +#include "../toxcore/crypto_core.h" +#include "../toxcore/net_crypto.h" +#include "check_compat.h" +#include "../other/fun/create_common.h" +#include "../toxcore/mem.h" + +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(rng); + } +} + +// These test vectors are from libsodium's test suite + +static const uint8_t alicesk[32] = { + 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, + 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, + 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, + 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a +}; + +static const uint8_t bobpk[32] = { + 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, + 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, + 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, + 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f +}; + +static const uint8_t test_nonce[24] = { + 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, + 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6, + 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 +}; + +static const uint8_t test_m[131] = { + 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, + 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, + 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, + 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc, + 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, + 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, + 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4, + 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, + 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, + 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57, + 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, + 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, + 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd, + 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, + 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, + 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64, + 0x5e, 0x07, 0x05 +}; + +static const uint8_t test_c[147] = { + 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, + 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, + 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, + 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, + 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, + 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, + 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, + 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, + 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, + 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, + 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, + 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, + 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, + 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, + 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, + 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, + 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, + 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, + 0xe3, 0x55, 0xa5 +}; + +static void test_known(void) +{ + uint8_t c[147]; + uint8_t m[131]; + uint16_t clen, mlen; + + ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), + "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); + ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); + ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); + + clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + + ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); + ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); + + mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + + ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); + ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); +} + +static void test_fast_known(void) +{ + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; + uint8_t c[147]; + uint8_t m[131]; + uint16_t clen, mlen; + + encrypt_precompute(bobpk, alicesk, k); + + ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), + "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); + ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); + ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); + + clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + + ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); + ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); + + mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + + ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); + ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); +} + +static const uint8_t test_nonce_chacha20[8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t test_nonce_chacha20_ietf[12] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t test_nonce_xchacha20[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t test_nonce_one_zero_byte[1] = { + 0x00 +}; + +static const uint8_t prologue[11] = { + 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x31, 0x32, 0x33 +}; + +uint8_t init_static[32] = { + 0xe6, 0x1e, 0xf9, 0x91, 0x9c, 0xde, 0x45, 0xdd, + 0x5f, 0x82, 0x16, 0x64, 0x04, 0xbd, 0x08, 0xe3, + 0x8b, 0xce, 0xb5, 0xdf, 0xdf, 0xde, 0xd0, 0xa3, + 0x4c, 0x8d, 0xf7, 0xed, 0x54, 0x22, 0x14, 0xd1 +}; + +uint8_t init_ephemeral[32] = { + 0x89, 0x3e, 0x28, 0xb9, 0xdc, 0x6c, 0xa8, 0xd6, + 0x11, 0xab, 0x66, 0x47, 0x54, 0xb8, 0xce, 0xb7, + 0xba, 0xc5, 0x11, 0x73, 0x49, 0xa4, 0x43, 0x9a, + 0x6b, 0x05, 0x69, 0xda, 0x97, 0x7c, 0x46, 0x4a +}; + +uint8_t init_remote_static[32] = { + 0x31, 0xe0, 0x30, 0x3f, 0xd6, 0x41, 0x8d, 0x2f, + 0x8c, 0x0e, 0x78, 0xb9, 0x1f, 0x22, 0xe8, 0xca, + 0xed, 0x0f, 0xbe, 0x48, 0x65, 0x6d, 0xcf, 0x47, + 0x67, 0xe4, 0x83, 0x4f, 0x70, 0x1b, 0x8f, 0x62 +}; + +uint8_t resp_static[32] = { + 0x4a, 0x3a, 0xcb, 0xfd, 0xb1, 0x63, 0xde, 0xc6, + 0x51, 0xdf, 0xa3, 0x19, 0x4d, 0xec, 0xe6, 0x76, + 0xd4, 0x37, 0x02, 0x9c, 0x62, 0xa4, 0x08, 0xb4, + 0xc5, 0xea, 0x91, 0x14, 0x24, 0x6e, 0x48, 0x93 +}; + +uint8_t resp_ephemeral[32] = { + 0xbb, 0xdb, 0x4c, 0xdb, 0xd3, 0x09, 0xf1, 0xa1, + 0xf2, 0xe1, 0x45, 0x69, 0x67, 0xfe, 0x28, 0x8c, + 0xad, 0xd6, 0xf7, 0x12, 0xd6, 0x5d, 0xc7, 0xb7, + 0x79, 0x3d, 0x5e, 0x63, 0xda, 0x6b, 0x37, 0x5b +}; + +uint8_t payload1[16] = { + 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f, + 0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 + }; + +static void test_fast_known2(void) +{ + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; + uint8_t m1[131]; + uint8_t m2[131]; + uint8_t xm1[131]; + uint8_t xm2[131]; + uint8_t c1[147]; + uint8_t c2[147]; + uint8_t xc1[147]; + uint8_t xc2[147]; + uint16_t xclen2, xmlen2; + unsigned long long mlen1 = 0; + unsigned long long clen1 = 0; + unsigned long long mlen2 = 0; + unsigned long long clen2 = 0; + unsigned long long xclen1 = 0; + unsigned long long xmlen1 = 0; + int result; + + uint8_t hash[CRYPTO_SHA512_SIZE]; + uint8_t send_key1[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t recv_key1[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t send_key2[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t recv_key2[CRYPTO_PUBLIC_KEY_SIZE]; + + encrypt_precompute(bobpk, alicesk, k); + + // ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), + // "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); + // ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); + + // crypto_sha512(hash, k, CRYPTO_PUBLIC_KEY_SIZE); + // crypto_hkdf(send_key1, recv_key1, NULL, k, + // CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, 0, + // CRYPTO_PUBLIC_KEY_SIZE, hash); + + // char send_key1_string[CRYPTO_SHA512_SIZE * 2 + 1]; + // char recv_key1_string[CRYPTO_SHA512_SIZE * 2 + 1]; + // bin2hex_toupper(send_key1_string, sizeof(send_key1_string), send_key1, CRYPTO_PUBLIC_KEY_SIZE); + // bin2hex_toupper(recv_key1_string, sizeof(recv_key1_string), recv_key1, CRYPTO_PUBLIC_KEY_SIZE); + // printf("libsodium-HMAC: %s\n", send_key1_string); + // printf("libsodium-HMAC: %s\n", recv_key1_string); + + // crypto_hkdf_libsodium(send_key2, recv_key2, NULL, k, + // CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, 0, + // CRYPTO_PUBLIC_KEY_SIZE, hash); + + // char send_key2_string[CRYPTO_SHA512_SIZE * 2 + 1]; + // char recv_key2_string[CRYPTO_SHA512_SIZE * 2 + 1]; + // bin2hex_toupper(send_key2_string, sizeof(send_key2_string), send_key2, CRYPTO_PUBLIC_KEY_SIZE); + // bin2hex_toupper(recv_key2_string, sizeof(recv_key2_string), recv_key2, CRYPTO_PUBLIC_KEY_SIZE); + // printf("libsodium-HKDF: %s\n", send_key2_string); + // printf("libsodium-HKDF: %s\n", recv_key2_string); + + char ciphertext_hex[147 * 2 + 1]; + + /* All-zero nonces with matching length (8/12/24 bytes)*/ + /* crypto_aead_chacha20poly1305_encrypt */ + crypto_aead_chacha20poly1305_encrypt(c1, &clen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_chacha20, k); + bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c1, clen1); + printf("crypto_aead_chacha20poly1305_encrypt: %s\n", ciphertext_hex); + /* crypto_aead_chacha20poly1305_ietf_encrypt */ + crypto_aead_chacha20poly1305_ietf_encrypt(c2, &clen2, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_chacha20_ietf, k); + bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c2, clen2); + printf("crypto_aead_chacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); + /* crypto_aead_xchacha20poly1305_ietf_encrypt */ + crypto_aead_xchacha20poly1305_ietf_encrypt(xc1, &xclen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_xchacha20, k); + bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc1, xclen1); + printf("crypto_aead_xchacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); + /* Tox crypto_core XChaCha20 */ + clen2 = encrypt_data_symmetric_xaead(k, test_nonce_xchacha20, test_m, sizeof(test_m) / sizeof(uint8_t), xc2, NULL, 0); + bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc2, xclen2); + printf("encrypt_data_symmetric_xaead(XChaCha20): %s\n", ciphertext_hex); + + /* nonce with only one zero byte => different results! */ + /* crypto_aead_chacha20poly1305_encrypt */ + // crypto_aead_chacha20poly1305_encrypt(c1, &clen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); + // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c1, clen1); + // printf("crypto_aead_chacha20poly1305_encrypt: %s\n", ciphertext_hex); + // /* crypto_aead_chacha20poly1305_ietf_encrypt */ + // crypto_aead_chacha20poly1305_ietf_encrypt(c2, &clen2, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); + // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c2, clen2); + // printf("crypto_aead_chacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); + // /* crypto_aead_xchacha20poly1305_ietf_encrypt */ + // crypto_aead_xchacha20poly1305_ietf_encrypt(xc1, &xclen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); + // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc1, xclen1); + // printf("crypto_aead_xchacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); + // /* Tox crypto_core XChaCha20 */ + // clen2 = encrypt_data_symmetric_xaead(k, test_nonce_one_zero_byte, test_m, sizeof(test_m) / sizeof(uint8_t), xc2, NULL, 0); + // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc2, xclen2); + // printf("encrypt_data_symmetric_xaead(XChaCha20): %s\n", ciphertext_hex); + + + // ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); + // ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); + + // char correct_plain[131 * 2 + 1]; + // char plaintext_hex[147 * 2 + 1]; + // bin2hex_toupper(correct_plain, sizeof(correct_plain), test_m, 131); + // printf("Correct Plaintext: %s\n", correct_plain); + + // /* All-zero nonces with matching length (8/12/24 bytes)*/ + // /* crypto_aead_chacha20poly1305_decrypt */ + // result = crypto_aead_chacha20poly1305_decrypt(m1, &mlen1, NULL, c1, clen1, NULL, 0, test_nonce_chacha20, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m1, mlen1); + // printf("crypto_aead_chacha20poly1305_decrypt: %d, %s\n", result, plaintext_hex); + // /* crypto_aead_chacha20poly1305_ietf_decrypt */ + // result = crypto_aead_chacha20poly1305_ietf_decrypt(m2, &mlen2, NULL, c2, clen2, NULL, 0, test_nonce_chacha20_ietf, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m2, mlen2); + // printf("crypto_aead_chacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); + // /* crypto_aead_xchacha20poly1305_ietf_decrypt */ + // result = crypto_aead_xchacha20poly1305_ietf_decrypt(xm1, &xmlen1, NULL, xc1, xclen1, NULL, 0, test_nonce_xchacha20, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm1, xmlen1); + // printf("crypto_aead_xchacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); + // /* Tox crypto_core XChaCha20 */ + // xmlen2 = decrypt_data_symmetric_xaead(k, test_nonce_xchacha20, xc2, xclen2, xm2, NULL, 0); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm2, xmlen2); + // printf("decrypt_data_symmetric_xaead(XChaCha20): %s\n", plaintext_hex); + + /* nonce with only one zero byte */ + /* crypto_aead_chacha20poly1305_decrypt */ + // result = crypto_aead_chacha20poly1305_decrypt(m1, &mlen1, NULL, c1, clen1, NULL, 0, test_nonce_one_zero_byte, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m1, mlen1); + // printf("crypto_aead_chacha20poly1305_decrypt: %d, %s\n", result, plaintext_hex); + // /* crypto_aead_chacha20poly1305_ietf_decrypt */ + // result = crypto_aead_chacha20poly1305_ietf_decrypt(m2, &mlen2, NULL, c2, clen2, NULL, 0, test_nonce_one_zero_byte, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m2, mlen2); + // printf("crypto_aead_chacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); + // /* crypto_aead_xchacha20poly1305_ietf_decrypt */ + // result = crypto_aead_xchacha20poly1305_ietf_decrypt(xm1, &xmlen1, NULL, xc1, xclen1, NULL, 0, test_nonce_one_zero_byte, k); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm1, xmlen1); + // printf("crypto_aead_xchacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); + // /* Tox crypto_core XChaCha20 */ + // xmlen2 = decrypt_data_symmetric_xaead(k, test_nonce_one_zero_byte, xc2, xclen2, xm2, NULL, 0); + // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm2, xmlen2); + // printf("decrypt_data_symmetric_xaead(XChaCha20): %s\n", plaintext_hex); + + // ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); + // ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); + + // INITIATOR: + Noise_Handshake *noise_handshake = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); + noise_handshake_init(nullptr, noise_handshake, init_static, init_remote_static, true); + + memcpy(noise_handshake->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake->ephemeral_public, init_ephemeral); + + char ephemeral_public_print[32 * 2 + 1]; + bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + printf("ephemeral_public_print: %s\n", ephemeral_public_print); + + char resp_static_print[32 * 2 + 1]; + uint8_t resp_static_pub[32]; + crypto_derive_public_key(resp_static_pub, resp_static); + bin2hex_toupper(resp_static_print, sizeof(resp_static_print), resp_static_pub, CRYPTO_PUBLIC_KEY_SIZE); + printf("resp_static_pub: %s\n", resp_static_print); + + /* e */ + noise_mix_hash(noise_handshake->hash, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: remove from production code + // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; + // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); + + /* es */ + uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + + /* s */ + //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 + /*Nonce provided as parameter is the base nonce! -> This adds nonce for static pub key encryption to packet (XChaCha20-Poly1305) */ + // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); + + /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + uint8_t ciphertext1[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; + noise_encrypt_and_hash(ciphertext1, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + noise_handshake->hash); + + char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; + bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); + printf("ciphertext1_print: %s\n", ciphertext1_print); + + //TODO: remove from production code + // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; + // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); + // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); + // char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); + + /* ss */ + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + + /* Noise Handshake Payload */ + // uint8_t handshake_payload_plain[15]; + uint8_t ciphertext2[sizeof(payload1) + CRYPTO_MAC_SIZE]; + + //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 + /* Add Handshake payload nonce */ + // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, + // handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); + + /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + noise_encrypt_and_hash(ciphertext2, + payload1, sizeof(payload1), noise_handshake_temp_key, + noise_handshake->hash); + + char ciphertext2_print[sizeof(ciphertext2) * 2 + 1]; + bin2hex_toupper(ciphertext2_print, sizeof(ciphertext2_print), ciphertext2, sizeof(ciphertext2)); + printf("ciphertext2_print: %s\n", ciphertext2_print); +} + +// 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]; +// uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; +// uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; +// uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; +// uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; +// uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; + +// uint8_t n[CRYPTO_NONCE_SIZE]; + +// enum { M_SIZE = 50 }; +// uint8_t m[M_SIZE]; +// uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; +// uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; +// uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; +// uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; +// uint8_t m1[sizeof(m)]; +// uint8_t m2[sizeof(m)]; +// uint8_t m3[sizeof(m)]; +// uint8_t m4[sizeof(m)]; + +// //Generate random message (random length from 10 to 50) +// const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; +// rand_bytes(rng, m, mlen); +// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + +// //Generate keypairs +// crypto_new_keypair(rng, pk1, sk1); +// crypto_new_keypair(rng, pk2, sk2); + +// //Precompute shared keys +// encrypt_precompute(pk2, sk1, k1); +// encrypt_precompute(pk1, sk2, k2); + +// ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); + +// //Encrypt all four ways +// const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); +// const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); +// const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); +// const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); + +// ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); +// ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); +// ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 +// && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); + +// //Decrypt all four ways +// const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); +// const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); +// const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); +// const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); + +// ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); +// ck_assert_msg(m1len == mlen, "wrong decrypted text length"); +// ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 +// && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); +// ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); +// } +// } + +// 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]; + +// const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; +// uint8_t *m1 = (uint8_t *)malloc(m1_size); +// uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); +// uint8_t *m1prime = (uint8_t *)malloc(m1_size); + +// const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; +// uint8_t *m2 = (uint8_t *)malloc(m2_size); +// uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); + +// ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); + +// //Generate random messages +// rand_bytes(rng, m1, m1_size); +// rand_bytes(rng, m2, m2_size); +// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + +// //Generate key +// 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); + +// ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); +// ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); + +// const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + +// ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); +// ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); + +// free(c2); +// free(m2); +// free(m1prime); +// free(c1); +// free(m1); +// } + +// 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]; + +// const size_t m1_size = 16 * 16 * 16; +// uint8_t *m1 = (uint8_t *)malloc(m1_size); +// uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); +// uint8_t *m1prime = (uint8_t *)malloc(m1_size); + +// ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); + +// //Generate random messages +// rand_bytes(rng, m1, m1_size); +// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + +// //Generate key +// 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"); + +// const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + +// ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); +// ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); + +// free(m1prime); +// free(c1); +// free(m1); +// } + +static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) +{ + uint32_t num1, num2; + memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); + num1 = net_ntohl(num1); + num2 = num + num1; + + if (num2 < num1) { + for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { + ++nonce[i - 1]; + + if (nonce[i - 1] != 0) { + break; + } + } + } + + num2 = net_htonl(num2); + memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); +} + +// 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(rng); +// } + +// uint8_t n1[CRYPTO_NONCE_SIZE]; + +// memcpy(n1, n, CRYPTO_NONCE_SIZE); + +// for (i = 0; i < (1 << 18); ++i) { +// increment_nonce_number_cmp(n, 1); +// increment_nonce(n1); +// ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); +// } + +// for (i = 0; i < (1 << 18); ++i) { +// 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"); +// } +// } + +static void test_memzero(void) +{ + uint8_t src[sizeof(test_c)]; + memcpy(src, test_c, sizeof(test_c)); + + crypto_memzero(src, sizeof(src)); + size_t i; + + for (i = 0; i < sizeof(src); i++) { + ck_assert_msg(src[i] == 0, "Memory is not zeroed"); + } +} + +int main(void) +{ + setvbuf(stdout, nullptr, _IONBF, 0); + + // test_known(); + // test_fast_known(); + test_fast_known2(); + // test_endtoend(); /* waiting up to 15 seconds */ + // test_large_data(); + // test_large_data_symmetric(); + // test_increment_nonce(); + // test_memzero(); + + return 0; +} diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 8026c9d549..fb86f68cd7 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -617,6 +617,131 @@ size_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S return plain_length; } +/* +* TODO: Helper function to print hashes, keys, packets, etc. +* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? +* bytes_to_string() from util.h +*/ +static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) +{ + bytes_to_string(bytes, bytes_length, string, string_length); +} + +// #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" +static const uint8_t noise_protocol[32] = "Noise_IK_25519_ChaChaPoly_SHA512"; + +/** + * @brief Initializes a Noise Handshake State with provided static X25519 ID key pair, X25519 static ID public key from peer + * and sets if initiator or not. + * + * cf. Noise section 5.3 + * Calls InitializeSymmetric(protocol_name). + * Calls MixHash(prologue). + * Sets the initiator, s, e, rs, and re variables to the corresponding arguments. + * Calls MixHash() once for each public key listed in the pre-messages. + * + * //TODO: remove Logger Param + * @param log Tox logger + * @param noise_handshake handshake struct to save the necessary values to + * @param self_secret_key static private ID X25519 key of this Tox instance + * @param peer_public_key X25519 static ID public key from peer to connect to + * @param initiator specifies if this Tox instance is the initiator of this crypto connection + * + * @return -1 on failure + * @return 0 on success + */ +int noise_handshake_init +(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +{ + //TODO: remove + if (log != nullptr) { + LOGGER_DEBUG(log, "ENTERING"); + } + + //TODO: move to handle_packet_crypto_hs()? + crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); + + /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h + Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ + uint8_t temp_hash[CRYPTO_SHA512_SIZE]; + memset(temp_hash, 0, CRYPTO_SHA512_SIZE); + memcpy(temp_hash, noise_protocol, sizeof(noise_protocol)); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + + //TODO: remove prologue for test vectors + static const uint8_t prologue[] = { + 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x31, 0x32, 0x33 + }; + noise_mix_hash(noise_handshake->hash, prologue, sizeof(prologue)); + + //TODO: remove + // char log_ck[CRYPTO_SHA512_SIZE*2+1]; + // if (log != nullptr) { + // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "ck: %s", log_ck); + // } + + /* Sets the initiator, s => ephemeral keys are set afterwards */ + noise_handshake->initiator = initiator; + if (self_secret_key != nullptr) { + memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + + //TODO: remove + if (log != nullptr) { + char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); + LOGGER_DEBUG(log, "static pub: %s", log_spub); + } + + } else { + // fprintf(stderr, "Local static private key required, but not provided.\n"); + LOGGER_DEBUG(log, "Local static private key required, but not provided."); + return -1; + } + /* <- s: pre-message from responder to initiator => sets rs (only initiator) */ + if (initiator) { + if (peer_public_key != nullptr) { + memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: Remove + if (log != nullptr) { + char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); + LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); + } + + /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ + noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: remove + // if (log != nullptr) { + // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "INITIATOR hash: %s", log_hash); + // } + } else { + // fprintf(stderr, "Remote peer static public key required, but not provided.\n"); + LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); + return -1; + } + } + /* Noise RESPONDER */ + else { + /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ + noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: remove + // if (log != nullptr) { + // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); + // } + } + + /* Ready to go */ + return 0; +} + /** * cf. Noise sections 4.3 and 5.1 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. @@ -735,7 +860,8 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE]) { - static const uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); unsigned long long encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, @@ -753,7 +879,8 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], uint8_t hash[CRYPTO_SHA512_SIZE]) { - static const uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); unsigned long long plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 9f8e683197..e1fe3bfdd5 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -16,6 +16,7 @@ #include #include "attributes.h" +#include "logger.h" #ifdef __cplusplus extern "C" { @@ -114,6 +115,25 @@ typedef struct Random { void *obj; } Random; +// TODO: struct necessary? +// TODO: move to crypto_core.h? +/** @brief Necessary Noise handshake state information/values. + */ +typedef struct Noise_Handshake { + // TODO: static_private? + uint8_t static_private[CRYPTO_SECRET_KEY_SIZE]; + uint8_t static_public[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t ephemeral_private[CRYPTO_SECRET_KEY_SIZE]; + uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; + + uint8_t hash[CRYPTO_SHA512_SIZE]; + uint8_t chaining_key[CRYPTO_SHA512_SIZE]; + + bool initiator; +} Noise_Handshake; + /** @brief System random number generator. * * Uses libsodium's CSPRNG (on Linux, `/dev/urandom`). @@ -621,6 +641,30 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, size_t second_len, const uint8_t *data, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); +/** + * @brief Initializes a Noise Handshake State with provided static X25519 ID key pair, X25519 static ID public key from peer + * and sets if initiator or not. + * + * cf. Noise section 5.3 + * Calls InitializeSymmetric(protocol_name). + * Calls MixHash(prologue). + * Sets the initiator, s, e, rs, and re variables to the corresponding arguments. + * Calls MixHash() once for each public key listed in the pre-messages. + * + * //TODO: remove Logger Param + * @param log Tox logger + * @param noise_handshake handshake struct to save the necessary values to + * @param self_secret_key static private ID X25519 key of this Tox instance + * @param peer_public_key X25519 static ID public key from peer to connect to + * @param initiator specifies if this Tox instance is the initiator of this crypto connection + * + * @return -1 on failure + * @return 0 on success + */ + //TODO: non_null +int noise_handshake_init +(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator); + /** * @brief Noise MixKey(input_key_material) * diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 8ac9b157ee..a1f6064745 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -493,6 +493,16 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, return COOKIE_LENGTH; } +/* +* TODO: Helper function to print hashes, keys, packets, etc. +* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? +* bytes_to_string() from util.h +*/ +static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) +{ + bytes_to_string(bytes, bytes_length, string, string_length); +} + /* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /* Noise: Necessary for Noise-based handshake */ @@ -505,122 +515,6 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) -/* -* TODO: Helper function to print hashes, keys, packets, etc. -* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? -* bytes_to_string() from util.h -*/ -static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) -{ - bytes_to_string(bytes, bytes_length, string, string_length); -} - -/** - * @brief Initializes a Noise Handshake State with provided static X25519 ID key pair, X25519 static ID public key from peer - * and sets if initiator or not. - * - * cf. Noise section 5.3 - * Calls InitializeSymmetric(protocol_name). - * Calls MixHash(prologue). - * Sets the initiator, s, e, rs, and re variables to the corresponding arguments. - * Calls MixHash() once for each public key listed in the pre-messages. - * - * //TODO: remove Logger Param - * @param log Tox logger - * @param noise_handshake handshake struct to save the necessary values to - * @param self_secret_key static private ID X25519 key of this Tox instance - * @param peer_public_key X25519 static ID public key from peer to connect to - * @param initiator specifies if this Tox instance is the initiator of this crypto connection - * - * @return -1 on failure - * @return 0 on success - */ -static int noise_handshake_init -(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) -{ - //TODO: remove - if (log != nullptr) { - LOGGER_DEBUG(log, "ENTERING"); - } - - //TODO: move to handle_packet_crypto_hs()? - crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); - - /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h - Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ - uint8_t temp_hash[CRYPTO_SHA512_SIZE]; - memset(temp_hash, '\0', CRYPTO_SHA512_SIZE); - memcpy(temp_hash, NOISE_PROTOCOL_NAME, sizeof(NOISE_PROTOCOL_NAME)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); - - //TODO: remove - // char log_ck[CRYPTO_SHA512_SIZE*2+1]; - // if (log != nullptr) { - // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "ck: %s", log_ck); - // } - - /* Sets the initiator, s => ephemeral keys are set afterwards */ - noise_handshake->initiator = initiator; - if (self_secret_key != nullptr) { - memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_SECRET_KEY_SIZE); - crypto_derive_public_key(noise_handshake->static_public, self_secret_key); - - //TODO: remove - if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); - LOGGER_DEBUG(log, "static pub: %s", log_spub); - } - - } else { - // fprintf(stderr, "Local static private key required, but not provided.\n"); - LOGGER_DEBUG(log, "Local static private key required, but not provided."); - return -1; - } - /* <- s: pre-message from responder to initiator => sets rs (only initiator) */ - if (initiator) { - if (peer_public_key != nullptr) { - memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - - //TODO: Remove - if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); - LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); - } - - /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ - noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - - //TODO: remove - // if (log != nullptr) { - // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "INITIATOR hash: %s", log_hash); - // } - } else { - // fprintf(stderr, "Remote peer static public key required, but not provided.\n"); - LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); - return -1; - } - } - /* Noise RESPONDER */ - else { - /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ - noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); - - //TODO: remove - // if (log != nullptr) { - // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); - // } - } - - /* Ready to go */ - return 0; -} - /** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. * * cf. Noise section 5.3 -> WriteMessage(payload, message_buffer) diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 09fe9ea2c4..192f8af580 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -120,8 +120,6 @@ typedef enum Packet_Id { #define DEFAULT_PING_CONNECTION 1000 #define DEFAULT_TCP_PING_CONNECTION 500 -#define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" - typedef struct Net_Crypto Net_Crypto; non_null() const uint8_t *nc_get_self_public_key(const Net_Crypto *c); @@ -129,25 +127,6 @@ non_null() const uint8_t *nc_get_self_secret_key(const Net_Crypto *c); non_null() TCP_Connections *nc_get_tcp_c(const Net_Crypto *c); non_null() DHT *nc_get_dht(const Net_Crypto *c); -// TODO: struct necessary? -// TODO: move to crypto_core.h? -/** @brief Necessary Noise handshake state information/values. - */ -typedef struct Noise_Handshake { - // TODO: static_private? - uint8_t static_private[CRYPTO_SECRET_KEY_SIZE]; - uint8_t static_public[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t ephemeral_private[CRYPTO_SECRET_KEY_SIZE]; - uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; - - uint8_t hash[CRYPTO_SHA512_SIZE]; - uint8_t chaining_key[CRYPTO_SHA512_SIZE]; - - bool initiator; -} Noise_Handshake; - typedef struct New_Connection { IP_Port source; // Necessary for non-Noise handshake From f9ad7c495824015fcb389729d40d56f5f5802cb7 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 4 Jun 2024 19:53:15 +0200 Subject: [PATCH 086/150] Fixed crypto_hkdf() in crypto_core.c and verified with test vectors. Added NoiseIK test vectors test file, currently hacked into crypto_test.c for compilation and easy local troubleshooting. --- auto_tests/crypto_test.c | 21 ++ auto_tests/crypto_test_NoiseIK_test_vectors.c | 22 ++ toxcore/crypto_core.c | 308 +++++++++++------- 3 files changed, 229 insertions(+), 122 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 90f6c5d59a..5daecd8912 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -188,6 +189,7 @@ uint8_t resp_ephemeral[32] = { 0x79, 0x3d, 0x5e, 0x63, 0xda, 0x6b, 0x37, 0x5b }; +// 4c 75 64 77 69 67 20 76 6f 6e 20 4d 69 73 65 73 uint8_t payload1[16] = { 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f, 0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 @@ -334,10 +336,24 @@ static void test_fast_known2(void) // ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); // ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); + char h_print[CRYPTO_SHA512_SIZE * 2 + 1]; + char ck_print[CRYPTO_SHA512_SIZE * 2 + 1]; + char key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // INITIATOR: Noise_Handshake *noise_handshake = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); + bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + printf("noise_handshake->hash: %s\n", h_print); + bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + printf("noise_handshake->chaining_key: %s\n", ck_print); noise_handshake_init(nullptr, noise_handshake, init_static, init_remote_static, true); + + bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + printf("noise_handshake->hash: %s\n", h_print); + bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + printf("noise_handshake->chaining_key: %s\n", ck_print); + memcpy(noise_handshake->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(noise_handshake->ephemeral_public, init_ephemeral); @@ -362,6 +378,11 @@ static void test_fast_known2(void) /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + printf("noise_handshake->chaining_key (after es): %s\n", ck_print); + + bin2hex_toupper(key_print, sizeof(key_print), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + printf("noise_handshake_temp_key (after es): %s\n", key_print); /* s */ //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 diff --git a/auto_tests/crypto_test_NoiseIK_test_vectors.c b/auto_tests/crypto_test_NoiseIK_test_vectors.c index 90f6c5d59a..694ecaaf22 100644 --- a/auto_tests/crypto_test_NoiseIK_test_vectors.c +++ b/auto_tests/crypto_test_NoiseIK_test_vectors.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -188,6 +189,7 @@ uint8_t resp_ephemeral[32] = { 0x79, 0x3d, 0x5e, 0x63, 0xda, 0x6b, 0x37, 0x5b }; +// 4c 75 64 77 69 67 20 76 6f 6e 20 4d 69 73 65 73 uint8_t payload1[16] = { 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f, 0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 @@ -334,10 +336,25 @@ static void test_fast_known2(void) // ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); // ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); + char h_print[CRYPTO_SHA512_SIZE * 2 + 1]; + char ck_print[CRYPTO_SHA512_SIZE * 2 + 1]; + char key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // INITIATOR: Noise_Handshake *noise_handshake = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); + bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + printf("noise_handshake->hash: %s\n", h_print); + bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + printf("noise_handshake->chaining_key: %s\n", ck_print); + noise_handshake_init(nullptr, noise_handshake, init_static, init_remote_static, true); + + bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + printf("noise_handshake->hash: %s\n", h_print); + bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + printf("noise_handshake->chaining_key: %s\n", ck_print); + memcpy(noise_handshake->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(noise_handshake->ephemeral_public, init_ephemeral); @@ -362,6 +379,11 @@ static void test_fast_known2(void) /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + printf("noise_handshake->chaining_key (after es): %s\n", ck_print); + + bin2hex_toupper(key_print, sizeof(key_print), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + printf("noise_handshake_temp_key (after es): %s\n", key_print); /* s */ //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index fb86f68cd7..031551121a 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -623,125 +623,13 @@ size_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S * bytes_to_string() from util.h */ static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) -{ +{ bytes_to_string(bytes, bytes_length, string, string_length); } // #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" static const uint8_t noise_protocol[32] = "Noise_IK_25519_ChaChaPoly_SHA512"; -/** - * @brief Initializes a Noise Handshake State with provided static X25519 ID key pair, X25519 static ID public key from peer - * and sets if initiator or not. - * - * cf. Noise section 5.3 - * Calls InitializeSymmetric(protocol_name). - * Calls MixHash(prologue). - * Sets the initiator, s, e, rs, and re variables to the corresponding arguments. - * Calls MixHash() once for each public key listed in the pre-messages. - * - * //TODO: remove Logger Param - * @param log Tox logger - * @param noise_handshake handshake struct to save the necessary values to - * @param self_secret_key static private ID X25519 key of this Tox instance - * @param peer_public_key X25519 static ID public key from peer to connect to - * @param initiator specifies if this Tox instance is the initiator of this crypto connection - * - * @return -1 on failure - * @return 0 on success - */ -int noise_handshake_init -(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) -{ - //TODO: remove - if (log != nullptr) { - LOGGER_DEBUG(log, "ENTERING"); - } - - //TODO: move to handle_packet_crypto_hs()? - crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); - - /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h - Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ - uint8_t temp_hash[CRYPTO_SHA512_SIZE]; - memset(temp_hash, 0, CRYPTO_SHA512_SIZE); - memcpy(temp_hash, noise_protocol, sizeof(noise_protocol)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); - - //TODO: remove prologue for test vectors - static const uint8_t prologue[] = { - 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x31, 0x32, 0x33 - }; - noise_mix_hash(noise_handshake->hash, prologue, sizeof(prologue)); - - //TODO: remove - // char log_ck[CRYPTO_SHA512_SIZE*2+1]; - // if (log != nullptr) { - // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "ck: %s", log_ck); - // } - - /* Sets the initiator, s => ephemeral keys are set afterwards */ - noise_handshake->initiator = initiator; - if (self_secret_key != nullptr) { - memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_SECRET_KEY_SIZE); - crypto_derive_public_key(noise_handshake->static_public, self_secret_key); - - //TODO: remove - if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); - LOGGER_DEBUG(log, "static pub: %s", log_spub); - } - - } else { - // fprintf(stderr, "Local static private key required, but not provided.\n"); - LOGGER_DEBUG(log, "Local static private key required, but not provided."); - return -1; - } - /* <- s: pre-message from responder to initiator => sets rs (only initiator) */ - if (initiator) { - if (peer_public_key != nullptr) { - memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - - //TODO: Remove - if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); - LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); - } - - /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ - noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); - - //TODO: remove - // if (log != nullptr) { - // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "INITIATOR hash: %s", log_hash); - // } - } else { - // fprintf(stderr, "Remote peer static public key required, but not provided.\n"); - LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); - return -1; - } - } - /* Noise RESPONDER */ - else { - /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ - noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); - - //TODO: remove - // if (log != nullptr) { - // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); - // } - } - - /* Ready to go */ - return 0; -} - /** * cf. Noise sections 4.3 and 5.1 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. @@ -776,27 +664,72 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * length. Also note that the HKDF() function is simply HKDF with the * chaining_key as HKDF salt, and zero-length HKDF info. */ +// void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, +// size_t second_len, const uint8_t *data, +// size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) +// { +// uint8_t output[CRYPTO_SHA512_SIZE + 1]; +// // temp_key = secret in WG +// uint8_t temp_key[CRYPTO_SHA512_SIZE]; + +// /* Extract entropy from data into temp_key */ +// // data => input_key_material => DH result in Noise +// crypto_hmac512(temp_key, chaining_key, data, data_len); + +// /* Expand first key: key = temp_key, data = 0x1 */ +// output[0] = 1; +// crypto_hmac512(output, temp_key, output, 1); +// memcpy(output1, output, first_len); + +// /* Expand second key: key = secret, data = first-key || 0x2 */ +// output[CRYPTO_SHA512_SIZE] = 2; +// crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); +// memcpy(output2, output, second_len); + +// /* Expand third key: key = temp_key, data = second-key || 0x3 */ +// /* Currently output3 not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ +// // output[CRYPTO_SHA512_SIZE] = 3; +// // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); +// // memcpy(output3, output, third_len); + +// /* Clear sensitive data from stack */ +// crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); +// crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); +// } void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, size_t second_len, const uint8_t *data, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) { - uint8_t output[CRYPTO_SHA512_SIZE + 1]; + // uint8_t output[CRYPTO_SHA512_SIZE + 1]; // temp_key = secret in WG uint8_t temp_key[CRYPTO_SHA512_SIZE]; /* Extract entropy from data into temp_key */ // data => input_key_material => DH result in Noise - crypto_hmac512(temp_key, chaining_key, data, data_len); + //TODO: This is correct, same result as crypto_kdf_hkdf_sha512_extract() + // crypto_hmac512(temp_key, chaining_key, data, data_len); + + /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. + Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ + crypto_kdf_hkdf_sha512_extract(temp_key, chaining_key, CRYPTO_SHA512_SIZE, data, data_len); /* Expand first key: key = temp_key, data = 0x1 */ - output[0] = 1; - crypto_hmac512(output, temp_key, output, 1); - memcpy(output1, output, first_len); + /* TODO: Not correct, unsure why */ + // output[0] = 1; + // crypto_hmac512(output, temp_key, output, 1); + // memcpy(output1, output, first_len); + + /* Expand both keys in one operation (verified): */ + uint8_t output_temp[CRYPTO_SHA512_SIZE*2]; + crypto_kdf_hkdf_sha512_expand(output_temp, CRYPTO_SHA512_SIZE*2, nullptr, 0, temp_key); + memcpy(output1, output_temp, first_len); + memcpy(output2, output_temp+CRYPTO_SHA512_SIZE, second_len); /* Expand second key: key = secret, data = first-key || 0x2 */ - output[CRYPTO_SHA512_SIZE] = 2; - crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); - memcpy(output2, output, second_len); + /* TODO: Not correct, unsure why */ + // output[CRYPTO_SHA512_SIZE] = 2; + // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); + // memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ /* Currently output3 not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ @@ -804,9 +737,18 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); // memcpy(output3, output, third_len); + // ctx = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) + /* Works, correct result */ + // crypto_kdf_hkdf_sha512_expand(output1, first_len, nullptr, 0, temp_key); + + // ctx = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) + /* Same result as expand1, so doesn't work like this */ + // crypto_kdf_hkdf_sha512_expand(output2, second_len, 0, 0, temp_key); + /* Clear sensitive data from stack */ crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); - crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); + // crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); + crypto_memzero(output_temp, CRYPTO_SHA512_SIZE + 1); } /* @@ -829,10 +771,18 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], if (crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { return -1; } + + //uint8_t shared_key_temp[CRYPTO_SHA512_SIZE]; + // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! + //TODO: change back to shared_key to shared_key_temp? crypto_hkdf(chaining_key, CRYPTO_SHA512_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, CRYPTO_SHARED_KEY_SIZE, chaining_key); // If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() + //TODO: no difference in case of libsodium HKDF in output + // memcpy(shared_key, shared_key_temp, CRYPTO_SHARED_KEY_SIZE); + // crypto_memzero(shared_key_temp, CRYPTO_SHA512_SIZE); + crypto_memzero(dh_calculation, CRYPTO_SHARED_KEY_SIZE); return 0; @@ -890,3 +840,117 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, return plaintext_length; } + +/** + * @brief Initializes a Noise Handshake State with provided static X25519 ID key pair, X25519 static ID public key from peer + * and sets if initiator or not. + * + * cf. Noise section 5.3 + * Calls InitializeSymmetric(protocol_name). + * Calls MixHash(prologue). + * Sets the initiator, s, e, rs, and re variables to the corresponding arguments. + * Calls MixHash() once for each public key listed in the pre-messages. + * + * //TODO: remove Logger Param + * @param log Tox logger + * @param noise_handshake handshake struct to save the necessary values to + * @param self_secret_key static private ID X25519 key of this Tox instance + * @param peer_public_key X25519 static ID public key from peer to connect to + * @param initiator specifies if this Tox instance is the initiator of this crypto connection + * + * @return -1 on failure + * @return 0 on success + */ +int noise_handshake_init +(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +{ + //TODO: remove + if (log != nullptr) { + LOGGER_DEBUG(log, "ENTERING"); + } + + //TODO: move to handle_packet_crypto_hs()? + crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); + + /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h + Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ + uint8_t temp_hash[CRYPTO_SHA512_SIZE]; + memset(temp_hash, 0, CRYPTO_SHA512_SIZE); + memcpy(temp_hash, noise_protocol, sizeof(noise_protocol)); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + + //TODO: remove prologue for test vectors + static const uint8_t prologue[] = { + // 50 72 6f 6c 6f 67 75 65 31 323 3 + 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x31, 0x32, 0x33 + }; + //TODO: IMPORTANT need to call also with empty prologue? Should I add prologue again?! + noise_mix_hash(noise_handshake->hash, prologue, sizeof(prologue)); + + //TODO: remove + // char log_ck[CRYPTO_SHA512_SIZE*2+1]; + // if (log != nullptr) { + // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "ck: %s", log_ck); + // } + + /* Sets the initiator, s => ephemeral keys are set afterwards */ + noise_handshake->initiator = initiator; + if (self_secret_key != nullptr) { + memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + + //TODO: remove + if (log != nullptr) { + char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); + LOGGER_DEBUG(log, "static pub: %s", log_spub); + } + + } else { + // fprintf(stderr, "Local static private key required, but not provided.\n"); + LOGGER_DEBUG(log, "Local static private key required, but not provided."); + return -1; + } + /* <- s: pre-message from responder to initiator => sets rs (only initiator) */ + if (initiator) { + if (peer_public_key != nullptr) { + memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: Remove + if (log != nullptr) { + char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); + LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); + } + + /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ + noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: remove + // if (log != nullptr) { + // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "INITIATOR hash: %s", log_hash); + // } + } else { + // fprintf(stderr, "Remote peer static public key required, but not provided.\n"); + LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); + return -1; + } + } + /* Noise RESPONDER */ + else { + /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ + noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: remove + // if (log != nullptr) { + // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); + // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); + // } + } + + /* Ready to go */ + return 0; +} \ No newline at end of file From 252c443d6675640e4395b4303abb46c734f8a25d Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 10 Jun 2024 16:35:25 +0200 Subject: [PATCH 087/150] Added further testing steps. Everything correct (incl. final handshake hash value) besides ciphertext4_transport1_initiator_print. --- auto_tests/crypto_test.c | 218 ++++++++++++++--- auto_tests/crypto_test_NoiseIK_test_vectors.c | 219 +++++++++++++++--- toxcore/crypto_core.c | 1 + 3 files changed, 375 insertions(+), 63 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 5daecd8912..224dc316cf 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -190,11 +191,22 @@ uint8_t resp_ephemeral[32] = { }; // 4c 75 64 77 69 67 20 76 6f 6e 20 4d 69 73 65 73 -uint8_t payload1[16] = { +uint8_t payload_hs_initiator[16] = { 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f, 0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 }; +// 4d 75 72 72 61 79 20 52 6f 74 68 62 61 72 64 +uint8_t payload_hs_responder[15] = { + 0x4d, 0x75, 0x72, 0x72, 0x61, 0x79, 0x20, 0x52, + 0x6f, 0x74, 0x68, 0x62, 0x61, 0x72, 0x64 + }; + +// 46 2e 20 41 2e 20 48 61 79 65 6b +uint8_t payload_transport_initiator1[11] = { + 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, 0x79, 0x65, 0x6b + }; + static void test_fast_known2(void) { uint8_t k[CRYPTO_SHARED_KEY_SIZE]; @@ -340,25 +352,28 @@ static void test_fast_known2(void) char ck_print[CRYPTO_SHA512_SIZE * 2 + 1]; char key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // INITIATOR: - Noise_Handshake *noise_handshake = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); - bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - printf("noise_handshake->hash: %s\n", h_print); - bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - printf("noise_handshake->chaining_key: %s\n", ck_print); - noise_handshake_init(nullptr, noise_handshake, init_static, init_remote_static, true); + // INITIATOR: Create handshake packet for responder + Noise_Handshake *noise_handshake_initiator = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); - - bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - printf("noise_handshake->hash: %s\n", h_print); - bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - printf("noise_handshake->chaining_key: %s\n", ck_print); + /* Troubleshooting info, intermediary values */ + // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->hash: %s\n", h_print); + // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->chaining_key: %s\n", ck_print); - memcpy(noise_handshake->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); - crypto_derive_public_key(noise_handshake->ephemeral_public, init_ephemeral); + noise_handshake_init(nullptr, noise_handshake_initiator, init_static, init_remote_static, true); + + /* Troubleshooting info, intermediary values */ + // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->hash: %s\n", h_print); + // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->chaining_key: %s\n", ck_print); + + memcpy(noise_handshake_initiator->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake_initiator->ephemeral_public, init_ephemeral); char ephemeral_public_print[32 * 2 + 1]; - bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); printf("ephemeral_public_print: %s\n", ephemeral_public_print); char resp_static_print[32 * 2 + 1]; @@ -368,21 +383,22 @@ static void test_fast_known2(void) printf("resp_static_pub: %s\n", resp_static_print); /* e */ - noise_mix_hash(noise_handshake->hash, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: remove from production code + /* Troubleshooting info, intermediary values */ // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); - bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - printf("noise_handshake->chaining_key (after es): %s\n", ck_print); + noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key, noise_handshake_initiator->ephemeral_private, noise_handshake_initiator->remote_static); - bin2hex_toupper(key_print, sizeof(key_print), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - printf("noise_handshake_temp_key (after es): %s\n", key_print); + /* Troubleshooting info, intermediary values */ + // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->chaining_key (after es): %s\n", ck_print); + // bin2hex_toupper(key_print, sizeof(key_print), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + // printf("noise_handshake_temp_key (after es): %s\n", key_print); /* s */ //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 @@ -393,12 +409,12 @@ static void test_fast_known2(void) /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ uint8_t ciphertext1[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; - noise_encrypt_and_hash(ciphertext1, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - noise_handshake->hash); + noise_encrypt_and_hash(ciphertext1, noise_handshake_initiator->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + noise_handshake_initiator->hash); char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); - printf("ciphertext1_print: %s\n", ciphertext1_print); + printf("Initiator: HS ciphertext static pub key: %s\n", ciphertext1_print); //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; @@ -409,11 +425,12 @@ static void test_fast_known2(void) // LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); /* ss */ - noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key, + noise_handshake_initiator->static_private, noise_handshake_initiator->remote_static); /* Noise Handshake Payload */ // uint8_t handshake_payload_plain[15]; - uint8_t ciphertext2[sizeof(payload1) + CRYPTO_MAC_SIZE]; + uint8_t ciphertext2[sizeof(payload_hs_initiator) + CRYPTO_MAC_SIZE]; //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 /* Add Handshake payload nonce */ @@ -424,12 +441,151 @@ static void test_fast_known2(void) /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(ciphertext2, - payload1, sizeof(payload1), noise_handshake_temp_key, - noise_handshake->hash); + payload_hs_initiator, sizeof(payload_hs_initiator), noise_handshake_temp_key, + noise_handshake_initiator->hash); char ciphertext2_print[sizeof(ciphertext2) * 2 + 1]; bin2hex_toupper(ciphertext2_print, sizeof(ciphertext2_print), ciphertext2, sizeof(ciphertext2)); - printf("ciphertext2_print: %s\n", ciphertext2_print); + printf("Initiator: HS ciphertext payload: %s\n", ciphertext2_print); + + // INITIATOR: END Create handshake packet for responder + + // RESPONDER: Consume handshake packet from initiator + Noise_Handshake *noise_handshake_responder = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); + + /* Troubleshooting info, intermediary values */ + // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->hash: %s\n", h_print); + // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->chaining_key: %s\n", ck_print); + + char init_static_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + uint8_t init_static_pub[CRYPTO_PUBLIC_KEY_SIZE]; + crypto_derive_public_key(init_static_pub, init_static); + bin2hex_toupper(init_static_print, sizeof(init_static_print), init_static_pub, CRYPTO_PUBLIC_KEY_SIZE); + printf("init_static_pub: %s\n", init_static_print); + + noise_handshake_init(nullptr, noise_handshake_responder, resp_static, init_static_pub, false); + + /* e */ + memcpy(noise_handshake_responder->remote_ephemeral, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake_responder->hash, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + /* es */ + uint8_t noise_handshake_temp_key_resp[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp, + noise_handshake_responder->static_private, noise_handshake_responder->remote_ephemeral); + + /* s */ + noise_decrypt_and_hash(noise_handshake_responder->remote_static, ciphertext1, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + noise_handshake_temp_key_resp, noise_handshake_responder->hash); + + /* ss */ + noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp, noise_handshake_responder->static_private, + noise_handshake_responder->remote_static); + + /* Payload decryption */ + uint8_t handshake_payload_plain_initiator[sizeof(payload_hs_initiator)]; + noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext2, + sizeof(ciphertext2), noise_handshake_temp_key_resp, + noise_handshake_responder->hash); + + // RESPONDER: Create handshake packet for initiator + + /* set ephemeral private+public */ + memcpy(noise_handshake_responder->ephemeral_private, resp_ephemeral, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake_responder->ephemeral_public, resp_ephemeral); + + char ephemeral_public_print_responder[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + bin2hex_toupper(ephemeral_public_print_responder, sizeof(ephemeral_public_print_responder), noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + printf("Responder ephemeral public:: %s\n", ephemeral_public_print_responder); + + /* e */ + noise_mix_hash(noise_handshake_responder->hash, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + /* ee */ + uint8_t noise_handshake_temp_key_resp2[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp2, noise_handshake_responder->ephemeral_private, + noise_handshake_responder->remote_ephemeral); + + /* se */ + noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp2, noise_handshake_responder->ephemeral_private, + noise_handshake_responder->remote_static); + + + /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + uint8_t ciphertext3_hs_responder[sizeof(payload_hs_responder) + CRYPTO_MAC_SIZE]; + noise_encrypt_and_hash(ciphertext3_hs_responder, + payload_hs_responder, sizeof(payload_hs_responder), noise_handshake_temp_key_resp2, + noise_handshake_responder->hash); + + char ciphertext3_print[sizeof(ciphertext3_hs_responder) * 2 + 1]; + bin2hex_toupper(ciphertext3_print, sizeof(ciphertext3_print), ciphertext3_hs_responder, sizeof(ciphertext3_hs_responder)); + printf("Responder: HS ciphertext payload: %s\n", ciphertext3_print); + + // RESPONDER: END create handshake packet for initiator# + + // INITIATOR: Consume handshake packet from responder + memcpy(noise_handshake_initiator->remote_ephemeral, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + + /* ee */ + uint8_t noise_handshake_temp_key_init[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->ephemeral_private, + noise_handshake_initiator->remote_ephemeral); + + /* se */ + noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->static_private, + noise_handshake_initiator->remote_ephemeral); + + uint8_t handshake_payload_plain_responder[sizeof(payload_hs_responder)]; + if(noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext3_hs_responder, + sizeof(ciphertext3_hs_responder), noise_handshake_temp_key_init, + noise_handshake_initiator->hash) != sizeof(payload_hs_responder)) { + printf("Initiator: HS decryption failed\n"); + } + + /* INITIATOR Noise Split(), nonces already set in crypto connection */ + uint8_t initiator_send_key[CRYPTO_SHARED_KEY_SIZE]; + uint8_t initiator_recv_key[CRYPTO_SHARED_KEY_SIZE]; + crypto_hkdf(initiator_send_key, CRYPTO_SHARED_KEY_SIZE, initiator_recv_key, CRYPTO_SHARED_KEY_SIZE, nullptr, 0, + noise_handshake_initiator->chaining_key); + + char handshake_hash_initiator_print[sizeof(noise_handshake_initiator->hash) * 2 + 1]; + bin2hex_toupper(handshake_hash_initiator_print, sizeof(handshake_hash_initiator_print), noise_handshake_initiator->hash, sizeof(noise_handshake_initiator->hash)); + printf("Initiator: final handshake hash: %s\n", handshake_hash_initiator_print); + + /* Troubleshooting info, intermediary values */ + char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + char initiator_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + bin2hex_toupper(initiator_send_key_print, sizeof(initiator_send_key_print), initiator_send_key, CRYPTO_SHARED_KEY_SIZE); + printf("initiator_send_key_print: %s\n", initiator_send_key_print); + bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); + printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); + + uint8_t ciphertext4_transport1_initiator[sizeof(payload_transport_initiator1) + CRYPTO_MAC_SIZE]; + size_t length = encrypt_data_symmetric_aead(initiator_send_key, 0, payload_transport_initiator1, sizeof(payload_transport_initiator1), ciphertext4_transport1_initiator, nullptr, 0); + + char ciphertext4_transport1_initiator_print[sizeof(ciphertext4_transport1_initiator) * 2 + 1]; + bin2hex_toupper(ciphertext4_transport1_initiator_print, sizeof(ciphertext4_transport1_initiator_print), ciphertext4_transport1_initiator, sizeof(ciphertext4_transport1_initiator)); + printf("Initiator: Transport1 ciphertext: %s\n", ciphertext4_transport1_initiator_print); + + /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ + uint8_t responder_send_key[CRYPTO_SHARED_KEY_SIZE]; + uint8_t responder_recv_key[CRYPTO_SHARED_KEY_SIZE]; + crypto_hkdf(responder_recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, responder_send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, noise_handshake_responder->chaining_key); + + /* Troubleshooting info, intermediary values */ + char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + char responder_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + bin2hex_toupper(responder_send_key_print, sizeof(responder_send_key_print), responder_send_key, CRYPTO_SHARED_KEY_SIZE); + printf("responder_send_key_print: %s\n", responder_send_key_print); + bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); + printf("responder_recv_key_print: %s\n", responder_recv_key_print); + + char handshake_hash_responder_print[sizeof(noise_handshake_responder->hash) * 2 + 1]; + bin2hex_toupper(handshake_hash_responder_print, sizeof(handshake_hash_responder_print), noise_handshake_responder->hash, sizeof(noise_handshake_responder->hash)); + printf("Responder: final handshake hash: %s\n", handshake_hash_responder_print); } // static void test_endtoend(void) diff --git a/auto_tests/crypto_test_NoiseIK_test_vectors.c b/auto_tests/crypto_test_NoiseIK_test_vectors.c index 694ecaaf22..224dc316cf 100644 --- a/auto_tests/crypto_test_NoiseIK_test_vectors.c +++ b/auto_tests/crypto_test_NoiseIK_test_vectors.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -190,11 +191,22 @@ uint8_t resp_ephemeral[32] = { }; // 4c 75 64 77 69 67 20 76 6f 6e 20 4d 69 73 65 73 -uint8_t payload1[16] = { +uint8_t payload_hs_initiator[16] = { 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f, 0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 }; +// 4d 75 72 72 61 79 20 52 6f 74 68 62 61 72 64 +uint8_t payload_hs_responder[15] = { + 0x4d, 0x75, 0x72, 0x72, 0x61, 0x79, 0x20, 0x52, + 0x6f, 0x74, 0x68, 0x62, 0x61, 0x72, 0x64 + }; + +// 46 2e 20 41 2e 20 48 61 79 65 6b +uint8_t payload_transport_initiator1[11] = { + 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, 0x79, 0x65, 0x6b + }; + static void test_fast_known2(void) { uint8_t k[CRYPTO_SHARED_KEY_SIZE]; @@ -340,26 +352,28 @@ static void test_fast_known2(void) char ck_print[CRYPTO_SHA512_SIZE * 2 + 1]; char key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // INITIATOR: - Noise_Handshake *noise_handshake = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); - bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - printf("noise_handshake->hash: %s\n", h_print); - bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - printf("noise_handshake->chaining_key: %s\n", ck_print); - - noise_handshake_init(nullptr, noise_handshake, init_static, init_remote_static, true); + // INITIATOR: Create handshake packet for responder + Noise_Handshake *noise_handshake_initiator = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); - - bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - printf("noise_handshake->hash: %s\n", h_print); - bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - printf("noise_handshake->chaining_key: %s\n", ck_print); + /* Troubleshooting info, intermediary values */ + // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->hash: %s\n", h_print); + // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->chaining_key: %s\n", ck_print); + + noise_handshake_init(nullptr, noise_handshake_initiator, init_static, init_remote_static, true); - memcpy(noise_handshake->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); - crypto_derive_public_key(noise_handshake->ephemeral_public, init_ephemeral); + /* Troubleshooting info, intermediary values */ + // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->hash: %s\n", h_print); + // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->chaining_key: %s\n", ck_print); + + memcpy(noise_handshake_initiator->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake_initiator->ephemeral_public, init_ephemeral); char ephemeral_public_print[32 * 2 + 1]; - bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); printf("ephemeral_public_print: %s\n", ephemeral_public_print); char resp_static_print[32 * 2 + 1]; @@ -369,21 +383,22 @@ static void test_fast_known2(void) printf("resp_static_pub: %s\n", resp_static_print); /* e */ - noise_mix_hash(noise_handshake->hash, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: remove from production code + /* Troubleshooting info, intermediary values */ // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); - bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - printf("noise_handshake->chaining_key (after es): %s\n", ck_print); + noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key, noise_handshake_initiator->ephemeral_private, noise_handshake_initiator->remote_static); - bin2hex_toupper(key_print, sizeof(key_print), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - printf("noise_handshake_temp_key (after es): %s\n", key_print); + /* Troubleshooting info, intermediary values */ + // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->chaining_key (after es): %s\n", ck_print); + // bin2hex_toupper(key_print, sizeof(key_print), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + // printf("noise_handshake_temp_key (after es): %s\n", key_print); /* s */ //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 @@ -394,12 +409,12 @@ static void test_fast_known2(void) /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ uint8_t ciphertext1[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; - noise_encrypt_and_hash(ciphertext1, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - noise_handshake->hash); + noise_encrypt_and_hash(ciphertext1, noise_handshake_initiator->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, + noise_handshake_initiator->hash); char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); - printf("ciphertext1_print: %s\n", ciphertext1_print); + printf("Initiator: HS ciphertext static pub key: %s\n", ciphertext1_print); //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; @@ -410,11 +425,12 @@ static void test_fast_known2(void) // LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); /* ss */ - noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key, + noise_handshake_initiator->static_private, noise_handshake_initiator->remote_static); /* Noise Handshake Payload */ // uint8_t handshake_payload_plain[15]; - uint8_t ciphertext2[sizeof(payload1) + CRYPTO_MAC_SIZE]; + uint8_t ciphertext2[sizeof(payload_hs_initiator) + CRYPTO_MAC_SIZE]; //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 /* Add Handshake payload nonce */ @@ -425,12 +441,151 @@ static void test_fast_known2(void) /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(ciphertext2, - payload1, sizeof(payload1), noise_handshake_temp_key, - noise_handshake->hash); + payload_hs_initiator, sizeof(payload_hs_initiator), noise_handshake_temp_key, + noise_handshake_initiator->hash); char ciphertext2_print[sizeof(ciphertext2) * 2 + 1]; bin2hex_toupper(ciphertext2_print, sizeof(ciphertext2_print), ciphertext2, sizeof(ciphertext2)); - printf("ciphertext2_print: %s\n", ciphertext2_print); + printf("Initiator: HS ciphertext payload: %s\n", ciphertext2_print); + + // INITIATOR: END Create handshake packet for responder + + // RESPONDER: Consume handshake packet from initiator + Noise_Handshake *noise_handshake_responder = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); + + /* Troubleshooting info, intermediary values */ + // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->hash: %s\n", h_print); + // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); + // printf("noise_handshake->chaining_key: %s\n", ck_print); + + char init_static_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + uint8_t init_static_pub[CRYPTO_PUBLIC_KEY_SIZE]; + crypto_derive_public_key(init_static_pub, init_static); + bin2hex_toupper(init_static_print, sizeof(init_static_print), init_static_pub, CRYPTO_PUBLIC_KEY_SIZE); + printf("init_static_pub: %s\n", init_static_print); + + noise_handshake_init(nullptr, noise_handshake_responder, resp_static, init_static_pub, false); + + /* e */ + memcpy(noise_handshake_responder->remote_ephemeral, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake_responder->hash, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + /* es */ + uint8_t noise_handshake_temp_key_resp[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp, + noise_handshake_responder->static_private, noise_handshake_responder->remote_ephemeral); + + /* s */ + noise_decrypt_and_hash(noise_handshake_responder->remote_static, ciphertext1, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + noise_handshake_temp_key_resp, noise_handshake_responder->hash); + + /* ss */ + noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp, noise_handshake_responder->static_private, + noise_handshake_responder->remote_static); + + /* Payload decryption */ + uint8_t handshake_payload_plain_initiator[sizeof(payload_hs_initiator)]; + noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext2, + sizeof(ciphertext2), noise_handshake_temp_key_resp, + noise_handshake_responder->hash); + + // RESPONDER: Create handshake packet for initiator + + /* set ephemeral private+public */ + memcpy(noise_handshake_responder->ephemeral_private, resp_ephemeral, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake_responder->ephemeral_public, resp_ephemeral); + + char ephemeral_public_print_responder[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + bin2hex_toupper(ephemeral_public_print_responder, sizeof(ephemeral_public_print_responder), noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + printf("Responder ephemeral public:: %s\n", ephemeral_public_print_responder); + + /* e */ + noise_mix_hash(noise_handshake_responder->hash, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + + /* ee */ + uint8_t noise_handshake_temp_key_resp2[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp2, noise_handshake_responder->ephemeral_private, + noise_handshake_responder->remote_ephemeral); + + /* se */ + noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp2, noise_handshake_responder->ephemeral_private, + noise_handshake_responder->remote_static); + + + /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ + uint8_t ciphertext3_hs_responder[sizeof(payload_hs_responder) + CRYPTO_MAC_SIZE]; + noise_encrypt_and_hash(ciphertext3_hs_responder, + payload_hs_responder, sizeof(payload_hs_responder), noise_handshake_temp_key_resp2, + noise_handshake_responder->hash); + + char ciphertext3_print[sizeof(ciphertext3_hs_responder) * 2 + 1]; + bin2hex_toupper(ciphertext3_print, sizeof(ciphertext3_print), ciphertext3_hs_responder, sizeof(ciphertext3_hs_responder)); + printf("Responder: HS ciphertext payload: %s\n", ciphertext3_print); + + // RESPONDER: END create handshake packet for initiator# + + // INITIATOR: Consume handshake packet from responder + memcpy(noise_handshake_initiator->remote_ephemeral, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + + /* ee */ + uint8_t noise_handshake_temp_key_init[CRYPTO_SHARED_KEY_SIZE]; + noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->ephemeral_private, + noise_handshake_initiator->remote_ephemeral); + + /* se */ + noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->static_private, + noise_handshake_initiator->remote_ephemeral); + + uint8_t handshake_payload_plain_responder[sizeof(payload_hs_responder)]; + if(noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext3_hs_responder, + sizeof(ciphertext3_hs_responder), noise_handshake_temp_key_init, + noise_handshake_initiator->hash) != sizeof(payload_hs_responder)) { + printf("Initiator: HS decryption failed\n"); + } + + /* INITIATOR Noise Split(), nonces already set in crypto connection */ + uint8_t initiator_send_key[CRYPTO_SHARED_KEY_SIZE]; + uint8_t initiator_recv_key[CRYPTO_SHARED_KEY_SIZE]; + crypto_hkdf(initiator_send_key, CRYPTO_SHARED_KEY_SIZE, initiator_recv_key, CRYPTO_SHARED_KEY_SIZE, nullptr, 0, + noise_handshake_initiator->chaining_key); + + char handshake_hash_initiator_print[sizeof(noise_handshake_initiator->hash) * 2 + 1]; + bin2hex_toupper(handshake_hash_initiator_print, sizeof(handshake_hash_initiator_print), noise_handshake_initiator->hash, sizeof(noise_handshake_initiator->hash)); + printf("Initiator: final handshake hash: %s\n", handshake_hash_initiator_print); + + /* Troubleshooting info, intermediary values */ + char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + char initiator_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + bin2hex_toupper(initiator_send_key_print, sizeof(initiator_send_key_print), initiator_send_key, CRYPTO_SHARED_KEY_SIZE); + printf("initiator_send_key_print: %s\n", initiator_send_key_print); + bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); + printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); + + uint8_t ciphertext4_transport1_initiator[sizeof(payload_transport_initiator1) + CRYPTO_MAC_SIZE]; + size_t length = encrypt_data_symmetric_aead(initiator_send_key, 0, payload_transport_initiator1, sizeof(payload_transport_initiator1), ciphertext4_transport1_initiator, nullptr, 0); + + char ciphertext4_transport1_initiator_print[sizeof(ciphertext4_transport1_initiator) * 2 + 1]; + bin2hex_toupper(ciphertext4_transport1_initiator_print, sizeof(ciphertext4_transport1_initiator_print), ciphertext4_transport1_initiator, sizeof(ciphertext4_transport1_initiator)); + printf("Initiator: Transport1 ciphertext: %s\n", ciphertext4_transport1_initiator_print); + + /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ + uint8_t responder_send_key[CRYPTO_SHARED_KEY_SIZE]; + uint8_t responder_recv_key[CRYPTO_SHARED_KEY_SIZE]; + crypto_hkdf(responder_recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, responder_send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, noise_handshake_responder->chaining_key); + + /* Troubleshooting info, intermediary values */ + char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + char responder_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + bin2hex_toupper(responder_send_key_print, sizeof(responder_send_key_print), responder_send_key, CRYPTO_SHARED_KEY_SIZE); + printf("responder_send_key_print: %s\n", responder_send_key_print); + bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); + printf("responder_recv_key_print: %s\n", responder_recv_key_print); + + char handshake_hash_responder_print[sizeof(noise_handshake_responder->hash) * 2 + 1]; + bin2hex_toupper(handshake_hash_responder_print, sizeof(handshake_hash_responder_print), noise_handshake_responder->hash, sizeof(noise_handshake_responder->hash)); + printf("Responder: final handshake hash: %s\n", handshake_hash_responder_print); } // static void test_endtoend(void) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 031551121a..24ffce6769 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -720,6 +720,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // memcpy(output1, output, first_len); /* Expand both keys in one operation (verified): */ + /* HKDF -> T(0) + T(1); cf. RFC TODO: */ uint8_t output_temp[CRYPTO_SHA512_SIZE*2]; crypto_kdf_hkdf_sha512_expand(output_temp, CRYPTO_SHA512_SIZE*2, nullptr, 0, temp_key); memcpy(output1, output_temp, first_len); From a47fbbc8ef336aa3eadd30d691407ea545587a3d Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Mon, 10 Jun 2024 20:16:02 +0200 Subject: [PATCH 088/150] Adapted return type of aead/xaead encrypt/decrypt functions and removed unnecessary unsigned long long. Added and verified all test vectors values. --- auto_tests/crypto_test.c | 85 ++++++++++++++---- auto_tests/crypto_test_NoiseIK_test_vectors.c | 86 +++++++++++++++---- toxcore/crypto_core.c | 54 ++++++------ toxcore/crypto_core.h | 8 +- 4 files changed, 170 insertions(+), 63 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 224dc316cf..853fcfa425 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -204,7 +205,25 @@ uint8_t payload_hs_responder[15] = { // 46 2e 20 41 2e 20 48 61 79 65 6b uint8_t payload_transport_initiator1[11] = { - 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, 0x79, 0x65, 0x6b + 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, 0x79, + 0x65, 0x6b + }; + +// 43 61 72 6c 20 4d 65 6e 67 65 72 +uint8_t payload_transport_responder1[11] = { + 0x43, 0x61, 0x72, 0x6c, 0x20, 0x4d, 0x65, 0x6e, 0x67, 0x65, 0x72 + }; + +// 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 +uint8_t payload_transport_initiator2[17] = { + 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, + 0x74, 0x65, 0x20, 0x53, 0x61, 0x79 +}; + +// 45 75 67 65 6e 20 42 f6 68 6d 20 76 6f 6e 20 42 61 77 65 72 6b +uint8_t payload_transport_responder2[21] = { + 0x45, 0x75, 0x67, 0x65, 0x6e, 0x20, 0x42, 0xf6, 0x68, 0x6d, 0x20, + 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b }; static void test_fast_known2(void) @@ -556,36 +575,68 @@ static void test_fast_known2(void) printf("Initiator: final handshake hash: %s\n", handshake_hash_initiator_print); /* Troubleshooting info, intermediary values */ - char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - char initiator_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - bin2hex_toupper(initiator_send_key_print, sizeof(initiator_send_key_print), initiator_send_key, CRYPTO_SHARED_KEY_SIZE); - printf("initiator_send_key_print: %s\n", initiator_send_key_print); - bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); - printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); + // char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // char initiator_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // bin2hex_toupper(initiator_send_key_print, sizeof(initiator_send_key_print), initiator_send_key, CRYPTO_SHARED_KEY_SIZE); + // printf("initiator_send_key_print: %s\n", initiator_send_key_print); + // bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); + // printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); uint8_t ciphertext4_transport1_initiator[sizeof(payload_transport_initiator1) + CRYPTO_MAC_SIZE]; - size_t length = encrypt_data_symmetric_aead(initiator_send_key, 0, payload_transport_initiator1, sizeof(payload_transport_initiator1), ciphertext4_transport1_initiator, nullptr, 0); + uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + int32_t length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, payload_transport_initiator1, sizeof(payload_transport_initiator1), ciphertext4_transport1_initiator, nullptr, 0); char ciphertext4_transport1_initiator_print[sizeof(ciphertext4_transport1_initiator) * 2 + 1]; bin2hex_toupper(ciphertext4_transport1_initiator_print, sizeof(ciphertext4_transport1_initiator_print), ciphertext4_transport1_initiator, sizeof(ciphertext4_transport1_initiator)); - printf("Initiator: Transport1 ciphertext: %s\n", ciphertext4_transport1_initiator_print); + printf("Initiator: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext4_transport1_initiator_print); /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ uint8_t responder_send_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t responder_recv_key[CRYPTO_SHARED_KEY_SIZE]; crypto_hkdf(responder_recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, responder_send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, noise_handshake_responder->chaining_key); - /* Troubleshooting info, intermediary values */ - char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - char responder_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - bin2hex_toupper(responder_send_key_print, sizeof(responder_send_key_print), responder_send_key, CRYPTO_SHARED_KEY_SIZE); - printf("responder_send_key_print: %s\n", responder_send_key_print); - bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); - printf("responder_recv_key_print: %s\n", responder_recv_key_print); - char handshake_hash_responder_print[sizeof(noise_handshake_responder->hash) * 2 + 1]; bin2hex_toupper(handshake_hash_responder_print, sizeof(handshake_hash_responder_print), noise_handshake_responder->hash, sizeof(noise_handshake_responder->hash)); printf("Responder: final handshake hash: %s\n", handshake_hash_responder_print); + + /* Troubleshooting info, intermediary values */ + // char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // char responder_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // bin2hex_toupper(responder_send_key_print, sizeof(responder_send_key_print), responder_send_key, CRYPTO_SHARED_KEY_SIZE); + // printf("responder_send_key_print: %s\n", responder_send_key_print); + // bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); + // printf("responder_recv_key_print: %s\n", responder_recv_key_print); + + uint8_t ciphertext5_transport1_responder[sizeof(payload_transport_responder1) + CRYPTO_MAC_SIZE]; + int32_t length_ciphertext5_transport1_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, + payload_transport_responder1, sizeof(payload_transport_responder1), ciphertext5_transport1_responder, nullptr, 0); + + char ciphertext5_transport1_responder_print[sizeof(ciphertext5_transport1_responder) * 2 + 1]; + bin2hex_toupper(ciphertext5_transport1_responder_print, sizeof(ciphertext5_transport1_responder_print), ciphertext5_transport1_responder, sizeof(ciphertext5_transport1_responder)); + printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext5_transport1_responder_print); + + sodium_increment(nonce_chacha20_ietf, CRYPTO_NOISEIK_NONCE_SIZE); + // uint8_t nonce_chacha20_ietf_1[CRYPTO_NOISEIK_NONCE_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00, + // 0x00, 0x01 }; + uint8_t ciphertext6_transport2_initiator[sizeof(payload_transport_initiator2) + CRYPTO_MAC_SIZE]; + int32_t ciphertext6_transport2_initiator_length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, + payload_transport_initiator2, sizeof(payload_transport_initiator2), ciphertext6_transport2_initiator, nullptr, 0); + + char ciphertext6_transport2_initiator_print[sizeof(ciphertext6_transport2_initiator) * 2 + 1]; + bin2hex_toupper(ciphertext6_transport2_initiator_print, sizeof(ciphertext6_transport2_initiator_print), + ciphertext6_transport2_initiator, sizeof(ciphertext6_transport2_initiator)); + printf("Initiator: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext6_transport2_initiator_print); + + uint8_t ciphertext7_transport2_responder[sizeof(payload_transport_responder2) + CRYPTO_MAC_SIZE]; + int32_t length_ciphertext7_transport2_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, + payload_transport_responder2, sizeof(payload_transport_responder2), ciphertext7_transport2_responder, nullptr, 0); + + char ciphertext7_transport2_responder_print[sizeof(ciphertext7_transport2_responder) * 2 + 1]; + bin2hex_toupper(ciphertext7_transport2_responder_print, sizeof(ciphertext7_transport2_responder_print), + ciphertext7_transport2_responder, sizeof(ciphertext7_transport2_responder)); + printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext7_transport2_responder_print); + + } // static void test_endtoend(void) diff --git a/auto_tests/crypto_test_NoiseIK_test_vectors.c b/auto_tests/crypto_test_NoiseIK_test_vectors.c index 224dc316cf..2fa8c37652 100644 --- a/auto_tests/crypto_test_NoiseIK_test_vectors.c +++ b/auto_tests/crypto_test_NoiseIK_test_vectors.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -204,7 +205,25 @@ uint8_t payload_hs_responder[15] = { // 46 2e 20 41 2e 20 48 61 79 65 6b uint8_t payload_transport_initiator1[11] = { - 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, 0x79, 0x65, 0x6b + 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, 0x79, + 0x65, 0x6b + }; + +// 43 61 72 6c 20 4d 65 6e 67 65 72 +uint8_t payload_transport_responder1[11] = { + 0x43, 0x61, 0x72, 0x6c, 0x20, 0x4d, 0x65, 0x6e, 0x67, 0x65, 0x72 + }; + +// 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 +uint8_t payload_transport_initiator2[17] = { + 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, + 0x74, 0x65, 0x20, 0x53, 0x61, 0x79 +}; + +// 45 75 67 65 6e 20 42 f6 68 6d 20 76 6f 6e 20 42 61 77 65 72 6b +uint8_t payload_transport_responder2[21] = { + 0x45, 0x75, 0x67, 0x65, 0x6e, 0x20, 0x42, 0xf6, 0x68, 0x6d, 0x20, + 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b }; static void test_fast_known2(void) @@ -556,36 +575,69 @@ static void test_fast_known2(void) printf("Initiator: final handshake hash: %s\n", handshake_hash_initiator_print); /* Troubleshooting info, intermediary values */ - char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - char initiator_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - bin2hex_toupper(initiator_send_key_print, sizeof(initiator_send_key_print), initiator_send_key, CRYPTO_SHARED_KEY_SIZE); - printf("initiator_send_key_print: %s\n", initiator_send_key_print); - bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); - printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); + // char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // char initiator_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // bin2hex_toupper(initiator_send_key_print, sizeof(initiator_send_key_print), initiator_send_key, CRYPTO_SHARED_KEY_SIZE); + // printf("initiator_send_key_print: %s\n", initiator_send_key_print); + // bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); + // printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); uint8_t ciphertext4_transport1_initiator[sizeof(payload_transport_initiator1) + CRYPTO_MAC_SIZE]; - size_t length = encrypt_data_symmetric_aead(initiator_send_key, 0, payload_transport_initiator1, sizeof(payload_transport_initiator1), ciphertext4_transport1_initiator, nullptr, 0); + uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + int32_t length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, payload_transport_initiator1, sizeof(payload_transport_initiator1), ciphertext4_transport1_initiator, nullptr, 0); char ciphertext4_transport1_initiator_print[sizeof(ciphertext4_transport1_initiator) * 2 + 1]; bin2hex_toupper(ciphertext4_transport1_initiator_print, sizeof(ciphertext4_transport1_initiator_print), ciphertext4_transport1_initiator, sizeof(ciphertext4_transport1_initiator)); - printf("Initiator: Transport1 ciphertext: %s\n", ciphertext4_transport1_initiator_print); + printf("Initiator: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext4_transport1_initiator_print); /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ uint8_t responder_send_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t responder_recv_key[CRYPTO_SHARED_KEY_SIZE]; crypto_hkdf(responder_recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, responder_send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, noise_handshake_responder->chaining_key); - /* Troubleshooting info, intermediary values */ - char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - char responder_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - bin2hex_toupper(responder_send_key_print, sizeof(responder_send_key_print), responder_send_key, CRYPTO_SHARED_KEY_SIZE); - printf("responder_send_key_print: %s\n", responder_send_key_print); - bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); - printf("responder_recv_key_print: %s\n", responder_recv_key_print); - char handshake_hash_responder_print[sizeof(noise_handshake_responder->hash) * 2 + 1]; bin2hex_toupper(handshake_hash_responder_print, sizeof(handshake_hash_responder_print), noise_handshake_responder->hash, sizeof(noise_handshake_responder->hash)); printf("Responder: final handshake hash: %s\n", handshake_hash_responder_print); + + /* Troubleshooting info, intermediary values */ + // char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // char responder_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; + // bin2hex_toupper(responder_send_key_print, sizeof(responder_send_key_print), responder_send_key, CRYPTO_SHARED_KEY_SIZE); + // printf("responder_send_key_print: %s\n", responder_send_key_print); + // bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); + // printf("responder_recv_key_print: %s\n", responder_recv_key_print); + + uint8_t ciphertext5_transport1_responder[sizeof(payload_transport_responder1) + CRYPTO_MAC_SIZE]; + int32_t length_ciphertext5_transport1_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, + payload_transport_responder1, sizeof(payload_transport_responder1), ciphertext5_transport1_responder, nullptr, 0); + + char ciphertext5_transport1_responder_print[sizeof(ciphertext5_transport1_responder) * 2 + 1]; + bin2hex_toupper(ciphertext5_transport1_responder_print, sizeof(ciphertext5_transport1_responder_print), ciphertext5_transport1_responder, sizeof(ciphertext5_transport1_responder)); + printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length_ciphertext5_transport1_responder, ciphertext5_transport1_responder_print); + + //TODO: Last two ciphertext currently not the same, maybe nonce is the problem + // sodium_increment(nonce_chacha20_ietf, CRYPTO_NOISEIK_NONCE_SIZE); + // // uint8_t nonce_chacha20_ietf_1[CRYPTO_NOISEIK_NONCE_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00, + // // 0x00, 0x01 }; + // uint8_t ciphertext6_transport2_initiator[sizeof(payload_transport_initiator2) + CRYPTO_MAC_SIZE]; + // int32_t ciphertext6_transport2_initiator_length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, + // payload_transport_initiator2, sizeof(payload_transport_initiator2), ciphertext6_transport2_initiator, nullptr, 0); + + // char ciphertext6_transport2_initiator_print[sizeof(ciphertext6_transport2_initiator) * 2 + 1]; + // bin2hex_toupper(ciphertext6_transport2_initiator_print, sizeof(ciphertext6_transport2_initiator_print), + // ciphertext6_transport2_initiator, sizeof(ciphertext6_transport2_initiator)); + // printf("Initiator: Transport2 ciphertext: (length: %d) %s\n", ciphertext6_transport2_initiator_length, ciphertext6_transport2_initiator_print); + + // uint8_t ciphertext7_transport2_responder[sizeof(payload_transport_responder2) + CRYPTO_MAC_SIZE]; + // int32_t length_ciphertext7_transport2_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, + // payload_transport_responder2, sizeof(payload_transport_responder2), ciphertext7_transport2_responder, nullptr, 0); + + // char ciphertext7_transport2_responder_print[sizeof(ciphertext7_transport2_responder) * 2 + 1]; + // bin2hex_toupper(ciphertext7_transport2_responder_print, sizeof(ciphertext7_transport2_responder_print), + // ciphertext7_transport2_responder, sizeof(ciphertext7_transport2_responder)); + // printf("Responder: Transport2 ciphertext: (length: %d) %s\n", length_ciphertext7_transport2_responder, ciphertext7_transport2_responder_print); + + } // static void test_endtoend(void) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 24ffce6769..166d9b17c7 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -531,7 +531,7 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length) /* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ -size_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], +int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) { @@ -540,19 +540,20 @@ size_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SI return -1; } - unsigned long long encrypted_length = 0; + /* Passing NULL instead, encrypted length is clear anwyay (plain_length + crypto_aead_chacha20poly1305_IETF_ABYTES) */ + // unsigned long long encrypted_length = 0; - // nsec is not used by this particular construction and should always be NULL. - if (crypto_aead_chacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, + /* nsec is not used by this particular construction and should always be NULL. */ + if (crypto_aead_chacha20poly1305_ietf_encrypt(encrypted, NULL, plain, plain_length, ad, ad_length, nullptr, nonce, shared_key) != 0) { return -1; } - // assert(length < INT32_MAX - crypto_box_MACBYTES); - return encrypted_length; + assert(plain_length < INT32_MAX - crypto_aead_chacha20poly1305_IETF_ABYTES); + return (int32_t)(plain_length + crypto_aead_chacha20poly1305_IETF_ABYTES); } -size_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], +int32_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length) { @@ -562,19 +563,20 @@ size_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SI return -1; } - unsigned long long plain_length = 0; + /* Passing NULL instead, encrypted length is clear anwyay (plain_length + crypto_aead_chacha20poly1305_IETF_ABYTES) */ + // unsigned long long plain_length = 0; - if (crypto_aead_chacha20poly1305_ietf_decrypt(plain, &plain_length, nullptr, encrypted, + if (crypto_aead_chacha20poly1305_ietf_decrypt(plain, NULL, nullptr, encrypted, encrypted_length, ad, ad_length, nonce, shared_key) != 0) { return -1; } - // assert(length > crypto_box_MACBYTES); - // assert(length < INT32_MAX); - return plain_length; + assert(encrypted_length > crypto_aead_chacha20poly1305_IETF_ABYTES); + assert(encrypted_length < INT32_MAX); + return (int32_t)(encrypted_length - crypto_aead_chacha20poly1305_IETF_ABYTES); } -size_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], +int32_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) { @@ -583,19 +585,20 @@ size_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S return -1; } - unsigned long long encrypted_length = 0; + /* Passing NULL instead, encrypted length is clear anwyay (plain_length + crypto_aead_xchacha20poly1305_ietf_ABYTES) */ + // unsigned long long encrypted_length = 0; // nsec is not used by this particular construction and should always be NULL. - if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_length, plain, plain_length, + if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, NULL, plain, plain_length, ad, ad_length, nullptr, nonce, shared_key) != 0) { return -1; } - // assert(length < INT32_MAX - crypto_box_MACBYTES); - return encrypted_length; + assert(plain_length < INT32_MAX - crypto_aead_xchacha20poly1305_ietf_ABYTES); + return (int32_t)(plain_length + crypto_aead_xchacha20poly1305_ietf_ABYTES); } -size_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], +int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length) { @@ -605,16 +608,17 @@ size_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S return -1; } - unsigned long long plain_length = 0; + /* Passing NULL instead, encrypted length is clear anwyay (plain_length + crypto_aead_xchacha20poly1305_ietf_ABYTES) */ + // unsigned long long plain_length = 0; - if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, &plain_length, nullptr, encrypted, + if (crypto_aead_xchacha20poly1305_ietf_decrypt(plain, NULL, nullptr, encrypted, encrypted_length, ad, ad_length, nonce, shared_key) != 0) { return -1; } - // assert(length > crypto_box_MACBYTES); - // assert(length < INT32_MAX); - return plain_length; + assert(encrypted_length > crypto_aead_xchacha20poly1305_ietf_ABYTES); + assert(encrypted_length < INT32_MAX); + return (int32_t)(encrypted_length - crypto_aead_xchacha20poly1305_ietf_ABYTES); } /* @@ -814,7 +818,7 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); - unsigned long long encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, + int32_t encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, hash, CRYPTO_SHA512_SIZE); @@ -833,7 +837,7 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); - unsigned long long plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, + int32_t plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, hash, CRYPTO_SHA512_SIZE); diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index e1fe3bfdd5..4bfd5087e1 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -540,7 +540,7 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); * @return length of encrypted data if everything was fine. */ non_null(1, 2, 3, 5) nullable(6) -size_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *plain, size_t plain_length, +int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length); /** @@ -554,7 +554,7 @@ size_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SI * @return length of plain data if everything was fine. */ non_null(1, 2, 3, 5) nullable(6) -size_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, +int32_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); /** @@ -569,7 +569,7 @@ size_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SI * @return length of encrypted data if everything was fine. */ non_null(1, 2, 3, 5) nullable(6) -size_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t plain_length, +int32_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length); /** @@ -583,7 +583,7 @@ size_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S * @return length of plain data if everything was fine. */ non_null(1, 2, 3, 5) nullable(6) -size_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, +int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); /** From 55b3ef561da119c29e88f65c3fc57e409ba316b8 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 14:52:54 +0200 Subject: [PATCH 089/150] feat: Added verification of Noise_IK_25519_ChaChaPoly_SHA512 test vectors to crypto_test.c. Deleted intermediary test files. Added final version of crypto_hkdf() to crypto_core. Added prologue/prologue_length parameters to noise_handshake_init() (necessary in general, and in special for verification of test vectors). Added parameters to calls in net_crypto. --- auto_tests/crypto_test.c | 946 +++++++++--------- auto_tests/crypto_test.c.real | 372 ------- auto_tests/crypto_test_NoiseIK_test_vectors.c | 868 ---------------- toxcore/crypto_core.c | 90 +- toxcore/crypto_core.h | 10 +- toxcore/net_crypto.c | 8 +- 6 files changed, 481 insertions(+), 1813 deletions(-) delete mode 100644 auto_tests/crypto_test.c.real delete mode 100644 auto_tests/crypto_test_NoiseIK_test_vectors.c diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 853fcfa425..87ae7040a3 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -1,23 +1,16 @@ -#include -#include #include -#include #include #include -#include #include "../testing/misc_tools.h" #include "../toxcore/crypto_core.h" #include "../toxcore/net_crypto.h" #include "check_compat.h" #include "../other/fun/create_common.h" -#include "../toxcore/mem.h" static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) { - size_t i; - - for (i = 0; i < blen; i++) { + for (size_t i = 0; i < blen; i++) { b[i] = random_u08(rng); } } @@ -90,19 +83,18 @@ static void test_known(void) { uint8_t c[147]; uint8_t m[131]; - uint16_t clen, mlen; ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); @@ -113,7 +105,6 @@ static void test_fast_known(void) uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t c[147]; uint8_t m[131]; - uint16_t clen, mlen; encrypt_precompute(bobpk, alicesk, k); @@ -122,256 +113,413 @@ static void test_fast_known(void) ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); } -static const uint8_t test_nonce_chacha20[8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; +static void test_endtoend(void) +{ + const Random *rng = os_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]; + uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; + uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; + uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; + uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; + + uint8_t n[CRYPTO_NONCE_SIZE]; + + enum { M_SIZE = 50 }; + uint8_t m[M_SIZE]; + uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; + uint8_t m1[sizeof(m)]; + uint8_t m2[sizeof(m)]; + uint8_t m3[sizeof(m)]; + uint8_t m4[sizeof(m)]; + + //Generate random message (random length from 10 to 50) + const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; + rand_bytes(rng, m, mlen); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + + //Generate keypairs + crypto_new_keypair(rng, pk1, sk1); + crypto_new_keypair(rng, pk2, sk2); + + //Precompute shared keys + encrypt_precompute(pk2, sk1, k1); + encrypt_precompute(pk1, sk2, k2); + + ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); + + //Encrypt all four ways + const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); + const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); + const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); + const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); + + ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); + ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); + ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 + && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); + + //Decrypt all four ways + const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); + const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); + const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); + const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); + + ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); + ck_assert_msg(m1len == mlen, "wrong decrypted text length"); + ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 + && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); + ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); + } +} -static const uint8_t test_nonce_chacha20_ietf[12] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; +static void test_large_data(void) +{ + const Random *rng = os_random(); + ck_assert(rng != nullptr); + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; + uint8_t n[CRYPTO_NONCE_SIZE]; -static const uint8_t test_nonce_xchacha20[24] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; + const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; + uint8_t *m1 = (uint8_t *)malloc(m1_size); + uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); + uint8_t *m1prime = (uint8_t *)malloc(m1_size); -static const uint8_t test_nonce_one_zero_byte[1] = { - 0x00 -}; + const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; + uint8_t *m2 = (uint8_t *)malloc(m2_size); + uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); + + ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); + + //Generate random messages + rand_bytes(rng, m1, m1_size); + rand_bytes(rng, m2, m2_size); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + + //Generate key + 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); + + ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); + ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); + + const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + + ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); + ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); + + free(c2); + free(m2); + free(m1prime); + free(c1); + free(m1); +} + +static void test_large_data_symmetric(void) +{ + const Random *rng = os_random(); + ck_assert(rng != nullptr); + uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; + uint8_t n[CRYPTO_NONCE_SIZE]; + + const size_t m1_size = 16 * 16 * 16; + uint8_t *m1 = (uint8_t *)malloc(m1_size); + uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); + uint8_t *m1prime = (uint8_t *)malloc(m1_size); + + ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); + + //Generate random messages + rand_bytes(rng, m1, m1_size); + rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + + //Generate key + 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"); + + const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + + ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); + ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); + + free(m1prime); + free(c1); + free(m1); +} + +static void test_very_large_data(void) +{ + const Random *rng = os_random(); + ck_assert(rng != nullptr); + + const uint8_t nonce[CRYPTO_NONCE_SIZE] = {0}; + uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t sk[CRYPTO_SECRET_KEY_SIZE]; + crypto_new_keypair(rng, pk, sk); + + // 100 MiB of data (all zeroes, doesn't matter what's inside). + const uint32_t plain_size = 100 * 1024 * 1024; + uint8_t *plain = (uint8_t *)malloc(plain_size); + uint8_t *encrypted = (uint8_t *)malloc(plain_size + CRYPTO_MAC_SIZE); + + ck_assert(plain != nullptr); + ck_assert(encrypted != nullptr); + + encrypt_data(pk, sk, nonce, plain, plain_size, encrypted); + + free(encrypted); + free(plain); +} + +static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) +{ + uint32_t num1 = 0; + memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); + num1 = net_ntohl(num1); + uint32_t num2 = num + num1; + + if (num2 < num1) { + for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { + ++nonce[i - 1]; + + if (nonce[i - 1] != 0) { + break; + } + } + } + + num2 = net_htonl(num2); + memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); +} + +static void test_increment_nonce(void) +{ + const Random *rng = os_random(); + ck_assert(rng != nullptr); + + uint8_t n[CRYPTO_NONCE_SIZE]; + + for (uint32_t i = 0; i < CRYPTO_NONCE_SIZE; ++i) { + n[i] = random_u08(rng); + } + + uint8_t n1[CRYPTO_NONCE_SIZE]; + + memcpy(n1, n, CRYPTO_NONCE_SIZE); + + for (uint32_t i = 0; i < (1 << 18); ++i) { + increment_nonce_number_cmp(n, 1); + increment_nonce(n1); + ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); + } + + for (uint32_t i = 0; i < (1 << 18); ++i) { + 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"); + } +} + +static void test_memzero(void) +{ + uint8_t src[sizeof(test_c)]; + memcpy(src, test_c, sizeof(test_c)); + + crypto_memzero(src, sizeof(src)); + + for (size_t i = 0; i < sizeof(src); i++) { + ck_assert_msg(src[i] == 0, "Memory is not zeroed"); + } +} + +/* Noise_IK_25519_ChaChaPoly_SHA512 test vectors from here: https://github.com/rweather/noise-c/blob/cfe25410979a87391bb9ac8d4d4bef64e9f268c6/tests/vector/noise-c-basic.txt */ +/* "init_prologue": "50726f6c6f677565313233" (same as `resp_prologue`) */ static const uint8_t prologue[11] = { - 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x31, 0x32, 0x33 + 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, + 0x31, 0x32, 0x33 }; -uint8_t init_static[32] = { +/* Initiator static private key + "init_static": "e61ef9919cde45dd5f82166404bd08e38bceb5dfdfded0a34c8df7ed542214d1" */ +static const uint8_t init_static[CRYPTO_SECRET_KEY_SIZE] = { 0xe6, 0x1e, 0xf9, 0x91, 0x9c, 0xde, 0x45, 0xdd, 0x5f, 0x82, 0x16, 0x64, 0x04, 0xbd, 0x08, 0xe3, 0x8b, 0xce, 0xb5, 0xdf, 0xdf, 0xde, 0xd0, 0xa3, 0x4c, 0x8d, 0xf7, 0xed, 0x54, 0x22, 0x14, 0xd1 }; -uint8_t init_ephemeral[32] = { +/* Initiator ephemeral private key + "init_ephemeral": "893e28b9dc6ca8d611ab664754b8ceb7bac5117349a4439a6b0569da977c464a" */ +static const uint8_t init_ephemeral[CRYPTO_SECRET_KEY_SIZE] = { 0x89, 0x3e, 0x28, 0xb9, 0xdc, 0x6c, 0xa8, 0xd6, 0x11, 0xab, 0x66, 0x47, 0x54, 0xb8, 0xce, 0xb7, 0xba, 0xc5, 0x11, 0x73, 0x49, 0xa4, 0x43, 0x9a, 0x6b, 0x05, 0x69, 0xda, 0x97, 0x7c, 0x46, 0x4a }; -uint8_t init_remote_static[32] = { +/* Responder static public key + "init_remote_static": "31e0303fd6418d2f8c0e78b91f22e8caed0fbe48656dcf4767e4834f701b8f62" */ +static const uint8_t init_remote_static[CRYPTO_PUBLIC_KEY_SIZE] = { 0x31, 0xe0, 0x30, 0x3f, 0xd6, 0x41, 0x8d, 0x2f, 0x8c, 0x0e, 0x78, 0xb9, 0x1f, 0x22, 0xe8, 0xca, 0xed, 0x0f, 0xbe, 0x48, 0x65, 0x6d, 0xcf, 0x47, 0x67, 0xe4, 0x83, 0x4f, 0x70, 0x1b, 0x8f, 0x62 }; -uint8_t resp_static[32] = { +/* Responder static private key + "resp_static": "4a3acbfdb163dec651dfa3194dece676d437029c62a408b4c5ea9114246e4893" */ +static const uint8_t resp_static[CRYPTO_SECRET_KEY_SIZE] = { 0x4a, 0x3a, 0xcb, 0xfd, 0xb1, 0x63, 0xde, 0xc6, 0x51, 0xdf, 0xa3, 0x19, 0x4d, 0xec, 0xe6, 0x76, 0xd4, 0x37, 0x02, 0x9c, 0x62, 0xa4, 0x08, 0xb4, 0xc5, 0xea, 0x91, 0x14, 0x24, 0x6e, 0x48, 0x93 }; -uint8_t resp_ephemeral[32] = { +/* Responder ephermal private key + "resp_ephemeral": "bbdb4cdbd309f1a1f2e1456967fe288cadd6f712d65dc7b7793d5e63da6b375b" */ +static const uint8_t resp_ephemeral[CRYPTO_SECRET_KEY_SIZE] = { 0xbb, 0xdb, 0x4c, 0xdb, 0xd3, 0x09, 0xf1, 0xa1, 0xf2, 0xe1, 0x45, 0x69, 0x67, 0xfe, 0x28, 0x8c, 0xad, 0xd6, 0xf7, 0x12, 0xd6, 0x5d, 0xc7, 0xb7, 0x79, 0x3d, 0x5e, 0x63, 0xda, 0x6b, 0x37, 0x5b }; -// 4c 75 64 77 69 67 20 76 6f 6e 20 4d 69 73 65 73 -uint8_t payload_hs_initiator[16] = { - 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f, - 0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 - }; - -// 4d 75 72 72 61 79 20 52 6f 74 68 62 61 72 64 -uint8_t payload_hs_responder[15] = { - 0x4d, 0x75, 0x72, 0x72, 0x61, 0x79, 0x20, 0x52, - 0x6f, 0x74, 0x68, 0x62, 0x61, 0x72, 0x64 - }; - -// 46 2e 20 41 2e 20 48 61 79 65 6b -uint8_t payload_transport_initiator1[11] = { - 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, 0x79, - 0x65, 0x6b - }; - -// 43 61 72 6c 20 4d 65 6e 67 65 72 -uint8_t payload_transport_responder1[11] = { - 0x43, 0x61, 0x72, 0x6c, 0x20, 0x4d, 0x65, 0x6e, 0x67, 0x65, 0x72 - }; - -// 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 -uint8_t payload_transport_initiator2[17] = { - 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, - 0x74, 0x65, 0x20, 0x53, 0x61, 0x79 +/* Payload for initiator handshake message + "payload": "4c756477696720766f6e204d69736573" */ +static const uint8_t init_payload_hs[16] = { + 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, + 0x6f,0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 +}; +/* "ciphertext": is actually three values for initiator handshake message: + Initiator ephemeral public key in plaintext: ca35def5ae56cec33dc2036731ab14896bc4c75dbb07a61f879f8e3afa4c7944 + Encrypted static public key (of initiator): 7a2281c0f1aee0c48c41333a1abbb349ee4bf12e09f8c4fd66635aabbb7dad345826d359e4bd6ebee659f5c6cb3d2d4e + Encrypted payload: d12f7c7ffc9fe5513818d9cf9b8778d1502f90649c42ab4a1e3df7199a3d6a13 */ +static const uint8_t init_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { + 0xca, 0x35, 0xde, 0xf5, 0xae, 0x56, 0xce, 0xc3, + 0x3d, 0xc2, 0x03, 0x67, 0x31, 0xab, 0x14, 0x89, + 0x6b, 0xc4, 0xc7, 0x5d, 0xbb, 0x07, 0xa6, 0x1f, + 0x87, 0x9f, 0x8e, 0x3a, 0xfa, 0x4c, 0x79, 0x44 +}; +static const uint8_t init_encrypted_static_public[CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE] = { + 0x7a, 0x22, 0x81, 0xc0, 0xf1, 0xae, 0xe0, 0xc4, + 0x8c, 0x41, 0x33, 0x3a, 0x1a, 0xbb, 0xb3, 0x49, + 0xee, 0x4b, 0xf1, 0x2e, 0x09, 0xf8, 0xc4, 0xfd, + 0x66, 0x63, 0x5a, 0xab, 0xbb, 0x7d, 0xad, 0x34, + 0x58, 0x26, 0xd3, 0x59, 0xe4, 0xbd, 0x6e, 0xbe, + 0xe6, 0x59, 0xf5, 0xc6, 0xcb, 0x3d, 0x2d, 0x4e +}; +static const uint8_t init_payload_hs_encrypted[sizeof(init_payload_hs)+CRYPTO_MAC_SIZE] = { + 0xd1, 0x2f, 0x7c, 0x7f, 0xfc, 0x9f, 0xe5, 0x51, + 0x38, 0x18, 0xd9, 0xcf, 0x9b, 0x87, 0x78, 0xd1, + 0x50, 0x2f, 0x90, 0x64, 0x9c, 0x42, 0xab, 0x4a, + 0x1e, 0x3d, 0xf7, 0x19, 0x9a, 0x3d, 0x6a, 0x13 +}; + +/* Payload for responder handshake message + "payload": "4d757272617920526f746862617264", */ +static const uint8_t resp_payload_hs[15] = { + 0x4d, 0x75, 0x72, 0x72, 0x61, 0x79, 0x20, 0x52, + 0x6f, 0x74, 0x68, 0x62, 0x61, 0x72, 0x64 +}; +/* "ciphertext": is actually two values for responder handshake message: + Responder ephemeral public key in plaintext: 95ebc60d2b1fa672c1f46a8aa265ef51bfe38e7ccb39ec5be34069f144808843 + Encrypted payload: f58050451a0edd2a40bb8b0f6b51ea63e1f1f429f1afd583e5d6e53f44da1e */ +static const uint8_t resp_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { + 0x95, 0xeb, 0xc6, 0x0d, 0x2b, 0x1f, 0xa6, 0x72, + 0xc1, 0xf4, 0x6a, 0x8a, 0xa2, 0x65, 0xef, 0x51, + 0xbf, 0xe3, 0x8e, 0x7c, 0xcb, 0x39, 0xec, 0x5b, + 0xe3, 0x40, 0x69, 0xf1, 0x44, 0x80, 0x88, 0x43 +}; +static const uint8_t resp_payload_hs_encrypted[sizeof(resp_payload_hs)+CRYPTO_MAC_SIZE] = { + 0xf5, 0x80, 0x50, 0x45, 0x1a, 0x0e, 0xdd, 0x2a, + 0x40, 0xbb, 0x8b, 0x0f, 0x6b, 0x51, 0xea, 0x63, + 0xe1, 0xf1, 0xf4, 0x29, 0xf1, 0xaf, 0xd5, 0x83, + 0xe5, 0xd6, 0xe5, 0x3f, 0x44, 0xda, 0x1e }; -// 45 75 67 65 6e 20 42 f6 68 6d 20 76 6f 6e 20 42 61 77 65 72 6b -uint8_t payload_transport_responder2[21] = { - 0x45, 0x75, 0x67, 0x65, 0x6e, 0x20, 0x42, 0xf6, 0x68, 0x6d, 0x20, - 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b - }; +/* Payload for initiator transport message 1 + "payload": "462e20412e20486179656b" */ +static const uint8_t init_payload_transport1[11] = { + 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, + 0x79, + 0x65, 0x6b +}; +/* Payload ciphertext for initiator transport message 1 + "ciphertext": "cae0b6af5460d026e80e22c27572a92048176872538f91a056a8df" */ +static const uint8_t init_payload_transport1_encrypted[sizeof(init_payload_transport1)+CRYPTO_MAC_SIZE] = { + 0xca, 0xe0, 0xb6, 0xaf, 0x54, 0x60, 0xd0, 0x26, + 0xe8, 0x0e, 0x22, 0xc2, 0x75, 0x72, 0xa9, 0x20, + 0x48, 0x17, 0x68, 0x72, 0x53, 0x8f, 0x91, 0xa0, + 0x56, 0xa8, 0xdf +}; -static void test_fast_known2(void) -{ - uint8_t k[CRYPTO_SHARED_KEY_SIZE]; - uint8_t m1[131]; - uint8_t m2[131]; - uint8_t xm1[131]; - uint8_t xm2[131]; - uint8_t c1[147]; - uint8_t c2[147]; - uint8_t xc1[147]; - uint8_t xc2[147]; - uint16_t xclen2, xmlen2; - unsigned long long mlen1 = 0; - unsigned long long clen1 = 0; - unsigned long long mlen2 = 0; - unsigned long long clen2 = 0; - unsigned long long xclen1 = 0; - unsigned long long xmlen1 = 0; - int result; - - uint8_t hash[CRYPTO_SHA512_SIZE]; - uint8_t send_key1[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t recv_key1[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t send_key2[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t recv_key2[CRYPTO_PUBLIC_KEY_SIZE]; +/* Payload for responder transport message 1 + "payload": "4361726c204d656e676572" */ +static const uint8_t resp_payload_transport1[11] = { + 0x43, 0x61, 0x72, 0x6c, 0x20, 0x4d, 0x65, 0x6e, + 0x67, 0x65, 0x72 +}; +/* Payload ciphertext for responder transport message 1 + "ciphertext": "ab1440d2b5892c638a11a7fa6412beaea5cee62342147f02d75a68" */ +static const uint8_t resp_payload_transport1_encrypted[sizeof(resp_payload_transport1)+CRYPTO_MAC_SIZE] = { + 0xab, 0x14 , 0x40 , 0xd2, 0xb5, 0x89, 0x2c, 0x63, + 0x8a, 0x11, 0xa7, 0xfa, 0x64, 0x12, 0xbe, 0xae, + 0xa5, 0xce, 0xe6, 0x23, 0x42, 0x14, 0x7f, 0x02, + 0xd7, 0x5a, 0x68 +}; - encrypt_precompute(bobpk, alicesk, k); +/* Final handshake hash value (MUST be the same for both initiator and responder) + "handshake_hash": "48d8b650f042c4767cf1f3c26b22ccdd4bc8cff341166603109954eab8a9bd20915d284b6b618a325e93a8e949a23f4b62ba3094aad0b640c14cbd4f14ccd1e1" */ +static const uint8_t handshake_hash[CRYPTO_SHA512_SIZE] = { + 0x48 ,0xd8, 0xb6, 0x50, 0xf0, 0x42, 0xc4, 0x76, + 0x7c, 0xf1, 0xf3, 0xc2, 0x6b, 0x22, 0xcc, 0xdd, + 0x4b, 0xc8, 0xcf, 0xf3, 0x41, 0x16, 0x66, 0x03, + 0x10, 0x99, 0x54, 0xea, 0xb8, 0xa9, 0xbd, 0x20, + 0x91, 0x5d, 0x28, 0x4b, 0x6b, 0x61, 0x8a, 0x32, + 0x5e, 0x93, 0xa8, 0xe9, 0x49, 0xa2, 0x3f, 0x4b, + 0x62, 0xba, 0x30, 0x94, 0xaa, 0xd0, 0xb6, 0x40, + 0xc1, 0x4c, 0xbd, 0x4f, 0x14, 0xcc, 0xd1, 0xe1 +}; - // ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), - // "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); - // ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - - // crypto_sha512(hash, k, CRYPTO_PUBLIC_KEY_SIZE); - // crypto_hkdf(send_key1, recv_key1, NULL, k, - // CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, 0, - // CRYPTO_PUBLIC_KEY_SIZE, hash); - - // char send_key1_string[CRYPTO_SHA512_SIZE * 2 + 1]; - // char recv_key1_string[CRYPTO_SHA512_SIZE * 2 + 1]; - // bin2hex_toupper(send_key1_string, sizeof(send_key1_string), send_key1, CRYPTO_PUBLIC_KEY_SIZE); - // bin2hex_toupper(recv_key1_string, sizeof(recv_key1_string), recv_key1, CRYPTO_PUBLIC_KEY_SIZE); - // printf("libsodium-HMAC: %s\n", send_key1_string); - // printf("libsodium-HMAC: %s\n", recv_key1_string); - - // crypto_hkdf_libsodium(send_key2, recv_key2, NULL, k, - // CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, 0, - // CRYPTO_PUBLIC_KEY_SIZE, hash); - - // char send_key2_string[CRYPTO_SHA512_SIZE * 2 + 1]; - // char recv_key2_string[CRYPTO_SHA512_SIZE * 2 + 1]; - // bin2hex_toupper(send_key2_string, sizeof(send_key2_string), send_key2, CRYPTO_PUBLIC_KEY_SIZE); - // bin2hex_toupper(recv_key2_string, sizeof(recv_key2_string), recv_key2, CRYPTO_PUBLIC_KEY_SIZE); - // printf("libsodium-HKDF: %s\n", send_key2_string); - // printf("libsodium-HKDF: %s\n", recv_key2_string); - - char ciphertext_hex[147 * 2 + 1]; - - /* All-zero nonces with matching length (8/12/24 bytes)*/ - /* crypto_aead_chacha20poly1305_encrypt */ - crypto_aead_chacha20poly1305_encrypt(c1, &clen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_chacha20, k); - bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c1, clen1); - printf("crypto_aead_chacha20poly1305_encrypt: %s\n", ciphertext_hex); - /* crypto_aead_chacha20poly1305_ietf_encrypt */ - crypto_aead_chacha20poly1305_ietf_encrypt(c2, &clen2, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_chacha20_ietf, k); - bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c2, clen2); - printf("crypto_aead_chacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); - /* crypto_aead_xchacha20poly1305_ietf_encrypt */ - crypto_aead_xchacha20poly1305_ietf_encrypt(xc1, &xclen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_xchacha20, k); - bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc1, xclen1); - printf("crypto_aead_xchacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); - /* Tox crypto_core XChaCha20 */ - clen2 = encrypt_data_symmetric_xaead(k, test_nonce_xchacha20, test_m, sizeof(test_m) / sizeof(uint8_t), xc2, NULL, 0); - bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc2, xclen2); - printf("encrypt_data_symmetric_xaead(XChaCha20): %s\n", ciphertext_hex); - - /* nonce with only one zero byte => different results! */ - /* crypto_aead_chacha20poly1305_encrypt */ - // crypto_aead_chacha20poly1305_encrypt(c1, &clen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); - // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c1, clen1); - // printf("crypto_aead_chacha20poly1305_encrypt: %s\n", ciphertext_hex); - // /* crypto_aead_chacha20poly1305_ietf_encrypt */ - // crypto_aead_chacha20poly1305_ietf_encrypt(c2, &clen2, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); - // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c2, clen2); - // printf("crypto_aead_chacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); - // /* crypto_aead_xchacha20poly1305_ietf_encrypt */ - // crypto_aead_xchacha20poly1305_ietf_encrypt(xc1, &xclen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); - // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc1, xclen1); - // printf("crypto_aead_xchacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); - // /* Tox crypto_core XChaCha20 */ - // clen2 = encrypt_data_symmetric_xaead(k, test_nonce_one_zero_byte, test_m, sizeof(test_m) / sizeof(uint8_t), xc2, NULL, 0); - // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc2, xclen2); - // printf("encrypt_data_symmetric_xaead(XChaCha20): %s\n", ciphertext_hex); - - - // ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); - // ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - - // char correct_plain[131 * 2 + 1]; - // char plaintext_hex[147 * 2 + 1]; - // bin2hex_toupper(correct_plain, sizeof(correct_plain), test_m, 131); - // printf("Correct Plaintext: %s\n", correct_plain); - - // /* All-zero nonces with matching length (8/12/24 bytes)*/ - // /* crypto_aead_chacha20poly1305_decrypt */ - // result = crypto_aead_chacha20poly1305_decrypt(m1, &mlen1, NULL, c1, clen1, NULL, 0, test_nonce_chacha20, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m1, mlen1); - // printf("crypto_aead_chacha20poly1305_decrypt: %d, %s\n", result, plaintext_hex); - // /* crypto_aead_chacha20poly1305_ietf_decrypt */ - // result = crypto_aead_chacha20poly1305_ietf_decrypt(m2, &mlen2, NULL, c2, clen2, NULL, 0, test_nonce_chacha20_ietf, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m2, mlen2); - // printf("crypto_aead_chacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); - // /* crypto_aead_xchacha20poly1305_ietf_decrypt */ - // result = crypto_aead_xchacha20poly1305_ietf_decrypt(xm1, &xmlen1, NULL, xc1, xclen1, NULL, 0, test_nonce_xchacha20, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm1, xmlen1); - // printf("crypto_aead_xchacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); - // /* Tox crypto_core XChaCha20 */ - // xmlen2 = decrypt_data_symmetric_xaead(k, test_nonce_xchacha20, xc2, xclen2, xm2, NULL, 0); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm2, xmlen2); - // printf("decrypt_data_symmetric_xaead(XChaCha20): %s\n", plaintext_hex); - - /* nonce with only one zero byte */ - /* crypto_aead_chacha20poly1305_decrypt */ - // result = crypto_aead_chacha20poly1305_decrypt(m1, &mlen1, NULL, c1, clen1, NULL, 0, test_nonce_one_zero_byte, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m1, mlen1); - // printf("crypto_aead_chacha20poly1305_decrypt: %d, %s\n", result, plaintext_hex); - // /* crypto_aead_chacha20poly1305_ietf_decrypt */ - // result = crypto_aead_chacha20poly1305_ietf_decrypt(m2, &mlen2, NULL, c2, clen2, NULL, 0, test_nonce_one_zero_byte, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m2, mlen2); - // printf("crypto_aead_chacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); - // /* crypto_aead_xchacha20poly1305_ietf_decrypt */ - // result = crypto_aead_xchacha20poly1305_ietf_decrypt(xm1, &xmlen1, NULL, xc1, xclen1, NULL, 0, test_nonce_one_zero_byte, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm1, xmlen1); - // printf("crypto_aead_xchacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); - // /* Tox crypto_core XChaCha20 */ - // xmlen2 = decrypt_data_symmetric_xaead(k, test_nonce_one_zero_byte, xc2, xclen2, xm2, NULL, 0); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm2, xmlen2); - // printf("decrypt_data_symmetric_xaead(XChaCha20): %s\n", plaintext_hex); - - // ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); - // ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); - - char h_print[CRYPTO_SHA512_SIZE * 2 + 1]; - char ck_print[CRYPTO_SHA512_SIZE * 2 + 1]; - char key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - - // INITIATOR: Create handshake packet for responder +/* Currently unused */ +// // 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 +// static const uint8_t init_payload_transport2[17] = { +// 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, +// 0x74, 0x65, 0x20, 0x53, 0x61, 0x79 +// }; + +// // 45 75 67 65 6e 20 42 f6 68 6d 20 76 6f 6e 20 42 61 77 65 72 6b +// static const uint8_t payload_transport_responder2[21] = { +// 0x45, 0x75, 0x67, 0x65, 0x6e, 0x20, 0x42, 0xf6, 0x68, 0x6d, 0x20, +// 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b +// }; + +static void test_noiseik() { + /* INITIATOR: Create handshake packet for responder */ Noise_Handshake *noise_handshake_initiator = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); /* Troubleshooting info, intermediary values */ @@ -380,7 +528,7 @@ static void test_fast_known2(void) // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); // printf("noise_handshake->chaining_key: %s\n", ck_print); - noise_handshake_init(nullptr, noise_handshake_initiator, init_static, init_remote_static, true); + noise_handshake_init(nullptr, noise_handshake_initiator, init_static, init_remote_static, true, prologue, sizeof(prologue)); /* Troubleshooting info, intermediary values */ // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); @@ -391,15 +539,21 @@ static void test_fast_known2(void) memcpy(noise_handshake_initiator->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(noise_handshake_initiator->ephemeral_public, init_ephemeral); - char ephemeral_public_print[32 * 2 + 1]; - bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - printf("ephemeral_public_print: %s\n", ephemeral_public_print); + ck_assert_msg(memcmp(noise_handshake_initiator->ephemeral_public, init_ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE) == 0, "initiator ephemeral public keys differ"); - char resp_static_print[32 * 2 + 1]; - uint8_t resp_static_pub[32]; + /* Troubleshooting info, intermediary values */ + // char ephemeral_public_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + // printf("ephemeral_public_print: %s\n", ephemeral_public_print); + + uint8_t resp_static_pub[CRYPTO_PUBLIC_KEY_SIZE]; crypto_derive_public_key(resp_static_pub, resp_static); - bin2hex_toupper(resp_static_print, sizeof(resp_static_print), resp_static_pub, CRYPTO_PUBLIC_KEY_SIZE); - printf("resp_static_pub: %s\n", resp_static_print); + ck_assert_msg(memcmp(resp_static_pub, init_remote_static, CRYPTO_PUBLIC_KEY_SIZE) == 0, "responder static public keys differ"); + + /* Troubleshooting info, intermediary values */ + // char resp_static_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bin2hex_toupper(resp_static_print, sizeof(resp_static_print), resp_static_pub, CRYPTO_PUBLIC_KEY_SIZE); + // printf("resp_static_pub: %s\n", resp_static_print); /* e */ noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -431,9 +585,12 @@ static void test_fast_known2(void) noise_encrypt_and_hash(ciphertext1, noise_handshake_initiator->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake_initiator->hash); - char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; - bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); - printf("Initiator: HS ciphertext static pub key: %s\n", ciphertext1_print); + ck_assert_msg(memcmp(ciphertext1, init_encrypted_static_public, CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE) == 0, "initiator encrypted static public keys differ"); + + /* Troubleshooting info, intermediary values */ + // char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; + // bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); + // printf("Initiator: HS ciphertext static pub key: %s\n", ciphertext1_print); //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; @@ -449,7 +606,7 @@ static void test_fast_known2(void) /* Noise Handshake Payload */ // uint8_t handshake_payload_plain[15]; - uint8_t ciphertext2[sizeof(payload_hs_initiator) + CRYPTO_MAC_SIZE]; + uint8_t ciphertext2[sizeof(init_payload_hs) + CRYPTO_MAC_SIZE]; //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 /* Add Handshake payload nonce */ @@ -460,12 +617,15 @@ static void test_fast_known2(void) /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(ciphertext2, - payload_hs_initiator, sizeof(payload_hs_initiator), noise_handshake_temp_key, + init_payload_hs, sizeof(init_payload_hs), noise_handshake_temp_key, noise_handshake_initiator->hash); - char ciphertext2_print[sizeof(ciphertext2) * 2 + 1]; - bin2hex_toupper(ciphertext2_print, sizeof(ciphertext2_print), ciphertext2, sizeof(ciphertext2)); - printf("Initiator: HS ciphertext payload: %s\n", ciphertext2_print); + ck_assert_msg(memcmp(ciphertext2, init_payload_hs_encrypted, sizeof(init_payload_hs_encrypted)) == 0, "initiator encrypted handshake payloads differ"); + + /* Troubleshooting info, intermediary values */ + // char ciphertext2_print[sizeof(ciphertext2) * 2 + 1]; + // bin2hex_toupper(ciphertext2_print, sizeof(ciphertext2_print), ciphertext2, sizeof(ciphertext2)); + // printf("Initiator: HS ciphertext payload: %s\n", ciphertext2_print); // INITIATOR: END Create handshake packet for responder @@ -478,13 +638,16 @@ static void test_fast_known2(void) // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); // printf("noise_handshake->chaining_key: %s\n", ck_print); - char init_static_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + uint8_t init_static_pub[CRYPTO_PUBLIC_KEY_SIZE]; crypto_derive_public_key(init_static_pub, init_static); - bin2hex_toupper(init_static_print, sizeof(init_static_print), init_static_pub, CRYPTO_PUBLIC_KEY_SIZE); - printf("init_static_pub: %s\n", init_static_print); - noise_handshake_init(nullptr, noise_handshake_responder, resp_static, init_static_pub, false); + /* Troubleshooting info, intermediary values */ + // char init_static_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bin2hex_toupper(init_static_print, sizeof(init_static_print), init_static_pub, CRYPTO_PUBLIC_KEY_SIZE); + // printf("init_static_pub: %s\n", init_static_print); + + noise_handshake_init(nullptr, noise_handshake_responder, resp_static, init_static_pub, false, prologue, sizeof(prologue)); /* e */ memcpy(noise_handshake_responder->remote_ephemeral, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -504,7 +667,7 @@ static void test_fast_known2(void) noise_handshake_responder->remote_static); /* Payload decryption */ - uint8_t handshake_payload_plain_initiator[sizeof(payload_hs_initiator)]; + uint8_t handshake_payload_plain_initiator[sizeof(init_payload_hs)]; noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext2, sizeof(ciphertext2), noise_handshake_temp_key_resp, noise_handshake_responder->hash); @@ -515,9 +678,12 @@ static void test_fast_known2(void) memcpy(noise_handshake_responder->ephemeral_private, resp_ephemeral, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(noise_handshake_responder->ephemeral_public, resp_ephemeral); - char ephemeral_public_print_responder[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bin2hex_toupper(ephemeral_public_print_responder, sizeof(ephemeral_public_print_responder), noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - printf("Responder ephemeral public:: %s\n", ephemeral_public_print_responder); + ck_assert_msg(memcmp(noise_handshake_responder->ephemeral_public, resp_ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE) == 0, "responder ephemeral public keys differ"); + + /* Troubleshooting info, intermediary values */ + // char ephemeral_public_print_responder[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bin2hex_toupper(ephemeral_public_print_responder, sizeof(ephemeral_public_print_responder), noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + // printf("Responder ephemeral public: %s\n", ephemeral_public_print_responder); /* e */ noise_mix_hash(noise_handshake_responder->hash, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -533,14 +699,17 @@ static void test_fast_known2(void) /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ - uint8_t ciphertext3_hs_responder[sizeof(payload_hs_responder) + CRYPTO_MAC_SIZE]; + uint8_t ciphertext3_hs_responder[sizeof(resp_payload_hs) + CRYPTO_MAC_SIZE]; noise_encrypt_and_hash(ciphertext3_hs_responder, - payload_hs_responder, sizeof(payload_hs_responder), noise_handshake_temp_key_resp2, + resp_payload_hs, sizeof(resp_payload_hs), noise_handshake_temp_key_resp2, noise_handshake_responder->hash); - char ciphertext3_print[sizeof(ciphertext3_hs_responder) * 2 + 1]; - bin2hex_toupper(ciphertext3_print, sizeof(ciphertext3_print), ciphertext3_hs_responder, sizeof(ciphertext3_hs_responder)); - printf("Responder: HS ciphertext payload: %s\n", ciphertext3_print); + ck_assert_msg(memcmp(ciphertext3_hs_responder, resp_payload_hs_encrypted, sizeof(resp_payload_hs_encrypted)) == 0, "responder encrypted handshake payloads differ"); + + /* Troubleshooting info, intermediary values */ + // char ciphertext3_print[sizeof(ciphertext3_hs_responder) * 2 + 1]; + // bin2hex_toupper(ciphertext3_print, sizeof(ciphertext3_print), ciphertext3_hs_responder, sizeof(ciphertext3_hs_responder)); + // printf("Responder: HS ciphertext payload: %s\n", ciphertext3_print); // RESPONDER: END create handshake packet for initiator# @@ -557,10 +726,10 @@ static void test_fast_known2(void) noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->static_private, noise_handshake_initiator->remote_ephemeral); - uint8_t handshake_payload_plain_responder[sizeof(payload_hs_responder)]; + uint8_t handshake_payload_plain_responder[sizeof(resp_payload_hs)]; if(noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext3_hs_responder, sizeof(ciphertext3_hs_responder), noise_handshake_temp_key_init, - noise_handshake_initiator->hash) != sizeof(payload_hs_responder)) { + noise_handshake_initiator->hash) != sizeof(resp_payload_hs)) { printf("Initiator: HS decryption failed\n"); } @@ -570,9 +739,12 @@ static void test_fast_known2(void) crypto_hkdf(initiator_send_key, CRYPTO_SHARED_KEY_SIZE, initiator_recv_key, CRYPTO_SHARED_KEY_SIZE, nullptr, 0, noise_handshake_initiator->chaining_key); - char handshake_hash_initiator_print[sizeof(noise_handshake_initiator->hash) * 2 + 1]; - bin2hex_toupper(handshake_hash_initiator_print, sizeof(handshake_hash_initiator_print), noise_handshake_initiator->hash, sizeof(noise_handshake_initiator->hash)); - printf("Initiator: final handshake hash: %s\n", handshake_hash_initiator_print); + ck_assert_msg(memcmp(noise_handshake_initiator->hash, handshake_hash, CRYPTO_SHA512_SIZE) == 0, "initiator handshake hash differ"); + + /* Troubleshooting info, intermediary values */ + // char handshake_hash_initiator_print[sizeof(noise_handshake_initiator->hash) * 2 + 1]; + // bin2hex_toupper(handshake_hash_initiator_print, sizeof(handshake_hash_initiator_print), noise_handshake_initiator->hash, sizeof(noise_handshake_initiator->hash)); + // printf("Initiator: final handshake hash: %s\n", handshake_hash_initiator_print); /* Troubleshooting info, intermediary values */ // char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; @@ -582,22 +754,28 @@ static void test_fast_known2(void) // bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); // printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); - uint8_t ciphertext4_transport1_initiator[sizeof(payload_transport_initiator1) + CRYPTO_MAC_SIZE]; + uint8_t ciphertext4_transport1_initiator[sizeof(init_payload_transport1) + CRYPTO_MAC_SIZE]; uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; - int32_t length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, payload_transport_initiator1, sizeof(payload_transport_initiator1), ciphertext4_transport1_initiator, nullptr, 0); + int32_t length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, init_payload_transport1, sizeof(init_payload_transport1), ciphertext4_transport1_initiator, nullptr, 0); - char ciphertext4_transport1_initiator_print[sizeof(ciphertext4_transport1_initiator) * 2 + 1]; - bin2hex_toupper(ciphertext4_transport1_initiator_print, sizeof(ciphertext4_transport1_initiator_print), ciphertext4_transport1_initiator, sizeof(ciphertext4_transport1_initiator)); - printf("Initiator: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext4_transport1_initiator_print); + ck_assert_msg(memcmp(ciphertext4_transport1_initiator, init_payload_transport1_encrypted, sizeof(init_payload_transport1_encrypted)) == 0, "initiator transport1 ciphertext differ"); + + /* Troubleshooting info, intermediary values */ + // char ciphertext4_transport1_initiator_print[sizeof(ciphertext4_transport1_initiator) * 2 + 1]; + // bin2hex_toupper(ciphertext4_transport1_initiator_print, sizeof(ciphertext4_transport1_initiator_print), ciphertext4_transport1_initiator, sizeof(ciphertext4_transport1_initiator)); + // printf("Initiator: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext4_transport1_initiator_print); /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ uint8_t responder_send_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t responder_recv_key[CRYPTO_SHARED_KEY_SIZE]; crypto_hkdf(responder_recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, responder_send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, noise_handshake_responder->chaining_key); - char handshake_hash_responder_print[sizeof(noise_handshake_responder->hash) * 2 + 1]; - bin2hex_toupper(handshake_hash_responder_print, sizeof(handshake_hash_responder_print), noise_handshake_responder->hash, sizeof(noise_handshake_responder->hash)); - printf("Responder: final handshake hash: %s\n", handshake_hash_responder_print); + ck_assert_msg(memcmp(noise_handshake_responder->hash, handshake_hash, CRYPTO_SHA512_SIZE) == 0, "responder handshake hash differ"); + + /* Troubleshooting info, intermediary values */ + // char handshake_hash_responder_print[sizeof(noise_handshake_responder->hash) * 2 + 1]; + // bin2hex_toupper(handshake_hash_responder_print, sizeof(handshake_hash_responder_print), noise_handshake_responder->hash, sizeof(noise_handshake_responder->hash)); + // printf("Responder: final handshake hash: %s\n", handshake_hash_responder_print); /* Troubleshooting info, intermediary values */ // char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; @@ -607,261 +785,31 @@ static void test_fast_known2(void) // bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); // printf("responder_recv_key_print: %s\n", responder_recv_key_print); - uint8_t ciphertext5_transport1_responder[sizeof(payload_transport_responder1) + CRYPTO_MAC_SIZE]; + uint8_t ciphertext5_transport1_responder[sizeof(resp_payload_transport1) + CRYPTO_MAC_SIZE]; int32_t length_ciphertext5_transport1_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, - payload_transport_responder1, sizeof(payload_transport_responder1), ciphertext5_transport1_responder, nullptr, 0); - - char ciphertext5_transport1_responder_print[sizeof(ciphertext5_transport1_responder) * 2 + 1]; - bin2hex_toupper(ciphertext5_transport1_responder_print, sizeof(ciphertext5_transport1_responder_print), ciphertext5_transport1_responder, sizeof(ciphertext5_transport1_responder)); - printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext5_transport1_responder_print); - - sodium_increment(nonce_chacha20_ietf, CRYPTO_NOISEIK_NONCE_SIZE); - // uint8_t nonce_chacha20_ietf_1[CRYPTO_NOISEIK_NONCE_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00, - // 0x00, 0x01 }; - uint8_t ciphertext6_transport2_initiator[sizeof(payload_transport_initiator2) + CRYPTO_MAC_SIZE]; - int32_t ciphertext6_transport2_initiator_length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, - payload_transport_initiator2, sizeof(payload_transport_initiator2), ciphertext6_transport2_initiator, nullptr, 0); - - char ciphertext6_transport2_initiator_print[sizeof(ciphertext6_transport2_initiator) * 2 + 1]; - bin2hex_toupper(ciphertext6_transport2_initiator_print, sizeof(ciphertext6_transport2_initiator_print), - ciphertext6_transport2_initiator, sizeof(ciphertext6_transport2_initiator)); - printf("Initiator: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext6_transport2_initiator_print); - - uint8_t ciphertext7_transport2_responder[sizeof(payload_transport_responder2) + CRYPTO_MAC_SIZE]; - int32_t length_ciphertext7_transport2_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, - payload_transport_responder2, sizeof(payload_transport_responder2), ciphertext7_transport2_responder, nullptr, 0); - - char ciphertext7_transport2_responder_print[sizeof(ciphertext7_transport2_responder) * 2 + 1]; - bin2hex_toupper(ciphertext7_transport2_responder_print, sizeof(ciphertext7_transport2_responder_print), - ciphertext7_transport2_responder, sizeof(ciphertext7_transport2_responder)); - printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext7_transport2_responder_print); - - -} - -// 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]; -// uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; -// uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; -// uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; -// uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; -// uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; - -// uint8_t n[CRYPTO_NONCE_SIZE]; - -// enum { M_SIZE = 50 }; -// uint8_t m[M_SIZE]; -// uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; -// uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; -// uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; -// uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; -// uint8_t m1[sizeof(m)]; -// uint8_t m2[sizeof(m)]; -// uint8_t m3[sizeof(m)]; -// uint8_t m4[sizeof(m)]; - -// //Generate random message (random length from 10 to 50) -// const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; -// rand_bytes(rng, m, mlen); -// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - -// //Generate keypairs -// crypto_new_keypair(rng, pk1, sk1); -// crypto_new_keypair(rng, pk2, sk2); - -// //Precompute shared keys -// encrypt_precompute(pk2, sk1, k1); -// encrypt_precompute(pk1, sk2, k2); - -// ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); - -// //Encrypt all four ways -// const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); -// const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); -// const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); -// const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); - -// ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); -// ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); -// ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 -// && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); - -// //Decrypt all four ways -// const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); -// const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); -// const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); -// const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); - -// ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); -// ck_assert_msg(m1len == mlen, "wrong decrypted text length"); -// ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 -// && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); -// ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); -// } -// } - -// 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]; - -// const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; -// uint8_t *m1 = (uint8_t *)malloc(m1_size); -// uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); -// uint8_t *m1prime = (uint8_t *)malloc(m1_size); - -// const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; -// uint8_t *m2 = (uint8_t *)malloc(m2_size); -// uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); - -// ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); - -// //Generate random messages -// rand_bytes(rng, m1, m1_size); -// rand_bytes(rng, m2, m2_size); -// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - -// //Generate key -// 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); - -// ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); -// ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); - -// const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - -// ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); -// ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - -// free(c2); -// free(m2); -// free(m1prime); -// free(c1); -// free(m1); -// } - -// 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]; - -// const size_t m1_size = 16 * 16 * 16; -// uint8_t *m1 = (uint8_t *)malloc(m1_size); -// uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); -// uint8_t *m1prime = (uint8_t *)malloc(m1_size); - -// ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); - -// //Generate random messages -// rand_bytes(rng, m1, m1_size); -// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); + resp_payload_transport1, sizeof(resp_payload_transport1), ciphertext5_transport1_responder, nullptr, 0); -// //Generate key -// new_symmetric_key(rng, k); + ck_assert_msg(memcmp(ciphertext5_transport1_responder, resp_payload_transport1_encrypted, sizeof(resp_payload_transport1_encrypted)) == 0, "responder transport1 ciphertext differ"); -// const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); -// ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data"); - -// const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - -// ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); -// ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - -// free(m1prime); -// free(c1); -// free(m1); -// } - -static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) -{ - uint32_t num1, num2; - memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); - num1 = net_ntohl(num1); - num2 = num + num1; - - if (num2 < num1) { - for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { - ++nonce[i - 1]; - - if (nonce[i - 1] != 0) { - break; - } - } - } - - num2 = net_htonl(num2); - memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); -} - -// 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(rng); -// } - -// uint8_t n1[CRYPTO_NONCE_SIZE]; - -// memcpy(n1, n, CRYPTO_NONCE_SIZE); - -// for (i = 0; i < (1 << 18); ++i) { -// increment_nonce_number_cmp(n, 1); -// increment_nonce(n1); -// ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); -// } - -// for (i = 0; i < (1 << 18); ++i) { -// 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"); -// } -// } - -static void test_memzero(void) -{ - uint8_t src[sizeof(test_c)]; - memcpy(src, test_c, sizeof(test_c)); - - crypto_memzero(src, sizeof(src)); - size_t i; - - for (i = 0; i < sizeof(src); i++) { - ck_assert_msg(src[i] == 0, "Memory is not zeroed"); - } + /* Troubleshooting info, intermediary values */ + // char ciphertext5_transport1_responder_print[sizeof(ciphertext5_transport1_responder) * 2 + 1]; + // bin2hex_toupper(ciphertext5_transport1_responder_print, sizeof(ciphertext5_transport1_responder_print), ciphertext5_transport1_responder, sizeof(ciphertext5_transport1_responder)); + // printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length_ciphertext5_transport1_responder, ciphertext5_transport1_responder_print); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); - // test_known(); - // test_fast_known(); - test_fast_known2(); - // test_endtoend(); /* waiting up to 15 seconds */ - // test_large_data(); - // test_large_data_symmetric(); - // test_increment_nonce(); - // test_memzero(); + test_known(); + test_fast_known(); + test_endtoend(); /* waiting up to 15 seconds */ + test_large_data(); + test_large_data_symmetric(); + test_very_large_data(); + test_increment_nonce(); + test_memzero(); + test_noiseik(); return 0; } diff --git a/auto_tests/crypto_test.c.real b/auto_tests/crypto_test.c.real deleted file mode 100644 index 83f8c525a6..0000000000 --- a/auto_tests/crypto_test.c.real +++ /dev/null @@ -1,372 +0,0 @@ -#include -#include -#include - -#include "../testing/misc_tools.h" -#include "../toxcore/crypto_core.h" -#include "../toxcore/net_crypto.h" -#include "check_compat.h" - -static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) -{ - for (size_t i = 0; i < blen; i++) { - b[i] = random_u08(rng); - } -} - -// These test vectors are from libsodium's test suite - -static const uint8_t alicesk[32] = { - 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, - 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, - 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, - 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a -}; - -static const uint8_t bobpk[32] = { - 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, - 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, - 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, - 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f -}; - -static const uint8_t test_nonce[24] = { - 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, - 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6, - 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 -}; - -static const uint8_t test_m[131] = { - 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, - 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, - 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, - 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc, - 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, - 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, - 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4, - 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, - 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, - 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57, - 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, - 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, - 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd, - 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, - 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, - 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64, - 0x5e, 0x07, 0x05 -}; - -static const uint8_t test_c[147] = { - 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, - 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, - 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, - 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, - 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, - 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, - 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, - 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, - 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, - 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, - 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, - 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, - 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, - 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, - 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, - 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, - 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, - 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, - 0xe3, 0x55, 0xa5 -}; - -static void test_known(void) -{ - uint8_t c[147]; - uint8_t m[131]; - - ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), - "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); - ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); - ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - - const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); - - ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); - ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - - const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); - - ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); - ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); -} - -static void test_fast_known(void) -{ - uint8_t k[CRYPTO_SHARED_KEY_SIZE]; - uint8_t c[147]; - uint8_t m[131]; - - encrypt_precompute(bobpk, alicesk, k); - - ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), - "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); - ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); - ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - - const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); - - ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); - ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - - const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); - - ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); - ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); -} - -static void test_endtoend(void) -{ - const Random *rng = os_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]; - uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; - uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; - uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; - uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; - - uint8_t n[CRYPTO_NONCE_SIZE]; - - enum { M_SIZE = 50 }; - uint8_t m[M_SIZE]; - uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; - uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; - uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; - uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; - uint8_t m1[sizeof(m)]; - uint8_t m2[sizeof(m)]; - uint8_t m3[sizeof(m)]; - uint8_t m4[sizeof(m)]; - - //Generate random message (random length from 10 to 50) - const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; - rand_bytes(rng, m, mlen); - rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - - //Generate keypairs - crypto_new_keypair(rng, pk1, sk1); - crypto_new_keypair(rng, pk2, sk2); - - //Precompute shared keys - encrypt_precompute(pk2, sk1, k1); - encrypt_precompute(pk1, sk2, k2); - - ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); - - //Encrypt all four ways - const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); - const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); - const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); - const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); - - ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); - ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); - ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 - && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); - - //Decrypt all four ways - const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); - const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); - const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); - const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); - - ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); - ck_assert_msg(m1len == mlen, "wrong decrypted text length"); - ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 - && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); - ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); - } -} - -static void test_large_data(void) -{ - const Random *rng = os_random(); - ck_assert(rng != nullptr); - uint8_t k[CRYPTO_SHARED_KEY_SIZE]; - uint8_t n[CRYPTO_NONCE_SIZE]; - - const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; - uint8_t *m1 = (uint8_t *)malloc(m1_size); - uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); - uint8_t *m1prime = (uint8_t *)malloc(m1_size); - - const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; - uint8_t *m2 = (uint8_t *)malloc(m2_size); - uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); - - ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); - - //Generate random messages - rand_bytes(rng, m1, m1_size); - rand_bytes(rng, m2, m2_size); - rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - - //Generate key - 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); - - ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); - ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); - - const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - - ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); - ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - - free(c2); - free(m2); - free(m1prime); - free(c1); - free(m1); -} - -static void test_large_data_symmetric(void) -{ - const Random *rng = os_random(); - ck_assert(rng != nullptr); - uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; - - uint8_t n[CRYPTO_NONCE_SIZE]; - - const size_t m1_size = 16 * 16 * 16; - uint8_t *m1 = (uint8_t *)malloc(m1_size); - uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); - uint8_t *m1prime = (uint8_t *)malloc(m1_size); - - ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); - - //Generate random messages - rand_bytes(rng, m1, m1_size); - rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - - //Generate key - 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"); - - const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - - ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); - ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - - free(m1prime); - free(c1); - free(m1); -} - -static void test_very_large_data(void) -{ - const Random *rng = os_random(); - ck_assert(rng != nullptr); - - const uint8_t nonce[CRYPTO_NONCE_SIZE] = {0}; - uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk[CRYPTO_SECRET_KEY_SIZE]; - crypto_new_keypair(rng, pk, sk); - - // 100 MiB of data (all zeroes, doesn't matter what's inside). - const uint32_t plain_size = 100 * 1024 * 1024; - uint8_t *plain = (uint8_t *)malloc(plain_size); - uint8_t *encrypted = (uint8_t *)malloc(plain_size + CRYPTO_MAC_SIZE); - - ck_assert(plain != nullptr); - ck_assert(encrypted != nullptr); - - encrypt_data(pk, sk, nonce, plain, plain_size, encrypted); - - free(encrypted); - free(plain); -} - -static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) -{ - uint32_t num1 = 0; - memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); - num1 = net_ntohl(num1); - uint32_t num2 = num + num1; - - if (num2 < num1) { - for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { - ++nonce[i - 1]; - - if (nonce[i - 1] != 0) { - break; - } - } - } - - num2 = net_htonl(num2); - memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); -} - -static void test_increment_nonce(void) -{ - const Random *rng = os_random(); - ck_assert(rng != nullptr); - - uint8_t n[CRYPTO_NONCE_SIZE]; - - for (uint32_t i = 0; i < CRYPTO_NONCE_SIZE; ++i) { - n[i] = random_u08(rng); - } - - uint8_t n1[CRYPTO_NONCE_SIZE]; - - memcpy(n1, n, CRYPTO_NONCE_SIZE); - - for (uint32_t i = 0; i < (1 << 18); ++i) { - increment_nonce_number_cmp(n, 1); - increment_nonce(n1); - ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); - } - - for (uint32_t i = 0; i < (1 << 18); ++i) { - 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"); - } -} - -static void test_memzero(void) -{ - uint8_t src[sizeof(test_c)]; - memcpy(src, test_c, sizeof(test_c)); - - crypto_memzero(src, sizeof(src)); - - for (size_t i = 0; i < sizeof(src); i++) { - ck_assert_msg(src[i] == 0, "Memory is not zeroed"); - } -} - -int main(void) -{ - setvbuf(stdout, nullptr, _IONBF, 0); - - test_known(); - test_fast_known(); - test_endtoend(); /* waiting up to 15 seconds */ - test_large_data(); - test_large_data_symmetric(); - test_very_large_data(); - test_increment_nonce(); - test_memzero(); - - return 0; -} diff --git a/auto_tests/crypto_test_NoiseIK_test_vectors.c b/auto_tests/crypto_test_NoiseIK_test_vectors.c deleted file mode 100644 index 2fa8c37652..0000000000 --- a/auto_tests/crypto_test_NoiseIK_test_vectors.c +++ /dev/null @@ -1,868 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "../testing/misc_tools.h" -#include "../toxcore/crypto_core.h" -#include "../toxcore/net_crypto.h" -#include "check_compat.h" -#include "../other/fun/create_common.h" -#include "../toxcore/mem.h" - -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(rng); - } -} - -// These test vectors are from libsodium's test suite - -static const uint8_t alicesk[32] = { - 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, - 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, - 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, - 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a -}; - -static const uint8_t bobpk[32] = { - 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, - 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, - 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, - 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f -}; - -static const uint8_t test_nonce[24] = { - 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, - 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6, - 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 -}; - -static const uint8_t test_m[131] = { - 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, - 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, - 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, - 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc, - 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, - 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, - 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4, - 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, - 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, - 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57, - 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, - 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, - 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd, - 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, - 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, - 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64, - 0x5e, 0x07, 0x05 -}; - -static const uint8_t test_c[147] = { - 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, - 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, - 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, - 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, - 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, - 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, - 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, - 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, - 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, - 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, - 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, - 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, - 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, - 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, - 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, - 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, - 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, - 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, - 0xe3, 0x55, 0xa5 -}; - -static void test_known(void) -{ - uint8_t c[147]; - uint8_t m[131]; - uint16_t clen, mlen; - - ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), - "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); - ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); - ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - - clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); - - ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); - ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - - mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); - - ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); - ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); -} - -static void test_fast_known(void) -{ - uint8_t k[CRYPTO_SHARED_KEY_SIZE]; - uint8_t c[147]; - uint8_t m[131]; - uint16_t clen, mlen; - - encrypt_precompute(bobpk, alicesk, k); - - ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), - "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); - ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); - ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - - clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); - - ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); - ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - - mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); - - ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); - ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); -} - -static const uint8_t test_nonce_chacha20[8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const uint8_t test_nonce_chacha20_ietf[12] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -static const uint8_t test_nonce_xchacha20[24] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const uint8_t test_nonce_one_zero_byte[1] = { - 0x00 -}; - -static const uint8_t prologue[11] = { - 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x31, 0x32, 0x33 -}; - -uint8_t init_static[32] = { - 0xe6, 0x1e, 0xf9, 0x91, 0x9c, 0xde, 0x45, 0xdd, - 0x5f, 0x82, 0x16, 0x64, 0x04, 0xbd, 0x08, 0xe3, - 0x8b, 0xce, 0xb5, 0xdf, 0xdf, 0xde, 0xd0, 0xa3, - 0x4c, 0x8d, 0xf7, 0xed, 0x54, 0x22, 0x14, 0xd1 -}; - -uint8_t init_ephemeral[32] = { - 0x89, 0x3e, 0x28, 0xb9, 0xdc, 0x6c, 0xa8, 0xd6, - 0x11, 0xab, 0x66, 0x47, 0x54, 0xb8, 0xce, 0xb7, - 0xba, 0xc5, 0x11, 0x73, 0x49, 0xa4, 0x43, 0x9a, - 0x6b, 0x05, 0x69, 0xda, 0x97, 0x7c, 0x46, 0x4a -}; - -uint8_t init_remote_static[32] = { - 0x31, 0xe0, 0x30, 0x3f, 0xd6, 0x41, 0x8d, 0x2f, - 0x8c, 0x0e, 0x78, 0xb9, 0x1f, 0x22, 0xe8, 0xca, - 0xed, 0x0f, 0xbe, 0x48, 0x65, 0x6d, 0xcf, 0x47, - 0x67, 0xe4, 0x83, 0x4f, 0x70, 0x1b, 0x8f, 0x62 -}; - -uint8_t resp_static[32] = { - 0x4a, 0x3a, 0xcb, 0xfd, 0xb1, 0x63, 0xde, 0xc6, - 0x51, 0xdf, 0xa3, 0x19, 0x4d, 0xec, 0xe6, 0x76, - 0xd4, 0x37, 0x02, 0x9c, 0x62, 0xa4, 0x08, 0xb4, - 0xc5, 0xea, 0x91, 0x14, 0x24, 0x6e, 0x48, 0x93 -}; - -uint8_t resp_ephemeral[32] = { - 0xbb, 0xdb, 0x4c, 0xdb, 0xd3, 0x09, 0xf1, 0xa1, - 0xf2, 0xe1, 0x45, 0x69, 0x67, 0xfe, 0x28, 0x8c, - 0xad, 0xd6, 0xf7, 0x12, 0xd6, 0x5d, 0xc7, 0xb7, - 0x79, 0x3d, 0x5e, 0x63, 0xda, 0x6b, 0x37, 0x5b -}; - -// 4c 75 64 77 69 67 20 76 6f 6e 20 4d 69 73 65 73 -uint8_t payload_hs_initiator[16] = { - 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f, - 0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 - }; - -// 4d 75 72 72 61 79 20 52 6f 74 68 62 61 72 64 -uint8_t payload_hs_responder[15] = { - 0x4d, 0x75, 0x72, 0x72, 0x61, 0x79, 0x20, 0x52, - 0x6f, 0x74, 0x68, 0x62, 0x61, 0x72, 0x64 - }; - -// 46 2e 20 41 2e 20 48 61 79 65 6b -uint8_t payload_transport_initiator1[11] = { - 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, 0x79, - 0x65, 0x6b - }; - -// 43 61 72 6c 20 4d 65 6e 67 65 72 -uint8_t payload_transport_responder1[11] = { - 0x43, 0x61, 0x72, 0x6c, 0x20, 0x4d, 0x65, 0x6e, 0x67, 0x65, 0x72 - }; - -// 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 -uint8_t payload_transport_initiator2[17] = { - 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, - 0x74, 0x65, 0x20, 0x53, 0x61, 0x79 -}; - -// 45 75 67 65 6e 20 42 f6 68 6d 20 76 6f 6e 20 42 61 77 65 72 6b -uint8_t payload_transport_responder2[21] = { - 0x45, 0x75, 0x67, 0x65, 0x6e, 0x20, 0x42, 0xf6, 0x68, 0x6d, 0x20, - 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b - }; - -static void test_fast_known2(void) -{ - uint8_t k[CRYPTO_SHARED_KEY_SIZE]; - uint8_t m1[131]; - uint8_t m2[131]; - uint8_t xm1[131]; - uint8_t xm2[131]; - uint8_t c1[147]; - uint8_t c2[147]; - uint8_t xc1[147]; - uint8_t xc2[147]; - uint16_t xclen2, xmlen2; - unsigned long long mlen1 = 0; - unsigned long long clen1 = 0; - unsigned long long mlen2 = 0; - unsigned long long clen2 = 0; - unsigned long long xclen1 = 0; - unsigned long long xmlen1 = 0; - int result; - - uint8_t hash[CRYPTO_SHA512_SIZE]; - uint8_t send_key1[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t recv_key1[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t send_key2[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t recv_key2[CRYPTO_PUBLIC_KEY_SIZE]; - - encrypt_precompute(bobpk, alicesk, k); - - // ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), - // "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); - // ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - - // crypto_sha512(hash, k, CRYPTO_PUBLIC_KEY_SIZE); - // crypto_hkdf(send_key1, recv_key1, NULL, k, - // CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, 0, - // CRYPTO_PUBLIC_KEY_SIZE, hash); - - // char send_key1_string[CRYPTO_SHA512_SIZE * 2 + 1]; - // char recv_key1_string[CRYPTO_SHA512_SIZE * 2 + 1]; - // bin2hex_toupper(send_key1_string, sizeof(send_key1_string), send_key1, CRYPTO_PUBLIC_KEY_SIZE); - // bin2hex_toupper(recv_key1_string, sizeof(recv_key1_string), recv_key1, CRYPTO_PUBLIC_KEY_SIZE); - // printf("libsodium-HMAC: %s\n", send_key1_string); - // printf("libsodium-HMAC: %s\n", recv_key1_string); - - // crypto_hkdf_libsodium(send_key2, recv_key2, NULL, k, - // CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE, 0, - // CRYPTO_PUBLIC_KEY_SIZE, hash); - - // char send_key2_string[CRYPTO_SHA512_SIZE * 2 + 1]; - // char recv_key2_string[CRYPTO_SHA512_SIZE * 2 + 1]; - // bin2hex_toupper(send_key2_string, sizeof(send_key2_string), send_key2, CRYPTO_PUBLIC_KEY_SIZE); - // bin2hex_toupper(recv_key2_string, sizeof(recv_key2_string), recv_key2, CRYPTO_PUBLIC_KEY_SIZE); - // printf("libsodium-HKDF: %s\n", send_key2_string); - // printf("libsodium-HKDF: %s\n", recv_key2_string); - - char ciphertext_hex[147 * 2 + 1]; - - /* All-zero nonces with matching length (8/12/24 bytes)*/ - /* crypto_aead_chacha20poly1305_encrypt */ - crypto_aead_chacha20poly1305_encrypt(c1, &clen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_chacha20, k); - bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c1, clen1); - printf("crypto_aead_chacha20poly1305_encrypt: %s\n", ciphertext_hex); - /* crypto_aead_chacha20poly1305_ietf_encrypt */ - crypto_aead_chacha20poly1305_ietf_encrypt(c2, &clen2, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_chacha20_ietf, k); - bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c2, clen2); - printf("crypto_aead_chacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); - /* crypto_aead_xchacha20poly1305_ietf_encrypt */ - crypto_aead_xchacha20poly1305_ietf_encrypt(xc1, &xclen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_xchacha20, k); - bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc1, xclen1); - printf("crypto_aead_xchacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); - /* Tox crypto_core XChaCha20 */ - clen2 = encrypt_data_symmetric_xaead(k, test_nonce_xchacha20, test_m, sizeof(test_m) / sizeof(uint8_t), xc2, NULL, 0); - bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc2, xclen2); - printf("encrypt_data_symmetric_xaead(XChaCha20): %s\n", ciphertext_hex); - - /* nonce with only one zero byte => different results! */ - /* crypto_aead_chacha20poly1305_encrypt */ - // crypto_aead_chacha20poly1305_encrypt(c1, &clen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); - // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c1, clen1); - // printf("crypto_aead_chacha20poly1305_encrypt: %s\n", ciphertext_hex); - // /* crypto_aead_chacha20poly1305_ietf_encrypt */ - // crypto_aead_chacha20poly1305_ietf_encrypt(c2, &clen2, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); - // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), c2, clen2); - // printf("crypto_aead_chacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); - // /* crypto_aead_xchacha20poly1305_ietf_encrypt */ - // crypto_aead_xchacha20poly1305_ietf_encrypt(xc1, &xclen1, test_m, sizeof(test_m) / sizeof(uint8_t), NULL, 0, NULL, test_nonce_one_zero_byte, k); - // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc1, xclen1); - // printf("crypto_aead_xchacha20poly1305_ietf_encrypt: %s\n", ciphertext_hex); - // /* Tox crypto_core XChaCha20 */ - // clen2 = encrypt_data_symmetric_xaead(k, test_nonce_one_zero_byte, test_m, sizeof(test_m) / sizeof(uint8_t), xc2, NULL, 0); - // bin2hex_toupper(ciphertext_hex, sizeof(ciphertext_hex), xc2, xclen2); - // printf("encrypt_data_symmetric_xaead(XChaCha20): %s\n", ciphertext_hex); - - - // ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); - // ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - - // char correct_plain[131 * 2 + 1]; - // char plaintext_hex[147 * 2 + 1]; - // bin2hex_toupper(correct_plain, sizeof(correct_plain), test_m, 131); - // printf("Correct Plaintext: %s\n", correct_plain); - - // /* All-zero nonces with matching length (8/12/24 bytes)*/ - // /* crypto_aead_chacha20poly1305_decrypt */ - // result = crypto_aead_chacha20poly1305_decrypt(m1, &mlen1, NULL, c1, clen1, NULL, 0, test_nonce_chacha20, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m1, mlen1); - // printf("crypto_aead_chacha20poly1305_decrypt: %d, %s\n", result, plaintext_hex); - // /* crypto_aead_chacha20poly1305_ietf_decrypt */ - // result = crypto_aead_chacha20poly1305_ietf_decrypt(m2, &mlen2, NULL, c2, clen2, NULL, 0, test_nonce_chacha20_ietf, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m2, mlen2); - // printf("crypto_aead_chacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); - // /* crypto_aead_xchacha20poly1305_ietf_decrypt */ - // result = crypto_aead_xchacha20poly1305_ietf_decrypt(xm1, &xmlen1, NULL, xc1, xclen1, NULL, 0, test_nonce_xchacha20, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm1, xmlen1); - // printf("crypto_aead_xchacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); - // /* Tox crypto_core XChaCha20 */ - // xmlen2 = decrypt_data_symmetric_xaead(k, test_nonce_xchacha20, xc2, xclen2, xm2, NULL, 0); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm2, xmlen2); - // printf("decrypt_data_symmetric_xaead(XChaCha20): %s\n", plaintext_hex); - - /* nonce with only one zero byte */ - /* crypto_aead_chacha20poly1305_decrypt */ - // result = crypto_aead_chacha20poly1305_decrypt(m1, &mlen1, NULL, c1, clen1, NULL, 0, test_nonce_one_zero_byte, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m1, mlen1); - // printf("crypto_aead_chacha20poly1305_decrypt: %d, %s\n", result, plaintext_hex); - // /* crypto_aead_chacha20poly1305_ietf_decrypt */ - // result = crypto_aead_chacha20poly1305_ietf_decrypt(m2, &mlen2, NULL, c2, clen2, NULL, 0, test_nonce_one_zero_byte, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), m2, mlen2); - // printf("crypto_aead_chacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); - // /* crypto_aead_xchacha20poly1305_ietf_decrypt */ - // result = crypto_aead_xchacha20poly1305_ietf_decrypt(xm1, &xmlen1, NULL, xc1, xclen1, NULL, 0, test_nonce_one_zero_byte, k); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm1, xmlen1); - // printf("crypto_aead_xchacha20poly1305_ietf_decrypt: %d, %s\n", result, plaintext_hex); - // /* Tox crypto_core XChaCha20 */ - // xmlen2 = decrypt_data_symmetric_xaead(k, test_nonce_one_zero_byte, xc2, xclen2, xm2, NULL, 0); - // bin2hex_toupper(plaintext_hex, sizeof(plaintext_hex), xm2, xmlen2); - // printf("decrypt_data_symmetric_xaead(XChaCha20): %s\n", plaintext_hex); - - // ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); - // ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); - - char h_print[CRYPTO_SHA512_SIZE * 2 + 1]; - char ck_print[CRYPTO_SHA512_SIZE * 2 + 1]; - char key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - - // INITIATOR: Create handshake packet for responder - Noise_Handshake *noise_handshake_initiator = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); - - /* Troubleshooting info, intermediary values */ - // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->hash: %s\n", h_print); - // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->chaining_key: %s\n", ck_print); - - noise_handshake_init(nullptr, noise_handshake_initiator, init_static, init_remote_static, true); - - /* Troubleshooting info, intermediary values */ - // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->hash: %s\n", h_print); - // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->chaining_key: %s\n", ck_print); - - memcpy(noise_handshake_initiator->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); - crypto_derive_public_key(noise_handshake_initiator->ephemeral_public, init_ephemeral); - - char ephemeral_public_print[32 * 2 + 1]; - bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - printf("ephemeral_public_print: %s\n", ephemeral_public_print); - - char resp_static_print[32 * 2 + 1]; - uint8_t resp_static_pub[32]; - crypto_derive_public_key(resp_static_pub, resp_static); - bin2hex_toupper(resp_static_print, sizeof(resp_static_print), resp_static_pub, CRYPTO_PUBLIC_KEY_SIZE); - printf("resp_static_pub: %s\n", resp_static_print); - - /* e */ - noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - - /* Troubleshooting info, intermediary values */ - // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); - - /* es */ - uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key, noise_handshake_initiator->ephemeral_private, noise_handshake_initiator->remote_static); - - /* Troubleshooting info, intermediary values */ - // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->chaining_key (after es): %s\n", ck_print); - // bin2hex_toupper(key_print, sizeof(key_print), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - // printf("noise_handshake_temp_key (after es): %s\n", key_print); - - /* s */ - //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 - /*Nonce provided as parameter is the base nonce! -> This adds nonce for static pub key encryption to packet (XChaCha20-Poly1305) */ - // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - - /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ - uint8_t ciphertext1[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; - noise_encrypt_and_hash(ciphertext1, noise_handshake_initiator->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - noise_handshake_initiator->hash); - - char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; - bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); - printf("Initiator: HS ciphertext static pub key: %s\n", ciphertext1_print); - - //TODO: remove from production code - // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); - // char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); - - /* ss */ - noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key, - noise_handshake_initiator->static_private, noise_handshake_initiator->remote_static); - - /* Noise Handshake Payload */ - // uint8_t handshake_payload_plain[15]; - uint8_t ciphertext2[sizeof(payload_hs_initiator) + CRYPTO_MAC_SIZE]; - - //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 - /* Add Handshake payload nonce */ - // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, - // handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - - /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ - noise_encrypt_and_hash(ciphertext2, - payload_hs_initiator, sizeof(payload_hs_initiator), noise_handshake_temp_key, - noise_handshake_initiator->hash); - - char ciphertext2_print[sizeof(ciphertext2) * 2 + 1]; - bin2hex_toupper(ciphertext2_print, sizeof(ciphertext2_print), ciphertext2, sizeof(ciphertext2)); - printf("Initiator: HS ciphertext payload: %s\n", ciphertext2_print); - - // INITIATOR: END Create handshake packet for responder - - // RESPONDER: Consume handshake packet from initiator - Noise_Handshake *noise_handshake_responder = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); - - /* Troubleshooting info, intermediary values */ - // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->hash: %s\n", h_print); - // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->chaining_key: %s\n", ck_print); - - char init_static_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - uint8_t init_static_pub[CRYPTO_PUBLIC_KEY_SIZE]; - crypto_derive_public_key(init_static_pub, init_static); - bin2hex_toupper(init_static_print, sizeof(init_static_print), init_static_pub, CRYPTO_PUBLIC_KEY_SIZE); - printf("init_static_pub: %s\n", init_static_print); - - noise_handshake_init(nullptr, noise_handshake_responder, resp_static, init_static_pub, false); - - /* e */ - memcpy(noise_handshake_responder->remote_ephemeral, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake_responder->hash, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - - /* es */ - uint8_t noise_handshake_temp_key_resp[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp, - noise_handshake_responder->static_private, noise_handshake_responder->remote_ephemeral); - - /* s */ - noise_decrypt_and_hash(noise_handshake_responder->remote_static, ciphertext1, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - noise_handshake_temp_key_resp, noise_handshake_responder->hash); - - /* ss */ - noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp, noise_handshake_responder->static_private, - noise_handshake_responder->remote_static); - - /* Payload decryption */ - uint8_t handshake_payload_plain_initiator[sizeof(payload_hs_initiator)]; - noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext2, - sizeof(ciphertext2), noise_handshake_temp_key_resp, - noise_handshake_responder->hash); - - // RESPONDER: Create handshake packet for initiator - - /* set ephemeral private+public */ - memcpy(noise_handshake_responder->ephemeral_private, resp_ephemeral, CRYPTO_SECRET_KEY_SIZE); - crypto_derive_public_key(noise_handshake_responder->ephemeral_public, resp_ephemeral); - - char ephemeral_public_print_responder[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bin2hex_toupper(ephemeral_public_print_responder, sizeof(ephemeral_public_print_responder), noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - printf("Responder ephemeral public:: %s\n", ephemeral_public_print_responder); - - /* e */ - noise_mix_hash(noise_handshake_responder->hash, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - - /* ee */ - uint8_t noise_handshake_temp_key_resp2[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp2, noise_handshake_responder->ephemeral_private, - noise_handshake_responder->remote_ephemeral); - - /* se */ - noise_mix_key(noise_handshake_responder->chaining_key, noise_handshake_temp_key_resp2, noise_handshake_responder->ephemeral_private, - noise_handshake_responder->remote_static); - - - /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ - uint8_t ciphertext3_hs_responder[sizeof(payload_hs_responder) + CRYPTO_MAC_SIZE]; - noise_encrypt_and_hash(ciphertext3_hs_responder, - payload_hs_responder, sizeof(payload_hs_responder), noise_handshake_temp_key_resp2, - noise_handshake_responder->hash); - - char ciphertext3_print[sizeof(ciphertext3_hs_responder) * 2 + 1]; - bin2hex_toupper(ciphertext3_print, sizeof(ciphertext3_print), ciphertext3_hs_responder, sizeof(ciphertext3_hs_responder)); - printf("Responder: HS ciphertext payload: %s\n", ciphertext3_print); - - // RESPONDER: END create handshake packet for initiator# - - // INITIATOR: Consume handshake packet from responder - memcpy(noise_handshake_initiator->remote_ephemeral, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - - /* ee */ - uint8_t noise_handshake_temp_key_init[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->ephemeral_private, - noise_handshake_initiator->remote_ephemeral); - - /* se */ - noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->static_private, - noise_handshake_initiator->remote_ephemeral); - - uint8_t handshake_payload_plain_responder[sizeof(payload_hs_responder)]; - if(noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext3_hs_responder, - sizeof(ciphertext3_hs_responder), noise_handshake_temp_key_init, - noise_handshake_initiator->hash) != sizeof(payload_hs_responder)) { - printf("Initiator: HS decryption failed\n"); - } - - /* INITIATOR Noise Split(), nonces already set in crypto connection */ - uint8_t initiator_send_key[CRYPTO_SHARED_KEY_SIZE]; - uint8_t initiator_recv_key[CRYPTO_SHARED_KEY_SIZE]; - crypto_hkdf(initiator_send_key, CRYPTO_SHARED_KEY_SIZE, initiator_recv_key, CRYPTO_SHARED_KEY_SIZE, nullptr, 0, - noise_handshake_initiator->chaining_key); - - char handshake_hash_initiator_print[sizeof(noise_handshake_initiator->hash) * 2 + 1]; - bin2hex_toupper(handshake_hash_initiator_print, sizeof(handshake_hash_initiator_print), noise_handshake_initiator->hash, sizeof(noise_handshake_initiator->hash)); - printf("Initiator: final handshake hash: %s\n", handshake_hash_initiator_print); - - /* Troubleshooting info, intermediary values */ - // char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // char initiator_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // bin2hex_toupper(initiator_send_key_print, sizeof(initiator_send_key_print), initiator_send_key, CRYPTO_SHARED_KEY_SIZE); - // printf("initiator_send_key_print: %s\n", initiator_send_key_print); - // bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); - // printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); - - uint8_t ciphertext4_transport1_initiator[sizeof(payload_transport_initiator1) + CRYPTO_MAC_SIZE]; - uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; - int32_t length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, payload_transport_initiator1, sizeof(payload_transport_initiator1), ciphertext4_transport1_initiator, nullptr, 0); - - char ciphertext4_transport1_initiator_print[sizeof(ciphertext4_transport1_initiator) * 2 + 1]; - bin2hex_toupper(ciphertext4_transport1_initiator_print, sizeof(ciphertext4_transport1_initiator_print), ciphertext4_transport1_initiator, sizeof(ciphertext4_transport1_initiator)); - printf("Initiator: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext4_transport1_initiator_print); - - /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ - uint8_t responder_send_key[CRYPTO_SHARED_KEY_SIZE]; - uint8_t responder_recv_key[CRYPTO_SHARED_KEY_SIZE]; - crypto_hkdf(responder_recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, responder_send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, noise_handshake_responder->chaining_key); - - char handshake_hash_responder_print[sizeof(noise_handshake_responder->hash) * 2 + 1]; - bin2hex_toupper(handshake_hash_responder_print, sizeof(handshake_hash_responder_print), noise_handshake_responder->hash, sizeof(noise_handshake_responder->hash)); - printf("Responder: final handshake hash: %s\n", handshake_hash_responder_print); - - /* Troubleshooting info, intermediary values */ - // char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // char responder_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // bin2hex_toupper(responder_send_key_print, sizeof(responder_send_key_print), responder_send_key, CRYPTO_SHARED_KEY_SIZE); - // printf("responder_send_key_print: %s\n", responder_send_key_print); - // bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); - // printf("responder_recv_key_print: %s\n", responder_recv_key_print); - - uint8_t ciphertext5_transport1_responder[sizeof(payload_transport_responder1) + CRYPTO_MAC_SIZE]; - int32_t length_ciphertext5_transport1_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, - payload_transport_responder1, sizeof(payload_transport_responder1), ciphertext5_transport1_responder, nullptr, 0); - - char ciphertext5_transport1_responder_print[sizeof(ciphertext5_transport1_responder) * 2 + 1]; - bin2hex_toupper(ciphertext5_transport1_responder_print, sizeof(ciphertext5_transport1_responder_print), ciphertext5_transport1_responder, sizeof(ciphertext5_transport1_responder)); - printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length_ciphertext5_transport1_responder, ciphertext5_transport1_responder_print); - - //TODO: Last two ciphertext currently not the same, maybe nonce is the problem - // sodium_increment(nonce_chacha20_ietf, CRYPTO_NOISEIK_NONCE_SIZE); - // // uint8_t nonce_chacha20_ietf_1[CRYPTO_NOISEIK_NONCE_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00, - // // 0x00, 0x01 }; - // uint8_t ciphertext6_transport2_initiator[sizeof(payload_transport_initiator2) + CRYPTO_MAC_SIZE]; - // int32_t ciphertext6_transport2_initiator_length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, - // payload_transport_initiator2, sizeof(payload_transport_initiator2), ciphertext6_transport2_initiator, nullptr, 0); - - // char ciphertext6_transport2_initiator_print[sizeof(ciphertext6_transport2_initiator) * 2 + 1]; - // bin2hex_toupper(ciphertext6_transport2_initiator_print, sizeof(ciphertext6_transport2_initiator_print), - // ciphertext6_transport2_initiator, sizeof(ciphertext6_transport2_initiator)); - // printf("Initiator: Transport2 ciphertext: (length: %d) %s\n", ciphertext6_transport2_initiator_length, ciphertext6_transport2_initiator_print); - - // uint8_t ciphertext7_transport2_responder[sizeof(payload_transport_responder2) + CRYPTO_MAC_SIZE]; - // int32_t length_ciphertext7_transport2_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, - // payload_transport_responder2, sizeof(payload_transport_responder2), ciphertext7_transport2_responder, nullptr, 0); - - // char ciphertext7_transport2_responder_print[sizeof(ciphertext7_transport2_responder) * 2 + 1]; - // bin2hex_toupper(ciphertext7_transport2_responder_print, sizeof(ciphertext7_transport2_responder_print), - // ciphertext7_transport2_responder, sizeof(ciphertext7_transport2_responder)); - // printf("Responder: Transport2 ciphertext: (length: %d) %s\n", length_ciphertext7_transport2_responder, ciphertext7_transport2_responder_print); - - -} - -// 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]; -// uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; -// uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; -// uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; -// uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; -// uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; - -// uint8_t n[CRYPTO_NONCE_SIZE]; - -// enum { M_SIZE = 50 }; -// uint8_t m[M_SIZE]; -// uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; -// uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; -// uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; -// uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; -// uint8_t m1[sizeof(m)]; -// uint8_t m2[sizeof(m)]; -// uint8_t m3[sizeof(m)]; -// uint8_t m4[sizeof(m)]; - -// //Generate random message (random length from 10 to 50) -// const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; -// rand_bytes(rng, m, mlen); -// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - -// //Generate keypairs -// crypto_new_keypair(rng, pk1, sk1); -// crypto_new_keypair(rng, pk2, sk2); - -// //Precompute shared keys -// encrypt_precompute(pk2, sk1, k1); -// encrypt_precompute(pk1, sk2, k2); - -// ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); - -// //Encrypt all four ways -// const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); -// const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); -// const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); -// const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); - -// ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); -// ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); -// ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 -// && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); - -// //Decrypt all four ways -// const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); -// const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); -// const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); -// const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); - -// ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); -// ck_assert_msg(m1len == mlen, "wrong decrypted text length"); -// ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 -// && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); -// ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); -// } -// } - -// 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]; - -// const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; -// uint8_t *m1 = (uint8_t *)malloc(m1_size); -// uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); -// uint8_t *m1prime = (uint8_t *)malloc(m1_size); - -// const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; -// uint8_t *m2 = (uint8_t *)malloc(m2_size); -// uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); - -// ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); - -// //Generate random messages -// rand_bytes(rng, m1, m1_size); -// rand_bytes(rng, m2, m2_size); -// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - -// //Generate key -// 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); - -// ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); -// ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); - -// const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - -// ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); -// ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - -// free(c2); -// free(m2); -// free(m1prime); -// free(c1); -// free(m1); -// } - -// 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]; - -// const size_t m1_size = 16 * 16 * 16; -// uint8_t *m1 = (uint8_t *)malloc(m1_size); -// uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); -// uint8_t *m1prime = (uint8_t *)malloc(m1_size); - -// ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); - -// //Generate random messages -// rand_bytes(rng, m1, m1_size); -// rand_bytes(rng, n, CRYPTO_NONCE_SIZE); - -// //Generate key -// 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"); - -// const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); - -// ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); -// ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); - -// free(m1prime); -// free(c1); -// free(m1); -// } - -static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) -{ - uint32_t num1, num2; - memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); - num1 = net_ntohl(num1); - num2 = num + num1; - - if (num2 < num1) { - for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { - ++nonce[i - 1]; - - if (nonce[i - 1] != 0) { - break; - } - } - } - - num2 = net_htonl(num2); - memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); -} - -// 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(rng); -// } - -// uint8_t n1[CRYPTO_NONCE_SIZE]; - -// memcpy(n1, n, CRYPTO_NONCE_SIZE); - -// for (i = 0; i < (1 << 18); ++i) { -// increment_nonce_number_cmp(n, 1); -// increment_nonce(n1); -// ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); -// } - -// for (i = 0; i < (1 << 18); ++i) { -// 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"); -// } -// } - -static void test_memzero(void) -{ - uint8_t src[sizeof(test_c)]; - memcpy(src, test_c, sizeof(test_c)); - - crypto_memzero(src, sizeof(src)); - size_t i; - - for (i = 0; i < sizeof(src); i++) { - ck_assert_msg(src[i] == 0, "Memory is not zeroed"); - } -} - -int main(void) -{ - setvbuf(stdout, nullptr, _IONBF, 0); - - // test_known(); - // test_fast_known(); - test_fast_known2(); - // test_endtoend(); /* waiting up to 15 seconds */ - // test_large_data(); - // test_large_data_symmetric(); - // test_increment_nonce(); - // test_memzero(); - - return 0; -} diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 166d9b17c7..88c26f1096 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -650,7 +650,7 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S crypto_auth_hmacsha512(auth, data, data_length, key); } -/* This is Hugo Krawczyk's HKDF: +/* This is Hugo Krawczyk's HKDF (i.e. HKDF-SHA512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 * HKDF(chaining_key, input_key_material, num_outputs): Takes a @@ -668,67 +668,42 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * length. Also note that the HKDF() function is simply HKDF with the * chaining_key as HKDF salt, and zero-length HKDF info. */ -// void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, -// size_t second_len, const uint8_t *data, -// size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) -// { -// uint8_t output[CRYPTO_SHA512_SIZE + 1]; -// // temp_key = secret in WG -// uint8_t temp_key[CRYPTO_SHA512_SIZE]; - -// /* Extract entropy from data into temp_key */ -// // data => input_key_material => DH result in Noise -// crypto_hmac512(temp_key, chaining_key, data, data_len); - -// /* Expand first key: key = temp_key, data = 0x1 */ -// output[0] = 1; -// crypto_hmac512(output, temp_key, output, 1); -// memcpy(output1, output, first_len); - -// /* Expand second key: key = secret, data = first-key || 0x2 */ -// output[CRYPTO_SHA512_SIZE] = 2; -// crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); -// memcpy(output2, output, second_len); - -// /* Expand third key: key = temp_key, data = second-key || 0x3 */ -// /* Currently output3 not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ -// // output[CRYPTO_SHA512_SIZE] = 3; -// // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); -// // memcpy(output3, output, third_len); - -// /* Clear sensitive data from stack */ -// crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); -// crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); -// } void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, size_t second_len, const uint8_t *data, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) { + /* Implementing HKDF-SHA512 based on libsodium `crypto_auth_hmacsha512()` and WireGuard leads to wrong results. + Verified using Noise_IK_25519_ChaChaPoly_SHA512 test vectors. Keeping for documentation purposes. */ // uint8_t output[CRYPTO_SHA512_SIZE + 1]; // temp_key = secret in WG + uint8_t temp_key[CRYPTO_SHA512_SIZE]; /* Extract entropy from data into temp_key */ - // data => input_key_material => DH result in Noise - //TODO: This is correct, same result as crypto_kdf_hkdf_sha512_extract() + /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). + Result is a pseudo random key (PRK) = temp_key */ + /* data => input_key_material => X25519-DH result in Noise */ + /* TODO: This is correct, same result as libsodium `crypto_kdf_hkdf_sha512_extract()` */ // crypto_hmac512(temp_key, chaining_key, data, data_len); - /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ crypto_kdf_hkdf_sha512_extract(temp_key, chaining_key, CRYPTO_SHA512_SIZE, data, data_len); /* Expand first key: key = temp_key, data = 0x1 */ - /* TODO: Not correct, unsure why */ + /* TODO: Result not correct, unsure why */ // output[0] = 1; // crypto_hmac512(output, temp_key, output, 1); // memcpy(output1, output, first_len); /* Expand both keys in one operation (verified): */ - /* HKDF -> T(0) + T(1); cf. RFC TODO: */ + /* HKDF-Expand(PRK, info, L) -> OKM, where PRK = temp_key, zero-length HKDF info (ctx) + and L (length of output keying material in octets) = 2*64 byte (i.e. 2x HashLen) */ + /* OKM = HKDF -> T(0) + T(1); cf. RFC5869: https://datatracker.ietf.org/doc/html/rfc5869#section-2.3 */ + /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ uint8_t output_temp[CRYPTO_SHA512_SIZE*2]; crypto_kdf_hkdf_sha512_expand(output_temp, CRYPTO_SHA512_SIZE*2, nullptr, 0, temp_key); memcpy(output1, output_temp, first_len); - memcpy(output2, output_temp+CRYPTO_SHA512_SIZE, second_len); + memcpy(output2, output_temp + CRYPTO_SHA512_SIZE, second_len); /* Expand second key: key = secret, data = first-key || 0x2 */ /* TODO: Not correct, unsure why */ @@ -737,23 +712,15 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ - /* Currently output3 not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ + /* Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ // output[CRYPTO_SHA512_SIZE] = 3; // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); // memcpy(output3, output, third_len); - // ctx = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) - /* Works, correct result */ - // crypto_kdf_hkdf_sha512_expand(output1, first_len, nullptr, 0, temp_key); - - // ctx = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) - /* Same result as expand1, so doesn't work like this */ - // crypto_kdf_hkdf_sha512_expand(output2, second_len, 0, 0, temp_key); - /* Clear sensitive data from stack */ crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); // crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); - crypto_memzero(output_temp, CRYPTO_SHA512_SIZE + 1); + crypto_memzero(output_temp, CRYPTO_SHA512_SIZE*2); } /* @@ -772,21 +739,15 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t dh_calculation[CRYPTO_SHARED_KEY_SIZE]; memset(dh_calculation, 0, CRYPTO_SHARED_KEY_SIZE); - // X25519: returns plain DH result, afterwards hashed with HKDF + /* X25519: returns plain DH result, afterwards hashed with HKDF (necessary for NoiseIK) */ if (crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { return -1; } - //uint8_t shared_key_temp[CRYPTO_SHA512_SIZE]; - - // chaining_key is HKDF output1 and shared_key is HKDF output2 => different values! - //TODO: change back to shared_key to shared_key_temp? + /* chaining_key is HKDF output1 and shared_key is HKDF output2 => different values/results! */ + /* If HASHLEN is 64, then truncates temp_k (= shared_key) to 32 bytes. => done via call to crypto_hkdf() */ crypto_hkdf(chaining_key, CRYPTO_SHA512_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, CRYPTO_SHARED_KEY_SIZE, chaining_key); - // If HASHLEN is 64, then truncates temp_k to 32 bytes. => done via call to crypto_hkdf() - //TODO: no difference in case of libsodium HKDF in output - // memcpy(shared_key, shared_key_temp, CRYPTO_SHARED_KEY_SIZE); - // crypto_memzero(shared_key_temp, CRYPTO_SHA512_SIZE); crypto_memzero(dh_calculation, CRYPTO_SHARED_KEY_SIZE); @@ -862,12 +823,14 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, * @param self_secret_key static private ID X25519 key of this Tox instance * @param peer_public_key X25519 static ID public key from peer to connect to * @param initiator specifies if this Tox instance is the initiator of this crypto connection + * @param prologue specifies the prologue, used in call to MixHash(prologue) which maybe zero-length + * @param prologue_length length of prologue in bytes * * @return -1 on failure * @return 0 on success */ int noise_handshake_init -(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator) +(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length) { //TODO: remove if (log != nullptr) { @@ -885,13 +848,8 @@ int noise_handshake_init memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); - //TODO: remove prologue for test vectors - static const uint8_t prologue[] = { - // 50 72 6f 6c 6f 67 75 65 31 323 3 - 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x31, 0x32, 0x33 - }; - //TODO: IMPORTANT need to call also with empty prologue? Should I add prologue again?! - noise_mix_hash(noise_handshake->hash, prologue, sizeof(prologue)); + /* IMPORTANT needs to be called with (empty/zero-length) prologue! */ + noise_mix_hash(noise_handshake->hash, prologue, prologue_length); //TODO: remove // char log_ck[CRYPTO_SHA512_SIZE*2+1]; diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 4bfd5087e1..4bddd84838 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -606,7 +606,7 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S size_t data_length); /** - * @brief Computes the number of provides outputs (=keys) with HKDF. + * @brief Computes the number of provides outputs (=keys) with HKDF-SHA512. * * cf. Noise sections 4.3 and 5.1 * @@ -636,7 +636,7 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * @param data_len length of either zero bytes, 32 bytes, or DHLEN bytes * @param chaining_key Noise 64 byte chaining key as HKDF salt */ - non_null(1, 3, 7) nullable(5) +non_null(1, 3, 7) nullable(5) void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, size_t second_len, const uint8_t *data, size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]); @@ -657,13 +657,15 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * @param self_secret_key static private ID X25519 key of this Tox instance * @param peer_public_key X25519 static ID public key from peer to connect to * @param initiator specifies if this Tox instance is the initiator of this crypto connection + * @param prologue specifies the prologue, used in call to MixHash(prologue) which maybe zero-length + * @param prologue_length length of prologue in bytes * * @return -1 on failure * @return 0 on success */ - //TODO: non_null +non_null(2, 3) nullable(1, 4, 6) int noise_handshake_init -(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator); +(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); /** * @brief Noise MixKey(input_key_material) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index a1f6064745..0d5b74c036 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2382,7 +2382,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } // Noise: only necessary if Cookie response was successful - if (conn->noise_handshake_enabled && noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, conn->public_key, true) != 0) { + if (conn->noise_handshake_enabled && noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { return -1; } @@ -2467,7 +2467,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); - if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { + if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } @@ -2502,7 +2502,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change; also necessary without change */ - if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false) != 0) { + if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() @@ -2922,7 +2922,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (length != HANDSHAKE_PACKET_LENGTH) { //TODO: adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; - if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false) != 0) { + if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); From 336c5dec9ea8283a99d2c832eeb29041f70ad3bc Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 15:21:17 +0200 Subject: [PATCH 090/150] fix: removed logger.h from crypto_core.h and removed logging parameter for noise_handshake_init() --- auto_tests/crypto_test.c | 4 ++-- toxcore/crypto_core.c | 34 +++++++++++++++++----------------- toxcore/crypto_core.h | 6 +++--- toxcore/net_crypto.c | 8 ++++---- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 87ae7040a3..c8a6de23a3 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -528,7 +528,7 @@ static void test_noiseik() { // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); // printf("noise_handshake->chaining_key: %s\n", ck_print); - noise_handshake_init(nullptr, noise_handshake_initiator, init_static, init_remote_static, true, prologue, sizeof(prologue)); + noise_handshake_init(noise_handshake_initiator, init_static, init_remote_static, true, prologue, sizeof(prologue)); /* Troubleshooting info, intermediary values */ // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); @@ -647,7 +647,7 @@ static void test_noiseik() { // bin2hex_toupper(init_static_print, sizeof(init_static_print), init_static_pub, CRYPTO_PUBLIC_KEY_SIZE); // printf("init_static_pub: %s\n", init_static_print); - noise_handshake_init(nullptr, noise_handshake_responder, resp_static, init_static_pub, false, prologue, sizeof(prologue)); + noise_handshake_init(noise_handshake_responder, resp_static, init_static_pub, false, prologue, sizeof(prologue)); /* e */ memcpy(noise_handshake_responder->remote_ephemeral, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 88c26f1096..1c3f427a39 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -626,7 +626,7 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ * TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? * bytes_to_string() from util.h */ -static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) +static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length) { bytes_to_string(bytes, bytes_length, string, string_length); } @@ -830,12 +830,12 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, * @return 0 on success */ int noise_handshake_init -(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length) +(Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length) { //TODO: remove - if (log != nullptr) { - LOGGER_DEBUG(log, "ENTERING"); - } + // if (log != nullptr) { + // LOGGER_DEBUG(log, "ENTERING"); + // } //TODO: move to handle_packet_crypto_hs()? crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); @@ -865,15 +865,15 @@ int noise_handshake_init crypto_derive_public_key(noise_handshake->static_public, self_secret_key); //TODO: remove - if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); - LOGGER_DEBUG(log, "static pub: %s", log_spub); - } + // if (log != nullptr) { + // char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); + // LOGGER_DEBUG(log, "static pub: %s", log_spub); + // } } else { // fprintf(stderr, "Local static private key required, but not provided.\n"); - LOGGER_DEBUG(log, "Local static private key required, but not provided."); + // LOGGER_DEBUG(log, "Local static private key required, but not provided."); return -1; } /* <- s: pre-message from responder to initiator => sets rs (only initiator) */ @@ -882,11 +882,11 @@ int noise_handshake_init memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove - if (log != nullptr) { - char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); - LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); - } + // if (log != nullptr) { + // char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); + // LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); + // } /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -898,7 +898,7 @@ int noise_handshake_init // } } else { // fprintf(stderr, "Remote peer static public key required, but not provided.\n"); - LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); + // LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); return -1; } } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 4bddd84838..36f02ccecf 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -16,7 +16,6 @@ #include #include "attributes.h" -#include "logger.h" #ifdef __cplusplus extern "C" { @@ -665,8 +664,9 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, */ non_null(2, 3) nullable(1, 4, 6) int noise_handshake_init -(const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); - +(Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); +// int noise_handshake_init +// (const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); /** * @brief Noise MixKey(input_key_material) * diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 0d5b74c036..626184f2fa 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2382,7 +2382,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } // Noise: only necessary if Cookie response was successful - if (conn->noise_handshake_enabled && noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { + if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { return -1; } @@ -2467,7 +2467,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); - if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { + if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } @@ -2502,7 +2502,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change; also necessary without change */ - if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { + if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() @@ -2922,7 +2922,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (length != HANDSHAKE_PACKET_LENGTH) { //TODO: adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; - if (noise_handshake_init(nullptr, n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { + if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); From f7b7097c86a6f88b50330a35f9a6edc8bd03aa79 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 15:28:00 +0200 Subject: [PATCH 091/150] fix: removed logging param and added newline to crypto_core.c --- toxcore/crypto_core.c | 3 +-- toxcore/crypto_core.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 1c3f427a39..fdbd92048c 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -818,7 +818,6 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, * Calls MixHash() once for each public key listed in the pre-messages. * * //TODO: remove Logger Param - * @param log Tox logger * @param noise_handshake handshake struct to save the necessary values to * @param self_secret_key static private ID X25519 key of this Tox instance * @param peer_public_key X25519 static ID public key from peer to connect to @@ -916,4 +915,4 @@ int noise_handshake_init /* Ready to go */ return 0; -} \ No newline at end of file +} diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 36f02ccecf..527f1e3a31 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -651,7 +651,6 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * Calls MixHash() once for each public key listed in the pre-messages. * * //TODO: remove Logger Param - * @param log Tox logger * @param noise_handshake handshake struct to save the necessary values to * @param self_secret_key static private ID X25519 key of this Tox instance * @param peer_public_key X25519 static ID public key from peer to connect to From 23f2bb229fa0a185090a7f901d1dbeed6a0f7a2d Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 15:35:19 +0200 Subject: [PATCH 092/150] fix: fixes for CI --- auto_tests/crypto_test.c | 3 ++- toxcore/crypto_core.c | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index c8a6de23a3..1a875d9aeb 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -6,7 +6,8 @@ #include "../toxcore/crypto_core.h" #include "../toxcore/net_crypto.h" #include "check_compat.h" -#include "../other/fun/create_common.h" +//TODO: necessary to print bytes +// #include "../other/fun/create_common.h" static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) { diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index fdbd92048c..5d0822adfe 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -626,10 +626,10 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ * TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? * bytes_to_string() from util.h */ -static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length) -{ - bytes_to_string(bytes, bytes_length, string, string_length); -} +// static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length) +// { +// bytes_to_string(bytes, bytes_length, string, string_length); +// } // #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" static const uint8_t noise_protocol[32] = "Noise_IK_25519_ChaChaPoly_SHA512"; From c8566ef531dd6fd82d8fc7476b30bf064b95f9c0 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 15:49:48 +0200 Subject: [PATCH 093/150] fix: fixes for CI --- auto_tests/crypto_test.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 1a875d9aeb..07007f90f2 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -519,7 +519,8 @@ static const uint8_t handshake_hash[CRYPTO_SHA512_SIZE] = { // 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b // }; -static void test_noiseik() { +static void test_noiseik() +{ /* INITIATOR: Create handshake packet for responder */ Noise_Handshake *noise_handshake_initiator = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); @@ -727,12 +728,12 @@ static void test_noiseik() { noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->static_private, noise_handshake_initiator->remote_ephemeral); - uint8_t handshake_payload_plain_responder[sizeof(resp_payload_hs)]; - if(noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext3_hs_responder, - sizeof(ciphertext3_hs_responder), noise_handshake_temp_key_init, - noise_handshake_initiator->hash) != sizeof(resp_payload_hs)) { - printf("Initiator: HS decryption failed\n"); - } + // uint8_t handshake_payload_plain_responder[sizeof(resp_payload_hs)]; + // if(noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext3_hs_responder, + // sizeof(ciphertext3_hs_responder), noise_handshake_temp_key_init, + // noise_handshake_initiator->hash) != sizeof(resp_payload_hs)) { + // printf("Initiator: HS decryption failed\n"); + // } /* INITIATOR Noise Split(), nonces already set in crypto connection */ uint8_t initiator_send_key[CRYPTO_SHARED_KEY_SIZE]; @@ -757,7 +758,7 @@ static void test_noiseik() { uint8_t ciphertext4_transport1_initiator[sizeof(init_payload_transport1) + CRYPTO_MAC_SIZE]; uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; - int32_t length = encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, init_payload_transport1, sizeof(init_payload_transport1), ciphertext4_transport1_initiator, nullptr, 0); + encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, init_payload_transport1, sizeof(init_payload_transport1), ciphertext4_transport1_initiator, nullptr, 0); ck_assert_msg(memcmp(ciphertext4_transport1_initiator, init_payload_transport1_encrypted, sizeof(init_payload_transport1_encrypted)) == 0, "initiator transport1 ciphertext differ"); @@ -787,7 +788,7 @@ static void test_noiseik() { // printf("responder_recv_key_print: %s\n", responder_recv_key_print); uint8_t ciphertext5_transport1_responder[sizeof(resp_payload_transport1) + CRYPTO_MAC_SIZE]; - int32_t length_ciphertext5_transport1_responder = encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, + encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, resp_payload_transport1, sizeof(resp_payload_transport1), ciphertext5_transport1_responder, nullptr, 0); ck_assert_msg(memcmp(ciphertext5_transport1_responder, resp_payload_transport1_encrypted, sizeof(resp_payload_transport1_encrypted)) == 0, "responder transport1 ciphertext differ"); From bb95f245d69aebfeb923db04beccce52adbeb724 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 15:55:08 +0200 Subject: [PATCH 094/150] fix: fixes for CI --- auto_tests/crypto_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 07007f90f2..41d69da75b 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -519,7 +519,7 @@ static const uint8_t handshake_hash[CRYPTO_SHA512_SIZE] = { // 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b // }; -static void test_noiseik() +static void test_noiseik(void) { /* INITIATOR: Create handshake packet for responder */ Noise_Handshake *noise_handshake_initiator = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); From bbc1c3c1996cc2c29bf5fa1cccaed2b9a694ed87 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 16:07:42 +0200 Subject: [PATCH 095/150] fix: fixes for CI --- toxcore/crypto_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 527f1e3a31..1843c2e480 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -661,7 +661,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * @return -1 on failure * @return 0 on success */ -non_null(2, 3) nullable(1, 4, 6) +non_null(1, 2) nullable(3, 5) int noise_handshake_init (Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); // int noise_handshake_init @@ -696,7 +696,7 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], uint8_t shared_k * @param data_len length of data to hash * */ -non_null() +non_null(1) nullable(2) void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len); /** From 61825f1327979c4a79019055ad5f279c3b820b63 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 16:33:25 +0200 Subject: [PATCH 096/150] fix: fixed bug introduced in crypto_test with CI fixes --- auto_tests/crypto_test.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 41d69da75b..04f4bfeeae 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -649,7 +649,7 @@ static void test_noiseik(void) // bin2hex_toupper(init_static_print, sizeof(init_static_print), init_static_pub, CRYPTO_PUBLIC_KEY_SIZE); // printf("init_static_pub: %s\n", init_static_print); - noise_handshake_init(noise_handshake_responder, resp_static, init_static_pub, false, prologue, sizeof(prologue)); + noise_handshake_init(noise_handshake_responder, resp_static, nullptr, false, prologue, sizeof(prologue)); /* e */ memcpy(noise_handshake_responder->remote_ephemeral, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -728,12 +728,12 @@ static void test_noiseik(void) noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key_init, noise_handshake_initiator->static_private, noise_handshake_initiator->remote_ephemeral); - // uint8_t handshake_payload_plain_responder[sizeof(resp_payload_hs)]; - // if(noise_decrypt_and_hash(handshake_payload_plain_initiator, ciphertext3_hs_responder, - // sizeof(ciphertext3_hs_responder), noise_handshake_temp_key_init, - // noise_handshake_initiator->hash) != sizeof(resp_payload_hs)) { - // printf("Initiator: HS decryption failed\n"); - // } + uint8_t handshake_payload_plain_responder[sizeof(resp_payload_hs)]; + if(noise_decrypt_and_hash(handshake_payload_plain_responder, ciphertext3_hs_responder, + sizeof(ciphertext3_hs_responder), noise_handshake_temp_key_init, + noise_handshake_initiator->hash) != sizeof(resp_payload_hs)) { + printf("Initiator: HS decryption failed\n"); + } /* INITIATOR Noise Split(), nonces already set in crypto connection */ uint8_t initiator_send_key[CRYPTO_SHARED_KEY_SIZE]; From 920ec606f246e9f7e06730726082c50176ab5e8a Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 16:40:17 +0200 Subject: [PATCH 097/150] fix: fixed terminating null character, noiseIK test vectors still verify correctly. --- toxcore/crypto_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 5d0822adfe..b2bf29eb83 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -632,7 +632,8 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ // } // #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" -static const uint8_t noise_protocol[32] = "Noise_IK_25519_ChaChaPoly_SHA512"; +/* Actually only 32 bytes necessary, but test vectors still verify with 33 bytes */ +static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; /** * cf. Noise sections 4.3 and 5.1 From e7e30d20f2e49b08112e63011eaeef16ed8bc134 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Tue, 11 Jun 2024 17:00:52 +0200 Subject: [PATCH 098/150] fix: fixes for CI --- toxcore/crypto_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index b2bf29eb83..153737d47a 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -764,7 +764,9 @@ void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_ { VLA(uint8_t, to_hash, CRYPTO_SHA512_SIZE + data_len); memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); - memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); + if (data != nullptr) { + memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); + } crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); } From 1b4e9635c9ed0acf6c675e0818c3a66811bee03b Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Thu, 13 Jun 2024 19:36:02 +0200 Subject: [PATCH 099/150] feat: Implemented enabling/disabling of backwards compatiblity to non-Noise handshakes. --- toxcore/Messenger.c | 2 +- toxcore/net_crypto.c | 42 ++++++++++++++++++++++++++++++++---------- toxcore/net_crypto.h | 2 +- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index d6dc24d37a..391c2431eb 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -3619,7 +3619,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * return nullptr; } - m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info); + m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info, options->noise_compatibility_enabled); if (m->net_crypto == nullptr) { LOGGER_WARNING(m->log, "net_crypto initialisation failed"); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 626184f2fa..c225826054 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -64,7 +64,7 @@ typedef struct Crypto_Connection { uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ - // Necessary for Noise handshake + // Necessary for Noise handshake backwards compatibility bool noise_handshake_enabled; Noise_Handshake *noise_handshake; uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; @@ -179,6 +179,9 @@ struct Net_Crypto { uint32_t current_sleep_time; BS_List ip_port_list; + + /* Sets backwards compatibility to non-Noise handshake to true or false */ + bool noise_compatibility_enabled; }; const uint8_t *nc_get_self_public_key(const Net_Crypto *c) @@ -757,7 +760,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } } - /* non-Noise handshake */ + /* non-Noise handshake, check for enabled backwards compatibility happens in create_send_handshake() */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; @@ -1058,7 +1061,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } } - /* non-Noise handshake */ + /* non-Noise handshake, check for enabled backwards compatibility happens in calling functions */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); @@ -2107,7 +2110,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u } } /* non-Noise handshake*/ - else { + else if(c->noise_compatibility_enabled) { LOGGER_DEBUG(c->log, "non-Noise handshake"); uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; @@ -2121,6 +2124,9 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u return -1; } } + else { + return -1; + } send_temp_packet(c, crypt_connection_id); return 0; @@ -2395,13 +2401,16 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } else { return -1; } - } else { + } else if (c->noise_compatibility_enabled) { /* non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } } + else { + return -1; + } conn->status = CRYPTO_CONN_HANDSHAKE_SENT; return 0; @@ -2451,8 +2460,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (length != HANDSHAKE_PACKET_LENGTH) { conn->noise_handshake_enabled = true; //TODO: Wipe noise_handshake etc. in this case? - } else { + } else if (c->noise_compatibility_enabled) { conn->noise_handshake_enabled = false; + } else { + return -1; } if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { @@ -2940,7 +2951,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, mem_delete(c->mem, n_c.cookie); return -1; } - } else { /* case non-Noise handshake */ + } else if (c->noise_compatibility_enabled) { /* case non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); // Necessary for backwards compatibility n_c.noise_handshake = nullptr; @@ -2949,6 +2960,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, mem_delete(c->mem, n_c.cookie); return -1; } + } else { + return -1; } //TODO: remove @@ -3135,7 +3148,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } /* non-Noise handshake */ - else { + else if (c->noise_compatibility_enabled) { //TODO: remove LOGGER_DEBUG(c->log, "non-Noise handshake"); memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -3153,6 +3166,12 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) wipe_crypto_connection(c, crypt_connection_id); return -1; } + } else { + pthread_mutex_lock(&c->tcp_mutex); + kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + pthread_mutex_unlock(&c->tcp_mutex); + wipe_crypto_connection(c, crypt_connection_id); + return -1; } memcpy(conn->dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -3219,7 +3238,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); - // Necessary for backwards compatibility to non-Noise handshake + // Necessary for backwards compatibility to non-Noise handshake (if enabled with option noise_compatibility_enabled) conn->noise_handshake_enabled = true; conn->cookie_request_number = random_u64(c->rng); @@ -4219,7 +4238,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk) * Sets all the global connection variables to their default values. */ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns, - Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info) + Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info, const bool noise_compatibility_enabled) { if (dht == nullptr) { return nullptr; @@ -4247,6 +4266,9 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r set_packet_tcp_connection_callback(temp->tcp_c, &tcp_data_callback, temp); set_oob_packet_tcp_connection_callback(temp->tcp_c, &tcp_oob_callback, temp); + /* Sets backwards compatibility to non-Noise handshake to true or false */ + temp->noise_compatibility_enabled = noise_compatibility_enabled; + if (create_recursive_mutex(&temp->tcp_mutex) != 0 || pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) { kill_tcp_connections(temp->tcp_c); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 192f8af580..b185881b8d 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -416,7 +416,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk); */ non_null() Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns, - Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info); + Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info, const bool noise_compatibility_enabled); /** return the optimal interval in ms for running do_net_crypto. */ non_null() From 4b26a5dbd94767bd0ae52074159c7ee05db0efe2 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 14 Jun 2024 11:36:16 +0200 Subject: [PATCH 100/150] fix: fix two tests after adding Tox option to disable backwards compatibility to non-Noise handshake. --- auto_tests/forwarding_test.c | 2 +- auto_tests/onion_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/auto_tests/forwarding_test.c b/auto_tests/forwarding_test.c index 75e330a73e..b613090558 100644 --- a/auto_tests/forwarding_test.c +++ b/auto_tests/forwarding_test.c @@ -127,7 +127,7 @@ static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, subtox->dht = new_dht(subtox->log, mem, rng, ns, subtox->mono_time, subtox->net, true, true); const TCP_Proxy_Info inf = {{{{0}}}}; - subtox->c = new_net_crypto(subtox->log, mem, rng, ns, subtox->mono_time, subtox->dht, &inf); + subtox->c = new_net_crypto(subtox->log, mem, rng, ns, subtox->mono_time, subtox->dht, &inf, true); subtox->forwarding = new_forwarding(subtox->log, rng, subtox->mono_time, subtox->dht); ck_assert(subtox->forwarding != nullptr); diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 3a81df41b8..f37cd65219 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -472,7 +472,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u } TCP_Proxy_Info inf = {{{{0}}}}; - on->onion_c = new_onion_client(on->log, mem, rng, on->mono_time, new_net_crypto(on->log, mem, rng, ns, on->mono_time, dht, &inf)); + on->onion_c = new_onion_client(on->log, mem, rng, on->mono_time, new_net_crypto(on->log, mem, rng, ns, on->mono_time, dht, &inf, true)); if (!on->onion_c) { kill_onion_announce(on->onion_a); From 11cbf614f18c10c9b909afefd09f8ae767010d07 Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 14 Jun 2024 12:36:46 +0200 Subject: [PATCH 101/150] cleanup: code cleanup and documentation of net_crypto.c --- toxcore/net_crypto.c | 207 ++++++++----------------------------------- 1 file changed, 36 insertions(+), 171 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index c225826054..c2976f265e 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -52,7 +52,7 @@ typedef enum Crypto_Conn_State { } Crypto_Conn_State; typedef struct Crypto_Connection { - // (Currently) used for both non-Noise and Noise handshakes/connections + /* (Currently) all used for both non-Noise and Noise handshakes/connections */ uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ @@ -63,12 +63,11 @@ typedef struct Crypto_Connection { Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ - - // Necessary for Noise handshake backwards compatibility - bool noise_handshake_enabled; - Noise_Handshake *noise_handshake; - uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; - uint8_t recv_key[CRYPTO_SHARED_KEY_SIZE]; + + bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ + Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ + uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to encrypt outgoing packets after NoiseIK handshake */ + uint8_t recv_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to decrypt incoming packets after NoiseIK handshake */ //TODO: remove // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; @@ -509,11 +508,7 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte /* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /* Noise: Necessary for Noise-based handshake */ -//TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 -// #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -//TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 -// #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) @@ -546,20 +541,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise Handshake"); /* Noise INITIATOR: -> e, es, s, ss */ - /* Initiator: Handshake packet structure (Noise_IK_25519_XChaChaPoly_SHA512) - [uint8_t 26] - [session public key of the peer (32 bytes)] => currently in plain - [24 bytes nonce for static pub key encryption] - [encrypted static public key of the INITIATOR (32 bytes)] - [MAC encrypted static pubkey 16 bytes] - [24 bytes nonce handshake payload encryption] - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD - [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] - [MAC encrypted payload 16 bytes] - => 393 bytes in total - */ /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain @@ -593,12 +574,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); /* s */ - //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 - /*Nonce provided as parameter is the base nonce! -> This adds nonce for static pub key encryption to packet (XChaCha20-Poly1305) */ - // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake->hash); @@ -617,10 +592,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - // Noise: Cookie authenticated via ciphertext MAC - // crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - // Noise: Cookie from RESPONDER + /* Noise: Cookie from RESPONDER */ memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; @@ -633,13 +606,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return -1; } - //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 - /* Add Handshake payload nonce */ - // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, - // handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, @@ -653,31 +619,18 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); packet[0] = NET_PACKET_CRYPTO_HS; - // Noise: cookie (from other peer/RESPONDER) is encrypted and included in ciphertext - // memcpy(packet + 1, cookie, COOKIE_LENGTH); //TODO: remove from production code // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); // LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); - //TODO: memzero handshake_payload_plain crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* Noise RESPONDER: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_XChaChaPoly_SHA512) - [uint8_t 26] - [session public key of the peer (32 bytes)] => currently in plain - [24 bytes nonce for handshake payload encryption] - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD - ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK - [MAC encrypted payload 16 bytes] - => ~~321~~ 209 bytes in total - */ /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain @@ -722,40 +675,19 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - // Noise: Cookie authenticated via ciphertext MAC - // crypto_sha512(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - // Noise: Cookie from INITIATOR + /* Noise: Cookie from INITIATOR */ memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - //TODO: remove - /* OtherCookie is added to payload => NOT necessary for RESPONDER HS Packet */ - // uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - // 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->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, - // cookie_plain, c->secret_symmetric_key) != 0) { - // return -1; - // } - - //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 - /* Add Handshake payload nonce. Nonce provided as parameter is the base nonce! -> Add nonce for static pub key encryption to packet */ - // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, - // handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, noise_handshake->hash); packet[0] = NET_PACKET_CRYPTO_HS; - // Noise: cookie (from other peer/INITIATOR) is encrypted and included in ciphertext - // memcpy(packet + 1, cookie, COOKIE_LENGTH); - //TODO: memzero handshake_payload_plain crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } @@ -825,20 +757,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - /* Initiator: Handshake packet structure handled here (Noise_IK_25519_XChaChaPoly_SHA512) - [uint8_t 26] - [session public key of the peer (32 bytes)] => currently in plain - [24 bytes nonce static pub key encryption] - [encrypted static public key of the INITIATOR (32 bytes)] => handled by Noise - [MAC encrypted static pubkey 16 bytes] - [24 bytes nonce handshake payload encryption] - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message decryption after handshake - [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD - [112 bytes Other Cookie (used by the other to respond to the handshake packet)] - [MAC 16 bytes] - => 393 bytes in total - */ /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain @@ -874,24 +792,17 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); - char log_static[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "local static pub: %s", log_static); - bytes2string(log_static, sizeof(log_static), noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "remote ephemeral: %s", log_static); + // char log_static[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "local static pub: %s", log_static); + // bytes2string(log_static, sizeof(log_static), noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "remote ephemeral: %s", log_static); /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); + /* s */ - /* TODO: remove; Nonces contained in packet! */ - // memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - // if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - // noise_handshake_temp_key, noise_handshake->hash, nonce) != CRYPTO_PUBLIC_KEY_SIZE) { - // LOGGER_DEBUG(c->log, "RESPONDER: Noise ReadMessage remote static decryption failed"); - // return false; - // } - /* Nonce for static pub key decryption is _always_ 0 in case of ChaCha20-Poly1305 */ if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash) != CRYPTO_PUBLIC_KEY_SIZE) { @@ -900,8 +811,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } //TODO: remove - bytes2string(log_static, sizeof(log_static), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "local remote pub: %s", log_static); + // bytes2string(log_static, sizeof(log_static), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "local remote pub: %s", log_static); //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; @@ -912,14 +823,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; - /* TODO: remove; get Handshake payload nonce */ - // memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, CRYPTO_NONCE_SIZE); - // if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, - // sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - // noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { - // LOGGER_DEBUG(c->log, "RESPONDER: Noise HS payload decryption failed"); - // return false; - // } /* Nonce for payload decryption is _always_ 0 in case of ChaCha20-Poly1305 */ if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, @@ -939,37 +842,24 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - // received base nonce + /* received base nonce (from INITIATOR) */ memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); - // not necessary for Noise (=remote ephemeral) - // memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); - // cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() + /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); - // necessary + /* necessary */ memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); - //TODO: memzero handshake_payload_plain + crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_X25519_ChaChaPoly_SHA512) - [uint8_t 26] - [session public key of the peer (32 bytes)] - [24 bytes nonce handshake payload encryption] - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => Cookie encrypted and authenticated via XAEAD - ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK - [MAC 16 bytes] - => ~~321~~ 209 bytes in total - */ /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain @@ -1014,15 +904,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* Payload decryption */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; - /* TODO: remove; get Handshake payload nonce */ - // memcpy(nonce, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); - // if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, - // sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, - // noise_handshake->hash, nonce) != sizeof(handshake_payload_plain)) { - // LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); - // return false; - // } - /* Nonce for payload decryption is 0 in case of ChaCha20-Poly1305 */ if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, @@ -1041,21 +922,16 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - // neccessary, base nonce + /* neccessary, base nonce (from Noise RESPONDER) */ memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); - // not necessary for Noise (=remote ephemeral) - // memcpy(session_pk, packet + 1 + COOKIE_LENGTH, CRYPTO_PUBLIC_KEY_SIZE); - // not necessary for Noise INITIATOR - //memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); - // not necessary for Noise (=remote static) - // memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); - // necessary + /* necessary */ memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); - //TODO: memzero handshake_payload_plain + crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); + LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); return true; @@ -2094,9 +1970,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) { return -1; } - } - /* Noise RESPONDER */ - else { + } else { /* Noise RESPONDER */ uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER]; if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, @@ -2268,7 +2142,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); - //Noise: noise_handshake not necessary anymore => memzero and free + /* Noise: noise_handshake not necessary anymore => memzero and free */ crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, conn->noise_handshake); conn->noise_handshake = nullptr; @@ -2387,7 +2261,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } - // Noise: only necessary if Cookie response was successful + /* Noise: only necessary if Cookie response was successful */ if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { return -1; } @@ -2449,14 +2323,11 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // return -1; // } - // necessary for Noise and non-Noise + /* necessary for Noise and non-Noise */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - // necessary for Noise RESPONDER and non-Noise + /* necessary for Noise RESPONDER and non-Noise */ uint8_t cookie[COOKIE_LENGTH]; - //TODO: via noise_handshake struct? TODO: remove - // bool initiator_change = false; - if (length != HANDSHAKE_PACKET_LENGTH) { conn->noise_handshake_enabled = true; //TODO: Wipe noise_handshake etc. in this case? @@ -2494,9 +2365,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "ck: %s", ck_print); - // initiator_change = true; - - /* RESPONDER needs to send handshake packet, afterwards finished */ + /* Noise RESPONDER needs to send handshake packet, afterwards finished */ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } @@ -2540,7 +2409,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* non-Noise handshake */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - // necessary only for non-Noise + /* necessary only for non-Noise */ uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, nullptr)) { @@ -2974,7 +2843,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); - //TODO: This is only called if new_crypto_connection() was already called in the meantime! Now RESPONDER! + //TODO: This is only called if new_crypto_connection() was already called in the meantime! Now Noise RESPONDER! //TODO: Does it make sense to handle this case for NoiseIK handshake? if (crypt_connection_id != -1) { LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING"); @@ -2998,8 +2867,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(Noise_Handshake)); memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); - /* unnecessary for Noise */ - // memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); crypto_connection_add_source(c, crypt_connection_id, source); @@ -3050,7 +2917,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); mem_delete(c->mem, n_c.cookie); //TODO: remove; ret value is from friend_connection.c:handle_new_connections() - LOGGER_DEBUG(c->log, "ret (!= 0?): %d", ret); + // LOGGER_DEBUG(c->log, "ret (!= 0?): %d", ret); return ret; } @@ -3114,8 +2981,6 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // necessary -> TODO: duplicated code necessary? memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE); - // not necessary for Noise - // memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(c->rng, conn->sent_nonce); crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); @@ -3238,7 +3103,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); - // Necessary for backwards compatibility to non-Noise handshake (if enabled with option noise_compatibility_enabled) + /* Necessary for backwards compatibility to non-Noise handshake (if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; conn->cookie_request_number = random_u64(c->rng); From cea8d45e2ee8b63e72183c980215d73cf7d52d4e Mon Sep 17 00:00:00 2001 From: Tobias Buchberger Date: Fri, 14 Jun 2024 12:59:57 +0200 Subject: [PATCH 102/150] cleanup: minor cleanup of comments/documentation --- auto_tests/crypto_test.c | 8 ++++---- toxcore/crypto_core.c | 12 ++++++------ toxcore/crypto_core.h | 1 + 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 04f4bfeeae..e1c3d7d795 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -631,7 +631,7 @@ static void test_noiseik(void) // INITIATOR: END Create handshake packet for responder - // RESPONDER: Consume handshake packet from initiator + /* RESPONDER: Consume handshake packet from initiator */ Noise_Handshake *noise_handshake_responder = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); /* Troubleshooting info, intermediary values */ @@ -674,7 +674,7 @@ static void test_noiseik(void) sizeof(ciphertext2), noise_handshake_temp_key_resp, noise_handshake_responder->hash); - // RESPONDER: Create handshake packet for initiator + /* RESPONDER: Create handshake packet for initiator */ /* set ephemeral private+public */ memcpy(noise_handshake_responder->ephemeral_private, resp_ephemeral, CRYPTO_SECRET_KEY_SIZE); @@ -713,9 +713,9 @@ static void test_noiseik(void) // bin2hex_toupper(ciphertext3_print, sizeof(ciphertext3_print), ciphertext3_hs_responder, sizeof(ciphertext3_hs_responder)); // printf("Responder: HS ciphertext payload: %s\n", ciphertext3_print); - // RESPONDER: END create handshake packet for initiator# + /* RESPONDER: END create handshake packet for initiator */ - // INITIATOR: Consume handshake packet from responder + /* INITIATOR: Consume handshake packet from responder */ memcpy(noise_handshake_initiator->remote_ephemeral, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 153737d47a..e9292a4eac 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -535,7 +535,7 @@ int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) { - // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium + /* Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium */ if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { return -1; } @@ -557,7 +557,7 @@ int32_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length) { - // Additional data ad can be a NULL pointer with ad_length equal to 0; plain_length is calculated by libsodium + /* Additional data ad can be a NULL pointer with ad_length equal to 0; plain_length is calculated by libsodium */ if (encrypted_length <= CRYPTO_MAC_SIZE || shared_key == nullptr || nonce == nullptr || encrypted == nullptr || plain == nullptr) { return -1; @@ -580,7 +580,7 @@ int32_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) { - // Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium + /* Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium */ if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { return -1; } @@ -588,7 +588,7 @@ int32_t encrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ /* Passing NULL instead, encrypted length is clear anwyay (plain_length + crypto_aead_xchacha20poly1305_ietf_ABYTES) */ // unsigned long long encrypted_length = 0; - // nsec is not used by this particular construction and should always be NULL. + /* nsec is not used by this particular construction and should always be NULL. */ if (crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, NULL, plain, plain_length, ad, ad_length, nullptr, nonce, shared_key) != 0) { return -1; @@ -602,7 +602,7 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length) { - // Additional data ad can be a NULL pointer with ad_length equal to 0; plain_length is calculated by libsodium + /* Additional data ad can be a NULL pointer with ad_length equal to 0; plain_length is calculated by libsodium */ if (encrypted_length <= CRYPTO_MAC_SIZE || shared_key == nullptr || nonce == nullptr || encrypted == nullptr || plain == nullptr) { return -1; @@ -632,7 +632,7 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ // } // #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" -/* Actually only 32 bytes necessary, but test vectors still verify with 33 bytes */ +/* Actually only 32 bytes necessary (but terminator necessary for CI), but test vectors still verify with 33 bytes */ static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; /** diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 1843c2e480..2005c08932 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -664,6 +664,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, non_null(1, 2) nullable(3, 5) int noise_handshake_init (Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); +//TODO: remove // int noise_handshake_init // (const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); /** From a2da31817539815b0613f5458014994da98aade6 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sun, 17 Nov 2024 20:39:16 +0100 Subject: [PATCH 103/150] cleanup: code cleanup and documentation of net_crypto.c --- toxcore/net_crypto.c | 74 +++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 35 deletions(-) mode change 100644 => 100755 toxcore/net_crypto.c diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c old mode 100644 new mode 100755 index 1c91f6da31..66103dcf9e --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -52,18 +52,18 @@ typedef enum Crypto_Conn_State { } Crypto_Conn_State; typedef struct Crypto_Connection { - /* (Currently) all used for both non-Noise and Noise handshakes/connections */ - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ - uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ - uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ - uint8_t sessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public key for this session. */ - uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private key for this session. */ - uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. Not used in Noise handshake. */ - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. */ + /* (Currently) all used for both non-Noise and Noise handshakes/connections */ + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real/static identity public X25519 key of the peer. */ + uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ //TODO: Not use in Noise handshake + uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ //TODO: Not use in Noise handshake + uint8_t sessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public ephemeral X25519 key for this session. */ + uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private ephemeral X25519 key for this session. */ + uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public ephemeral X25519 key of the peer. Not used in Noise handshake. */ + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. (non-Noise handshake) */ Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ - uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ - + uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public X25519 key of the peer */ + bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to encrypt outgoing packets after NoiseIK handshake */ @@ -586,7 +586,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - /* Noise: Cookie from RESPONDER */ + /* Noise: Cookie from RESPONDER */ memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; @@ -669,7 +669,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - /* Noise: Cookie from INITIATOR */ + /* Noise: Cookie from INITIATOR */ memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ @@ -794,7 +794,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); - + /* s */ /* Nonce for static pub key decryption is _always_ 0 in case of ChaCha20-Poly1305 */ if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, @@ -835,14 +835,14 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - /* received base nonce (from INITIATOR) */ + /* received base nonce (from INITIATOR) */ memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); - /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ + /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); - /* necessary */ + /* necessary */ memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); @@ -893,7 +893,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t //TODO: Remove // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); - + /* Payload decryption */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; @@ -915,7 +915,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - /* neccessary, base nonce (from Noise RESPONDER) */ + /* neccessary, base nonce (from Noise RESPONDER) */ memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); /* necessary */ memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); @@ -1526,7 +1526,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ } else { /* Case non-Noise handshake */ len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); } - + if (len + 1 + sizeof(uint16_t) != packet_size) { LOGGER_ERROR(c->log, "encryption failed: %d", len); @@ -1720,7 +1720,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint length - (1 + sizeof(uint16_t)), data); } - + //TODO: remove // LOGGER_DEBUG(c->log, "data packet decrypt len: %d", len); @@ -2106,7 +2106,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); - /* Noise: noise_handshake not necessary anymore => memzero and free */ + /* Noise: noise_handshake not necessary anymore => memzero and free */ crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, conn->noise_handshake); conn->noise_handshake = nullptr; @@ -2223,7 +2223,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } - /* Noise: only necessary if Cookie response was successful */ + /* Noise: only necessary if Cookie response was successful */ if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { return -1; } @@ -2285,9 +2285,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // return -1; // } - /* necessary for Noise and non-Noise */ + /* necessary for Noise and non-Noise */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - /* necessary for Noise RESPONDER and non-Noise */ + /* necessary for Noise RESPONDER and non-Noise */ uint8_t cookie[COOKIE_LENGTH]; if (length != HANDSHAKE_PACKET_LENGTH) { @@ -2371,7 +2371,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* non-Noise handshake */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - /* necessary only for non-Noise */ + /* necessary only for non-Noise */ uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, nullptr)) { @@ -2414,16 +2414,15 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Backwards compatibility: non-Noise handshake case */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - //TODO: doesn't work if Noise handshake packet was sent before - // if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { + // if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { //TODO: doesn't work if Noise handshake packet was sent before if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } // } - /* Backwards compatibility: necessary for non-Noise handshake */ + /* Backwards compatibility: necessary for non-Noise handshake */ encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway - /* Backwards compatibility: necessary for non-Noise handshake */ + /* Backwards compatibility: necessary for non-Noise handshake */ conn->status = CRYPTO_CONN_NOT_CONFIRMED; } } else { @@ -2731,10 +2730,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, n_c.cookie_length = COOKIE_LENGTH; - /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ + /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { //TODO: adapt static allocation? - n_c.noise_handshake = &n_c.noise_handshake_data; + n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; @@ -2745,7 +2744,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); - /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ + /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ + //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); @@ -2753,7 +2753,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, mem_delete(c->mem, n_c.cookie); return -1; } - } else if (c->noise_compatibility_enabled) { /* case non-Noise handshake */ + } + /* case non-Noise handshake */ + else if (c->noise_compatibility_enabled) { LOGGER_DEBUG(c->log, "non-Noise handshake"); // Necessary for backwards compatibility n_c.noise_handshake = nullptr; @@ -2822,7 +2824,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, mem_delete(c->mem, n_c.cookie); return 0; - } else { /* case non-Noise handshake */ + } + /* case non-Noise handshake */ + else { LOGGER_DEBUG(c->log, "non-Noise handshake"); conn->noise_handshake_enabled = false; if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { @@ -3227,7 +3231,7 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port const uint8_t *data, uint16_t data_length) { return tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node, - chain_keys, chain_length, data, data_length); + chain_keys, chain_length, data, data_length); } /** @brief Copy a maximum of num random TCP relays we are connected to to tcp_relays. From d7b68143c09b9a727764f70fffd5dba8912b4bb3 Mon Sep 17 00:00:00 2001 From: goldroom Date: Tue, 3 Dec 2024 13:51:09 +0100 Subject: [PATCH 104/150] docs: Added doc and TODOs. --- toxcore/net_crypto.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 66103dcf9e..8e9a052c80 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -5,6 +5,12 @@ /** * Functions for the core network crypto. + * This implements NoiseIK: + * + * <- s + * ... + * -> e, es, s, ss + * <- e, ee, se * * NOTE: This code has to be perfect. We don't mess around with encryption. */ @@ -237,6 +243,9 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin { //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); + + //TODO: adapt for new Noise-cookie mechanism _only_ + //TODO: or different cookie mechanism? E.g. as in WireGuard? uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; memcpy(plain, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -593,6 +602,7 @@ 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); + //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise /* OtherCookie is added to payload */ if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, cookie_plain, c->secret_symmetric_key) != 0) { @@ -827,10 +837,12 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here if (open_cookie(c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { return false; } + /* Compares static identity public keys from the peer */ if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { return false; } @@ -907,10 +919,12 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here if (open_cookie(c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { return false; } + /* Compares static identity public keys from the peer */ if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { return false; } @@ -944,6 +958,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } + /* Compares static identity public keys from the peer */ if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { return false; } @@ -3028,7 +3043,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); - /* Necessary for backwards compatibility to non-Noise handshake (if enabled with option noise_compatibility_enabled) */ + /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; conn->cookie_request_number = random_u64(c->rng); From 841ba31716c8d26462476bb6aa05793008fed412 Mon Sep 17 00:00:00 2001 From: goldroom Date: Tue, 10 Dec 2024 23:41:26 +0100 Subject: [PATCH 105/150] refactor: Implemented Noise_IK_25519_ChaChaPoly_BLAKE2s instead of Noise_IK_25519_ChaChaPoly_SHA512. Verified with test vectors from Noise-C. Adapted HMAC, HKDF and noise_mix_hash() functions to use Blake2b instead of SHA512 in crypto_core. --- auto_tests/crypto_test.c | 266 ++++++++++++++++++++++++++++------- toxcore/crypto_core.c | 294 ++++++++++++++++++++++++++++++++++----- toxcore/crypto_core.h | 14 +- 3 files changed, 485 insertions(+), 89 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index e1c3d7d795..8ab5e161e8 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -357,7 +357,170 @@ static void test_memzero(void) } } -/* Noise_IK_25519_ChaChaPoly_SHA512 test vectors from here: https://github.com/rweather/noise-c/blob/cfe25410979a87391bb9ac8d4d4bef64e9f268c6/tests/vector/noise-c-basic.txt */ +//TODO: Remove if Blake2b? +// /* Noise_IK_25519_ChaChaPoly_SHA512 test vectors from here: https://github.com/rweather/noise-c/blob/cfe25410979a87391bb9ac8d4d4bef64e9f268c6/tests/vector/noise-c-basic.txt */ +// /* "init_prologue": "50726f6c6f677565313233" (same as `resp_prologue`) */ +// static const uint8_t prologue[11] = { +// 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, +// 0x31, 0x32, 0x33 +// }; + +// /* Initiator static private key +// "init_static": "e61ef9919cde45dd5f82166404bd08e38bceb5dfdfded0a34c8df7ed542214d1" */ +// static const uint8_t init_static[CRYPTO_SECRET_KEY_SIZE] = { +// 0xe6, 0x1e, 0xf9, 0x91, 0x9c, 0xde, 0x45, 0xdd, +// 0x5f, 0x82, 0x16, 0x64, 0x04, 0xbd, 0x08, 0xe3, +// 0x8b, 0xce, 0xb5, 0xdf, 0xdf, 0xde, 0xd0, 0xa3, +// 0x4c, 0x8d, 0xf7, 0xed, 0x54, 0x22, 0x14, 0xd1 +// }; + +// /* Initiator ephemeral private key +// "init_ephemeral": "893e28b9dc6ca8d611ab664754b8ceb7bac5117349a4439a6b0569da977c464a" */ +// static const uint8_t init_ephemeral[CRYPTO_SECRET_KEY_SIZE] = { +// 0x89, 0x3e, 0x28, 0xb9, 0xdc, 0x6c, 0xa8, 0xd6, +// 0x11, 0xab, 0x66, 0x47, 0x54, 0xb8, 0xce, 0xb7, +// 0xba, 0xc5, 0x11, 0x73, 0x49, 0xa4, 0x43, 0x9a, +// 0x6b, 0x05, 0x69, 0xda, 0x97, 0x7c, 0x46, 0x4a +// }; + +// /* Responder static public key +// "init_remote_static": "31e0303fd6418d2f8c0e78b91f22e8caed0fbe48656dcf4767e4834f701b8f62" */ +// static const uint8_t init_remote_static[CRYPTO_PUBLIC_KEY_SIZE] = { +// 0x31, 0xe0, 0x30, 0x3f, 0xd6, 0x41, 0x8d, 0x2f, +// 0x8c, 0x0e, 0x78, 0xb9, 0x1f, 0x22, 0xe8, 0xca, +// 0xed, 0x0f, 0xbe, 0x48, 0x65, 0x6d, 0xcf, 0x47, +// 0x67, 0xe4, 0x83, 0x4f, 0x70, 0x1b, 0x8f, 0x62 +// }; + +// /* Responder static private key +// "resp_static": "4a3acbfdb163dec651dfa3194dece676d437029c62a408b4c5ea9114246e4893" */ +// static const uint8_t resp_static[CRYPTO_SECRET_KEY_SIZE] = { +// 0x4a, 0x3a, 0xcb, 0xfd, 0xb1, 0x63, 0xde, 0xc6, +// 0x51, 0xdf, 0xa3, 0x19, 0x4d, 0xec, 0xe6, 0x76, +// 0xd4, 0x37, 0x02, 0x9c, 0x62, 0xa4, 0x08, 0xb4, +// 0xc5, 0xea, 0x91, 0x14, 0x24, 0x6e, 0x48, 0x93 +// }; + +// /* Responder ephermal private key +// "resp_ephemeral": "bbdb4cdbd309f1a1f2e1456967fe288cadd6f712d65dc7b7793d5e63da6b375b" */ +// static const uint8_t resp_ephemeral[CRYPTO_SECRET_KEY_SIZE] = { +// 0xbb, 0xdb, 0x4c, 0xdb, 0xd3, 0x09, 0xf1, 0xa1, +// 0xf2, 0xe1, 0x45, 0x69, 0x67, 0xfe, 0x28, 0x8c, +// 0xad, 0xd6, 0xf7, 0x12, 0xd6, 0x5d, 0xc7, 0xb7, +// 0x79, 0x3d, 0x5e, 0x63, 0xda, 0x6b, 0x37, 0x5b +// }; + +// /* Payload for initiator handshake message +// "payload": "4c756477696720766f6e204d69736573" */ +// static const uint8_t init_payload_hs[16] = { +// 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, +// 0x6f,0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 +// }; +// /* "ciphertext": is actually three values for initiator handshake message: +// Initiator ephemeral public key in plaintext: ca35def5ae56cec33dc2036731ab14896bc4c75dbb07a61f879f8e3afa4c7944 +// Encrypted static public key (of initiator): 7a2281c0f1aee0c48c41333a1abbb349ee4bf12e09f8c4fd66635aabbb7dad345826d359e4bd6ebee659f5c6cb3d2d4e +// Encrypted payload: d12f7c7ffc9fe5513818d9cf9b8778d1502f90649c42ab4a1e3df7199a3d6a13 */ +// static const uint8_t init_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { +// 0xca, 0x35, 0xde, 0xf5, 0xae, 0x56, 0xce, 0xc3, +// 0x3d, 0xc2, 0x03, 0x67, 0x31, 0xab, 0x14, 0x89, +// 0x6b, 0xc4, 0xc7, 0x5d, 0xbb, 0x07, 0xa6, 0x1f, +// 0x87, 0x9f, 0x8e, 0x3a, 0xfa, 0x4c, 0x79, 0x44 +// }; +// static const uint8_t init_encrypted_static_public[CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE] = { +// 0x7a, 0x22, 0x81, 0xc0, 0xf1, 0xae, 0xe0, 0xc4, +// 0x8c, 0x41, 0x33, 0x3a, 0x1a, 0xbb, 0xb3, 0x49, +// 0xee, 0x4b, 0xf1, 0x2e, 0x09, 0xf8, 0xc4, 0xfd, +// 0x66, 0x63, 0x5a, 0xab, 0xbb, 0x7d, 0xad, 0x34, +// 0x58, 0x26, 0xd3, 0x59, 0xe4, 0xbd, 0x6e, 0xbe, +// 0xe6, 0x59, 0xf5, 0xc6, 0xcb, 0x3d, 0x2d, 0x4e +// }; +// static const uint8_t init_payload_hs_encrypted[sizeof(init_payload_hs)+CRYPTO_MAC_SIZE] = { +// 0xd1, 0x2f, 0x7c, 0x7f, 0xfc, 0x9f, 0xe5, 0x51, +// 0x38, 0x18, 0xd9, 0xcf, 0x9b, 0x87, 0x78, 0xd1, +// 0x50, 0x2f, 0x90, 0x64, 0x9c, 0x42, 0xab, 0x4a, +// 0x1e, 0x3d, 0xf7, 0x19, 0x9a, 0x3d, 0x6a, 0x13 +// }; + +// /* Payload for responder handshake message +// "payload": "4d757272617920526f746862617264", */ +// static const uint8_t resp_payload_hs[15] = { +// 0x4d, 0x75, 0x72, 0x72, 0x61, 0x79, 0x20, 0x52, +// 0x6f, 0x74, 0x68, 0x62, 0x61, 0x72, 0x64 +// }; +// /* "ciphertext": is actually two values for responder handshake message: +// Responder ephemeral public key in plaintext: 95ebc60d2b1fa672c1f46a8aa265ef51bfe38e7ccb39ec5be34069f144808843 +// Encrypted payload: f58050451a0edd2a40bb8b0f6b51ea63e1f1f429f1afd583e5d6e53f44da1e */ +// static const uint8_t resp_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { +// 0x95, 0xeb, 0xc6, 0x0d, 0x2b, 0x1f, 0xa6, 0x72, +// 0xc1, 0xf4, 0x6a, 0x8a, 0xa2, 0x65, 0xef, 0x51, +// 0xbf, 0xe3, 0x8e, 0x7c, 0xcb, 0x39, 0xec, 0x5b, +// 0xe3, 0x40, 0x69, 0xf1, 0x44, 0x80, 0x88, 0x43 +// }; +// static const uint8_t resp_payload_hs_encrypted[sizeof(resp_payload_hs)+CRYPTO_MAC_SIZE] = { +// 0xf5, 0x80, 0x50, 0x45, 0x1a, 0x0e, 0xdd, 0x2a, +// 0x40, 0xbb, 0x8b, 0x0f, 0x6b, 0x51, 0xea, 0x63, +// 0xe1, 0xf1, 0xf4, 0x29, 0xf1, 0xaf, 0xd5, 0x83, +// 0xe5, 0xd6, 0xe5, 0x3f, 0x44, 0xda, 0x1e +// }; + +// /* Payload for initiator transport message 1 +// "payload": "462e20412e20486179656b" */ +// static const uint8_t init_payload_transport1[11] = { +// 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, +// 0x79, +// 0x65, 0x6b +// }; +// /* Payload ciphertext for initiator transport message 1 +// "ciphertext": "cae0b6af5460d026e80e22c27572a92048176872538f91a056a8df" */ +// static const uint8_t init_payload_transport1_encrypted[sizeof(init_payload_transport1)+CRYPTO_MAC_SIZE] = { +// 0xca, 0xe0, 0xb6, 0xaf, 0x54, 0x60, 0xd0, 0x26, +// 0xe8, 0x0e, 0x22, 0xc2, 0x75, 0x72, 0xa9, 0x20, +// 0x48, 0x17, 0x68, 0x72, 0x53, 0x8f, 0x91, 0xa0, +// 0x56, 0xa8, 0xdf +// }; + +// /* Payload for responder transport message 1 +// "payload": "4361726c204d656e676572" */ +// static const uint8_t resp_payload_transport1[11] = { +// 0x43, 0x61, 0x72, 0x6c, 0x20, 0x4d, 0x65, 0x6e, +// 0x67, 0x65, 0x72 +// }; +// /* Payload ciphertext for responder transport message 1 +// "ciphertext": "ab1440d2b5892c638a11a7fa6412beaea5cee62342147f02d75a68" */ +// static const uint8_t resp_payload_transport1_encrypted[sizeof(resp_payload_transport1)+CRYPTO_MAC_SIZE] = { +// 0xab, 0x14 , 0x40 , 0xd2, 0xb5, 0x89, 0x2c, 0x63, +// 0x8a, 0x11, 0xa7, 0xfa, 0x64, 0x12, 0xbe, 0xae, +// 0xa5, 0xce, 0xe6, 0x23, 0x42, 0x14, 0x7f, 0x02, +// 0xd7, 0x5a, 0x68 +// }; + +// /* Final handshake hash value (MUST be the same for both initiator and responder) +// "handshake_hash": "48d8b650f042c4767cf1f3c26b22ccdd4bc8cff341166603109954eab8a9bd20915d284b6b618a325e93a8e949a23f4b62ba3094aad0b640c14cbd4f14ccd1e1" */ +// static const uint8_t handshake_hash[CRYPTO_SHA512_SIZE] = { +// 0x48 ,0xd8, 0xb6, 0x50, 0xf0, 0x42, 0xc4, 0x76, +// 0x7c, 0xf1, 0xf3, 0xc2, 0x6b, 0x22, 0xcc, 0xdd, +// 0x4b, 0xc8, 0xcf, 0xf3, 0x41, 0x16, 0x66, 0x03, +// 0x10, 0x99, 0x54, 0xea, 0xb8, 0xa9, 0xbd, 0x20, +// 0x91, 0x5d, 0x28, 0x4b, 0x6b, 0x61, 0x8a, 0x32, +// 0x5e, 0x93, 0xa8, 0xe9, 0x49, 0xa2, 0x3f, 0x4b, +// 0x62, 0xba, 0x30, 0x94, 0xaa, 0xd0, 0xb6, 0x40, +// 0xc1, 0x4c, 0xbd, 0x4f, 0x14, 0xcc, 0xd1, 0xe1 +// }; + +/* TODO: Currently unused */ +// // 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 +// static const uint8_t init_payload_transport2[17] = { +// 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, +// 0x74, 0x65, 0x20, 0x53, 0x61, 0x79 +// }; + +// // 45 75 67 65 6e 20 42 f6 68 6d 20 76 6f 6e 20 42 61 77 65 72 6b +// static const uint8_t payload_transport_responder2[21] = { +// 0x45, 0x75, 0x67, 0x65, 0x6e, 0x20, 0x42, 0xf6, 0x68, 0x6d, 0x20, +// 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b +// }; + +/* Noise_IK_25519_ChaChaPoly_BLAKE2b test vectors from here: https://github.com/rweather/noise-c/blob/cfe25410979a87391bb9ac8d4d4bef64e9f268c6/tests/vector/noise-c-basic.txt */ /* "init_prologue": "50726f6c6f677565313233" (same as `resp_prologue`) */ static const uint8_t prologue[11] = { 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, @@ -415,10 +578,10 @@ static const uint8_t init_payload_hs[16] = { 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, 0x6f,0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 }; -/* "ciphertext": is actually three values for initiator handshake message: +/* "ciphertext": is actually three values for initiator handshake message: Initiator ephemeral public key in plaintext: ca35def5ae56cec33dc2036731ab14896bc4c75dbb07a61f879f8e3afa4c7944 - Encrypted static public key (of initiator): 7a2281c0f1aee0c48c41333a1abbb349ee4bf12e09f8c4fd66635aabbb7dad345826d359e4bd6ebee659f5c6cb3d2d4e - Encrypted payload: d12f7c7ffc9fe5513818d9cf9b8778d1502f90649c42ab4a1e3df7199a3d6a13 */ + Encrypted static public key (of initiator): ba83a447b38c83e327ad936929812f624884847b7831e95e197b2f797088efdd232fe541af156ec6d0657602902a8c3e + Encrypted payload: e64e470f4b6fcd9298ce0b56fe20f86e60d9d933ec6e103ffb09e6001d6abb64*/ static const uint8_t init_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { 0xca, 0x35, 0xde, 0xf5, 0xae, 0x56, 0xce, 0xc3, 0x3d, 0xc2, 0x03, 0x67, 0x31, 0xab, 0x14, 0x89, @@ -426,18 +589,18 @@ static const uint8_t init_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { 0x87, 0x9f, 0x8e, 0x3a, 0xfa, 0x4c, 0x79, 0x44 }; static const uint8_t init_encrypted_static_public[CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE] = { - 0x7a, 0x22, 0x81, 0xc0, 0xf1, 0xae, 0xe0, 0xc4, - 0x8c, 0x41, 0x33, 0x3a, 0x1a, 0xbb, 0xb3, 0x49, - 0xee, 0x4b, 0xf1, 0x2e, 0x09, 0xf8, 0xc4, 0xfd, - 0x66, 0x63, 0x5a, 0xab, 0xbb, 0x7d, 0xad, 0x34, - 0x58, 0x26, 0xd3, 0x59, 0xe4, 0xbd, 0x6e, 0xbe, - 0xe6, 0x59, 0xf5, 0xc6, 0xcb, 0x3d, 0x2d, 0x4e + 0xba, 0x83, 0xa4, 0x47, 0xb3, 0x8c, 0x83, 0xe3, + 0x27, 0xad, 0x93, 0x69, 0x29, 0x81, 0x2f, 0x62, + 0x48, 0x84, 0x84, 0x7b, 0x78, 0x31, 0xe9, 0x5e, + 0x19, 0x7b, 0x2f, 0x79, 0x70, 0x88, 0xef, 0xdd, + 0x23, 0x2f, 0xe5, 0x41, 0xaf, 0x15, 0x6e, 0xc6, + 0xd0, 0x65, 0x76, 0x02, 0x90, 0x2a, 0x8c, 0x3e }; static const uint8_t init_payload_hs_encrypted[sizeof(init_payload_hs)+CRYPTO_MAC_SIZE] = { - 0xd1, 0x2f, 0x7c, 0x7f, 0xfc, 0x9f, 0xe5, 0x51, - 0x38, 0x18, 0xd9, 0xcf, 0x9b, 0x87, 0x78, 0xd1, - 0x50, 0x2f, 0x90, 0x64, 0x9c, 0x42, 0xab, 0x4a, - 0x1e, 0x3d, 0xf7, 0x19, 0x9a, 0x3d, 0x6a, 0x13 + 0xe6, 0x4e, 0x47, 0x0f, 0x4b, 0x6f, 0xcd, 0x92, + 0x98, 0xce, 0x0b, 0x56, 0xfe, 0x20, 0xf8, 0x6e, + 0x60, 0xd9, 0xd9, 0x33, 0xec, 0x6e, 0x10, 0x3f, + 0xfb, 0x09, 0xe6, 0x00, 0x1d, 0x6a, 0xbb, 0x64 }; /* Payload for responder handshake message @@ -447,8 +610,10 @@ static const uint8_t resp_payload_hs[15] = { 0x6f, 0x74, 0x68, 0x62, 0x61, 0x72, 0x64 }; /* "ciphertext": is actually two values for responder handshake message: - Responder ephemeral public key in plaintext: 95ebc60d2b1fa672c1f46a8aa265ef51bfe38e7ccb39ec5be34069f144808843 - Encrypted payload: f58050451a0edd2a40bb8b0f6b51ea63e1f1f429f1afd583e5d6e53f44da1e */ + Responder ephemeral public key in plaintext: + 95ebc60d2b1fa672c1f46a8aa265ef51bfe38e7ccb39ec5be34069f144808843 + Encrypted payload: + 9f069b267a06b3de3ecb1043bcb09807c6cd101f3826192a65f11ef3fe4317 */ static const uint8_t resp_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { 0x95, 0xeb, 0xc6, 0x0d, 0x2b, 0x1f, 0xa6, 0x72, 0xc1, 0xf4, 0x6a, 0x8a, 0xa2, 0x65, 0xef, 0x51, @@ -456,26 +621,25 @@ static const uint8_t resp_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { 0xe3, 0x40, 0x69, 0xf1, 0x44, 0x80, 0x88, 0x43 }; static const uint8_t resp_payload_hs_encrypted[sizeof(resp_payload_hs)+CRYPTO_MAC_SIZE] = { - 0xf5, 0x80, 0x50, 0x45, 0x1a, 0x0e, 0xdd, 0x2a, - 0x40, 0xbb, 0x8b, 0x0f, 0x6b, 0x51, 0xea, 0x63, - 0xe1, 0xf1, 0xf4, 0x29, 0xf1, 0xaf, 0xd5, 0x83, - 0xe5, 0xd6, 0xe5, 0x3f, 0x44, 0xda, 0x1e + 0x9f, 0x06, 0x9b, 0x26, 0x7a, 0x06, 0xb3, 0xde, + 0x3e, 0xcb, 0x10, 0x43, 0xbc, 0xb0, 0x98, 0x07, + 0xc6, 0xcd, 0x10, 0x1f, 0x38, 0x26, 0x19, 0x2a, + 0x65, 0xf1, 0x1e, 0xf3, 0xfe, 0x43, 0x17 }; /* Payload for initiator transport message 1 "payload": "462e20412e20486179656b" */ static const uint8_t init_payload_transport1[11] = { 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, - 0x79, - 0x65, 0x6b + 0x79, 0x65, 0x6b }; /* Payload ciphertext for initiator transport message 1 - "ciphertext": "cae0b6af5460d026e80e22c27572a92048176872538f91a056a8df" */ + "ciphertext": "cd54383060e7a28434cca27fb1cc524cfbabeb18181589df219d07" */ static const uint8_t init_payload_transport1_encrypted[sizeof(init_payload_transport1)+CRYPTO_MAC_SIZE] = { - 0xca, 0xe0, 0xb6, 0xaf, 0x54, 0x60, 0xd0, 0x26, - 0xe8, 0x0e, 0x22, 0xc2, 0x75, 0x72, 0xa9, 0x20, - 0x48, 0x17, 0x68, 0x72, 0x53, 0x8f, 0x91, 0xa0, - 0x56, 0xa8, 0xdf + 0xcd, 0x54, 0x38, 0x30, 0x60, 0xe7, 0xa2, 0x84, + 0x34, 0xcc, 0xa2, 0x7f, 0xb1, 0xcc, 0x52, 0x4c, + 0xfb, 0xab, 0xeb, 0x18, 0x18, 0x15, 0x89, 0xdf, + 0x21, 0x9d, 0x07 }; /* Payload for responder transport message 1 @@ -485,39 +649,32 @@ static const uint8_t resp_payload_transport1[11] = { 0x67, 0x65, 0x72 }; /* Payload ciphertext for responder transport message 1 - "ciphertext": "ab1440d2b5892c638a11a7fa6412beaea5cee62342147f02d75a68" */ + "ciphertext": "a856d3bf0246bfc476c655009cd1ed677b8dcc5b349ae8ef2a05f2" */ static const uint8_t resp_payload_transport1_encrypted[sizeof(resp_payload_transport1)+CRYPTO_MAC_SIZE] = { - 0xab, 0x14 , 0x40 , 0xd2, 0xb5, 0x89, 0x2c, 0x63, - 0x8a, 0x11, 0xa7, 0xfa, 0x64, 0x12, 0xbe, 0xae, - 0xa5, 0xce, 0xe6, 0x23, 0x42, 0x14, 0x7f, 0x02, - 0xd7, 0x5a, 0x68 + 0xa8, 0x56, 0xd3, 0xbf, 0x02, 0x46, 0xbf, 0xc4, + 0x76, 0xc6, 0x55, 0x00, 0x9c, 0xd1, 0xed, 0x67, + 0x7b, 0x8d, 0xcc, 0x5b, 0x34, 0x9a, 0xe8, 0xef, + 0x2a, 0x05, 0xf2 }; /* Final handshake hash value (MUST be the same for both initiator and responder) - "handshake_hash": "48d8b650f042c4767cf1f3c26b22ccdd4bc8cff341166603109954eab8a9bd20915d284b6b618a325e93a8e949a23f4b62ba3094aad0b640c14cbd4f14ccd1e1" */ + "handshake_hash": "00e51d2aac81a9b8ebe441d6af3e1c8efc0f030cc608332edcb42588ff6a0ce26415ddc106e95277a5e6d54132f1e5245976b89caf96d262f1fe5a7f0c55c078" */ static const uint8_t handshake_hash[CRYPTO_SHA512_SIZE] = { - 0x48 ,0xd8, 0xb6, 0x50, 0xf0, 0x42, 0xc4, 0x76, - 0x7c, 0xf1, 0xf3, 0xc2, 0x6b, 0x22, 0xcc, 0xdd, - 0x4b, 0xc8, 0xcf, 0xf3, 0x41, 0x16, 0x66, 0x03, - 0x10, 0x99, 0x54, 0xea, 0xb8, 0xa9, 0xbd, 0x20, - 0x91, 0x5d, 0x28, 0x4b, 0x6b, 0x61, 0x8a, 0x32, - 0x5e, 0x93, 0xa8, 0xe9, 0x49, 0xa2, 0x3f, 0x4b, - 0x62, 0xba, 0x30, 0x94, 0xaa, 0xd0, 0xb6, 0x40, - 0xc1, 0x4c, 0xbd, 0x4f, 0x14, 0xcc, 0xd1, 0xe1 + 0x00, 0xe5, 0x1d, 0x2a, 0xac, 0x81, 0xa9, 0xb8, + 0xeb, 0xe4, 0x41, 0xd6, 0xaf, 0x3e, 0x1c, 0x8e, + 0xfc, 0x0f, 0x03, 0x0c, 0xc6, 0x08, 0x33, 0x2e, + 0xdc, 0xb4, 0x25, 0x88, 0xff, 0x6a, 0x0c, 0xe2, + 0x64, 0x15, 0xdd, 0xc1, 0x06, 0xe9, 0x52, 0x77, + 0xa5, 0xe6, 0xd5, 0x41, 0x32, 0xf1, 0xe5, 0x24, + 0x59, 0x76, 0xb8, 0x9c, 0xaf, 0x96, 0xd2, 0x62, + 0xf1, 0xfe, 0x5a, 0x7f, 0x0c, 0x55, 0xc0, 0x78 }; -/* Currently unused */ -// // 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 -// static const uint8_t init_payload_transport2[17] = { -// 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, -// 0x74, 0x65, 0x20, 0x53, 0x61, 0x79 -// }; +//TODO: "payload": "4a65616e2d426170746973746520536179", +//TODO: "ciphertext": "49063084b2c51f098337cb8a13739ac848f907e67cfb2cc8a8b60586467aa02fc7" -// // 45 75 67 65 6e 20 42 f6 68 6d 20 76 6f 6e 20 42 61 77 65 72 6b -// static const uint8_t payload_transport_responder2[21] = { -// 0x45, 0x75, 0x67, 0x65, 0x6e, 0x20, 0x42, 0xf6, 0x68, 0x6d, 0x20, -// 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b -// }; +//TODO: "payload": "457567656e2042f6686d20766f6e2042617765726b", +//TODO: "ciphertext": "8b9709d23b47e4639df7678d7a21741eba4ef1e9c60383001c7435549c20f9d56f30e935d3" static void test_noiseik(void) { @@ -587,13 +744,14 @@ static void test_noiseik(void) noise_encrypt_and_hash(ciphertext1, noise_handshake_initiator->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake_initiator->hash); - ck_assert_msg(memcmp(ciphertext1, init_encrypted_static_public, CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE) == 0, "initiator encrypted static public keys differ"); - /* Troubleshooting info, intermediary values */ // char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; // bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); // printf("Initiator: HS ciphertext static pub key: %s\n", ciphertext1_print); + ck_assert_msg(memcmp(ciphertext1, init_encrypted_static_public, CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE) == 0, "initiator encrypted static public keys differ"); + + //TODO: remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index e9292a4eac..3f6de34c73 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -6,6 +6,7 @@ #include "crypto_core.h" #include +#include #include #include @@ -13,6 +14,7 @@ #include "attributes.h" #include "ccompat.h" +#include "tox.h" #include "util.h" static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES, @@ -633,8 +635,11 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ // #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" /* Actually only 32 bytes necessary (but terminator necessary for CI), but test vectors still verify with 33 bytes */ -static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; +//TODO: Remove if Blake2b +// static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; +static const uint8_t noise_protocol[34] = "Noise_IK_25519_ChaChaPoly_BLAKE2b"; +//TODO: remove, unused function /** * cf. Noise sections 4.3 and 5.1 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. @@ -645,12 +650,101 @@ static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ -void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, +void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_length) { crypto_auth_hmacsha512(auth, data, data_length, key); } +/** + * cf. Noise sections 4.3 and 5.1 + * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=BLAKE2b) function. + * This function is only called via `crypto_hkdf()`. + * Necessary for Noise (cf. sections 4.3 and 12.8) to return 64 bytes (BLAKE2b HASHLEN). + * Cf. https://doc.libsodium.org/hashing/generic_hashing + * TODO: Still true? + * key is CRYPTO_BLAKE2b_HASH_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) + * is always HASHLEN bytes. + */ +void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_length, const uint8_t *key, + size_t key_length) +{ + crypto_generichash_blake2b_state state; + + /* + * (1) append zeros to the end of K to create a B byte string (e.g., if K is of length 20 bytes and B=64, + * then K will be appended with 44 zero bytes 0x00) + * B = Blake2b block length = 128 + * L the byte-length of Blake2b hash output = 64 + */ + uint8_t x_key[CRYPTO_BLAKE2b_BLOCK_SIZE] = { 0 }; + uint8_t i_hash[CRYPTO_BLAKE2b_HASH_SIZE]; + int i; + + /* + * The authentication key K can be of any length up to B, the + * block length of the hash function. Applications that use keys longer + * than B bytes will first hash the key using H and then use the + * resultant L byte string as the actual key to HMAC. + * In any case the minimal recommended length for K is L bytes (as the hash output + * length). + */ + if (key_length > CRYPTO_BLAKE2b_BLOCK_SIZE) { + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_update(&state, key, key_length); + crypto_generichash_blake2b_final(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); + } else { + memcpy(x_key, key, key_length); + } + + /* + * K XOR ipad, ipad = the byte 0x36 repeated B times + * (2) XOR (bitwise exclusive-OR) the B byte string computed in step + * (1) with ipad + */ + for (i = 0; i < CRYPTO_BLAKE2b_BLOCK_SIZE; ++i) { + x_key[i] ^= 0x36; + } + + /* + * H(K XOR ipad, text) + * (3) append the stream of data 'text' to the B byte string resulting + from step (2) + (4) apply H to the stream generated in step (3) + */ + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_update(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); + crypto_generichash_blake2b_update(&state, in, in_length); + crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + + /* + * K XOR opad, opad = the byte 0x5C repeated B times + * (5) XOR (bitwise exclusive-OR) the B byte string computed in + step (1) with opad + */ + for (i = 0; i < CRYPTO_BLAKE2b_BLOCK_SIZE; ++i) { + x_key[i] ^= 0x5c ^ 0x36; + } + + /* + * H(K XOR opad, H(K XOR ipad, text)) + * (6) append the H result from step (4) to the B byte string + resulting from step (5) + (7) apply H to the stream generated in step (6) and output + the result + */ + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_update(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); + crypto_generichash_blake2b_update(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + + memcpy(out, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + + /* Clear sensitive data from stack */ + crypto_memzero(x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); + crypto_memzero(i_hash, CRYPTO_BLAKE2b_HASH_SIZE); +} + /* This is Hugo Krawczyk's HKDF (i.e. HKDF-SHA512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 @@ -669,48 +763,111 @@ void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_S * length. Also note that the HKDF() function is simply HKDF with the * chaining_key as HKDF salt, and zero-length HKDF info. */ +// void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, +// size_t second_len, const uint8_t *data, +// size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) +// { +// /* Implementing HKDF-SHA512 based on libsodium `crypto_auth_hmacsha512()` and WireGuard leads to wrong results. +// Verified using Noise_IK_25519_ChaChaPoly_SHA512 test vectors. Keeping for documentation purposes. */ +// // uint8_t output[CRYPTO_SHA512_SIZE + 1]; +// // temp_key = secret in WG +// uint8_t temp_key[CRYPTO_SHA512_SIZE]; + +// /* Extract entropy from data into temp_key */ +// /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). +// Result is a pseudo random key (PRK) = temp_key */ +// /* data => input_key_material => X25519-DH result in Noise */ +// /* TODO: This is correct, same result as libsodium `crypto_kdf_hkdf_sha512_extract()` */ +// // crypto_hmac512(temp_key, chaining_key, data, data_len); +// /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. +// Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ +// crypto_kdf_hkdf_sha512_extract(temp_key, chaining_key, CRYPTO_SHA512_SIZE, data, data_len); + +// /* Expand first key: key = temp_key, data = 0x1 */ +// /* TODO: Result not correct, unsure why */ +// // output[0] = 1; +// // crypto_hmac512(output, temp_key, output, 1); +// // memcpy(output1, output, first_len); + +// /* Expand both keys in one operation (verified): */ +// /* HKDF-Expand(PRK, info, L) -> OKM, where PRK = temp_key, zero-length HKDF info (ctx) +// and L (length of output keying material in octets) = 2*64 byte (i.e. 2x HashLen) */ +// /* OKM = HKDF -> T(0) + T(1); cf. RFC5869: https://datatracker.ietf.org/doc/html/rfc5869#section-2.3 */ +// /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ +// uint8_t output_temp[CRYPTO_SHA512_SIZE*2]; +// crypto_kdf_hkdf_sha512_expand(output_temp, CRYPTO_SHA512_SIZE*2, nullptr, 0, temp_key); +// memcpy(output1, output_temp, first_len); +// memcpy(output2, output_temp + CRYPTO_SHA512_SIZE, second_len); + +// /* Expand second key: key = secret, data = first-key || 0x2 */ +// /* TODO: Not correct, unsure why */ +// // output[CRYPTO_SHA512_SIZE] = 2; +// // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); +// // memcpy(output2, output, second_len); + +// /* Expand third key: key = temp_key, data = second-key || 0x3 */ +// /* Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ +// // output[CRYPTO_SHA512_SIZE] = 3; +// // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); +// // memcpy(output3, output, third_len); + +// /* Clear sensitive data from stack */ +// crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); +// // crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); +// crypto_memzero(output_temp, CRYPTO_SHA512_SIZE*2); +// } + +/* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b): + * - https://eprint.iacr.org/2010/264.pdf + * - https://tools.ietf.org/html/rfc5869 + * HKDF(chaining_key, input_key_material, num_outputs): Takes a + * chaining_key byte sequence of length HASHLEN, and an input_key_material + * byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes. + * Returns a pair or triple of byte sequences each of length HASHLEN, + * depending on whether num_outputs is two or three: + * – Sets temp_key = HMAC-HASH(chaining_key, input_key_material). + * – Sets output1 = HMAC-HASH(temp_key, byte(0x01)). + * – Sets output2 = HMAC-HASH(temp_key, output1 || byte(0x02)). + * – If num_outputs == 2 then returns the pair (output1, output2). + * – Sets output3 = HMAC-HASH(temp_key, output2 || byte(0x03)). + * – Returns the triple (output1, output2, output3). + * Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in + * length. Also note that the HKDF() function is simply HKDF with the + * chaining_key as HKDF salt, and zero-length HKDF info. + * + * Verified using Noise_IK_25519_ChaChaPoly_BLAKE2b test vectors. + */ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, size_t second_len, const uint8_t *data, - size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) + size_t data_len, const uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE]) { - /* Implementing HKDF-SHA512 based on libsodium `crypto_auth_hmacsha512()` and WireGuard leads to wrong results. - Verified using Noise_IK_25519_ChaChaPoly_SHA512 test vectors. Keeping for documentation purposes. */ - // uint8_t output[CRYPTO_SHA512_SIZE + 1]; + uint8_t output[CRYPTO_BLAKE2b_HASH_SIZE + 1]; // temp_key = secret in WG - - uint8_t temp_key[CRYPTO_SHA512_SIZE]; + uint8_t temp_key[CRYPTO_BLAKE2b_HASH_SIZE]; /* Extract entropy from data into temp_key */ /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). Result is a pseudo random key (PRK) = temp_key */ /* data => input_key_material => X25519-DH result in Noise */ - /* TODO: This is correct, same result as libsodium `crypto_kdf_hkdf_sha512_extract()` */ - // crypto_hmac512(temp_key, chaining_key, data, data_len); + crypto_hmac_blake2b512(temp_key, data, data_len, chaining_key, CRYPTO_BLAKE2b_HASH_SIZE); /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ - crypto_kdf_hkdf_sha512_extract(temp_key, chaining_key, CRYPTO_SHA512_SIZE, data, data_len); /* Expand first key: key = temp_key, data = 0x1 */ - /* TODO: Result not correct, unsure why */ - // output[0] = 1; - // crypto_hmac512(output, temp_key, output, 1); - // memcpy(output1, output, first_len); + output[0] = 1; + crypto_hmac_blake2b512(output, output, 1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(output1, output, first_len); /* Expand both keys in one operation (verified): */ /* HKDF-Expand(PRK, info, L) -> OKM, where PRK = temp_key, zero-length HKDF info (ctx) and L (length of output keying material in octets) = 2*64 byte (i.e. 2x HashLen) */ /* OKM = HKDF -> T(0) + T(1); cf. RFC5869: https://datatracker.ietf.org/doc/html/rfc5869#section-2.3 */ /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ - uint8_t output_temp[CRYPTO_SHA512_SIZE*2]; - crypto_kdf_hkdf_sha512_expand(output_temp, CRYPTO_SHA512_SIZE*2, nullptr, 0, temp_key); - memcpy(output1, output_temp, first_len); - memcpy(output2, output_temp + CRYPTO_SHA512_SIZE, second_len); /* Expand second key: key = secret, data = first-key || 0x2 */ - /* TODO: Not correct, unsure why */ - // output[CRYPTO_SHA512_SIZE] = 2; - // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); - // memcpy(output2, output, second_len); + output[CRYPTO_SHA512_SIZE] = 2; + crypto_hmac_blake2b512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ /* Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ @@ -720,8 +877,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* Clear sensitive data from stack */ crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); - // crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); - crypto_memzero(output_temp, CRYPTO_SHA512_SIZE*2); + crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); } /* @@ -731,8 +887,43 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * - If HASHLEN is 64, then truncates temp_k to 32 bytes * - Calls InitializeKey(temp_k). * input_key_material = DH_X25519(private, public) + * + * based on HKDF-SHA512 */ -int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], +// int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], +// uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], +// const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], +// const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) +// { +// uint8_t dh_calculation[CRYPTO_SHARED_KEY_SIZE]; +// memset(dh_calculation, 0, CRYPTO_SHARED_KEY_SIZE); + +// /* X25519: returns plain DH result, afterwards hashed with HKDF (necessary for NoiseIK) */ +// if (crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { +// return -1; +// } + +// /* chaining_key is HKDF output1 and shared_key is HKDF output2 => different values/results! */ +// /* If HASHLEN is 64, then truncates temp_k (= shared_key) to 32 bytes. => done via call to crypto_hkdf() */ +// crypto_hkdf(chaining_key, CRYPTO_SHA512_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, +// CRYPTO_SHARED_KEY_SIZE, chaining_key); + +// crypto_memzero(dh_calculation, CRYPTO_SHARED_KEY_SIZE); + +// return 0; +// } + +/* + * cf. Noise section 5.2 + * Executes the following steps: + * - Sets ck, temp_k = HKDF(ck, input_key_material, 2). + * - If HASHLEN is 64, then truncates temp_k to 32 bytes + * - Calls InitializeKey(temp_k). + * input_key_material = DH_X25519(private, public) + * + * based on HKDF-BLAKE2b + */ +int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) @@ -747,7 +938,7 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], /* chaining_key is HKDF output1 and shared_key is HKDF output2 => different values/results! */ /* If HASHLEN is 64, then truncates temp_k (= shared_key) to 32 bytes. => done via call to crypto_hkdf() */ - crypto_hkdf(chaining_key, CRYPTO_SHA512_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, + crypto_hkdf(chaining_key, CRYPTO_BLAKE2b_HASH_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, CRYPTO_SHARED_KEY_SIZE, chaining_key); crypto_memzero(dh_calculation, CRYPTO_SHARED_KEY_SIZE); @@ -757,17 +948,40 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], /* * Noise MixHash(data): Sets h = HASH(h || data). + * SHA512 + * + * cf. Noise section 5.2 + */ +// void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) +// { +// //TODO: not necessary with Blake2b +// VLA(uint8_t, to_hash, CRYPTO_SHA512_SIZE + data_len); +// memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); +// if (data != nullptr) { +// memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); +// } +// // crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); + +// crypto_generichash_blake2b_state state; +// crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); +// crypto_generichash_blake2b_update(&state, hash, CRYPTO_BLAKE2b_HASH_SIZE); +// crypto_generichash_blake2b_update(&state, data, data_len); +// crypto_generichash_blake2b_final(&state, hash, CRYPTO_BLAKE2b_HASH_SIZE); +// } + +/* + * Noise MixHash(data): Sets h = HASH(h || data). + * Blake2b * * cf. Noise section 5.2 */ -void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) +void noise_mix_hash(uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE], const uint8_t *data, size_t data_len) { - VLA(uint8_t, to_hash, CRYPTO_SHA512_SIZE + data_len); - memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); - if (data != nullptr) { - memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); - } - crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); + crypto_generichash_blake2b_state state; + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_update(&state, hash, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_update(&state, data, data_len); + crypto_generichash_blake2b_final(&state, hash, CRYPTO_BLAKE2b_HASH_SIZE); } /* @@ -909,6 +1123,8 @@ int noise_handshake_init /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); + //TODO(goldroom): precompute static static here (ss)? cf. WireGuard wg_noise_handshake_init() + //TODO: remove // if (log != nullptr) { // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); @@ -919,3 +1135,13 @@ int noise_handshake_init /* Ready to go */ return 0; } + +//TODO(goldroom): abstract creation and handling of NoiseIK handshake packets from net_crypto (_after_ cookie adaption) +// /* Noise create INITIATOR: -> e, es, s, ss */ +// int noise_handshake_create_initiator() +// /* Noise handle INITIATOR: -> e, es, s, ss */ +// int noise_handshake_handle_initiator() +// /* Noise create RESPONDER: <- e, ee, se */ +// int noise_handshake_create_responder() +// /* Noise handle RESPONDER: <- e, ee, se */ +// int noise_handshake_handle_responder() diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 2005c08932..5db6a0b29d 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -82,6 +82,16 @@ extern "C" { */ #define CRYPTO_SHA512_SIZE 64 +/** + * @brief The number of bytes in a BLAKE2b hash. + */ +#define CRYPTO_BLAKE2b_HASH_SIZE 64 + +/** + * @brief The number of bytes in a BLAKE2b block. + */ +#define CRYPTO_BLAKE2b_BLOCK_SIZE 128 + /** @brief Fill a byte array with random bytes. * * This is the key generator callback and as such must be a cryptographically @@ -126,6 +136,8 @@ typedef struct Noise_Handshake { uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; + //TODO(goldroom): precompute static static? cf. WireGuard struct noise_handshake + // uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t hash[CRYPTO_SHA512_SIZE]; uint8_t chaining_key[CRYPTO_SHA512_SIZE]; @@ -601,7 +613,7 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ * @param key Secret key */ non_null(1, 2) nullable(3) -void crypto_hmac512(uint8_t auth[CRYPTO_SHA512_SIZE], const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, +void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_length); /** From c8130b88bcc01bb2e4ca45557135fdf3dd9b52a8 Mon Sep 17 00:00:00 2001 From: goldroom Date: Tue, 10 Dec 2024 23:46:00 +0100 Subject: [PATCH 106/150] fix: added static --- toxcore/crypto_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 3f6de34c73..aaccdf41cd 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -666,7 +666,7 @@ void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const * key is CRYPTO_BLAKE2b_HASH_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ -void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_length, const uint8_t *key, +static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_length, const uint8_t *key, size_t key_length) { crypto_generichash_blake2b_state state; From 39736cb11e54e004ba385db2835c0fa0e23ce6a1 Mon Sep 17 00:00:00 2001 From: goldroom Date: Tue, 10 Dec 2024 23:49:21 +0100 Subject: [PATCH 107/150] fix: fixed include, not sure where that came from --- toxcore/crypto_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index aaccdf41cd..ba373f4cfe 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -14,7 +14,6 @@ #include "attributes.h" #include "ccompat.h" -#include "tox.h" #include "util.h" static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES, From 87e6350aec11934c62a467df23f6159b12af11eb Mon Sep 17 00:00:00 2001 From: goldroom Date: Wed, 11 Dec 2024 13:48:05 +0100 Subject: [PATCH 108/150] fix: fixes after master merge --- third_party/cmp | 2 +- toxcore/crypto_core.c | 1 - toxcore/net_crypto.c | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/third_party/cmp b/third_party/cmp index 52bfcfa17d..2ac6bca152 160000 --- a/third_party/cmp +++ b/third_party/cmp @@ -1 +1 @@ -Subproject commit 52bfcfa17d2eb4322da2037ad625f5575129cece +Subproject commit 2ac6bca152987c805c04423ebbba4b750585337f diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 044aed5931..bb99b8c7e6 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -6,7 +6,6 @@ #include "crypto_core.h" #include -#include #include #include diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index f8bdffc8a0..c9d1afe815 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -604,7 +604,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise /* OtherCookie is added to payload */ - if (create_cookie(c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, + if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } @@ -838,7 +838,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here - if (open_cookie(c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { return false; } @@ -920,7 +920,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here - if (open_cookie(c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { return false; } From cabca2ae0a9cb179a1519a256c5bf81170435ef9 Mon Sep 17 00:00:00 2001 From: goldroom Date: Wed, 11 Dec 2024 14:01:08 +0100 Subject: [PATCH 109/150] fix: formatting after merge, ASAN caught memory leak in crypto_test.c --- auto_tests/crypto_test.c | 3 +++ toxcore/net_crypto.c | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index e433146996..a77319cfe3 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -971,6 +971,9 @@ static void test_noiseik(void) // char ciphertext5_transport1_responder_print[sizeof(ciphertext5_transport1_responder) * 2 + 1]; // bin2hex_toupper(ciphertext5_transport1_responder_print, sizeof(ciphertext5_transport1_responder_print), ciphertext5_transport1_responder, sizeof(ciphertext5_transport1_responder)); // printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length_ciphertext5_transport1_responder, ciphertext5_transport1_responder_print); + + free(noise_handshake_initiator); + free(noise_handshake_responder); } int main(void) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index c9d1afe815..994e353fe8 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -706,14 +706,14 @@ 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->mem, 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; - } + if (create_cookie(c->mem, 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(c->rng, packet + 1 + COOKIE_LENGTH); - const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), - packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); + random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); + const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), + packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { return -1; @@ -954,9 +954,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { - return false; - } + if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + return false; + } /* Compares static identity public keys from the peer */ if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { @@ -966,10 +966,10 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); - uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, - packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, - HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); + uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; + const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, + packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, + HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); if (len != sizeof(plain)) { return false; From fa59b7b6b7c52491c99ce47bb55ada58edb1d3ee Mon Sep 17 00:00:00 2001 From: goldroom Date: Wed, 18 Dec 2024 16:32:54 +0100 Subject: [PATCH 110/150] feat: started implementation of (possible) new cookie functionality. --- toxcore/crypto_core.c | 65 ++++++++++++++++++++++++++++++------------- toxcore/crypto_core.h | 22 ++++++++++++++- toxcore/net_crypto.c | 54 ++++++++++++++++++++++++++++++----- toxcore/net_crypto.h | 1 + 4 files changed, 115 insertions(+), 27 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index bb99b8c7e6..f33f73d531 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -46,6 +46,8 @@ static_assert(CRYPTO_SIGN_PUBLIC_KEY_SIZE == crypto_sign_PUBLICKEYBYTES, static_assert(CRYPTO_SIGN_SECRET_KEY_SIZE == crypto_sign_SECRETKEYBYTES, "CRYPTO_SIGN_SECRET_KEY_SIZE should be equal to crypto_sign_SECRETKEYBYTES"); +//TODO: add static_assert for NoiseIK sizes + bool create_extended_keypair(Extended_Public_Key *pk, Extended_Secret_Key *sk, const Random *rng) { /* create signature key pair */ @@ -638,12 +640,31 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ // } // #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" -/* Actually only 32 bytes necessary (but terminator necessary for CI), but test vectors still verify with 33 bytes */ //TODO: Remove if Blake2b +/* Actually only 32 bytes necessary (but terminator necessary for CI), but test vectors still verify with 33 bytes */ // static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; +/* Actually only 33 bytes necessary (but terminator necessary for CI), but test vectors still verify with 34 bytes */ static const uint8_t noise_protocol[34] = "Noise_IK_25519_ChaChaPoly_BLAKE2b"; -//TODO: remove, unused function +/* MAC key as input for crypto_mac_blake2b_128() */ +void precompute_mac_key(uint8_t out_mac_key[CRYPTO_SYMMETRIC_KEY_SIZE], + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t label[CRYPTO_COOKIE_LABEL_SIZE]) +{ + crypto_generichash_blake2b_state state; + + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_SYMMETRIC_KEY_SIZE); + crypto_generichash_blake2b_update(&state, label, CRYPTO_COOKIE_LABEL_SIZE); + crypto_generichash_blake2b_update(&state, public_key, CRYPTO_PUBLIC_KEY_SIZE); + crypto_generichash_blake2b_final(&state, out_mac_key, CRYPTO_SYMMETRIC_KEY_SIZE); +} + +//TODO: Mac(key, input) Keyed-Blake2b(key, input, 16), the keyed MAC variant of the BLAKE2b hash function, returning 16 bytes of output. +void crypto_mac_blake2b_128(uint8_t *out_mac, const uint8_t *key, size_t key_length, const uint8_t *in, size_t in_length) { + crypto_generichash(out_mac, CRYPTO_BLAKE2b_MAC_SIZE, in, in_length, key, key_length); +} + +//TODO: remove if Blake2b /** * cf. Noise sections 4.3 and 5.1 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. @@ -654,23 +675,25 @@ static const uint8_t noise_protocol[34] = "Noise_IK_25519_ChaChaPoly_BLAKE2b"; * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ -void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, - size_t data_length) -{ - crypto_auth_hmacsha512(auth, data, data_length, key); -} +// void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, +// size_t data_length) +// { +// crypto_auth_hmacsha512(auth, data, data_length, key); +// } /** - * cf. Noise sections 4.3 and 5.1 + * cf. Noise sections 4.3, 5.1 and 12.8: HMAC-BLAKE2b-512 + * HASH(input): BLAKE2b with digest length 64 + * HASHLEN = 64 + * BLOCKLEN = 128 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=BLAKE2b) function. * This function is only called via `crypto_hkdf()`. * Necessary for Noise (cf. sections 4.3 and 12.8) to return 64 bytes (BLAKE2b HASHLEN). * Cf. https://doc.libsodium.org/hashing/generic_hashing - * TODO: Still true? - * key is CRYPTO_BLAKE2b_HASH_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) + * TODO: key is CRYPTO_BLAKE2b_HASH_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ -static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_length, const uint8_t *key, +static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t in_length, const uint8_t *key, size_t key_length) { crypto_generichash_blake2b_state state; @@ -742,13 +765,14 @@ static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_le crypto_generichash_blake2b_update(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); - memcpy(out, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(out_hmac, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); /* Clear sensitive data from stack */ crypto_memzero(x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); crypto_memzero(i_hash, CRYPTO_BLAKE2b_HASH_SIZE); } +//TODO: remove if Blake2b /* This is Hugo Krawczyk's HKDF (i.e. HKDF-SHA512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 @@ -821,7 +845,7 @@ static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_le // crypto_memzero(output_temp, CRYPTO_SHA512_SIZE*2); // } -/* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b): +/* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b-512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 * HKDF(chaining_key, input_key_material, num_outputs): Takes a @@ -839,6 +863,10 @@ static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_le * length. Also note that the HKDF() function is simply HKDF with the * chaining_key as HKDF salt, and zero-length HKDF info. * + * HASH(input): BLAKE2b with digest length 64. + * HASHLEN = 64 + * BLOCKLEN = 128 + * * Verified using Noise_IK_25519_ChaChaPoly_BLAKE2b test vectors. */ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, @@ -853,13 +881,13 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). Result is a pseudo random key (PRK) = temp_key */ /* data => input_key_material => X25519-DH result in Noise */ - crypto_hmac_blake2b512(temp_key, data, data_len, chaining_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(temp_key, data, data_len, chaining_key, CRYPTO_BLAKE2b_HASH_SIZE); /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ /* Expand first key: key = temp_key, data = 0x1 */ output[0] = 1; - crypto_hmac_blake2b512(output, output, 1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(output, output, 1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(output1, output, first_len); /* Expand both keys in one operation (verified): */ @@ -870,11 +898,11 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* Expand second key: key = secret, data = first-key || 0x2 */ output[CRYPTO_SHA512_SIZE] = 2; - crypto_hmac_blake2b512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ - /* Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ + /* TODO: urrently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ // output[CRYPTO_SHA512_SIZE] = 3; // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); // memcpy(output3, output, third_len); @@ -918,14 +946,13 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // } /* - * cf. Noise section 5.2 + * cf. Noise section 5.2: based on HKDF-BLAKE2b * Executes the following steps: * - Sets ck, temp_k = HKDF(ck, input_key_material, 2). * - If HASHLEN is 64, then truncates temp_k to 32 bytes * - Calls InitializeKey(temp_k). * input_key_material = DH_X25519(private, public) * - * based on HKDF-BLAKE2b */ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 0196c37678..dc5a96caf3 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -84,7 +84,12 @@ extern "C" { #define CRYPTO_SHA512_SIZE 64 /** - * @brief The number of bytes in a BLAKE2b hash. + * @brief The number of bytes in a BLAKE2b-128 MAC. + */ +#define CRYPTO_BLAKE2b_MAC_SIZE 16 + +/** + * @brief The number of bytes in a BLAKE2b-512 hash. */ #define CRYPTO_BLAKE2b_HASH_SIZE 64 @@ -93,6 +98,14 @@ extern "C" { */ #define CRYPTO_BLAKE2b_BLOCK_SIZE 128 +/** + * @brief The number of bytes in a cookie label. + */ +#define CRYPTO_COOKIE_LABEL_SIZE 8 + +// #define NOISE_MAC1_KEY_LABEL "mac1----" +// #define NOISE_COOKIE_KEY_LABEL "cookie--" + /** @brief Fill a byte array with random bytes. * * This is the key generator callback and as such must be a cryptographically @@ -602,6 +615,13 @@ non_null(1, 2, 3, 5) nullable(6) int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); +//TODO: comment +/* MAC key as input for crypto_mac_blake2b_128() */ +non_null() +void precompute_mac_key(uint8_t out_mac_key[CRYPTO_SYMMETRIC_KEY_SIZE], + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t label[CRYPTO_COOKIE_LABEL_SIZE]); + /** * @brief Compute an HMAC-SHA512 authenticator (64 bytes). * diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 994e353fe8..3e0452c8b2 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -170,6 +170,9 @@ struct Net_Crypto { /* The secret key used for cookies */ uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + /* The secret key used for mac1 */ + uint8_t mac1_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + new_connection_cb *new_connection_callback; void *new_connection_callback_object; @@ -228,6 +231,9 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti #define COOKIE_REQUEST_LENGTH (uint16_t)(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) #define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) +static const uint8_t noise_mac1_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "mac1----"; +static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; + /** @brief Create a cookie request packet and put it in packet. * * dht_public_key is the dht public key of the other @@ -267,6 +273,8 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin } return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len; + + } /** @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key @@ -543,7 +551,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise Handshake"); /* Noise INITIATOR: -> e, es, s, ss */ - /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -557,6 +565,24 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [MAC encrypted payload 16 bytes] => 345 bytes in total */ + /* TODO: New Cookies + Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + [uint8_t 26] + [session public key of the peer (32 bytes)] => currently in plain + ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 + [encrypted static public key of the INITIATOR (32 bytes)] + [MAC encrypted static pubkey 16 bytes] + ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 + [Encrypted message containing: + ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ + //TODO: EchoID + [current ephemeral dht public key of the peer (32 bytes)] => necessary for the NoiseIK responder + [16 bytes "Other" (i.e. INITIATOR) Cookie (used by the other peer to respond to the handshake packet)] + [MAC encrypted payload 16 bytes] + [MAC1 16 bytes] + [MAC2 16 bytes] + => 177 bytes in total + */ if (noise_handshake->initiator) { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); @@ -634,7 +660,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* Noise RESPONDER: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -645,6 +671,18 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [MAC encrypted payload 16 bytes] => ~~321~~ 185 bytes in total */ + /* TODO: New Cookies + Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + [uint8_t 26] + [session public key of the peer (32 bytes)] => currently in plain + ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 + [Encrypted message containing: + ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ + [MAC encrypted payload 16 bytes] + [MAC1 16 bytes] + [MAC2 16 bytes] + => 81 bytes in total + */ else { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); @@ -760,7 +798,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_SHA512) + /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -865,7 +903,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -2386,9 +2424,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* non-Noise handshake */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - /* necessary only for non-Noise */ - uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, + /* TODO: NOT necessary only for non-Noise */ + // uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, nullptr, dht_public_key, cookie, packet, length, conn->public_key, nullptr)) { return -1; } @@ -4022,6 +4060,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r new_keys(temp); new_symmetric_key(rng, temp->secret_symmetric_key); + precompute_mac_key(temp->mac1_symmetric_key, dht_get_self_public_key(dht), noise_mac1_key_label); temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; @@ -4078,6 +4117,7 @@ uint32_t crypto_run_interval(const Net_Crypto *c) /** Main loop. */ void do_net_crypto(Net_Crypto *c, void *userdata) { + //TODO: update cookie symmetric key every ~2 minutes (cf. WireGuard)? kill_timedout(c, userdata); do_tcp(c, userdata); send_crypto_packets(c); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 3a9c7b78b7..828cab3383 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -134,6 +134,7 @@ typedef struct New_Connection { uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ // Necessary for Noise + //TODO: refactor to not use struct Noise_Handshake noise_handshake_data; Noise_Handshake *noise_handshake; //TODO: if no struct necessary From b3d73e2cb6f4d5fdb4d78683f36f79b97a6bb38d Mon Sep 17 00:00:00 2001 From: goldroom Date: Wed, 18 Dec 2024 16:54:40 +0100 Subject: [PATCH 111/150] fix: fixes for CI. --- toxcore/crypto_core.c | 1 + toxcore/crypto_core.h | 7 ++++++- toxcore/net_crypto.c | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index f33f73d531..34e106dfb2 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -660,6 +660,7 @@ void precompute_mac_key(uint8_t out_mac_key[CRYPTO_SYMMETRIC_KEY_SIZE], } //TODO: Mac(key, input) Keyed-Blake2b(key, input, 16), the keyed MAC variant of the BLAKE2b hash function, returning 16 bytes of output. +//TODO: static? void crypto_mac_blake2b_128(uint8_t *out_mac, const uint8_t *key, size_t key_length, const uint8_t *in, size_t in_length) { crypto_generichash(out_mac, CRYPTO_BLAKE2b_MAC_SIZE, in, in_length, key, key_length); } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index dc5a96caf3..5a58e91f68 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -100,8 +100,9 @@ extern "C" { /** * @brief The number of bytes in a cookie label. + * Actually only 8 bytes necessary (but terminator necessary for CI) */ -#define CRYPTO_COOKIE_LABEL_SIZE 8 +#define CRYPTO_COOKIE_LABEL_SIZE 9 // #define NOISE_MAC1_KEY_LABEL "mac1----" // #define NOISE_COOKIE_KEY_LABEL "cookie--" @@ -622,6 +623,10 @@ void precompute_mac_key(uint8_t out_mac_key[CRYPTO_SYMMETRIC_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t label[CRYPTO_COOKIE_LABEL_SIZE]); +//TODO: Mac(key, input) Keyed-Blake2b(key, input, 16), the keyed MAC variant of the BLAKE2b hash function, returning 16 bytes of output. +non_null() +void crypto_mac_blake2b_128(uint8_t *out_mac, const uint8_t *key, size_t key_length, const uint8_t *in, size_t in_length); + /** * @brief Compute an HMAC-SHA512 authenticator (64 bytes). * diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 3e0452c8b2..7b8e2c7945 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -232,7 +232,8 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti #define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) static const uint8_t noise_mac1_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "mac1----"; -static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; +//TODO: uncomment when used (currently commented for CI) +// static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; /** @brief Create a cookie request packet and put it in packet. * From fdb0163e6e2a9173322e096538b14649d8cac868 Mon Sep 17 00:00:00 2001 From: goldroom Date: Thu, 19 Dec 2024 22:02:45 +0100 Subject: [PATCH 112/150] feat: implementation of (possible) new cookie functionality. --- toxcore/net_crypto.c | 841 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 725 insertions(+), 116 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 7b8e2c7945..5d18d2859a 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -68,7 +68,7 @@ typedef struct Crypto_Connection { uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. (non-Noise handshake) */ Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ - uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public X25519 key of the peer */ + uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public X25519 key of the peer */ bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ @@ -168,10 +168,12 @@ struct Net_Crypto { uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; /* The secret key used for cookies */ - uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + uint8_t cookie_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; /* The secret key used for mac1 */ uint8_t mac1_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + /* The secret key used for mac1 */ + uint8_t cookie_xaead_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; new_connection_cb *new_connection_callback; void *new_connection_callback_object; @@ -225,15 +227,19 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti #define COOKIE_TIMEOUT 15 #define COOKIE_DATA_LENGTH (uint16_t)(CRYPTO_PUBLIC_KEY_SIZE * 2) #define COOKIE_CONTENTS_LENGTH (uint16_t)(sizeof(uint64_t) + COOKIE_DATA_LENGTH) +#define NOISE_COOKIE_LENGTH 16 +#define NOISE_MAC1_LENGTH 16 +#define NOISE_MAC2_LENGTH NOISE_MAC1_LENGTH #define COOKIE_LENGTH (uint16_t)(CRYPTO_NONCE_SIZE + COOKIE_CONTENTS_LENGTH + CRYPTO_MAC_SIZE) #define COOKIE_REQUEST_PLAIN_LENGTH (uint16_t)(COOKIE_DATA_LENGTH + sizeof(uint64_t)) #define COOKIE_REQUEST_LENGTH (uint16_t)(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) #define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) +#define NOISE_COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE) static const uint8_t noise_mac1_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "mac1----"; //TODO: uncomment when used (currently commented for CI) -// static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; +static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; /** @brief Create a cookie request packet and put it in packet. * @@ -301,6 +307,27 @@ static int create_cookie(const Memory *mem, const Random *rng, const Mono_Time * return 0; } +/** @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key + * + * @param cookie must be NOISE_COOKIE_LENGTH bytes. + * @param cookie_symmetric_key must be of size CRYPTO_SYMMETRIC_KEY_SIZE or bigger. Symmetric encryption key for τ := Mac(Rm, Am') + * @param source IP+Port of the peer this cookie is intended for. + * + * Am' represents a concatenation of the peer's external IP source address and source port + * + * @retval -1 on failure. + * @retval 0 on success. + */ +non_null() +static void noise_create_cookie(uint8_t cookie[NOISE_COOKIE_LENGTH], + const uint8_t cookie_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE], + const IP_Port *source) +{ + // calculate τ := Mac(Rm, Am′) + //TODO: change cookie symmetric key or hash timestamp into? + crypto_mac_blake2b_128(cookie, cookie_symmetric_key, CRYPTO_SECRET_KEY_SIZE, (uint8_t *) source, sizeof(struct IP_Port)); +} + /** @brief Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key * * @retval -1 on failure. @@ -347,7 +374,7 @@ 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->mem, c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { + if (create_cookie(c->mem, c->rng, c->mono_time, plain, cookie_plain, c->cookie_symmetric_key) != 0) { return -1; } @@ -363,6 +390,40 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui return COOKIE_RESPONSE_LENGTH; } +/** @brief Create a cookie response packet and put it in packet. + * + * @param packet must be of size NOISE_COOKIE_RESPONSE_LENGTH. + * @param source IP+Port of the peer this cookie response is intended for. + * @param noise_mac1_received MAC1 value of peer's handshake packet. + * + * @retval -1 on failure. + * @retval NOISE_COOKIE_RESPONSE_LENGTH on success. + */ +non_null() +static int noise_create_cookie_response(const Net_Crypto *c, uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], const IP_Port *source, + const uint8_t noise_mac1_received[NOISE_MAC1_LENGTH]) +{ + LOGGER_DEBUG(c->log, "ENTERING"); + // symmetric_cookie_encryption_key based on label + DHT public key + // handshake packet mac1 value (of the peer) + uint8_t noise_cookie[NOISE_COOKIE_LENGTH]; + + noise_create_cookie(noise_cookie, c->cookie_symmetric_key, source); + + packet[0] = NET_PACKET_COOKIE_RESPONSE; + // random nonce + random_nonce(c->rng, packet + 1); + // calculate msg.cookie := Xaead(Hash(Label-Cookie ‖ Spub m ), msg.nonce, τ, M ) + const int len = encrypt_data_symmetric_xaead(c->cookie_xaead_symmetric_key, packet + 1, noise_cookie, + NOISE_COOKIE_LENGTH, packet + 1 + CRYPTO_NONCE_SIZE, noise_mac1_received, NOISE_MAC1_LENGTH); + + if (len != (NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE)) { + return -1; + } + + return NOISE_COOKIE_RESPONSE_LENGTH; +} + /** @brief Handle the cookie request packet of length length. * Put what was in the request in request_plain (must be of size COOKIE_REQUEST_PLAIN_LENGTH) * Put the key used to decrypt the request into shared_key (of size CRYPTO_SHARED_KEY_SIZE) for use in the response. @@ -506,6 +567,37 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * return COOKIE_LENGTH; } +/** @brief Handle a cookie response packet of length encrypted with shared_key. + * put the cookie in the response in cookie + * + * @param cookie must be of length COOKIE_LENGTH. + * + * @retval -1 on failure. + * @retval COOKIE_LENGTH on success. + */ +non_null() +static int noise_handle_cookie_response(const Memory *mem, uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH], + const uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], + const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t noise_mac1_sent[NOISE_MAC1_LENGTH]) +{ + // if (length != COOKIE_RESPONSE_LENGTH) { + // return -1; + // } + + uint8_t peer_cookie_xaead_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + precompute_mac_key(peer_cookie_xaead_symmetric_key, peer_dht_public_key, noise_cookie_key_label); + + // decrypt msg.cookie := Xaead(Hash(Label-Cookie ‖ Spub m ), msg.nonce, τ, M ) + const int len = decrypt_data_symmetric_xaead(peer_cookie_xaead_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, + NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE, noise_peer_cookie, noise_mac1_sent, NOISE_MAC1_LENGTH); + + if (len != NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE) { + return -1; + } + + return NOISE_COOKIE_LENGTH; +} + /* * TODO: Helper function to print hashes, keys, packets, etc. * TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? @@ -518,12 +610,231 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte /* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -/* Noise: Necessary for Noise-based handshake */ -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) - +/* Noise: Necessary for Noise-based handshake (non-Noise cookie phase + Noise_IK_25519_ChaChaPoly_SHA512) */ +// #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +// #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +// #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) +// #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) + +/* Noise: Necessary for Noise-based handshake (Noise cookie phase + Noise_IK_25519_ChaChaPoly_BLAKE2b) */ +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER 0 + + +// /** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. +// * +// * cf. Noise section 5.3 -> WriteMessage(payload, message_buffer) +// * +// * @param cookie must be COOKIE_LENGTH bytes. +// * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. +// * @param nonce base nonce for this Tox instance, to be used for transport message encryption after handshake +// * @param ephemeral_private Ephemeral private X25519 key of this Tox instance for this handshake +// * @param ephemeral_public Ephemeral public X25519 key of this Tox instance for this handshake +// * @param peer_real_pk X25519 static ID public key from peer to connect to +// * @param peer_dht_pubkey X25519 DHT public key from peer to connect to +// * @param noise_handshake struct containing Noise information/values +// * +// * @retval -1 on failure. +// * @retval HANDSHAKE_PACKET_LENGTH on success (non-Noise handshake). +// * @retval NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR if Noise handshake initiator +// * @retval NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER if Noise handshake responder +// * +// */ +// non_null(1, 2, 3, 4, 6, 7, 8) nullable(5, 9) +// static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, +// const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake) +// { +// LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); +// /* Noise-based handshake */ +// if (noise_handshake != nullptr) { +// LOGGER_DEBUG(c->log, "Noise Handshake"); +// /* Noise INITIATOR: -> e, es, s, ss */ +// /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) +// [uint8_t 26] +// [session public key of the peer (32 bytes)] => currently in plain +// ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 +// [encrypted static public key of the INITIATOR (32 bytes)] +// [MAC encrypted static pubkey 16 bytes] +// ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 +// [Encrypted message containing: +// [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake +// [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD +// [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] +// [MAC encrypted payload 16 bytes] +// => 345 bytes in total +// */ +// if (noise_handshake->initiator) { +// /* set ephemeral private+public */ +// memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); +// memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + +// /* e */ +// memcpy(packet + 1, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); +// noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + +// //TODO: remove from production code +// // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; +// // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); + +// /* es */ +// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; +// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); + +// /* s */ +// /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ +// noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, +// noise_handshake->hash); + +// //TODO: remove from production code +// // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; +// // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); +// char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; +// bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); +// LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); + +// /* ss */ +// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); + +// /* Noise Handshake Payload */ +// uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; +// memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); + +// /* Noise: Cookie from RESPONDER */ +// memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + +// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; +// memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + +// //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise +// /* OtherCookie is added to payload */ +// if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, +// cookie_plain, c->cookie_symmetric_key) != 0) { +// return -1; +// } + +// /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ +// noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, +// handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, +// noise_handshake->hash); + +// //TODO: remove from production code +// // LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); +// // char log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*2+1]; +// // bytes2string(log_ciphertext, sizeof(log_ciphertext), (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE), +// // (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); +// // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); + +// packet[0] = NET_PACKET_CRYPTO_HS; + +// //TODO: remove from production code +// // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; +// // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); +// // LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); + +// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); +// crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); + +// return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; +// } +// /* Noise RESPONDER: <- e, ee, se */ +// /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) +// [uint8_t 26] +// [session public key of the peer (32 bytes)] => currently in plain +// ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 +// [Encrypted message containing: +// [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake +// [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD +// ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK +// [MAC encrypted payload 16 bytes] +// => ~~321~~ 185 bytes in total +// */ +// else { +// /* set ephemeral private+public */ +// memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); +// memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + +// /* e */ +// memcpy(packet + 1, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); +// noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + +// //TODO: Remove +// // char log_ck[CRYPTO_SHA512_SIZE*2+1]; +// // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "RESPONDER pre ee ck: %s", log_ck); + +// /* ee */ +// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; +// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); + +// //TODO: Remove +// // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; +// // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "RESPONDER ee temp_key: %s", log_temp_key); + +// /* se */ +// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); + +// //TODO: Remove +// // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); + +// /* Create Noise Handshake Payload */ +// uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; +// memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); + +// /* Noise: Cookie from INITIATOR */ +// memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + +// /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ +// noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, +// handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, +// noise_handshake->hash); + +// packet[0] = NET_PACKET_CRYPTO_HS; + +// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); +// crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); + +// return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; +// } +// } +// /* non-Noise handshake, check for enabled backwards compatibility happens in create_send_handshake() */ +// else { +// LOGGER_DEBUG(c->log, "non-Noise handshake"); +// uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; +// memcpy(plain, nonce, CRYPTO_NONCE_SIZE); +// memcpy(plain + CRYPTO_NONCE_SIZE, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); +// crypto_sha512(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, cookie, COOKIE_LENGTH); +// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; +// 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->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, +// cookie_plain, c->cookie_symmetric_key) != 0) { +// return -1; +// } + +// random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); +// const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), +// packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); + +// if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { +// return -1; +// } + +// packet[0] = NET_PACKET_CRYPTO_HS; +// memcpy(packet + 1, cookie, COOKIE_LENGTH); + +// return HANDSHAKE_PACKET_LENGTH; +// } +// } + +//TODO: adapt for new cookie phase and handshake /** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. * * cf. Noise section 5.3 -> WriteMessage(payload, message_buffer) @@ -545,27 +856,14 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte */ non_null(1, 2, 3, 4, 6, 7, 8) nullable(5, 9) static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, - const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake) + const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake, + const IP_Port *source) { LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); /* Noise-based handshake */ if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise Handshake"); /* Noise INITIATOR: -> e, es, s, ss */ - /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) - [uint8_t 26] - [session public key of the peer (32 bytes)] => currently in plain - ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 - [encrypted static public key of the INITIATOR (32 bytes)] - [MAC encrypted static pubkey 16 bytes] - ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD - [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] - [MAC encrypted payload 16 bytes] - => 345 bytes in total - */ /* TODO: New Cookies Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] @@ -576,15 +874,15 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ - //TODO: EchoID - [current ephemeral dht public key of the peer (32 bytes)] => necessary for the NoiseIK responder - [16 bytes "Other" (i.e. INITIATOR) Cookie (used by the other peer to respond to the handshake packet)] + [current ephemeral DHT public key of the INITIATOR (32 bytes)] => necessary for the NoiseIK responder + [16 bytes INITIATOR cookie (used by the RESPONDER peer to respond to the handshake packet)] + [current timestamp (8 bytes)] [MAC encrypted payload 16 bytes] [MAC1 16 bytes] [MAC2 16 bytes] - => 177 bytes in total + => 185 bytes in total = (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) */ - if (noise_handshake->initiator) { + if (noise_handshake->initiator) { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -620,21 +918,16 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; - memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - - /* Noise: Cookie from RESPONDER */ - memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + memcpy(handshake_payload_plain, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + /* Noise: Cookie from INITIATOR */ + uint8_t noise_cookie_initiator[NOISE_COOKIE_LENGTH]; + noise_create_cookie(noise_cookie_initiator, c->cookie_symmetric_key, source); + memcpy(handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE, noise_cookie_initiator, NOISE_COOKIE_LENGTH); - //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise - /* OtherCookie is added to payload */ - if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, - cookie_plain, c->secret_symmetric_key) != 0) { - return -1; - } + //TODO: create timestamp and memcpy + const uint64_t noise_temp_time = mono_time_get(c->mono_time); + memcpy(handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH, &noise_temp_time, sizeof(noise_temp_time)); /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, @@ -650,6 +943,21 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u packet[0] = NET_PACKET_CRYPTO_HS; + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); + uint8_t mac1[NOISE_MAC1_LENGTH]; + + crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, + mac1, NOISE_MAC1_LENGTH); + + /* MAC2 is 16 zero bytes at first */ + //TODO: if cookie is NULL + memset(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + 0, NOISE_MAC2_LENGTH); + //TODO: remove from production code // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); @@ -661,17 +969,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* Noise RESPONDER: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) - [uint8_t 26] - [session public key of the peer (32 bytes)] => currently in plain - ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 - [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD - ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK - [MAC encrypted payload 16 bytes] - => ~~321~~ 185 bytes in total - */ /* TODO: New Cookies Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] @@ -679,10 +976,11 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ + //TODO: add timestamp here? [MAC encrypted payload 16 bytes] [MAC1 16 bytes] [MAC2 16 bytes] - => 81 bytes in total + => 81 bytes in total => (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) */ else { /* set ephemeral private+public */ @@ -716,10 +1014,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; - memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - - /* Noise: Cookie from INITIATOR */ - memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, @@ -728,6 +1022,21 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u packet[0] = NET_PACKET_CRYPTO_HS; + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); + uint8_t mac1[NOISE_MAC1_LENGTH]; + + crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + mac1, NOISE_MAC1_LENGTH); + + uint8_t mac2[NOISE_MAC2_LENGTH]; + crypto_mac_blake2b_128(mac2, cookie, NOISE_COOKIE_LENGTH, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); + memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC2_LENGTH, + mac2, NOISE_MAC2_LENGTH); + crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); @@ -746,7 +1055,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); if (create_cookie(c->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, - cookie_plain, c->secret_symmetric_key) != 0) { + cookie_plain, c->cookie_symmetric_key) != 0) { return -1; } @@ -765,6 +1074,273 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u } } +// /** @brief Handle a crypto handshake packet of length. +// * put the base nonce contained in the packet in nonce, +// * the session public key in session_pk +// * the real public key of the peer in peer_real_pk +// * the dht public key of the peer in dht_public_key and +// * the cookie inside the encrypted part of the packet in cookie. +// * Currently supports noise-Noise and Noise handshake +// * +// * if expected_real_pk isn't NULL it denotes the real public key +// * the packet should be from. +// * +// * nonce must be at least CRYPTO_NONCE_SIZE +// * session_pk must be at least CRYPTO_PUBLIC_KEY_SIZE +// * peer_real_pk must be at least CRYPTO_PUBLIC_KEY_SIZE +// * cookie must be at least COOKIE_LENGTH +// * +// * cf. Noise section 5.3 -> ReadMessage(payload, message_buffer) +// * +// * @retval false on failure. +// * @retval true on success. +// */ +// non_null(1, 2, 5, 7) nullable(3, 4, 6, 9, 10) +// static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, +// uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, +// Noise_Handshake *noise_handshake) +// { +// LOGGER_DEBUG(c->log, "ENTERING"); +// /* Noise-based handshake */ +// if (noise_handshake != nullptr) { +// LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); + +// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + +// /* -> e, es, s, ss */ +// /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_BLAKE2b) +// [uint8_t 26] +// [session public key of the peer (32 bytes)] => currently in plain +// ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 +// [encrypted static public key of the INITIATOR (32 bytes)] +// [MAC encrypted static pubkey 16 bytes] +// ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 +// [Encrypted message containing: +// [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake +// [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD +// [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] +// [MAC encrypted payload 16 bytes] +// => 345 bytes in total +// */ +// if (!noise_handshake->initiator) { +// LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); +// if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { +// return false; +// } + +// //TODO: remove from production code +// // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; +// // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); +// // LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); + +// //TODO: Check here if remote_ephemeral is already the same ephemeral key? + +// /* e */ +// memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); +// noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + +// //TODO: remove from production code +// // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; +// // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); +// // char log_static[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; +// // bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "local static pub: %s", log_static); +// // bytes2string(log_static, sizeof(log_static), noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "remote ephemeral: %s", log_static); + +// /* es */ +// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; +// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); + +// /* s */ +// /* Nonce for static pub key decryption is _always_ 0 in case of ChaCha20-Poly1305 */ +// if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, +// noise_handshake_temp_key, noise_handshake->hash) != CRYPTO_PUBLIC_KEY_SIZE) { +// LOGGER_DEBUG(c->log, "RESPONDER: Noise ReadMessage remote static decryption failed"); +// return false; +// } + +// //TODO: remove +// // bytes2string(log_static, sizeof(log_static), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "local remote pub: %s", log_static); + +// //TODO: remove from production code +// // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; +// // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); + +// /* ss */ +// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); +// /* Payload decryption */ +// uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; + +// /* Nonce for payload decryption is _always_ 0 in case of ChaCha20-Poly1305 */ +// if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, +// sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, +// noise_handshake->hash) != sizeof(handshake_payload_plain)) { +// LOGGER_DEBUG(c->log, "RESPONDER: Noise HS payload decryption failed"); +// return false; +// } + +// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + +// //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here +// if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->cookie_symmetric_key) != 0) { +// return false; +// } + +// /* Compares static identity public keys from the peer */ +// if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { +// return false; +// } + +// /* received base nonce (from INITIATOR) */ +// memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); +// /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ +// memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); +// /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ +// //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? +// memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); +// /* necessary */ +// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); +// //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const +// // crypto_memzero(packet, length); + +// crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); + +// LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); +// return true; +// } +// /* Noise ReadMessage() if initiator: <- e, ee, se */ +// /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) +// [uint8_t 26] +// [session public key of the peer (32 bytes)] => currently in plain +// ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 +// [Encrypted message containing: +// [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake +// [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD +// ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK +// [MAC encrypted payload 16 bytes] +// => ~~321~~ 185 bytes in total +// */ +// else { +// LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); + +// if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { +// return false; +// } + +// memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); +// noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); + +// //TODO: Remove +// // char log_ck[CRYPTO_SHA512_SIZE*2+1]; +// // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "INITIATOR pre ee ck: %s", log_ck); + +// /* ee */ +// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; +// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); + +// //TODO: Remove +// // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; +// // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "INITIATOR ee temp_key: %s", log_temp_key); + +// /* se */ +// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); +// //TODO: Remove +// // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); +// // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); + +// /* Payload decryption */ +// uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; + +// /* Nonce for payload decryption is 0 in case of ChaCha20-Poly1305 */ +// if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, +// sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, +// noise_handshake->hash) != sizeof(handshake_payload_plain)) { +// LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); +// return false; +// } + +// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + +// //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here +// if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->cookie_symmetric_key) != 0) { +// return false; +// } + +// /* Compares static identity public keys from the peer */ +// if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { +// return false; +// } + +// /* neccessary, base nonce (from Noise RESPONDER) */ +// memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); +// /* necessary */ +// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + +// //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const +// // crypto_memzero(packet, length); + +// crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); + + +// LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); +// return true; +// } +// } +// /* non-Noise handshake, check for enabled backwards compatibility happens in calling functions */ +// else { +// LOGGER_DEBUG(c->log, "non-Noise handshake"); + +// if (length != HANDSHAKE_PACKET_LENGTH) { +// return false; +// } + +// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + +// if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->cookie_symmetric_key) != 0) { +// return false; +// } + +// /* Compares static identity public keys from the peer */ +// if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { +// return false; +// } + +// uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; +// crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); + +// uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; +// const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, +// packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, +// HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); + +// if (len != sizeof(plain)) { +// return false; +// } + +// if (!crypto_sha512_eq(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE)) { +// return false; +// } + +// memcpy(nonce, plain, CRYPTO_NONCE_SIZE); +// memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); +// memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); +// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + +// //TODO: memzero packet, unwatend side effects? +// // crypto_memzero(packet, length); + +// return true; +// } +// } + +//TODO: /** @brief Handle a crypto handshake packet of length. * put the base nonce contained in the packet in nonce, * the session public key in session_pk @@ -789,7 +1365,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u non_null(1, 2, 5, 7) nullable(3, 4, 6, 9, 10) static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, - Noise_Handshake *noise_handshake) + Noise_Handshake *noise_handshake, const IP_Port *source) { LOGGER_DEBUG(c->log, "ENTERING"); /* Noise-based handshake */ @@ -799,7 +1375,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* TODO: New Cookies + Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -807,11 +1384,14 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [MAC encrypted static pubkey 16 bytes] ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD - [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] + ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ + [current ephemeral DHT public key of the INITIATOR (32 bytes)] => necessary for the NoiseIK responder + [16 bytes INITIATOR cookie (used by the RESPONDER peer to respond to the handshake packet)] + [current timestamp (8 bytes)] [MAC encrypted payload 16 bytes] - => 345 bytes in total + [MAC1 16 bytes] + [MAC2 16 bytes] + => 185 bytes in total = (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) */ if (!noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); @@ -826,6 +1406,27 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t //TODO: Check here if remote_ephemeral is already the same ephemeral key? + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t mac1[NOISE_MAC1_LENGTH]; + crypto_mac_blake2b_128(mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, + packet_mac1, NOISE_MAC1_LENGTH) != 0) { + return false; + } + + /* Verify MAC2 */ + uint8_t mac2[NOISE_MAC2_LENGTH]; + uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH]; + memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + packet_mac2, NOISE_MAC2_LENGTH) != 0) { + return false; + } + /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -876,25 +1477,16 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here - if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { - return false; - } - - /* Compares static identity public keys from the peer */ - if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { - return false; - } - - /* received base nonce (from INITIATOR) */ - memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); + /* necessary */ + memcpy(dht_public_key, handshake_payload_plain, CRYPTO_PUBLIC_KEY_SIZE); /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ - memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); + memcpy(cookie, handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE, NOISE_COOKIE_LENGTH); + //TODO: handle and compare timestamp -> does this even make sense at this point? CPU already wasted if replayed => handle with states? + /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); - /* necessary */ - memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); @@ -904,16 +1496,18 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* TODO: New Cookies + Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD - ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK + ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ + //TODO: add timestamp here? [MAC encrypted payload 16 bytes] - => ~~321~~ 185 bytes in total + [MAC1 16 bytes] + [MAC2 16 bytes] + => 81 bytes in total => (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) */ else { LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); @@ -922,6 +1516,27 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t mac1[NOISE_MAC1_LENGTH]; + crypto_mac_blake2b_128(mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + packet_mac1, NOISE_MAC1_LENGTH) != 0) { + return false; + } + + /* Verify MAC2 */ + uint8_t mac2[NOISE_MAC2_LENGTH]; + uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH]; + memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + packet_mac2, NOISE_MAC2_LENGTH) != 0) { + return false; + } + memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -958,19 +1573,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here - if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { - return false; - } - - /* Compares static identity public keys from the peer */ - if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { - return false; - } - - /* neccessary, base nonce (from Noise RESPONDER) */ - memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); /* necessary */ + //TODO: remove memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const @@ -993,7 +1597,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->cookie_symmetric_key) != 0) { return false; } @@ -1987,12 +2591,13 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u /* Noise-based handshake */ if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { + const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); LOGGER_DEBUG(c->log, "NoiseIK handshake"); if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + conn->public_key, dht_public_key, conn->noise_handshake, &ip_port) != sizeof(handshake_packet)) { return -1; } @@ -2003,7 +2608,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER]; if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + conn->public_key, dht_public_key, conn->noise_handshake, &ip_port) != sizeof(handshake_packet)) { return -1; } @@ -2019,7 +2624,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u /* ephemeral_private and noise_handshake not necessary for old handshake */ if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, nullptr, conn->sessionpublic_key, - conn->public_key, dht_public_key, nullptr) != sizeof(handshake_packet)) { + conn->public_key, dht_public_key, nullptr, nullptr) != sizeof(handshake_packet)) { return -1; } @@ -2285,7 +2890,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); - if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { + if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { return -1; } } else { @@ -2294,7 +2899,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } else if (c->noise_compatibility_enabled) { /* non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); - if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { + if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { return -1; } } @@ -2355,12 +2960,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise handshake"); + const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, nullptr, - packet, length, conn->public_key, conn->noise_handshake)) { + packet, length, conn->public_key, conn->noise_handshake, &ip_port)) { return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { @@ -2372,7 +2978,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, - packet, length, nullptr, conn->noise_handshake)) { + packet, length, nullptr, conn->noise_handshake, &ip_port)) { return -1; } @@ -2404,7 +3010,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, - packet, length, nullptr, conn->noise_handshake)) { + packet, length, nullptr, conn->noise_handshake, &ip_port)) { return -1; } /* RESPONDER needs to send handshake packet, afterwards finished */ @@ -2428,12 +3034,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* TODO: NOT necessary only for non-Noise */ // uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, nullptr, dht_public_key, cookie, - packet, length, conn->public_key, nullptr)) { + packet, length, conn->public_key, nullptr, nullptr)) { return -1; } } - if (pk_equal(dht_public_key, conn->dht_public_key)) { + //TODO: adapt for Noise, makes only sense for RESPONDER not initiator + if (pk_equal(dht_public_key, conn->peer_dht_public_key)) { LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); @@ -2786,6 +3393,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { + //TODO: add check for MAC1 and MAC2, if both ok, call noise_create_cookie_response() //TODO: adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { @@ -2801,7 +3409,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { + n_c.cookie, data, length, nullptr, n_c.noise_handshake, source)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); @@ -2814,7 +3422,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // Necessary for backwards compatibility n_c.noise_handshake = nullptr; if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, nullptr)) { + n_c.cookie, data, length, nullptr, nullptr, nullptr)) { mem_delete(c->mem, n_c.cookie); return -1; } @@ -2842,7 +3450,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } - if (!pk_equal(n_c.dht_public_key, conn->dht_public_key)) { + if (!pk_equal(n_c.dht_public_key, conn->peer_dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ LOGGER_DEBUG(c->log, "Noise handshake"); @@ -3020,7 +3628,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - memcpy(conn->dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(conn->peer_dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; @@ -3080,7 +3688,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u 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_PUBLIC_KEY_SIZE); + memcpy(conn->peer_dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; @@ -3091,7 +3699,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u //TODO: remove // LOGGER_DEBUG(c->log, "INITIATOR: BEFORE: create_cookie_request()"); - if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, + if (create_cookie_request(c, cookie_request, conn->peer_dht_public_key, conn->cookie_request_number, conn->shared_key) != sizeof(cookie_request) || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); @@ -4060,8 +4668,9 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r temp->dht = dht; new_keys(temp); - new_symmetric_key(rng, temp->secret_symmetric_key); + new_symmetric_key(rng, temp->cookie_symmetric_key); precompute_mac_key(temp->mac1_symmetric_key, dht_get_self_public_key(dht), noise_mac1_key_label); + precompute_mac_key(temp->cookie_xaead_symmetric_key, dht_get_self_public_key(dht), noise_cookie_key_label); temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; From 344030249d2eb8ec8612ff9787558403980f2982 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 21 Dec 2024 23:18:53 +0100 Subject: [PATCH 113/150] feat: implementation of (possible) new cookie mechanism. --- toxcore/net_crypto.c | 218 ++++++++++++++++++++++++++----------------- 1 file changed, 132 insertions(+), 86 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 5d18d2859a..4a2b9482d3 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -567,7 +567,8 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * return COOKIE_LENGTH; } -/** @brief Handle a cookie response packet of length encrypted with shared_key. +/** TODO: adapt comment for new cookie mechanism + * @brief Handle a cookie response packet of length encrypted with shared_key. * put the cookie in the response in cookie * * @param cookie must be of length COOKIE_LENGTH. @@ -578,12 +579,13 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * non_null() static int noise_handle_cookie_response(const Memory *mem, uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH], const uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], - const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t noise_mac1_sent[NOISE_MAC1_LENGTH]) + const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *noise_mac1_sent) { - // if (length != COOKIE_RESPONSE_LENGTH) { + // if (length != NOISE_COOKIE_RESPONSE_LENGTH) { // return -1; // } + //TODO: precompute for crypto_connection? uint8_t peer_cookie_xaead_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; precompute_mac_key(peer_cookie_xaead_symmetric_key, peer_dht_public_key, noise_cookie_key_label); @@ -854,7 +856,7 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte * @retval NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER if Noise handshake responder * */ -non_null(1, 2, 3, 4, 6, 7, 8) nullable(5, 9) +non_null(1, 2, 4, 6, 7, 8) nullable(3, 5, 9, 10) static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake, const IP_Port *source) @@ -1032,10 +1034,10 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, mac1, NOISE_MAC1_LENGTH); - uint8_t mac2[NOISE_MAC2_LENGTH]; - crypto_mac_blake2b_128(mac2, cookie, NOISE_COOKIE_LENGTH, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); + uint8_t noise_mac2[NOISE_MAC2_LENGTH]; + crypto_mac_blake2b_128(noise_mac2, cookie, NOISE_COOKIE_LENGTH, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC2_LENGTH, - mac2, NOISE_MAC2_LENGTH); + noise_mac2, NOISE_MAC2_LENGTH); crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); @@ -1364,7 +1366,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u */ non_null(1, 2, 5, 7) nullable(3, 4, 6, 9, 10) static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, - uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, + uint8_t *dht_public_key, uint8_t *peer_cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, Noise_Handshake *noise_handshake, const IP_Port *source) { LOGGER_DEBUG(c->log, "ENTERING"); @@ -1406,27 +1408,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t //TODO: Check here if remote_ephemeral is already the same ephemeral key? - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, - packet_mac1, NOISE_MAC1_LENGTH) != 0) { - return false; - } - - /* Verify MAC2 */ - uint8_t mac2[NOISE_MAC2_LENGTH]; - uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - packet_mac2, NOISE_MAC2_LENGTH) != 0) { - return false; - } - /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -1480,7 +1461,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* necessary */ memcpy(dht_public_key, handshake_payload_plain, CRYPTO_PUBLIC_KEY_SIZE); /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ - memcpy(cookie, handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE, NOISE_COOKIE_LENGTH); + memcpy(peer_cookie, handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE, NOISE_COOKIE_LENGTH); //TODO: handle and compare timestamp -> does this even make sense at this point? CPU already wasted if replayed => handle with states? /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ @@ -1516,6 +1497,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } + /* Verify MAC1 */ uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); uint8_t mac1[NOISE_MAC1_LENGTH]; @@ -1624,7 +1606,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(nonce, plain, CRYPTO_NONCE_SIZE); memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(peer_cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); @@ -2573,7 +2555,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) * @retval -1 on failure. * @retval 0 on success. */ -non_null() +non_null(1, 4) nullable(3) static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { @@ -2871,39 +2853,47 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } - uint8_t cookie[COOKIE_LENGTH]; - uint64_t number; - - if (handle_cookie_response(c->mem, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { - return -1; - } - - if (number != conn->cookie_request_number) { + /* NoiseIK cookie mechanism */ + uint8_t noise_handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; + memcpy(noise_handshake_packet, conn->temp_packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR); + //TODO: memcpy or pass noise_handshake_packet? + // uint8_t noise_mac1_sent[NOISE_MAC1_LENGTH]; + // memcpy(noise_mac1_sent, conn->temp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, NOISE_MAC1_LENGTH); + uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH]; + if (noise_handle_cookie_response(c->mem, noise_peer_cookie, packet, conn->peer_dht_public_key, + noise_handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE) != NOISE_COOKIE_LENGTH) { return -1; } + //TODO: remove if new NoiseIK cookie mechanism + // uint8_t cookie[COOKIE_LENGTH]; + // uint64_t number; + // if (handle_cookie_response(c->mem, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { + // return -1; + // } + // if (number != conn->cookie_request_number) { + // return -1; + // } /* Noise: only necessary if Cookie response was successful */ - if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { - return -1; - } + // if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { + // return -1; + // } if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); - if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { + /* calculate NoiseIK MAC2 for initiator handshake packet */ + uint8_t noise_mac2[NOISE_MAC2_LENGTH]; + crypto_mac_blake2b_128(noise_mac2, noise_peer_cookie, NOISE_COOKIE_LENGTH, noise_handshake_packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + memcpy(noise_handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + noise_mac2, NOISE_MAC2_LENGTH); + if (new_temp_packet(c, crypt_connection_id, noise_handshake_packet, sizeof(noise_handshake_packet)) != 0) { return -1; } } else { return -1; } - } else if (c->noise_compatibility_enabled) { - /* non-Noise handshake */ - LOGGER_DEBUG(c->log, "non-Noise handshake"); - if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { - return -1; - } - } - else { + } else { return -1; } @@ -3373,27 +3363,65 @@ void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_cal * @retval 0 on success. */ non_null(1, 2, 3) nullable(5) -static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, - void *userdata) +static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *packet, uint16_t length, + void *userdata, bool is_udp) { //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); - uint8_t *cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH); - - if (cookie == nullptr) { - return -1; - } - New_Connection n_c = {{{{0}}}}; - n_c.cookie = cookie; - n_c.source = *source; - n_c.cookie_length = COOKIE_LENGTH; - /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { //TODO: add check for MAC1 and MAC2, if both ok, call noise_create_cookie_response() + + /* Verify MAC1 */ + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t noise_mac1[NOISE_MAC1_LENGTH]; + crypto_mac_blake2b_128(noise_mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, + packet_mac1, NOISE_MAC1_LENGTH) != 0) { + return -1; + } + + /* Verify MAC2 */ + uint8_t mac2[NOISE_MAC2_LENGTH]; + uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH]; + memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + packet_mac2, NOISE_MAC2_LENGTH) != 0) { + uint8_t noise_cookie_respone[NOISE_COOKIE_RESPONSE_LENGTH]; + + if (noise_create_cookie_response(c, noise_cookie_respone, source, noise_mac1) != NOISE_COOKIE_RESPONSE_LENGTH) { + return -1; + } + + //TODO: how to send cookie response packet from here? via UDP/TCP? + + // if (is_udp) { + // if ((uint32_t)sendpacket(dht_get_net(c->dht), source, noise_cookie_respone, sizeof(noise_cookie_respone)) != sizeof(noise_cookie_respone)) { + // return 1; + // } + // } else { + // const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data)); + // } + return -1; + } + + uint8_t *noise_peer_cookie = (uint8_t *)mem_balloc(c->mem, NOISE_COOKIE_LENGTH); + + if (noise_peer_cookie == nullptr) { + return -1; + } + + n_c.cookie = noise_peer_cookie; + n_c.source = *source; + n_c.cookie_length = NOISE_COOKIE_LENGTH; + //TODO: adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { @@ -3409,7 +3437,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, n_c.noise_handshake, source)) { + n_c.cookie, packet, length, nullptr, n_c.noise_handshake, source)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); @@ -3419,10 +3447,19 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* case non-Noise handshake */ else if (c->noise_compatibility_enabled) { LOGGER_DEBUG(c->log, "non-Noise handshake"); + uint8_t *cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH); + + if (cookie == nullptr) { + return -1; + } + + n_c.cookie = cookie; + n_c.source = *source; + n_c.cookie_length = COOKIE_LENGTH; // Necessary for backwards compatibility n_c.noise_handshake = nullptr; if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, nullptr, nullptr)) { + n_c.cookie, packet, length, nullptr, nullptr, nullptr)) { mem_delete(c->mem, n_c.cookie); return -1; } @@ -3693,34 +3730,43 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; - conn->cookie_request_number = random_u64(c->rng); - uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; + //TODO: remove // LOGGER_DEBUG(c->log, "INITIATOR: BEFORE: create_cookie_request()"); - if (create_cookie_request(c, cookie_request, conn->peer_dht_public_key, conn->cookie_request_number, - conn->shared_key) != sizeof(cookie_request) - || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { + //TODO: remove if new cookie mechanism + // conn->cookie_request_number = random_u64(c->rng); + // uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; + // if (create_cookie_request(c, cookie_request, conn->peer_dht_public_key, conn->cookie_request_number, + // conn->shared_key) != sizeof(cookie_request) + // || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // wipe_crypto_connection(c, crypt_connection_id); + // return -1; + // } + + //TODO: remove + // LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); + + //TODO: here? => yes, if new cookie mechanism + // only necessary if Cookie request was successful + if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true, nullptr, 0) != 0) { + // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + mem_delete(c->mem, conn->noise_handshake); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); return -1; } - //TODO: remove - // LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); + // uint8_t + // noise_create_cookie() - //TODO: here? - // only necessary if Cookie request was successful - // if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { - // // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // mem_delete(c->mem, conn->noise_handshake); - // pthread_mutex_lock(&c->tcp_mutex); - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // pthread_mutex_unlock(&c->tcp_mutex); - // wipe_crypto_connection(c, crypt_connection_id); - // return -1; - // } + if (create_send_handshake(c, crypt_connection_id, nullptr, conn->peer_dht_public_key) != 0) { + kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + wipe_crypto_connection(c, crypt_connection_id); + return -1; + } //TODO: remove LOGGER_DEBUG(c->log, "INITIATOR: END"); @@ -3811,7 +3857,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in if (packet[0] == NET_PACKET_CRYPTO_HS) { const IP_Port source = tcp_connections_number_to_ip_port(tcp_connections_number); - if (handle_new_connection_handshake(c, &source, packet, length, userdata) != 0) { + if (handle_new_connection_handshake(c, &source, packet, length, userdata, 0) != 0) { return -1; } @@ -4094,7 +4140,7 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t return 1; } - if (handle_new_connection_handshake(c, source, packet, length, userdata) != 0) { + if (handle_new_connection_handshake(c, source, packet, length, userdata, 1) != 0) { return 1; } From 44e58f78ab1a8b0f09bd8b5a33e317ec9512de12 Mon Sep 17 00:00:00 2001 From: goldroom Date: Mon, 23 Dec 2024 22:06:54 +0100 Subject: [PATCH 114/150] feat: implementation of possible new cookie mechanism. Currently broken because both peers are Noise-responder. --- toxcore/net_crypto.c | 326 ++++++++++++++++++++++++------------------- 1 file changed, 183 insertions(+), 143 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 4a2b9482d3..87a0d61824 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -237,6 +237,13 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti #define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) #define NOISE_COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE) + +/* Noise: Necessary for Noise-based handshake (Noise cookie phase + Noise_IK_25519_ChaChaPoly_BLAKE2b) */ +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER 0 + static const uint8_t noise_mac1_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "mac1----"; //TODO: uncomment when used (currently commented for CI) static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; @@ -307,7 +314,8 @@ static int create_cookie(const Memory *mem, const Random *rng, const Mono_Time * return 0; } -/** @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key +/** TODO: adapt for Noise + * @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key * * @param cookie must be NOISE_COOKIE_LENGTH bytes. * @param cookie_symmetric_key must be of size CRYPTO_SYMMETRIC_KEY_SIZE or bigger. Symmetric encryption key for τ := Mac(Rm, Am') @@ -390,6 +398,90 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui return COOKIE_RESPONSE_LENGTH; } +/* +* TODO: Helper function to print hashes, keys, packets, etc. +* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? +* bytes_to_string() from util.h +*/ +static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) +{ + bytes_to_string(bytes, bytes_length, string, string_length); +} + +//TODO: document +static bool noise_verify_mac1_mac2(const uint8_t *handshake_packet, size_t handshake_packet_length, const Net_Crypto *c, const IP_Port *source, bool verify_mac2) { + LOGGER_DEBUG(c->log, "ENTERING"); + if (handshake_packet_length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + LOGGER_DEBUG(c->log, "NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); + /* Verify MAC1 */ + uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1_data, handshake_packet + 1, sizeof(packet_mac1_data)); + uint8_t mac1_verify[NOISE_MAC1_LENGTH]; + crypto_mac_blake2b_128(mac1_verify, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); + + if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, + mac1_verify, NOISE_MAC1_LENGTH) != 0) { + return false; + } + LOGGER_DEBUG(c->log, "Responder: Initiator MAC1 verified"); + + if (verify_mac2 == true) { + //TODO: remove from production code + char log_handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; + bytes2string(log_handshake_packet, sizeof(log_handshake_packet), handshake_packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); + LOGGER_DEBUG(c->log, "Responder: INITIATOR handshake packet: %s", log_handshake_packet); + /* Verify MAC2 */ + uint8_t mac2_verify[NOISE_MAC2_LENGTH]; + uint8_t packet_mac2_data[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - 1 - NOISE_MAC2_LENGTH]; + memcpy(packet_mac2_data, handshake_packet + 1, sizeof(packet_mac2_data)); + //TODO: Other way to get cookie here? + uint8_t self_cookie[NOISE_COOKIE_LENGTH]; + noise_create_cookie(self_cookie, c->cookie_symmetric_key, source); + crypto_mac_blake2b_128(mac2_verify, self_cookie, NOISE_COOKIE_LENGTH, packet_mac2_data, sizeof(packet_mac2_data)); + + if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + mac2_verify, NOISE_MAC2_LENGTH) != 0) { + return false; + } + LOGGER_DEBUG(c->log, "Responder: Initiator MAC2 verified"); + } else { + return true; + } + } + else if (handshake_packet_length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + LOGGER_DEBUG(c->log, "NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); + /* Verify MAC1 */ + uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1_data, handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t mac1_verify[NOISE_MAC1_LENGTH]; + crypto_mac_blake2b_128(mac1_verify, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); + + if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + mac1_verify, NOISE_MAC1_LENGTH) != 0) { + return false; + } + LOGGER_DEBUG(c->log, "Initiator: Responder MAC1 verified"); + + if (verify_mac2 == true) { + /* Verify MAC2 */ + uint8_t mac2_verify[NOISE_MAC2_LENGTH]; + uint8_t packet_mac2_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH]; + memcpy(packet_mac2_data, handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH)); + uint8_t self_cookie[NOISE_COOKIE_LENGTH]; + noise_create_cookie(self_cookie, c->cookie_symmetric_key, source); + crypto_mac_blake2b_128(mac2_verify, self_cookie, NOISE_COOKIE_LENGTH, packet_mac2_data, sizeof(packet_mac2_data)); + + if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + mac2_verify, NOISE_MAC2_LENGTH) != 0) { + return false; + } + LOGGER_DEBUG(c->log, "Initiator: Responder MAC2 verified"); + } else { + return true; + } + } +} + /** @brief Create a cookie response packet and put it in packet. * * @param packet must be of size NOISE_COOKIE_RESPONSE_LENGTH. @@ -400,22 +492,36 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui * @retval NOISE_COOKIE_RESPONSE_LENGTH on success. */ non_null() -static int noise_create_cookie_response(const Net_Crypto *c, uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], const IP_Port *source, - const uint8_t noise_mac1_received[NOISE_MAC1_LENGTH]) +static int noise_create_cookie_response(const Net_Crypto *c, uint8_t noise_cookie_response_packet[NOISE_COOKIE_RESPONSE_LENGTH], const IP_Port *source, + const uint8_t noise_cookie_request_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]) { LOGGER_DEBUG(c->log, "ENTERING"); // symmetric_cookie_encryption_key based on label + DHT public key - // handshake packet mac1 value (of the peer) + + /* Verify handshake packet MAC1 (of the INITIATOR peer) */ + // uint8_t noise_mac1[NOISE_MAC1_LENGTH]; + // crypto_mac_blake2b_128(noise_mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + + // if (memcmp(noise_cookie_response_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, + // packet_mac1, NOISE_MAC1_LENGTH) != 0) { + // return -1; + // } + if (noise_verify_mac1_mac2(noise_cookie_request_packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c, nullptr, false) != true) { + return -1; + } + LOGGER_DEBUG(c->log, "after noise_verify_mac1_mac2()"); + uint8_t noise_cookie[NOISE_COOKIE_LENGTH]; noise_create_cookie(noise_cookie, c->cookie_symmetric_key, source); - packet[0] = NET_PACKET_COOKIE_RESPONSE; + noise_cookie_response_packet[0] = NET_PACKET_COOKIE_RESPONSE; // random nonce - random_nonce(c->rng, packet + 1); + random_nonce(c->rng, noise_cookie_response_packet + 1); // calculate msg.cookie := Xaead(Hash(Label-Cookie ‖ Spub m ), msg.nonce, τ, M ) - const int len = encrypt_data_symmetric_xaead(c->cookie_xaead_symmetric_key, packet + 1, noise_cookie, - NOISE_COOKIE_LENGTH, packet + 1 + CRYPTO_NONCE_SIZE, noise_mac1_received, NOISE_MAC1_LENGTH); + //TODO: AD ignores packet kind (otherwise not possible with NET_PACKET_COOKIE_REQUEST change to NET_PACKET_CRYPTO_HANDSHAKE) => problem/vulnerability? + const int len = encrypt_data_symmetric_xaead(c->cookie_xaead_symmetric_key, noise_cookie_response_packet + 1, noise_cookie, + NOISE_COOKIE_LENGTH, noise_cookie_response_packet + 1 + CRYPTO_NONCE_SIZE, noise_cookie_request_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, NOISE_MAC1_LENGTH); if (len != (NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE)) { return -1; @@ -455,30 +561,24 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui } /** Handle the cookie request packet (for raw UDP) */ -non_null(1, 2, 3) nullable(5) -static int udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, - void *userdata) +//TODO: Only handles NoiseIK cookie requests (i.e. handshake packet with invalid MAC2) +non_null(1, 2, 3) +static int noise_udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { + if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + return 1; + } const Net_Crypto *c = (const Net_Crypto *)object; //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); - uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; - uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - - if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0) { - return 1; - } - - uint8_t data[COOKIE_RESPONSE_LENGTH]; - - if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) { + uint8_t noise_data_cookie_response[NOISE_COOKIE_RESPONSE_LENGTH]; + if (noise_create_cookie_response(c, noise_data_cookie_response, source, packet) != sizeof(noise_data_cookie_response)) { return 1; } - if ((uint32_t)sendpacket(dht_get_net(c->dht), source, data, sizeof(data)) != sizeof(data)) { + if ((uint32_t)sendpacket(dht_get_net(c->dht), source, noise_data_cookie_response, sizeof(noise_data_cookie_response)) != sizeof(noise_data_cookie_response)) { return 1; } @@ -491,21 +591,14 @@ static int tcp_handle_cookie_request(const Net_Crypto *c, int connections_number uint16_t length) { LOGGER_DEBUG(c->log, "ENTERING"); - uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; - uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - - if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0) { - return -1; - } - uint8_t data[COOKIE_RESPONSE_LENGTH]; - - if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) { - return -1; + const IP_Port source = tcp_connections_number_to_ip_port(connections_number); + uint8_t noise_data_cookie_response[NOISE_COOKIE_RESPONSE_LENGTH]; + if (noise_create_cookie_response(c, noise_data_cookie_response, &source, packet) != sizeof(noise_data_cookie_response)) { + return 1; } - const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data)); + const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, noise_data_cookie_response, sizeof(noise_data_cookie_response)); return ret; } @@ -515,25 +608,14 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { LOGGER_DEBUG(c->log, "ENTERING"); - uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; - uint8_t dht_public_key_temp[CRYPTO_PUBLIC_KEY_SIZE]; - if (handle_cookie_request(c, request_plain, shared_key, dht_public_key_temp, packet, length) != 0) { - return -1; - } - - if (!pk_equal(dht_public_key, dht_public_key_temp)) { - return -1; - } - - uint8_t data[COOKIE_RESPONSE_LENGTH]; - - if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) { - return -1; + const IP_Port source = tcp_connections_number_to_ip_port(tcp_connections_number); + uint8_t noise_data_cookie_response[NOISE_COOKIE_RESPONSE_LENGTH]; + if (noise_create_cookie_response(c, noise_data_cookie_response, &source, packet) != sizeof(noise_data_cookie_response)) { + return 1; } - const int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, data, sizeof(data)); + const int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, noise_data_cookie_response, sizeof(noise_data_cookie_response)); return ret; } @@ -577,13 +659,14 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * * @retval COOKIE_LENGTH on success. */ non_null() -static int noise_handle_cookie_response(const Memory *mem, uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH], +static int noise_handle_cookie_response(const Net_Crypto *c, uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH], const uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *noise_mac1_sent) { // if (length != NOISE_COOKIE_RESPONSE_LENGTH) { // return -1; // } + LOGGER_DEBUG(c->log, "ENTERING: noise_handle_cookie_response()"); //TODO: precompute for crypto_connection? uint8_t peer_cookie_xaead_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; @@ -593,23 +676,15 @@ static int noise_handle_cookie_response(const Memory *mem, uint8_t noise_peer_co const int len = decrypt_data_symmetric_xaead(peer_cookie_xaead_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE, noise_peer_cookie, noise_mac1_sent, NOISE_MAC1_LENGTH); - if (len != NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE) { + LOGGER_DEBUG(c->log, "len: %d", len); + + if (len != NOISE_COOKIE_LENGTH) { return -1; } return NOISE_COOKIE_LENGTH; } -/* -* TODO: Helper function to print hashes, keys, packets, etc. -* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? -* bytes_to_string() from util.h -*/ -static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) -{ - bytes_to_string(bytes, bytes_length, string, string_length); -} - /* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /* Noise: Necessary for Noise-based handshake (non-Noise cookie phase + Noise_IK_25519_ChaChaPoly_SHA512) */ @@ -618,12 +693,6 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte // #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) // #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) -/* Noise: Necessary for Noise-based handshake (Noise cookie phase + Noise_IK_25519_ChaChaPoly_BLAKE2b) */ -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER 0 - // /** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. // * @@ -943,15 +1012,18 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); - packet[0] = NET_PACKET_CRYPTO_HS; + /* NoiseIK cookie mechanism sent INITIATOR hs packet as cookie request */ + // packet[0] = NET_PACKET_CRYPTO_HS; + packet[0] = NET_PACKET_COOKIE_REQUEST; - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + //TODO: MAC1+MAC2 exclude packet type => problem? + uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1_data, packet + 1, sizeof(packet_mac1_data)); uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); uint8_t mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, mac1, NOISE_MAC1_LENGTH); @@ -1024,18 +1096,19 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u packet[0] = NET_PACKET_CRYPTO_HS; - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + //TODO: MAC1+MAC2 exclude packet type => problem? + uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1_data, packet +1, sizeof(packet_mac1_data)); uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); uint8_t mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, mac1, NOISE_MAC1_LENGTH); uint8_t noise_mac2[NOISE_MAC2_LENGTH]; - crypto_mac_blake2b_128(noise_mac2, cookie, NOISE_COOKIE_LENGTH, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(noise_mac2, cookie, NOISE_COOKIE_LENGTH, packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH)); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC2_LENGTH, noise_mac2, NOISE_MAC2_LENGTH); @@ -1374,8 +1447,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); - uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - /* -> e, es, s, ss */ /* TODO: New Cookies Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) @@ -1497,28 +1568,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - /* Verify MAC1 */ - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - packet_mac1, NOISE_MAC1_LENGTH) != 0) { - return false; - } - - /* Verify MAC2 */ - uint8_t mac2[NOISE_MAC2_LENGTH]; - uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); - crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - packet_mac2, NOISE_MAC2_LENGTH) != 0) { - return false; - } - memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -1557,7 +1606,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* necessary */ //TODO: remove - memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + // memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); @@ -2526,7 +2575,7 @@ non_null() static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) { //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, "ENTERING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2543,7 +2592,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); - // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); + LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); ++conn->temp_packet_num_sent; return 0; } @@ -2860,7 +2909,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, // uint8_t noise_mac1_sent[NOISE_MAC1_LENGTH]; // memcpy(noise_mac1_sent, conn->temp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, NOISE_MAC1_LENGTH); uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH]; - if (noise_handle_cookie_response(c->mem, noise_peer_cookie, packet, conn->peer_dht_public_key, + if (noise_handle_cookie_response(c, noise_peer_cookie, packet, conn->peer_dht_public_key, noise_handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE) != NOISE_COOKIE_LENGTH) { return -1; } @@ -2882,14 +2931,21 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); + noise_handshake_packet[0] = NET_PACKET_CRYPTO_HS; /* calculate NoiseIK MAC2 for initiator handshake packet */ uint8_t noise_mac2[NOISE_MAC2_LENGTH]; - crypto_mac_blake2b_128(noise_mac2, noise_peer_cookie, NOISE_COOKIE_LENGTH, noise_handshake_packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(noise_mac2, noise_peer_cookie, NOISE_COOKIE_LENGTH, noise_handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - 1 - NOISE_MAC2_LENGTH)); memcpy(noise_handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, noise_mac2, NOISE_MAC2_LENGTH); if (new_temp_packet(c, crypt_connection_id, noise_handshake_packet, sizeof(noise_handshake_packet)) != 0) { return -1; } + + //TODO: remove from production code + char log_handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; + bytes2string(log_handshake_packet, sizeof(log_handshake_packet), noise_handshake_packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); + LOGGER_DEBUG(c->log, "INITIATOR handshake packet: %s", log_handshake_packet); + send_temp_packet(c, crypt_connection_id); } else { return -1; } @@ -2898,6 +2954,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } conn->status = CRYPTO_CONN_HANDSHAKE_SENT; + LOGGER_DEBUG(c->log, "end"); return 0; } @@ -2951,16 +3008,26 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise handshake"); const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); + LOGGER_DEBUG(c->log, "after return_ip_port_connection()"); if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? + if (noise_verify_mac1_mac2(packet, length, c, &ip_port, true) != true) { + return -1; + } + if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, nullptr, packet, length, conn->public_key, conn->noise_handshake, &ip_port)) { return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); + + if (noise_verify_mac1_mac2(packet, length, c, &ip_port, true) != true) { + return -1; + } + if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } @@ -2993,6 +3060,11 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const else { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); + + if (noise_verify_mac1_mac2(packet, length, c, &ip_port, true) != true) { + return -1; + } + /* necessary, otherwise broken after INITIATOR to RESPONDER change; also necessary without change */ if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; @@ -3373,42 +3445,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { - //TODO: add check for MAC1 and MAC2, if both ok, call noise_create_cookie_response() - - /* Verify MAC1 */ - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t noise_mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(noise_mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, - packet_mac1, NOISE_MAC1_LENGTH) != 0) { - return -1; - } + //TODO: add check for MAC1 and MAC2, if both ok, send RESPONDER handshake packet - /* Verify MAC2 */ - uint8_t mac2[NOISE_MAC2_LENGTH]; - uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - packet_mac2, NOISE_MAC2_LENGTH) != 0) { - uint8_t noise_cookie_respone[NOISE_COOKIE_RESPONSE_LENGTH]; - - if (noise_create_cookie_response(c, noise_cookie_respone, source, noise_mac1) != NOISE_COOKIE_RESPONSE_LENGTH) { - return -1; - } - - //TODO: how to send cookie response packet from here? via UDP/TCP? - - // if (is_udp) { - // if ((uint32_t)sendpacket(dht_get_net(c->dht), source, noise_cookie_respone, sizeof(noise_cookie_respone)) != sizeof(noise_cookie_respone)) { - // return 1; - // } - // } else { - // const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data)); - // } + /* Verify MAC1 and MAC2 */ + if (noise_verify_mac1_mac2(packet, length, c, source, true) != true) { return -1; } @@ -3500,7 +3540,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(Noise_Handshake)); - memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); + // memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); crypto_connection_add_source(c, crypt_connection_id, source); @@ -4720,7 +4760,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; - networking_registerhandler(dht_get_net(dht), NET_PACKET_COOKIE_REQUEST, &udp_handle_cookie_request, temp); + networking_registerhandler(dht_get_net(dht), NET_PACKET_COOKIE_REQUEST, &noise_udp_handle_cookie_request, temp); networking_registerhandler(dht_get_net(dht), NET_PACKET_COOKIE_RESPONSE, &udp_handle_packet, temp); networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp); networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp); From 7ec460f502ffd5b466617b9db8a2d07f6bbbc780 Mon Sep 17 00:00:00 2001 From: goldroom Date: Tue, 7 Jan 2025 18:43:51 +0100 Subject: [PATCH 115/150] fix: added debug output and fixed NoiseIK cookie implementation issues. This lead to the discovery, that usage of IP_Port is currently broken implementation-wise and by design (NoiseIK-initiator doesn't know the actual IP_Port when the handshake packet is created). --- toxcore/crypto_core.c | 26 ++++++------ toxcore/net_crypto.c | 93 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 98 insertions(+), 21 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 34e106dfb2..3dc377fce1 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -543,8 +543,8 @@ int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) { - /* Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium */ - if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { + /* Plaintext+additional data ad can be a NULL pointer with plain_length/ad_length equal to 0; encrypted_length is calculated by libsodium */ + if (shared_key == nullptr || nonce == nullptr || encrypted == nullptr) { return -1; } @@ -898,7 +898,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ /* Expand second key: key = secret, data = first-key || 0x2 */ - output[CRYPTO_SHA512_SIZE] = 2; + output[CRYPTO_BLAKE2b_HASH_SIZE] = 2; crypto_hmac_blake2b_512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(output2, output, second_len); @@ -909,8 +909,8 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // memcpy(output3, output, third_len); /* Clear sensitive data from stack */ - crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); - crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); + crypto_memzero(temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_memzero(output, CRYPTO_BLAKE2b_HASH_SIZE + 1); } /* @@ -1023,14 +1023,14 @@ void noise_mix_hash(uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE], const uint8_t *data, */ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE]) + uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE]) { static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); int32_t encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, - hash, CRYPTO_SHA512_SIZE); + hash, CRYPTO_BLAKE2b_HASH_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); } @@ -1042,14 +1042,14 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, */ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE]) + uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE]) { static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); int32_t plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, - hash, CRYPTO_SHA512_SIZE); + hash, CRYPTO_BLAKE2b_HASH_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); @@ -1090,11 +1090,11 @@ int noise_handshake_init /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ - uint8_t temp_hash[CRYPTO_SHA512_SIZE]; - memset(temp_hash, 0, CRYPTO_SHA512_SIZE); + uint8_t temp_hash[CRYPTO_BLAKE2b_HASH_SIZE]; + memset(temp_hash, 0, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(temp_hash, noise_protocol, sizeof(noise_protocol)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_BLAKE2b_HASH_SIZE); /* IMPORTANT needs to be called with (empty/zero-length) prologue! */ noise_mix_hash(noise_handshake->hash, prologue, prologue_length); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 87a0d61824..8cf9779ac5 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -333,6 +333,7 @@ static void noise_create_cookie(uint8_t cookie[NOISE_COOKIE_LENGTH], { // calculate τ := Mac(Rm, Am′) //TODO: change cookie symmetric key or hash timestamp into? + //FIXME: Source cannot bis used this way crypto_mac_blake2b_128(cookie, cookie_symmetric_key, CRYPTO_SECRET_KEY_SIZE, (uint8_t *) source, sizeof(struct IP_Port)); } @@ -444,6 +445,7 @@ static bool noise_verify_mac1_mac2(const uint8_t *handshake_packet, size_t hands return false; } LOGGER_DEBUG(c->log, "Responder: Initiator MAC2 verified"); + return true; } else { return true; } @@ -452,30 +454,67 @@ static bool noise_verify_mac1_mac2(const uint8_t *handshake_packet, size_t hands LOGGER_DEBUG(c->log, "NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); /* Verify MAC1 */ uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1_data, handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + memcpy(packet_mac1_data, handshake_packet + 1, sizeof(packet_mac1_data)); uint8_t mac1_verify[NOISE_MAC1_LENGTH]; crypto_mac_blake2b_128(mac1_verify, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); + //TODO: remove from production code + char log_mac1[NOISE_MAC1_LENGTH*2+1]; + bytes2string(log_mac1, sizeof(log_mac1), handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, NOISE_MAC1_LENGTH, c->log); + LOGGER_DEBUG(c->log, "MAC1 received: %s", log_mac1); + memset(log_mac1, 0, sizeof(log_mac1)); + bytes2string(log_mac1, sizeof(log_mac1), mac1_verify, NOISE_MAC1_LENGTH, c->log); + LOGGER_DEBUG(c->log, "MAC1 calculated: %s", log_mac1); + if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, mac1_verify, NOISE_MAC1_LENGTH) != 0) { return false; } LOGGER_DEBUG(c->log, "Initiator: Responder MAC1 verified"); + //FIXME: Currently broken, wrong IP_Port used in initial initiator-cookie creation if (verify_mac2 == true) { /* Verify MAC2 */ uint8_t mac2_verify[NOISE_MAC2_LENGTH]; uint8_t packet_mac2_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2_data, handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH)); + memcpy(packet_mac2_data, handshake_packet + 1, sizeof(packet_mac2_data)); + + //TODO: remove + char log_source[sizeof(struct IP_Port) * 2 + 1]; + bytes2string(log_source, sizeof(log_source), (uint8_t *) source, sizeof(struct IP_Port), c->log); + LOGGER_DEBUG(c->log, "log_source: %s", log_source); + + Ip_Ntoa ip_str; + net_ip_ntoa(&source->ip, &ip_str); + //TODO: remove from production code + char log_ip[ip_str.length*2+1]; + bytes2string(log_ip, sizeof(log_ip), (uint8_t *) ip_str.buf, ip_str.length, c->log); + LOGGER_DEBUG(c->log, "INITIATOR log_ip: %s, bool: %d", log_ip, ip_str.ip_is_valid); + + //TODO: Other way to get cookie here? uint8_t self_cookie[NOISE_COOKIE_LENGTH]; noise_create_cookie(self_cookie, c->cookie_symmetric_key, source); crypto_mac_blake2b_128(mac2_verify, self_cookie, NOISE_COOKIE_LENGTH, packet_mac2_data, sizeof(packet_mac2_data)); + //TODO: remove from production code + char log_cookie[NOISE_COOKIE_LENGTH*2+1]; + bytes2string(log_cookie, sizeof(log_cookie), self_cookie, NOISE_COOKIE_LENGTH, c->log); + LOGGER_DEBUG(c->log, "INITIATOR cookie: %s", log_cookie); + + //TODO: remove from production code + char log_mac2[NOISE_MAC2_LENGTH*2+1]; + bytes2string(log_mac2, sizeof(log_mac2), handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, NOISE_MAC2_LENGTH, c->log); + LOGGER_DEBUG(c->log, "MAC2 received: %s", log_mac2); + memset(log_mac2, 0, sizeof(log_mac2)); + bytes2string(log_mac2, sizeof(log_mac2), mac2_verify, NOISE_MAC2_LENGTH, c->log); + LOGGER_DEBUG(c->log, "MAC2 calculated: %s", log_mac2); + if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, mac2_verify, NOISE_MAC2_LENGTH) != 0) { return false; } LOGGER_DEBUG(c->log, "Initiator: Responder MAC2 verified"); + return true; } else { return true; } @@ -954,6 +993,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u => 185 bytes in total = (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) */ if (noise_handshake->initiator) { + LOGGER_DEBUG(c->log, "INITIATOR"); /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -989,7 +1029,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; - memcpy(handshake_payload_plain, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + /* Noise: DHT public key from INITIATOR */ + memcpy(handshake_payload_plain, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE); + + //TODO: remove + char log_source[sizeof(struct IP_Port) * 2 + 1]; + bytes2string(log_source, sizeof(log_source), (uint8_t *) source, sizeof(struct IP_Port), c->log); + LOGGER_DEBUG(c->log, "log_source: %s", log_source); /* Noise: Cookie from INITIATOR */ uint8_t noise_cookie_initiator[NOISE_COOKIE_LENGTH]; @@ -1087,18 +1133,18 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); /* Create Noise Handshake Payload */ - uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; + uint8_t *handshake_payload_plain = nullptr; /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, - handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, + handshake_payload_plain, 0, noise_handshake_temp_key, noise_handshake->hash); packet[0] = NET_PACKET_CRYPTO_HS; //TODO: MAC1+MAC2 exclude packet type => problem? uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1_data, packet +1, sizeof(packet_mac1_data)); + memcpy(packet_mac1_data, packet + 1, sizeof(packet_mac1_data)); uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); uint8_t mac1[NOISE_MAC1_LENGTH]; @@ -1107,13 +1153,19 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, mac1, NOISE_MAC1_LENGTH); + //TODO: remove from production code + char log_cookie[NOISE_COOKIE_LENGTH*2+1]; + bytes2string(log_cookie, sizeof(log_cookie), cookie, NOISE_COOKIE_LENGTH, c->log); + LOGGER_DEBUG(c->log, "INITIATOR cookie: %s", log_cookie); + uint8_t noise_mac2[NOISE_MAC2_LENGTH]; crypto_mac_blake2b_128(noise_mac2, cookie, NOISE_COOKIE_LENGTH, packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH)); - memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC2_LENGTH, + memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, noise_mac2, NOISE_MAC2_LENGTH); crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); + //TODO: remove + // crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } @@ -2587,6 +2639,8 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) return -1; } + LOGGER_DEBUG(c->log, "conn->temp_packet[0]: %d", conn->temp_packet[0]); + if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0) { return -1; } @@ -2627,6 +2681,13 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; + Ip_Ntoa ip_str; + net_ip_ntoa(&ip_port.ip, &ip_str); + //TODO: remove from production code + char log_ip[ip_str.length*2+1]; + bytes2string(log_ip, sizeof(log_ip), (uint8_t *) ip_str.buf, ip_str.length, c->log); + LOGGER_DEBUG(c->log, "INITIATOR log_ip: %s, bool: %d", log_ip, ip_str.ip_is_valid); + if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, conn->public_key, dht_public_key, conn->noise_handshake, &ip_port) != sizeof(handshake_packet)) { return -1; @@ -3009,6 +3070,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "Noise handshake"); const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); LOGGER_DEBUG(c->log, "after return_ip_port_connection()"); + Ip_Ntoa ip_str; + net_ip_ntoa(&ip_port.ip, &ip_str); + //TODO: remove from production code + char log_ip[ip_str.length*2+1]; + bytes2string(log_ip, sizeof(log_ip), (uint8_t *) ip_str.buf, ip_str.length, c->log); + LOGGER_DEBUG(c->log, "log_ip: %s, bool: %d", log_ip, ip_str.ip_is_valid); if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); @@ -3025,10 +3092,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); if (noise_verify_mac1_mac2(packet, length, c, &ip_port, true) != true) { + LOGGER_DEBUG(c->log, "failed"); return -1; } + //TODO: memzero conn->noise_handshake here? + /* there is already something in conn->noise_handshake -> necessary to memzero in this case! */ + // crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { + LOGGER_DEBUG(c->log, "failed"); return -1; } @@ -3036,6 +3109,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake, &ip_port)) { + LOGGER_DEBUG(c->log, "failed"); return -1; } @@ -3046,6 +3120,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise RESPONDER needs to send handshake packet, afterwards finished */ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { + LOGGER_DEBUG(c->log, "failed"); return -1; } //TODO: here? @@ -3802,6 +3877,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // uint8_t // noise_create_cookie() + //FIXME: Corrent IP_Port of peer not known at this point (but necessary for initiator-cookie) if (create_send_handshake(c, crypt_connection_id, nullptr, conn->peer_dht_public_key) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); @@ -4813,6 +4889,7 @@ uint32_t crypto_run_interval(const Net_Crypto *c) /** Main loop. */ void do_net_crypto(Net_Crypto *c, void *userdata) { + LOGGER_DEBUG(c->log, "do_net_crypto()"); //TODO: update cookie symmetric key every ~2 minutes (cf. WireGuard)? kill_timedout(c, userdata); do_tcp(c, userdata); From 5ac12e7e4edee70ce68fdb0088692ea0b37084f8 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 19:11:55 +0100 Subject: [PATCH 116/150] fix: fixed typo --- toxcore/net_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 8cf9779ac5..4f7a77d67b 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -3877,7 +3877,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // uint8_t // noise_create_cookie() - //FIXME: Corrent IP_Port of peer not known at this point (but necessary for initiator-cookie) + //FIXME: Current IP_Port of peer not known at this point (but necessary for initiator-cookie) if (create_send_handshake(c, crypt_connection_id, nullptr, conn->peer_dht_public_key) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); From 8c5b5c81479f93939da448766a798b73c06bc29b Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 19:43:35 +0100 Subject: [PATCH 117/150] Revert "fix: fixed typo" This reverts commit 5ac12e7e4edee70ce68fdb0088692ea0b37084f8. --- toxcore/net_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 4f7a77d67b..8cf9779ac5 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -3877,7 +3877,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // uint8_t // noise_create_cookie() - //FIXME: Current IP_Port of peer not known at this point (but necessary for initiator-cookie) + //FIXME: Corrent IP_Port of peer not known at this point (but necessary for initiator-cookie) if (create_send_handshake(c, crypt_connection_id, nullptr, conn->peer_dht_public_key) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); From db6571ade9128f05742312dea5cc7a3a4614f451 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 19:44:17 +0100 Subject: [PATCH 118/150] Revert "fix: added debug output and fixed NoiseIK cookie implementation issues. This lead to the discovery, that usage of IP_Port is currently broken implementation-wise and by design (NoiseIK-initiator doesn't know the actual IP_Port when the handshake packet is created)." This reverts commit 7ec460f502ffd5b466617b9db8a2d07f6bbbc780. --- toxcore/crypto_core.c | 26 ++++++------ toxcore/net_crypto.c | 93 ++++--------------------------------------- 2 files changed, 21 insertions(+), 98 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 3dc377fce1..34e106dfb2 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -543,8 +543,8 @@ int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) { - /* Plaintext+additional data ad can be a NULL pointer with plain_length/ad_length equal to 0; encrypted_length is calculated by libsodium */ - if (shared_key == nullptr || nonce == nullptr || encrypted == nullptr) { + /* Additional data ad can be a NULL pointer with ad_length equal to 0; encrypted_length is calculated by libsodium */ + if (plain_length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { return -1; } @@ -898,7 +898,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ /* Expand second key: key = secret, data = first-key || 0x2 */ - output[CRYPTO_BLAKE2b_HASH_SIZE] = 2; + output[CRYPTO_SHA512_SIZE] = 2; crypto_hmac_blake2b_512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(output2, output, second_len); @@ -909,8 +909,8 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // memcpy(output3, output, third_len); /* Clear sensitive data from stack */ - crypto_memzero(temp_key, CRYPTO_BLAKE2b_HASH_SIZE); - crypto_memzero(output, CRYPTO_BLAKE2b_HASH_SIZE + 1); + crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); + crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); } /* @@ -1023,14 +1023,14 @@ void noise_mix_hash(uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE], const uint8_t *data, */ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE]) + uint8_t hash[CRYPTO_SHA512_SIZE]) { static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); int32_t encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, - hash, CRYPTO_BLAKE2b_HASH_SIZE); + hash, CRYPTO_SHA512_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); } @@ -1042,14 +1042,14 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, */ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE]) + uint8_t hash[CRYPTO_SHA512_SIZE]) { static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); int32_t plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, - hash, CRYPTO_BLAKE2b_HASH_SIZE); + hash, CRYPTO_SHA512_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); @@ -1090,11 +1090,11 @@ int noise_handshake_init /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ - uint8_t temp_hash[CRYPTO_BLAKE2b_HASH_SIZE]; - memset(temp_hash, 0, CRYPTO_BLAKE2b_HASH_SIZE); + uint8_t temp_hash[CRYPTO_SHA512_SIZE]; + memset(temp_hash, 0, CRYPTO_SHA512_SIZE); memcpy(temp_hash, noise_protocol, sizeof(noise_protocol)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_BLAKE2b_HASH_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); /* IMPORTANT needs to be called with (empty/zero-length) prologue! */ noise_mix_hash(noise_handshake->hash, prologue, prologue_length); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 8cf9779ac5..87a0d61824 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -333,7 +333,6 @@ static void noise_create_cookie(uint8_t cookie[NOISE_COOKIE_LENGTH], { // calculate τ := Mac(Rm, Am′) //TODO: change cookie symmetric key or hash timestamp into? - //FIXME: Source cannot bis used this way crypto_mac_blake2b_128(cookie, cookie_symmetric_key, CRYPTO_SECRET_KEY_SIZE, (uint8_t *) source, sizeof(struct IP_Port)); } @@ -445,7 +444,6 @@ static bool noise_verify_mac1_mac2(const uint8_t *handshake_packet, size_t hands return false; } LOGGER_DEBUG(c->log, "Responder: Initiator MAC2 verified"); - return true; } else { return true; } @@ -454,67 +452,30 @@ static bool noise_verify_mac1_mac2(const uint8_t *handshake_packet, size_t hands LOGGER_DEBUG(c->log, "NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); /* Verify MAC1 */ uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1_data, handshake_packet + 1, sizeof(packet_mac1_data)); + memcpy(packet_mac1_data, handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); uint8_t mac1_verify[NOISE_MAC1_LENGTH]; crypto_mac_blake2b_128(mac1_verify, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); - //TODO: remove from production code - char log_mac1[NOISE_MAC1_LENGTH*2+1]; - bytes2string(log_mac1, sizeof(log_mac1), handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, NOISE_MAC1_LENGTH, c->log); - LOGGER_DEBUG(c->log, "MAC1 received: %s", log_mac1); - memset(log_mac1, 0, sizeof(log_mac1)); - bytes2string(log_mac1, sizeof(log_mac1), mac1_verify, NOISE_MAC1_LENGTH, c->log); - LOGGER_DEBUG(c->log, "MAC1 calculated: %s", log_mac1); - if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, mac1_verify, NOISE_MAC1_LENGTH) != 0) { return false; } LOGGER_DEBUG(c->log, "Initiator: Responder MAC1 verified"); - //FIXME: Currently broken, wrong IP_Port used in initial initiator-cookie creation if (verify_mac2 == true) { /* Verify MAC2 */ uint8_t mac2_verify[NOISE_MAC2_LENGTH]; uint8_t packet_mac2_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2_data, handshake_packet + 1, sizeof(packet_mac2_data)); - - //TODO: remove - char log_source[sizeof(struct IP_Port) * 2 + 1]; - bytes2string(log_source, sizeof(log_source), (uint8_t *) source, sizeof(struct IP_Port), c->log); - LOGGER_DEBUG(c->log, "log_source: %s", log_source); - - Ip_Ntoa ip_str; - net_ip_ntoa(&source->ip, &ip_str); - //TODO: remove from production code - char log_ip[ip_str.length*2+1]; - bytes2string(log_ip, sizeof(log_ip), (uint8_t *) ip_str.buf, ip_str.length, c->log); - LOGGER_DEBUG(c->log, "INITIATOR log_ip: %s, bool: %d", log_ip, ip_str.ip_is_valid); - - //TODO: Other way to get cookie here? + memcpy(packet_mac2_data, handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH)); uint8_t self_cookie[NOISE_COOKIE_LENGTH]; noise_create_cookie(self_cookie, c->cookie_symmetric_key, source); crypto_mac_blake2b_128(mac2_verify, self_cookie, NOISE_COOKIE_LENGTH, packet_mac2_data, sizeof(packet_mac2_data)); - //TODO: remove from production code - char log_cookie[NOISE_COOKIE_LENGTH*2+1]; - bytes2string(log_cookie, sizeof(log_cookie), self_cookie, NOISE_COOKIE_LENGTH, c->log); - LOGGER_DEBUG(c->log, "INITIATOR cookie: %s", log_cookie); - - //TODO: remove from production code - char log_mac2[NOISE_MAC2_LENGTH*2+1]; - bytes2string(log_mac2, sizeof(log_mac2), handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, NOISE_MAC2_LENGTH, c->log); - LOGGER_DEBUG(c->log, "MAC2 received: %s", log_mac2); - memset(log_mac2, 0, sizeof(log_mac2)); - bytes2string(log_mac2, sizeof(log_mac2), mac2_verify, NOISE_MAC2_LENGTH, c->log); - LOGGER_DEBUG(c->log, "MAC2 calculated: %s", log_mac2); - if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, mac2_verify, NOISE_MAC2_LENGTH) != 0) { return false; } LOGGER_DEBUG(c->log, "Initiator: Responder MAC2 verified"); - return true; } else { return true; } @@ -993,7 +954,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u => 185 bytes in total = (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) */ if (noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "INITIATOR"); /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -1029,13 +989,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; - /* Noise: DHT public key from INITIATOR */ - memcpy(handshake_payload_plain, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE); - - //TODO: remove - char log_source[sizeof(struct IP_Port) * 2 + 1]; - bytes2string(log_source, sizeof(log_source), (uint8_t *) source, sizeof(struct IP_Port), c->log); - LOGGER_DEBUG(c->log, "log_source: %s", log_source); + memcpy(handshake_payload_plain, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); /* Noise: Cookie from INITIATOR */ uint8_t noise_cookie_initiator[NOISE_COOKIE_LENGTH]; @@ -1133,18 +1087,18 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); /* Create Noise Handshake Payload */ - uint8_t *handshake_payload_plain = nullptr; + uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, - handshake_payload_plain, 0, noise_handshake_temp_key, + handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, noise_handshake->hash); packet[0] = NET_PACKET_CRYPTO_HS; //TODO: MAC1+MAC2 exclude packet type => problem? uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1_data, packet + 1, sizeof(packet_mac1_data)); + memcpy(packet_mac1_data, packet +1, sizeof(packet_mac1_data)); uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); uint8_t mac1[NOISE_MAC1_LENGTH]; @@ -1153,19 +1107,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, mac1, NOISE_MAC1_LENGTH); - //TODO: remove from production code - char log_cookie[NOISE_COOKIE_LENGTH*2+1]; - bytes2string(log_cookie, sizeof(log_cookie), cookie, NOISE_COOKIE_LENGTH, c->log); - LOGGER_DEBUG(c->log, "INITIATOR cookie: %s", log_cookie); - uint8_t noise_mac2[NOISE_MAC2_LENGTH]; crypto_mac_blake2b_128(noise_mac2, cookie, NOISE_COOKIE_LENGTH, packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH)); - memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC2_LENGTH, noise_mac2, NOISE_MAC2_LENGTH); crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - //TODO: remove - // crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); + crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } @@ -2639,8 +2587,6 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) return -1; } - LOGGER_DEBUG(c->log, "conn->temp_packet[0]: %d", conn->temp_packet[0]); - if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0) { return -1; } @@ -2681,13 +2627,6 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; - Ip_Ntoa ip_str; - net_ip_ntoa(&ip_port.ip, &ip_str); - //TODO: remove from production code - char log_ip[ip_str.length*2+1]; - bytes2string(log_ip, sizeof(log_ip), (uint8_t *) ip_str.buf, ip_str.length, c->log); - LOGGER_DEBUG(c->log, "INITIATOR log_ip: %s, bool: %d", log_ip, ip_str.ip_is_valid); - if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, conn->public_key, dht_public_key, conn->noise_handshake, &ip_port) != sizeof(handshake_packet)) { return -1; @@ -3070,12 +3009,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "Noise handshake"); const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); LOGGER_DEBUG(c->log, "after return_ip_port_connection()"); - Ip_Ntoa ip_str; - net_ip_ntoa(&ip_port.ip, &ip_str); - //TODO: remove from production code - char log_ip[ip_str.length*2+1]; - bytes2string(log_ip, sizeof(log_ip), (uint8_t *) ip_str.buf, ip_str.length, c->log); - LOGGER_DEBUG(c->log, "log_ip: %s, bool: %d", log_ip, ip_str.ip_is_valid); if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); @@ -3092,16 +3025,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); if (noise_verify_mac1_mac2(packet, length, c, &ip_port, true) != true) { - LOGGER_DEBUG(c->log, "failed"); return -1; } - //TODO: memzero conn->noise_handshake here? - /* there is already something in conn->noise_handshake -> necessary to memzero in this case! */ - // crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); - if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { - LOGGER_DEBUG(c->log, "failed"); return -1; } @@ -3109,7 +3036,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake, &ip_port)) { - LOGGER_DEBUG(c->log, "failed"); return -1; } @@ -3120,7 +3046,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise RESPONDER needs to send handshake packet, afterwards finished */ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { - LOGGER_DEBUG(c->log, "failed"); return -1; } //TODO: here? @@ -3877,7 +3802,6 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // uint8_t // noise_create_cookie() - //FIXME: Corrent IP_Port of peer not known at this point (but necessary for initiator-cookie) if (create_send_handshake(c, crypt_connection_id, nullptr, conn->peer_dht_public_key) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); @@ -4889,7 +4813,6 @@ uint32_t crypto_run_interval(const Net_Crypto *c) /** Main loop. */ void do_net_crypto(Net_Crypto *c, void *userdata) { - LOGGER_DEBUG(c->log, "do_net_crypto()"); //TODO: update cookie symmetric key every ~2 minutes (cf. WireGuard)? kill_timedout(c, userdata); do_tcp(c, userdata); From cead98b1259c7097ee95e0be6b06482e27fbd7ac Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 19:44:31 +0100 Subject: [PATCH 119/150] Revert "feat: implementation of possible new cookie mechanism. Currently broken because both peers are Noise-responder." This reverts commit 44e58f78ab1a8b0f09bd8b5a33e317ec9512de12. --- toxcore/net_crypto.c | 326 +++++++++++++++++++------------------------ 1 file changed, 143 insertions(+), 183 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 87a0d61824..4a2b9482d3 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -237,13 +237,6 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti #define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) #define NOISE_COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE) - -/* Noise: Necessary for Noise-based handshake (Noise cookie phase + Noise_IK_25519_ChaChaPoly_BLAKE2b) */ -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER 0 - static const uint8_t noise_mac1_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "mac1----"; //TODO: uncomment when used (currently commented for CI) static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; @@ -314,8 +307,7 @@ static int create_cookie(const Memory *mem, const Random *rng, const Mono_Time * return 0; } -/** TODO: adapt for Noise - * @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key +/** @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key * * @param cookie must be NOISE_COOKIE_LENGTH bytes. * @param cookie_symmetric_key must be of size CRYPTO_SYMMETRIC_KEY_SIZE or bigger. Symmetric encryption key for τ := Mac(Rm, Am') @@ -398,90 +390,6 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui return COOKIE_RESPONSE_LENGTH; } -/* -* TODO: Helper function to print hashes, keys, packets, etc. -* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? -* bytes_to_string() from util.h -*/ -static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) -{ - bytes_to_string(bytes, bytes_length, string, string_length); -} - -//TODO: document -static bool noise_verify_mac1_mac2(const uint8_t *handshake_packet, size_t handshake_packet_length, const Net_Crypto *c, const IP_Port *source, bool verify_mac2) { - LOGGER_DEBUG(c->log, "ENTERING"); - if (handshake_packet_length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - LOGGER_DEBUG(c->log, "NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); - /* Verify MAC1 */ - uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1_data, handshake_packet + 1, sizeof(packet_mac1_data)); - uint8_t mac1_verify[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1_verify, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); - - if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, - mac1_verify, NOISE_MAC1_LENGTH) != 0) { - return false; - } - LOGGER_DEBUG(c->log, "Responder: Initiator MAC1 verified"); - - if (verify_mac2 == true) { - //TODO: remove from production code - char log_handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; - bytes2string(log_handshake_packet, sizeof(log_handshake_packet), handshake_packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); - LOGGER_DEBUG(c->log, "Responder: INITIATOR handshake packet: %s", log_handshake_packet); - /* Verify MAC2 */ - uint8_t mac2_verify[NOISE_MAC2_LENGTH]; - uint8_t packet_mac2_data[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - 1 - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2_data, handshake_packet + 1, sizeof(packet_mac2_data)); - //TODO: Other way to get cookie here? - uint8_t self_cookie[NOISE_COOKIE_LENGTH]; - noise_create_cookie(self_cookie, c->cookie_symmetric_key, source); - crypto_mac_blake2b_128(mac2_verify, self_cookie, NOISE_COOKIE_LENGTH, packet_mac2_data, sizeof(packet_mac2_data)); - - if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - mac2_verify, NOISE_MAC2_LENGTH) != 0) { - return false; - } - LOGGER_DEBUG(c->log, "Responder: Initiator MAC2 verified"); - } else { - return true; - } - } - else if (handshake_packet_length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { - LOGGER_DEBUG(c->log, "NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); - /* Verify MAC1 */ - uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1_data, handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t mac1_verify[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1_verify, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); - - if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - mac1_verify, NOISE_MAC1_LENGTH) != 0) { - return false; - } - LOGGER_DEBUG(c->log, "Initiator: Responder MAC1 verified"); - - if (verify_mac2 == true) { - /* Verify MAC2 */ - uint8_t mac2_verify[NOISE_MAC2_LENGTH]; - uint8_t packet_mac2_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2_data, handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH)); - uint8_t self_cookie[NOISE_COOKIE_LENGTH]; - noise_create_cookie(self_cookie, c->cookie_symmetric_key, source); - crypto_mac_blake2b_128(mac2_verify, self_cookie, NOISE_COOKIE_LENGTH, packet_mac2_data, sizeof(packet_mac2_data)); - - if (memcmp(handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - mac2_verify, NOISE_MAC2_LENGTH) != 0) { - return false; - } - LOGGER_DEBUG(c->log, "Initiator: Responder MAC2 verified"); - } else { - return true; - } - } -} - /** @brief Create a cookie response packet and put it in packet. * * @param packet must be of size NOISE_COOKIE_RESPONSE_LENGTH. @@ -492,36 +400,22 @@ static bool noise_verify_mac1_mac2(const uint8_t *handshake_packet, size_t hands * @retval NOISE_COOKIE_RESPONSE_LENGTH on success. */ non_null() -static int noise_create_cookie_response(const Net_Crypto *c, uint8_t noise_cookie_response_packet[NOISE_COOKIE_RESPONSE_LENGTH], const IP_Port *source, - const uint8_t noise_cookie_request_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]) +static int noise_create_cookie_response(const Net_Crypto *c, uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], const IP_Port *source, + const uint8_t noise_mac1_received[NOISE_MAC1_LENGTH]) { LOGGER_DEBUG(c->log, "ENTERING"); // symmetric_cookie_encryption_key based on label + DHT public key - - /* Verify handshake packet MAC1 (of the INITIATOR peer) */ - // uint8_t noise_mac1[NOISE_MAC1_LENGTH]; - // crypto_mac_blake2b_128(noise_mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - - // if (memcmp(noise_cookie_response_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, - // packet_mac1, NOISE_MAC1_LENGTH) != 0) { - // return -1; - // } - if (noise_verify_mac1_mac2(noise_cookie_request_packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c, nullptr, false) != true) { - return -1; - } - LOGGER_DEBUG(c->log, "after noise_verify_mac1_mac2()"); - + // handshake packet mac1 value (of the peer) uint8_t noise_cookie[NOISE_COOKIE_LENGTH]; noise_create_cookie(noise_cookie, c->cookie_symmetric_key, source); - noise_cookie_response_packet[0] = NET_PACKET_COOKIE_RESPONSE; + packet[0] = NET_PACKET_COOKIE_RESPONSE; // random nonce - random_nonce(c->rng, noise_cookie_response_packet + 1); + random_nonce(c->rng, packet + 1); // calculate msg.cookie := Xaead(Hash(Label-Cookie ‖ Spub m ), msg.nonce, τ, M ) - //TODO: AD ignores packet kind (otherwise not possible with NET_PACKET_COOKIE_REQUEST change to NET_PACKET_CRYPTO_HANDSHAKE) => problem/vulnerability? - const int len = encrypt_data_symmetric_xaead(c->cookie_xaead_symmetric_key, noise_cookie_response_packet + 1, noise_cookie, - NOISE_COOKIE_LENGTH, noise_cookie_response_packet + 1 + CRYPTO_NONCE_SIZE, noise_cookie_request_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, NOISE_MAC1_LENGTH); + const int len = encrypt_data_symmetric_xaead(c->cookie_xaead_symmetric_key, packet + 1, noise_cookie, + NOISE_COOKIE_LENGTH, packet + 1 + CRYPTO_NONCE_SIZE, noise_mac1_received, NOISE_MAC1_LENGTH); if (len != (NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE)) { return -1; @@ -561,24 +455,30 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui } /** Handle the cookie request packet (for raw UDP) */ -//TODO: Only handles NoiseIK cookie requests (i.e. handshake packet with invalid MAC2) -non_null(1, 2, 3) -static int noise_udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) +non_null(1, 2, 3) nullable(5) +static int udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, + void *userdata) { - if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - return 1; - } const Net_Crypto *c = (const Net_Crypto *)object; //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); - uint8_t noise_data_cookie_response[NOISE_COOKIE_RESPONSE_LENGTH]; - if (noise_create_cookie_response(c, noise_data_cookie_response, source, packet) != sizeof(noise_data_cookie_response)) { + uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; + uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + + if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0) { + return 1; + } + + uint8_t data[COOKIE_RESPONSE_LENGTH]; + + if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) { return 1; } - if ((uint32_t)sendpacket(dht_get_net(c->dht), source, noise_data_cookie_response, sizeof(noise_data_cookie_response)) != sizeof(noise_data_cookie_response)) { + if ((uint32_t)sendpacket(dht_get_net(c->dht), source, data, sizeof(data)) != sizeof(data)) { return 1; } @@ -591,14 +491,21 @@ static int tcp_handle_cookie_request(const Net_Crypto *c, int connections_number uint16_t length) { LOGGER_DEBUG(c->log, "ENTERING"); + uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; + uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - const IP_Port source = tcp_connections_number_to_ip_port(connections_number); - uint8_t noise_data_cookie_response[NOISE_COOKIE_RESPONSE_LENGTH]; - if (noise_create_cookie_response(c, noise_data_cookie_response, &source, packet) != sizeof(noise_data_cookie_response)) { - return 1; + if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0) { + return -1; } - const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, noise_data_cookie_response, sizeof(noise_data_cookie_response)); + uint8_t data[COOKIE_RESPONSE_LENGTH]; + + if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) { + return -1; + } + + const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data)); return ret; } @@ -608,14 +515,25 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { LOGGER_DEBUG(c->log, "ENTERING"); + uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; + uint8_t dht_public_key_temp[CRYPTO_PUBLIC_KEY_SIZE]; - const IP_Port source = tcp_connections_number_to_ip_port(tcp_connections_number); - uint8_t noise_data_cookie_response[NOISE_COOKIE_RESPONSE_LENGTH]; - if (noise_create_cookie_response(c, noise_data_cookie_response, &source, packet) != sizeof(noise_data_cookie_response)) { - return 1; + if (handle_cookie_request(c, request_plain, shared_key, dht_public_key_temp, packet, length) != 0) { + return -1; } - const int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, noise_data_cookie_response, sizeof(noise_data_cookie_response)); + if (!pk_equal(dht_public_key, dht_public_key_temp)) { + return -1; + } + + uint8_t data[COOKIE_RESPONSE_LENGTH]; + + if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) { + return -1; + } + + const int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, data, sizeof(data)); return ret; } @@ -659,14 +577,13 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * * @retval COOKIE_LENGTH on success. */ non_null() -static int noise_handle_cookie_response(const Net_Crypto *c, uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH], +static int noise_handle_cookie_response(const Memory *mem, uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH], const uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *noise_mac1_sent) { // if (length != NOISE_COOKIE_RESPONSE_LENGTH) { // return -1; // } - LOGGER_DEBUG(c->log, "ENTERING: noise_handle_cookie_response()"); //TODO: precompute for crypto_connection? uint8_t peer_cookie_xaead_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; @@ -676,15 +593,23 @@ static int noise_handle_cookie_response(const Net_Crypto *c, uint8_t noise_peer_ const int len = decrypt_data_symmetric_xaead(peer_cookie_xaead_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE, noise_peer_cookie, noise_mac1_sent, NOISE_MAC1_LENGTH); - LOGGER_DEBUG(c->log, "len: %d", len); - - if (len != NOISE_COOKIE_LENGTH) { + if (len != NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE) { return -1; } return NOISE_COOKIE_LENGTH; } +/* +* TODO: Helper function to print hashes, keys, packets, etc. +* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? +* bytes_to_string() from util.h +*/ +static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) +{ + bytes_to_string(bytes, bytes_length, string, string_length); +} + /* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /* Noise: Necessary for Noise-based handshake (non-Noise cookie phase + Noise_IK_25519_ChaChaPoly_SHA512) */ @@ -693,6 +618,12 @@ static int noise_handle_cookie_response(const Net_Crypto *c, uint8_t noise_peer_ // #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) // #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) +/* Noise: Necessary for Noise-based handshake (Noise cookie phase + Noise_IK_25519_ChaChaPoly_BLAKE2b) */ +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER 0 + // /** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. // * @@ -1012,18 +943,15 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); - /* NoiseIK cookie mechanism sent INITIATOR hs packet as cookie request */ - // packet[0] = NET_PACKET_CRYPTO_HS; - packet[0] = NET_PACKET_COOKIE_REQUEST; + packet[0] = NET_PACKET_CRYPTO_HS; - //TODO: MAC1+MAC2 exclude packet type => problem? - uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1_data, packet + 1, sizeof(packet_mac1_data)); + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); uint8_t mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); + crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, mac1, NOISE_MAC1_LENGTH); @@ -1096,19 +1024,18 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u packet[0] = NET_PACKET_CRYPTO_HS; - //TODO: MAC1+MAC2 exclude packet type => problem? - uint8_t packet_mac1_data[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1_data, packet +1, sizeof(packet_mac1_data)); + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); uint8_t mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1_data, sizeof(packet_mac1_data)); + crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, mac1, NOISE_MAC1_LENGTH); uint8_t noise_mac2[NOISE_MAC2_LENGTH]; - crypto_mac_blake2b_128(noise_mac2, cookie, NOISE_COOKIE_LENGTH, packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - 1 - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(noise_mac2, cookie, NOISE_COOKIE_LENGTH, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC2_LENGTH, noise_mac2, NOISE_MAC2_LENGTH); @@ -1447,6 +1374,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + /* -> e, es, s, ss */ /* TODO: New Cookies Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) @@ -1568,6 +1497,28 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } + /* Verify MAC1 */ + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t mac1[NOISE_MAC1_LENGTH]; + crypto_mac_blake2b_128(mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, + packet_mac1, NOISE_MAC1_LENGTH) != 0) { + return false; + } + + /* Verify MAC2 */ + uint8_t mac2[NOISE_MAC2_LENGTH]; + uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH]; + memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + packet_mac2, NOISE_MAC2_LENGTH) != 0) { + return false; + } + memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -1606,7 +1557,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* necessary */ //TODO: remove - // memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); @@ -2575,7 +2526,7 @@ non_null() static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + // LOGGER_DEBUG(c->log, "ENTERING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2592,7 +2543,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); - LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); + // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); ++conn->temp_packet_num_sent; return 0; } @@ -2909,7 +2860,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, // uint8_t noise_mac1_sent[NOISE_MAC1_LENGTH]; // memcpy(noise_mac1_sent, conn->temp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, NOISE_MAC1_LENGTH); uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH]; - if (noise_handle_cookie_response(c, noise_peer_cookie, packet, conn->peer_dht_public_key, + if (noise_handle_cookie_response(c->mem, noise_peer_cookie, packet, conn->peer_dht_public_key, noise_handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE) != NOISE_COOKIE_LENGTH) { return -1; } @@ -2931,21 +2882,14 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); - noise_handshake_packet[0] = NET_PACKET_CRYPTO_HS; /* calculate NoiseIK MAC2 for initiator handshake packet */ uint8_t noise_mac2[NOISE_MAC2_LENGTH]; - crypto_mac_blake2b_128(noise_mac2, noise_peer_cookie, NOISE_COOKIE_LENGTH, noise_handshake_packet + 1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - 1 - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(noise_mac2, noise_peer_cookie, NOISE_COOKIE_LENGTH, noise_handshake_packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); memcpy(noise_handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, noise_mac2, NOISE_MAC2_LENGTH); if (new_temp_packet(c, crypt_connection_id, noise_handshake_packet, sizeof(noise_handshake_packet)) != 0) { return -1; } - - //TODO: remove from production code - char log_handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; - bytes2string(log_handshake_packet, sizeof(log_handshake_packet), noise_handshake_packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); - LOGGER_DEBUG(c->log, "INITIATOR handshake packet: %s", log_handshake_packet); - send_temp_packet(c, crypt_connection_id); } else { return -1; } @@ -2954,7 +2898,6 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } conn->status = CRYPTO_CONN_HANDSHAKE_SENT; - LOGGER_DEBUG(c->log, "end"); return 0; } @@ -3008,26 +2951,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise handshake"); const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "after return_ip_port_connection()"); if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? - if (noise_verify_mac1_mac2(packet, length, c, &ip_port, true) != true) { - return -1; - } - if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, nullptr, packet, length, conn->public_key, conn->noise_handshake, &ip_port)) { return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); - - if (noise_verify_mac1_mac2(packet, length, c, &ip_port, true) != true) { - return -1; - } - if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } @@ -3060,11 +2993,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const else { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); - - if (noise_verify_mac1_mac2(packet, length, c, &ip_port, true) != true) { - return -1; - } - /* necessary, otherwise broken after INITIATOR to RESPONDER change; also necessary without change */ if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; @@ -3445,10 +3373,42 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { - //TODO: add check for MAC1 and MAC2, if both ok, send RESPONDER handshake packet + //TODO: add check for MAC1 and MAC2, if both ok, call noise_create_cookie_response() + + /* Verify MAC1 */ + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t noise_mac1[NOISE_MAC1_LENGTH]; + crypto_mac_blake2b_128(noise_mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, + packet_mac1, NOISE_MAC1_LENGTH) != 0) { + return -1; + } - /* Verify MAC1 and MAC2 */ - if (noise_verify_mac1_mac2(packet, length, c, source, true) != true) { + /* Verify MAC2 */ + uint8_t mac2[NOISE_MAC2_LENGTH]; + uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH]; + memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + packet_mac2, NOISE_MAC2_LENGTH) != 0) { + uint8_t noise_cookie_respone[NOISE_COOKIE_RESPONSE_LENGTH]; + + if (noise_create_cookie_response(c, noise_cookie_respone, source, noise_mac1) != NOISE_COOKIE_RESPONSE_LENGTH) { + return -1; + } + + //TODO: how to send cookie response packet from here? via UDP/TCP? + + // if (is_udp) { + // if ((uint32_t)sendpacket(dht_get_net(c->dht), source, noise_cookie_respone, sizeof(noise_cookie_respone)) != sizeof(noise_cookie_respone)) { + // return 1; + // } + // } else { + // const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data)); + // } return -1; } @@ -3540,7 +3500,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(Noise_Handshake)); - // memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); + memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); crypto_connection_add_source(c, crypt_connection_id, source); @@ -4760,7 +4720,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; - networking_registerhandler(dht_get_net(dht), NET_PACKET_COOKIE_REQUEST, &noise_udp_handle_cookie_request, temp); + networking_registerhandler(dht_get_net(dht), NET_PACKET_COOKIE_REQUEST, &udp_handle_cookie_request, temp); networking_registerhandler(dht_get_net(dht), NET_PACKET_COOKIE_RESPONSE, &udp_handle_packet, temp); networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp); networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp); From 9817f28eb09832d40bec28650c7bb142dacca829 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 19:44:45 +0100 Subject: [PATCH 120/150] Revert "feat: implementation of (possible) new cookie mechanism." This reverts commit 344030249d2eb8ec8612ff9787558403980f2982. --- toxcore/net_crypto.c | 218 +++++++++++++++++-------------------------- 1 file changed, 86 insertions(+), 132 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 4a2b9482d3..5d18d2859a 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -567,8 +567,7 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * return COOKIE_LENGTH; } -/** TODO: adapt comment for new cookie mechanism - * @brief Handle a cookie response packet of length encrypted with shared_key. +/** @brief Handle a cookie response packet of length encrypted with shared_key. * put the cookie in the response in cookie * * @param cookie must be of length COOKIE_LENGTH. @@ -579,13 +578,12 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * non_null() static int noise_handle_cookie_response(const Memory *mem, uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH], const uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], - const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *noise_mac1_sent) + const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t noise_mac1_sent[NOISE_MAC1_LENGTH]) { - // if (length != NOISE_COOKIE_RESPONSE_LENGTH) { + // if (length != COOKIE_RESPONSE_LENGTH) { // return -1; // } - //TODO: precompute for crypto_connection? uint8_t peer_cookie_xaead_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; precompute_mac_key(peer_cookie_xaead_symmetric_key, peer_dht_public_key, noise_cookie_key_label); @@ -856,7 +854,7 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte * @retval NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER if Noise handshake responder * */ -non_null(1, 2, 4, 6, 7, 8) nullable(3, 5, 9, 10) +non_null(1, 2, 3, 4, 6, 7, 8) nullable(5, 9) static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake, const IP_Port *source) @@ -1034,10 +1032,10 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, mac1, NOISE_MAC1_LENGTH); - uint8_t noise_mac2[NOISE_MAC2_LENGTH]; - crypto_mac_blake2b_128(noise_mac2, cookie, NOISE_COOKIE_LENGTH, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); + uint8_t mac2[NOISE_MAC2_LENGTH]; + crypto_mac_blake2b_128(mac2, cookie, NOISE_COOKIE_LENGTH, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC2_LENGTH, - noise_mac2, NOISE_MAC2_LENGTH); + mac2, NOISE_MAC2_LENGTH); crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); @@ -1366,7 +1364,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u */ non_null(1, 2, 5, 7) nullable(3, 4, 6, 9, 10) static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, - uint8_t *dht_public_key, uint8_t *peer_cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, + uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, Noise_Handshake *noise_handshake, const IP_Port *source) { LOGGER_DEBUG(c->log, "ENTERING"); @@ -1408,6 +1406,27 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t //TODO: Check here if remote_ephemeral is already the same ephemeral key? + uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; + memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + uint8_t mac1[NOISE_MAC1_LENGTH]; + crypto_mac_blake2b_128(mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, + packet_mac1, NOISE_MAC1_LENGTH) != 0) { + return false; + } + + /* Verify MAC2 */ + uint8_t mac2[NOISE_MAC2_LENGTH]; + uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH]; + memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); + + if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, + packet_mac2, NOISE_MAC2_LENGTH) != 0) { + return false; + } + /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -1461,7 +1480,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* necessary */ memcpy(dht_public_key, handshake_payload_plain, CRYPTO_PUBLIC_KEY_SIZE); /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ - memcpy(peer_cookie, handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE, NOISE_COOKIE_LENGTH); + memcpy(cookie, handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE, NOISE_COOKIE_LENGTH); //TODO: handle and compare timestamp -> does this even make sense at this point? CPU already wasted if replayed => handle with states? /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ @@ -1497,7 +1516,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - /* Verify MAC1 */ uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); uint8_t mac1[NOISE_MAC1_LENGTH]; @@ -1606,7 +1624,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t memcpy(nonce, plain, CRYPTO_NONCE_SIZE); memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(peer_cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); @@ -2555,7 +2573,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) * @retval -1 on failure. * @retval 0 on success. */ -non_null(1, 4) nullable(3) +non_null() static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { @@ -2853,47 +2871,39 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } - /* NoiseIK cookie mechanism */ - uint8_t noise_handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; - memcpy(noise_handshake_packet, conn->temp_packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR); - //TODO: memcpy or pass noise_handshake_packet? - // uint8_t noise_mac1_sent[NOISE_MAC1_LENGTH]; - // memcpy(noise_mac1_sent, conn->temp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, NOISE_MAC1_LENGTH); - uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH]; - if (noise_handle_cookie_response(c->mem, noise_peer_cookie, packet, conn->peer_dht_public_key, - noise_handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE) != NOISE_COOKIE_LENGTH) { + uint8_t cookie[COOKIE_LENGTH]; + uint64_t number; + + if (handle_cookie_response(c->mem, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { + return -1; + } + + if (number != conn->cookie_request_number) { return -1; } - //TODO: remove if new NoiseIK cookie mechanism - // uint8_t cookie[COOKIE_LENGTH]; - // uint64_t number; - // if (handle_cookie_response(c->mem, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { - // return -1; - // } - // if (number != conn->cookie_request_number) { - // return -1; - // } /* Noise: only necessary if Cookie response was successful */ - // if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { - // return -1; - // } + if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { + return -1; + } if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); - /* calculate NoiseIK MAC2 for initiator handshake packet */ - uint8_t noise_mac2[NOISE_MAC2_LENGTH]; - crypto_mac_blake2b_128(noise_mac2, noise_peer_cookie, NOISE_COOKIE_LENGTH, noise_handshake_packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - memcpy(noise_handshake_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - noise_mac2, NOISE_MAC2_LENGTH); - if (new_temp_packet(c, crypt_connection_id, noise_handshake_packet, sizeof(noise_handshake_packet)) != 0) { + if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { return -1; } } else { return -1; } - } else { + } else if (c->noise_compatibility_enabled) { + /* non-Noise handshake */ + LOGGER_DEBUG(c->log, "non-Noise handshake"); + if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { + return -1; + } + } + else { return -1; } @@ -3363,65 +3373,27 @@ void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_cal * @retval 0 on success. */ non_null(1, 2, 3) nullable(5) -static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *packet, uint16_t length, - void *userdata, bool is_udp) +static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, + void *userdata) { //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); + uint8_t *cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH); + + if (cookie == nullptr) { + return -1; + } + New_Connection n_c = {{{{0}}}}; + n_c.cookie = cookie; + n_c.source = *source; + n_c.cookie_length = COOKIE_LENGTH; + /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { //TODO: add check for MAC1 and MAC2, if both ok, call noise_create_cookie_response() - - /* Verify MAC1 */ - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t noise_mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(noise_mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, - packet_mac1, NOISE_MAC1_LENGTH) != 0) { - return -1; - } - - /* Verify MAC2 */ - uint8_t mac2[NOISE_MAC2_LENGTH]; - uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - packet_mac2, NOISE_MAC2_LENGTH) != 0) { - uint8_t noise_cookie_respone[NOISE_COOKIE_RESPONSE_LENGTH]; - - if (noise_create_cookie_response(c, noise_cookie_respone, source, noise_mac1) != NOISE_COOKIE_RESPONSE_LENGTH) { - return -1; - } - - //TODO: how to send cookie response packet from here? via UDP/TCP? - - // if (is_udp) { - // if ((uint32_t)sendpacket(dht_get_net(c->dht), source, noise_cookie_respone, sizeof(noise_cookie_respone)) != sizeof(noise_cookie_respone)) { - // return 1; - // } - // } else { - // const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data)); - // } - return -1; - } - - uint8_t *noise_peer_cookie = (uint8_t *)mem_balloc(c->mem, NOISE_COOKIE_LENGTH); - - if (noise_peer_cookie == nullptr) { - return -1; - } - - n_c.cookie = noise_peer_cookie; - n_c.source = *source; - n_c.cookie_length = NOISE_COOKIE_LENGTH; - //TODO: adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { @@ -3437,7 +3409,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, - n_c.cookie, packet, length, nullptr, n_c.noise_handshake, source)) { + n_c.cookie, data, length, nullptr, n_c.noise_handshake, source)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); @@ -3447,19 +3419,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* case non-Noise handshake */ else if (c->noise_compatibility_enabled) { LOGGER_DEBUG(c->log, "non-Noise handshake"); - uint8_t *cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH); - - if (cookie == nullptr) { - return -1; - } - - n_c.cookie = cookie; - n_c.source = *source; - n_c.cookie_length = COOKIE_LENGTH; // Necessary for backwards compatibility n_c.noise_handshake = nullptr; if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, - n_c.cookie, packet, length, nullptr, nullptr, nullptr)) { + n_c.cookie, data, length, nullptr, nullptr, nullptr)) { mem_delete(c->mem, n_c.cookie); return -1; } @@ -3730,43 +3693,34 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; - + conn->cookie_request_number = random_u64(c->rng); + uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; //TODO: remove // LOGGER_DEBUG(c->log, "INITIATOR: BEFORE: create_cookie_request()"); - //TODO: remove if new cookie mechanism - // conn->cookie_request_number = random_u64(c->rng); - // uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; - // if (create_cookie_request(c, cookie_request, conn->peer_dht_public_key, conn->cookie_request_number, - // conn->shared_key) != sizeof(cookie_request) - // || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // wipe_crypto_connection(c, crypt_connection_id); - // return -1; - // } - - //TODO: remove - // LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); - - //TODO: here? => yes, if new cookie mechanism - // only necessary if Cookie request was successful - if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, real_public_key, true, nullptr, 0) != 0) { - // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - mem_delete(c->mem, conn->noise_handshake); + if (create_cookie_request(c, cookie_request, conn->peer_dht_public_key, conn->cookie_request_number, + conn->shared_key) != sizeof(cookie_request) + || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); return -1; } - // uint8_t - // noise_create_cookie() + //TODO: remove + // LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); - if (create_send_handshake(c, crypt_connection_id, nullptr, conn->peer_dht_public_key) != 0) { - kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - wipe_crypto_connection(c, crypt_connection_id); - return -1; - } + //TODO: here? + // only necessary if Cookie request was successful + // if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { + // // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); + // mem_delete(c->mem, conn->noise_handshake); + // pthread_mutex_lock(&c->tcp_mutex); + // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + // pthread_mutex_unlock(&c->tcp_mutex); + // wipe_crypto_connection(c, crypt_connection_id); + // return -1; + // } //TODO: remove LOGGER_DEBUG(c->log, "INITIATOR: END"); @@ -3857,7 +3811,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in if (packet[0] == NET_PACKET_CRYPTO_HS) { const IP_Port source = tcp_connections_number_to_ip_port(tcp_connections_number); - if (handle_new_connection_handshake(c, &source, packet, length, userdata, 0) != 0) { + if (handle_new_connection_handshake(c, &source, packet, length, userdata) != 0) { return -1; } @@ -4140,7 +4094,7 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t return 1; } - if (handle_new_connection_handshake(c, source, packet, length, userdata, 1) != 0) { + if (handle_new_connection_handshake(c, source, packet, length, userdata) != 0) { return 1; } From 5e17a8786761a53149b25460582dc983d63ec635 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 19:45:08 +0100 Subject: [PATCH 121/150] Revert "feat: implementation of (possible) new cookie functionality." This reverts commit fdb0163e6e2a9173322e096538b14649d8cac868. --- toxcore/net_crypto.c | 841 ++++++------------------------------------- 1 file changed, 116 insertions(+), 725 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 5d18d2859a..7b8e2c7945 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -68,7 +68,7 @@ typedef struct Crypto_Connection { uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. (non-Noise handshake) */ Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ - uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public X25519 key of the peer */ + uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public X25519 key of the peer */ bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ @@ -168,12 +168,10 @@ struct Net_Crypto { uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; /* The secret key used for cookies */ - uint8_t cookie_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; /* The secret key used for mac1 */ uint8_t mac1_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - /* The secret key used for mac1 */ - uint8_t cookie_xaead_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; new_connection_cb *new_connection_callback; void *new_connection_callback_object; @@ -227,19 +225,15 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti #define COOKIE_TIMEOUT 15 #define COOKIE_DATA_LENGTH (uint16_t)(CRYPTO_PUBLIC_KEY_SIZE * 2) #define COOKIE_CONTENTS_LENGTH (uint16_t)(sizeof(uint64_t) + COOKIE_DATA_LENGTH) -#define NOISE_COOKIE_LENGTH 16 -#define NOISE_MAC1_LENGTH 16 -#define NOISE_MAC2_LENGTH NOISE_MAC1_LENGTH #define COOKIE_LENGTH (uint16_t)(CRYPTO_NONCE_SIZE + COOKIE_CONTENTS_LENGTH + CRYPTO_MAC_SIZE) #define COOKIE_REQUEST_PLAIN_LENGTH (uint16_t)(COOKIE_DATA_LENGTH + sizeof(uint64_t)) #define COOKIE_REQUEST_LENGTH (uint16_t)(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) #define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) -#define NOISE_COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE) static const uint8_t noise_mac1_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "mac1----"; //TODO: uncomment when used (currently commented for CI) -static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; +// static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; /** @brief Create a cookie request packet and put it in packet. * @@ -307,27 +301,6 @@ static int create_cookie(const Memory *mem, const Random *rng, const Mono_Time * return 0; } -/** @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key - * - * @param cookie must be NOISE_COOKIE_LENGTH bytes. - * @param cookie_symmetric_key must be of size CRYPTO_SYMMETRIC_KEY_SIZE or bigger. Symmetric encryption key for τ := Mac(Rm, Am') - * @param source IP+Port of the peer this cookie is intended for. - * - * Am' represents a concatenation of the peer's external IP source address and source port - * - * @retval -1 on failure. - * @retval 0 on success. - */ -non_null() -static void noise_create_cookie(uint8_t cookie[NOISE_COOKIE_LENGTH], - const uint8_t cookie_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE], - const IP_Port *source) -{ - // calculate τ := Mac(Rm, Am′) - //TODO: change cookie symmetric key or hash timestamp into? - crypto_mac_blake2b_128(cookie, cookie_symmetric_key, CRYPTO_SECRET_KEY_SIZE, (uint8_t *) source, sizeof(struct IP_Port)); -} - /** @brief Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key * * @retval -1 on failure. @@ -374,7 +347,7 @@ 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->mem, c->rng, c->mono_time, plain, cookie_plain, c->cookie_symmetric_key) != 0) { + if (create_cookie(c->mem, c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } @@ -390,40 +363,6 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui return COOKIE_RESPONSE_LENGTH; } -/** @brief Create a cookie response packet and put it in packet. - * - * @param packet must be of size NOISE_COOKIE_RESPONSE_LENGTH. - * @param source IP+Port of the peer this cookie response is intended for. - * @param noise_mac1_received MAC1 value of peer's handshake packet. - * - * @retval -1 on failure. - * @retval NOISE_COOKIE_RESPONSE_LENGTH on success. - */ -non_null() -static int noise_create_cookie_response(const Net_Crypto *c, uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], const IP_Port *source, - const uint8_t noise_mac1_received[NOISE_MAC1_LENGTH]) -{ - LOGGER_DEBUG(c->log, "ENTERING"); - // symmetric_cookie_encryption_key based on label + DHT public key - // handshake packet mac1 value (of the peer) - uint8_t noise_cookie[NOISE_COOKIE_LENGTH]; - - noise_create_cookie(noise_cookie, c->cookie_symmetric_key, source); - - packet[0] = NET_PACKET_COOKIE_RESPONSE; - // random nonce - random_nonce(c->rng, packet + 1); - // calculate msg.cookie := Xaead(Hash(Label-Cookie ‖ Spub m ), msg.nonce, τ, M ) - const int len = encrypt_data_symmetric_xaead(c->cookie_xaead_symmetric_key, packet + 1, noise_cookie, - NOISE_COOKIE_LENGTH, packet + 1 + CRYPTO_NONCE_SIZE, noise_mac1_received, NOISE_MAC1_LENGTH); - - if (len != (NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE)) { - return -1; - } - - return NOISE_COOKIE_RESPONSE_LENGTH; -} - /** @brief Handle the cookie request packet of length length. * Put what was in the request in request_plain (must be of size COOKIE_REQUEST_PLAIN_LENGTH) * Put the key used to decrypt the request into shared_key (of size CRYPTO_SHARED_KEY_SIZE) for use in the response. @@ -567,37 +506,6 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * return COOKIE_LENGTH; } -/** @brief Handle a cookie response packet of length encrypted with shared_key. - * put the cookie in the response in cookie - * - * @param cookie must be of length COOKIE_LENGTH. - * - * @retval -1 on failure. - * @retval COOKIE_LENGTH on success. - */ -non_null() -static int noise_handle_cookie_response(const Memory *mem, uint8_t noise_peer_cookie[NOISE_COOKIE_LENGTH], - const uint8_t packet[NOISE_COOKIE_RESPONSE_LENGTH], - const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t noise_mac1_sent[NOISE_MAC1_LENGTH]) -{ - // if (length != COOKIE_RESPONSE_LENGTH) { - // return -1; - // } - - uint8_t peer_cookie_xaead_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - precompute_mac_key(peer_cookie_xaead_symmetric_key, peer_dht_public_key, noise_cookie_key_label); - - // decrypt msg.cookie := Xaead(Hash(Label-Cookie ‖ Spub m ), msg.nonce, τ, M ) - const int len = decrypt_data_symmetric_xaead(peer_cookie_xaead_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE, noise_peer_cookie, noise_mac1_sent, NOISE_MAC1_LENGTH); - - if (len != NOISE_COOKIE_LENGTH + CRYPTO_MAC_SIZE) { - return -1; - } - - return NOISE_COOKIE_LENGTH; -} - /* * TODO: Helper function to print hashes, keys, packets, etc. * TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? @@ -610,231 +518,12 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte /* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -/* Noise: Necessary for Noise-based handshake (non-Noise cookie phase + Noise_IK_25519_ChaChaPoly_SHA512) */ -// #define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -// #define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -// #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) -// #define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) - -/* Noise: Necessary for Noise-based handshake (Noise cookie phase + Noise_IK_25519_ChaChaPoly_BLAKE2b) */ -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER 0 - - -// /** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. -// * -// * cf. Noise section 5.3 -> WriteMessage(payload, message_buffer) -// * -// * @param cookie must be COOKIE_LENGTH bytes. -// * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. -// * @param nonce base nonce for this Tox instance, to be used for transport message encryption after handshake -// * @param ephemeral_private Ephemeral private X25519 key of this Tox instance for this handshake -// * @param ephemeral_public Ephemeral public X25519 key of this Tox instance for this handshake -// * @param peer_real_pk X25519 static ID public key from peer to connect to -// * @param peer_dht_pubkey X25519 DHT public key from peer to connect to -// * @param noise_handshake struct containing Noise information/values -// * -// * @retval -1 on failure. -// * @retval HANDSHAKE_PACKET_LENGTH on success (non-Noise handshake). -// * @retval NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR if Noise handshake initiator -// * @retval NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER if Noise handshake responder -// * -// */ -// non_null(1, 2, 3, 4, 6, 7, 8) nullable(5, 9) -// static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, -// const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake) -// { -// LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); -// /* Noise-based handshake */ -// if (noise_handshake != nullptr) { -// LOGGER_DEBUG(c->log, "Noise Handshake"); -// /* Noise INITIATOR: -> e, es, s, ss */ -// /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) -// [uint8_t 26] -// [session public key of the peer (32 bytes)] => currently in plain -// ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 -// [encrypted static public key of the INITIATOR (32 bytes)] -// [MAC encrypted static pubkey 16 bytes] -// ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 -// [Encrypted message containing: -// [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake -// [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD -// [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] -// [MAC encrypted payload 16 bytes] -// => 345 bytes in total -// */ -// if (noise_handshake->initiator) { -// /* set ephemeral private+public */ -// memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); -// memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - -// /* e */ -// memcpy(packet + 1, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); -// noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - -// //TODO: remove from production code -// // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; -// // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); - -// /* es */ -// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; -// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); - -// /* s */ -// /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ -// noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, -// noise_handshake->hash); - -// //TODO: remove from production code -// // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; -// // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); -// char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; -// bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); -// LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); - -// /* ss */ -// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); - -// /* Noise Handshake Payload */ -// uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; -// memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - -// /* Noise: Cookie from RESPONDER */ -// memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - -// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; -// memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - -// //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise -// /* OtherCookie is added to payload */ -// if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, -// cookie_plain, c->cookie_symmetric_key) != 0) { -// return -1; -// } - -// /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ -// noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, -// handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, -// noise_handshake->hash); - -// //TODO: remove from production code -// // LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); -// // char log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*2+1]; -// // bytes2string(log_ciphertext, sizeof(log_ciphertext), (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE), -// // (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); -// // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); - -// packet[0] = NET_PACKET_CRYPTO_HS; - -// //TODO: remove from production code -// // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; -// // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); -// // LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); - -// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); -// crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); - -// return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; -// } -// /* Noise RESPONDER: <- e, ee, se */ -// /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) -// [uint8_t 26] -// [session public key of the peer (32 bytes)] => currently in plain -// ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 -// [Encrypted message containing: -// [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake -// [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD -// ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK -// [MAC encrypted payload 16 bytes] -// => ~~321~~ 185 bytes in total -// */ -// else { -// /* set ephemeral private+public */ -// memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); -// memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - -// /* e */ -// memcpy(packet + 1, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); -// noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - -// //TODO: Remove -// // char log_ck[CRYPTO_SHA512_SIZE*2+1]; -// // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "RESPONDER pre ee ck: %s", log_ck); - -// /* ee */ -// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; -// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); - -// //TODO: Remove -// // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; -// // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "RESPONDER ee temp_key: %s", log_temp_key); - -// /* se */ -// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); - -// //TODO: Remove -// // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); - -// /* Create Noise Handshake Payload */ -// uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; -// memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - -// /* Noise: Cookie from INITIATOR */ -// memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - -// /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ -// noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, -// handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, -// noise_handshake->hash); - -// packet[0] = NET_PACKET_CRYPTO_HS; - -// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); -// crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); - -// return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; -// } -// } -// /* non-Noise handshake, check for enabled backwards compatibility happens in create_send_handshake() */ -// else { -// LOGGER_DEBUG(c->log, "non-Noise handshake"); -// uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; -// memcpy(plain, nonce, CRYPTO_NONCE_SIZE); -// memcpy(plain + CRYPTO_NONCE_SIZE, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); -// crypto_sha512(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, cookie, COOKIE_LENGTH); -// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; -// 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->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, -// cookie_plain, c->cookie_symmetric_key) != 0) { -// return -1; -// } - -// random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); -// const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), -// packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); - -// if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { -// return -1; -// } - -// packet[0] = NET_PACKET_CRYPTO_HS; -// memcpy(packet + 1, cookie, COOKIE_LENGTH); - -// return HANDSHAKE_PACKET_LENGTH; -// } -// } - -//TODO: adapt for new cookie phase and handshake +/* Noise: Necessary for Noise-based handshake */ +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) + /** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. * * cf. Noise section 5.3 -> WriteMessage(payload, message_buffer) @@ -856,14 +545,27 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte */ non_null(1, 2, 3, 4, 6, 7, 8) nullable(5, 9) static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, - const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake, - const IP_Port *source) + const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake) { LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); /* Noise-based handshake */ if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise Handshake"); /* Noise INITIATOR: -> e, es, s, ss */ + /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + [uint8_t 26] + [session public key of the peer (32 bytes)] => currently in plain + ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 + [encrypted static public key of the INITIATOR (32 bytes)] + [MAC encrypted static pubkey 16 bytes] + ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD + [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] + [MAC encrypted payload 16 bytes] + => 345 bytes in total + */ /* TODO: New Cookies Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] @@ -874,15 +576,15 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ - [current ephemeral DHT public key of the INITIATOR (32 bytes)] => necessary for the NoiseIK responder - [16 bytes INITIATOR cookie (used by the RESPONDER peer to respond to the handshake packet)] - [current timestamp (8 bytes)] + //TODO: EchoID + [current ephemeral dht public key of the peer (32 bytes)] => necessary for the NoiseIK responder + [16 bytes "Other" (i.e. INITIATOR) Cookie (used by the other peer to respond to the handshake packet)] [MAC encrypted payload 16 bytes] [MAC1 16 bytes] [MAC2 16 bytes] - => 185 bytes in total = (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) + => 177 bytes in total */ - if (noise_handshake->initiator) { + if (noise_handshake->initiator) { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -918,16 +620,21 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; - memcpy(handshake_payload_plain, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); + + /* Noise: Cookie from RESPONDER */ + memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); - /* Noise: Cookie from INITIATOR */ - uint8_t noise_cookie_initiator[NOISE_COOKIE_LENGTH]; - noise_create_cookie(noise_cookie_initiator, c->cookie_symmetric_key, source); - memcpy(handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE, noise_cookie_initiator, NOISE_COOKIE_LENGTH); + uint8_t cookie_plain[COOKIE_DATA_LENGTH]; + memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: create timestamp and memcpy - const uint64_t noise_temp_time = mono_time_get(c->mono_time); - memcpy(handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH, &noise_temp_time, sizeof(noise_temp_time)); + //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise + /* OtherCookie is added to payload */ + if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, + cookie_plain, c->secret_symmetric_key) != 0) { + return -1; + } /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, @@ -943,21 +650,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u packet[0] = NET_PACKET_CRYPTO_HS; - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); - uint8_t mac1[NOISE_MAC1_LENGTH]; - - crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, - mac1, NOISE_MAC1_LENGTH); - - /* MAC2 is 16 zero bytes at first */ - //TODO: if cookie is NULL - memset(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - 0, NOISE_MAC2_LENGTH); - //TODO: remove from production code // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); @@ -969,6 +661,17 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* Noise RESPONDER: <- e, ee, se */ + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + [uint8_t 26] + [session public key of the peer (32 bytes)] => currently in plain + ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 + [Encrypted message containing: + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD + ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK + [MAC encrypted payload 16 bytes] + => ~~321~~ 185 bytes in total + */ /* TODO: New Cookies Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] @@ -976,11 +679,10 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ - //TODO: add timestamp here? [MAC encrypted payload 16 bytes] [MAC1 16 bytes] [MAC2 16 bytes] - => 81 bytes in total => (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) + => 81 bytes in total */ else { /* set ephemeral private+public */ @@ -1014,6 +716,10 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; + memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); + + /* Noise: Cookie from INITIATOR */ + memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, @@ -1022,21 +728,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u packet[0] = NET_PACKET_CRYPTO_HS; - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t mac1_peer_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - precompute_mac_key(mac1_peer_symmetric_key, peer_dht_pubkey, noise_mac1_key_label); - uint8_t mac1[NOISE_MAC1_LENGTH]; - - crypto_mac_blake2b_128(mac1, mac1_peer_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - mac1, NOISE_MAC1_LENGTH); - - uint8_t mac2[NOISE_MAC2_LENGTH]; - crypto_mac_blake2b_128(mac2, cookie, NOISE_COOKIE_LENGTH, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); - memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC2_LENGTH, - mac2, NOISE_MAC2_LENGTH); - crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); @@ -1055,7 +746,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); if (create_cookie(c->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, - cookie_plain, c->cookie_symmetric_key) != 0) { + cookie_plain, c->secret_symmetric_key) != 0) { return -1; } @@ -1074,273 +765,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u } } -// /** @brief Handle a crypto handshake packet of length. -// * put the base nonce contained in the packet in nonce, -// * the session public key in session_pk -// * the real public key of the peer in peer_real_pk -// * the dht public key of the peer in dht_public_key and -// * the cookie inside the encrypted part of the packet in cookie. -// * Currently supports noise-Noise and Noise handshake -// * -// * if expected_real_pk isn't NULL it denotes the real public key -// * the packet should be from. -// * -// * nonce must be at least CRYPTO_NONCE_SIZE -// * session_pk must be at least CRYPTO_PUBLIC_KEY_SIZE -// * peer_real_pk must be at least CRYPTO_PUBLIC_KEY_SIZE -// * cookie must be at least COOKIE_LENGTH -// * -// * cf. Noise section 5.3 -> ReadMessage(payload, message_buffer) -// * -// * @retval false on failure. -// * @retval true on success. -// */ -// non_null(1, 2, 5, 7) nullable(3, 4, 6, 9, 10) -// static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, -// uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, -// Noise_Handshake *noise_handshake) -// { -// LOGGER_DEBUG(c->log, "ENTERING"); -// /* Noise-based handshake */ -// if (noise_handshake != nullptr) { -// LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); - -// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - -// /* -> e, es, s, ss */ -// /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_BLAKE2b) -// [uint8_t 26] -// [session public key of the peer (32 bytes)] => currently in plain -// ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 -// [encrypted static public key of the INITIATOR (32 bytes)] -// [MAC encrypted static pubkey 16 bytes] -// ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 -// [Encrypted message containing: -// [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake -// [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD -// [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] -// [MAC encrypted payload 16 bytes] -// => 345 bytes in total -// */ -// if (!noise_handshake->initiator) { -// LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); -// if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { -// return false; -// } - -// //TODO: remove from production code -// // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; -// // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); -// // LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); - -// //TODO: Check here if remote_ephemeral is already the same ephemeral key? - -// /* e */ -// memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); -// noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - -// //TODO: remove from production code -// // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; -// // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); -// // char log_static[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; -// // bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "local static pub: %s", log_static); -// // bytes2string(log_static, sizeof(log_static), noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "remote ephemeral: %s", log_static); - -// /* es */ -// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; -// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); - -// /* s */ -// /* Nonce for static pub key decryption is _always_ 0 in case of ChaCha20-Poly1305 */ -// if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, -// noise_handshake_temp_key, noise_handshake->hash) != CRYPTO_PUBLIC_KEY_SIZE) { -// LOGGER_DEBUG(c->log, "RESPONDER: Noise ReadMessage remote static decryption failed"); -// return false; -// } - -// //TODO: remove -// // bytes2string(log_static, sizeof(log_static), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "local remote pub: %s", log_static); - -// //TODO: remove from production code -// // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; -// // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); - -// /* ss */ -// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); -// /* Payload decryption */ -// uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; - -// /* Nonce for payload decryption is _always_ 0 in case of ChaCha20-Poly1305 */ -// if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, -// sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, -// noise_handshake->hash) != sizeof(handshake_payload_plain)) { -// LOGGER_DEBUG(c->log, "RESPONDER: Noise HS payload decryption failed"); -// return false; -// } - -// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - -// //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here -// if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->cookie_symmetric_key) != 0) { -// return false; -// } - -// /* Compares static identity public keys from the peer */ -// if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { -// return false; -// } - -// /* received base nonce (from INITIATOR) */ -// memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); -// /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ -// memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); -// /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ -// //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? -// memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); -// /* necessary */ -// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); -// //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const -// // crypto_memzero(packet, length); - -// crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); - -// LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); -// return true; -// } -// /* Noise ReadMessage() if initiator: <- e, ee, se */ -// /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) -// [uint8_t 26] -// [session public key of the peer (32 bytes)] => currently in plain -// ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 -// [Encrypted message containing: -// [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake -// [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD -// ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK -// [MAC encrypted payload 16 bytes] -// => ~~321~~ 185 bytes in total -// */ -// else { -// LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); - -// if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { -// return false; -// } - -// memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); -// noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - -// //TODO: Remove -// // char log_ck[CRYPTO_SHA512_SIZE*2+1]; -// // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "INITIATOR pre ee ck: %s", log_ck); - -// /* ee */ -// uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; -// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); - -// //TODO: Remove -// // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; -// // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "INITIATOR ee temp_key: %s", log_temp_key); - -// /* se */ -// noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); -// //TODO: Remove -// // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); -// // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); - -// /* Payload decryption */ -// uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; - -// /* Nonce for payload decryption is 0 in case of ChaCha20-Poly1305 */ -// if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, -// sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, -// noise_handshake->hash) != sizeof(handshake_payload_plain)) { -// LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); -// return false; -// } - -// crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - -// //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here -// if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->cookie_symmetric_key) != 0) { -// return false; -// } - -// /* Compares static identity public keys from the peer */ -// if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { -// return false; -// } - -// /* neccessary, base nonce (from Noise RESPONDER) */ -// memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); -// /* necessary */ -// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - -// //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const -// // crypto_memzero(packet, length); - -// crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); - - -// LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); -// return true; -// } -// } -// /* non-Noise handshake, check for enabled backwards compatibility happens in calling functions */ -// else { -// LOGGER_DEBUG(c->log, "non-Noise handshake"); - -// if (length != HANDSHAKE_PACKET_LENGTH) { -// return false; -// } - -// uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - -// if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->cookie_symmetric_key) != 0) { -// return false; -// } - -// /* Compares static identity public keys from the peer */ -// if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { -// return false; -// } - -// uint8_t cookie_hash[CRYPTO_SHA512_SIZE]; -// crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); - -// uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; -// const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, -// packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, -// HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); - -// if (len != sizeof(plain)) { -// return false; -// } - -// if (!crypto_sha512_eq(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE)) { -// return false; -// } - -// memcpy(nonce, plain, CRYPTO_NONCE_SIZE); -// memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); -// memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); -// memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - -// //TODO: memzero packet, unwatend side effects? -// // crypto_memzero(packet, length); - -// return true; -// } -// } - -//TODO: /** @brief Handle a crypto handshake packet of length. * put the base nonce contained in the packet in nonce, * the session public key in session_pk @@ -1365,7 +789,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u non_null(1, 2, 5, 7) nullable(3, 4, 6, 9, 10) static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, - Noise_Handshake *noise_handshake, const IP_Port *source) + Noise_Handshake *noise_handshake) { LOGGER_DEBUG(c->log, "ENTERING"); /* Noise-based handshake */ @@ -1375,8 +799,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - /* TODO: New Cookies - Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -1384,14 +807,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t [MAC encrypted static pubkey 16 bytes] ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: - ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ - [current ephemeral DHT public key of the INITIATOR (32 bytes)] => necessary for the NoiseIK responder - [16 bytes INITIATOR cookie (used by the RESPONDER peer to respond to the handshake packet)] - [current timestamp (8 bytes)] + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD + [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] [MAC encrypted payload 16 bytes] - [MAC1 16 bytes] - [MAC2 16 bytes] - => 185 bytes in total = (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) + => 345 bytes in total */ if (!noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); @@ -1406,27 +826,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t //TODO: Check here if remote_ephemeral is already the same ephemeral key? - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE, - packet_mac1, NOISE_MAC1_LENGTH) != 0) { - return false; - } - - /* Verify MAC2 */ - uint8_t mac2[NOISE_MAC2_LENGTH]; - uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_PUBLIC_KEY_SIZE + NOISE_COOKIE_LENGTH + 8 + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - packet_mac2, NOISE_MAC2_LENGTH) != 0) { - return false; - } - /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -1477,16 +876,25 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - /* necessary */ - memcpy(dht_public_key, handshake_payload_plain, CRYPTO_PUBLIC_KEY_SIZE); - /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ - memcpy(cookie, handshake_payload_plain + CRYPTO_PUBLIC_KEY_SIZE, NOISE_COOKIE_LENGTH); - //TODO: handle and compare timestamp -> does this even make sense at this point? CPU already wasted if replayed => handle with states? + //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here + if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { + return false; + } + + /* Compares static identity public keys from the peer */ + if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { + return false; + } + /* received base nonce (from INITIATOR) */ + memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); + /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ + memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); - + /* necessary */ + memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); @@ -1496,18 +904,16 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* TODO: New Cookies - Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: - ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ - //TODO: add timestamp here? + [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD + ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK [MAC encrypted payload 16 bytes] - [MAC1 16 bytes] - [MAC2 16 bytes] - => 81 bytes in total => (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH + NOISE_MAC2_LENGTH) + => ~~321~~ 185 bytes in total */ else { LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); @@ -1516,27 +922,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - uint8_t packet_mac1[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH]; - memcpy(packet_mac1, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - uint8_t mac1[NOISE_MAC1_LENGTH]; - crypto_mac_blake2b_128(mac1, c->mac1_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac1, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC1_LENGTH - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, - packet_mac1, NOISE_MAC1_LENGTH) != 0) { - return false; - } - - /* Verify MAC2 */ - uint8_t mac2[NOISE_MAC2_LENGTH]; - uint8_t packet_mac2[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH]; - memcpy(packet_mac2, packet, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); - crypto_mac_blake2b_128(mac2, c->cookie_symmetric_key, CRYPTO_SYMMETRIC_KEY_SIZE, packet_mac2, (NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER - NOISE_MAC2_LENGTH)); - - if (memcmp(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + NOISE_MAC1_LENGTH, - packet_mac2, NOISE_MAC2_LENGTH) != 0) { - return false; - } - memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -1573,8 +958,19 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); + //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here + if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { + return false; + } + + /* Compares static identity public keys from the peer */ + if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { + return false; + } + + /* neccessary, base nonce (from Noise RESPONDER) */ + memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); /* necessary */ - //TODO: remove memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const @@ -1597,7 +993,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->cookie_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { return false; } @@ -2591,13 +1987,12 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u /* Noise-based handshake */ if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { - const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); LOGGER_DEBUG(c->log, "NoiseIK handshake"); if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key, conn->noise_handshake, &ip_port) != sizeof(handshake_packet)) { + conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { return -1; } @@ -2608,7 +2003,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER]; if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key, conn->noise_handshake, &ip_port) != sizeof(handshake_packet)) { + conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { return -1; } @@ -2624,7 +2019,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u /* ephemeral_private and noise_handshake not necessary for old handshake */ if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, nullptr, conn->sessionpublic_key, - conn->public_key, dht_public_key, nullptr, nullptr) != sizeof(handshake_packet)) { + conn->public_key, dht_public_key, nullptr) != sizeof(handshake_packet)) { return -1; } @@ -2890,7 +2285,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); - if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { + if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } } else { @@ -2899,7 +2294,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } else if (c->noise_compatibility_enabled) { /* non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); - if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { + if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { return -1; } } @@ -2960,13 +2355,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise handshake"); - const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, nullptr, - packet, length, conn->public_key, conn->noise_handshake, &ip_port)) { + packet, length, conn->public_key, conn->noise_handshake)) { return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { @@ -2978,7 +2372,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, - packet, length, nullptr, conn->noise_handshake, &ip_port)) { + packet, length, nullptr, conn->noise_handshake)) { return -1; } @@ -3010,7 +2404,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, - packet, length, nullptr, conn->noise_handshake, &ip_port)) { + packet, length, nullptr, conn->noise_handshake)) { return -1; } /* RESPONDER needs to send handshake packet, afterwards finished */ @@ -3034,13 +2428,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* TODO: NOT necessary only for non-Noise */ // uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, nullptr, dht_public_key, cookie, - packet, length, conn->public_key, nullptr, nullptr)) { + packet, length, conn->public_key, nullptr)) { return -1; } } - //TODO: adapt for Noise, makes only sense for RESPONDER not initiator - if (pk_equal(dht_public_key, conn->peer_dht_public_key)) { + if (pk_equal(dht_public_key, conn->dht_public_key)) { LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); @@ -3393,7 +2786,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { - //TODO: add check for MAC1 and MAC2, if both ok, call noise_create_cookie_response() //TODO: adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { @@ -3409,7 +2801,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, n_c.noise_handshake, source)) { + n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); @@ -3422,7 +2814,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // Necessary for backwards compatibility n_c.noise_handshake = nullptr; if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, nullptr, nullptr)) { + n_c.cookie, data, length, nullptr, nullptr)) { mem_delete(c->mem, n_c.cookie); return -1; } @@ -3450,7 +2842,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } - if (!pk_equal(n_c.dht_public_key, conn->peer_dht_public_key)) { + if (!pk_equal(n_c.dht_public_key, conn->dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ LOGGER_DEBUG(c->log, "Noise handshake"); @@ -3628,7 +3020,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - memcpy(conn->peer_dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(conn->dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; @@ -3688,7 +3080,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; conn->rtt_time = DEFAULT_PING_CONNECTION; - memcpy(conn->peer_dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(conn->dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; @@ -3699,7 +3091,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u //TODO: remove // LOGGER_DEBUG(c->log, "INITIATOR: BEFORE: create_cookie_request()"); - if (create_cookie_request(c, cookie_request, conn->peer_dht_public_key, conn->cookie_request_number, + if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, conn->shared_key) != sizeof(cookie_request) || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); @@ -4668,9 +4060,8 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r temp->dht = dht; new_keys(temp); - new_symmetric_key(rng, temp->cookie_symmetric_key); + new_symmetric_key(rng, temp->secret_symmetric_key); precompute_mac_key(temp->mac1_symmetric_key, dht_get_self_public_key(dht), noise_mac1_key_label); - precompute_mac_key(temp->cookie_xaead_symmetric_key, dht_get_self_public_key(dht), noise_cookie_key_label); temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; From c780c618a4d20029856e7d9b9b2309b7616ec0e1 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 19:45:52 +0100 Subject: [PATCH 122/150] Revert "fix: fixes for CI." This reverts commit b3d73e2cb6f4d5fdb4d78683f36f79b97a6bb38d. --- toxcore/crypto_core.c | 1 - toxcore/crypto_core.h | 7 +------ toxcore/net_crypto.c | 3 +-- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 34e106dfb2..f33f73d531 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -660,7 +660,6 @@ void precompute_mac_key(uint8_t out_mac_key[CRYPTO_SYMMETRIC_KEY_SIZE], } //TODO: Mac(key, input) Keyed-Blake2b(key, input, 16), the keyed MAC variant of the BLAKE2b hash function, returning 16 bytes of output. -//TODO: static? void crypto_mac_blake2b_128(uint8_t *out_mac, const uint8_t *key, size_t key_length, const uint8_t *in, size_t in_length) { crypto_generichash(out_mac, CRYPTO_BLAKE2b_MAC_SIZE, in, in_length, key, key_length); } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 5a58e91f68..dc5a96caf3 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -100,9 +100,8 @@ extern "C" { /** * @brief The number of bytes in a cookie label. - * Actually only 8 bytes necessary (but terminator necessary for CI) */ -#define CRYPTO_COOKIE_LABEL_SIZE 9 +#define CRYPTO_COOKIE_LABEL_SIZE 8 // #define NOISE_MAC1_KEY_LABEL "mac1----" // #define NOISE_COOKIE_KEY_LABEL "cookie--" @@ -623,10 +622,6 @@ void precompute_mac_key(uint8_t out_mac_key[CRYPTO_SYMMETRIC_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t label[CRYPTO_COOKIE_LABEL_SIZE]); -//TODO: Mac(key, input) Keyed-Blake2b(key, input, 16), the keyed MAC variant of the BLAKE2b hash function, returning 16 bytes of output. -non_null() -void crypto_mac_blake2b_128(uint8_t *out_mac, const uint8_t *key, size_t key_length, const uint8_t *in, size_t in_length); - /** * @brief Compute an HMAC-SHA512 authenticator (64 bytes). * diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 7b8e2c7945..3e0452c8b2 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -232,8 +232,7 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti #define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) static const uint8_t noise_mac1_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "mac1----"; -//TODO: uncomment when used (currently commented for CI) -// static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; +static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; /** @brief Create a cookie request packet and put it in packet. * From 04c4a38f38f8f449a0614172ccc576144dddaa66 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 19:46:21 +0100 Subject: [PATCH 123/150] Revert "feat: started implementation of (possible) new cookie functionality." This reverts commit fa59b7b6b7c52491c99ce47bb55ada58edb1d3ee. --- toxcore/crypto_core.c | 65 +++++++++++++------------------------------ toxcore/crypto_core.h | 22 +-------------- toxcore/net_crypto.c | 54 +++++------------------------------ toxcore/net_crypto.h | 1 - 4 files changed, 27 insertions(+), 115 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index f33f73d531..bb99b8c7e6 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -46,8 +46,6 @@ static_assert(CRYPTO_SIGN_PUBLIC_KEY_SIZE == crypto_sign_PUBLICKEYBYTES, static_assert(CRYPTO_SIGN_SECRET_KEY_SIZE == crypto_sign_SECRETKEYBYTES, "CRYPTO_SIGN_SECRET_KEY_SIZE should be equal to crypto_sign_SECRETKEYBYTES"); -//TODO: add static_assert for NoiseIK sizes - bool create_extended_keypair(Extended_Public_Key *pk, Extended_Secret_Key *sk, const Random *rng) { /* create signature key pair */ @@ -640,31 +638,12 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ // } // #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" -//TODO: Remove if Blake2b /* Actually only 32 bytes necessary (but terminator necessary for CI), but test vectors still verify with 33 bytes */ +//TODO: Remove if Blake2b // static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; -/* Actually only 33 bytes necessary (but terminator necessary for CI), but test vectors still verify with 34 bytes */ static const uint8_t noise_protocol[34] = "Noise_IK_25519_ChaChaPoly_BLAKE2b"; -/* MAC key as input for crypto_mac_blake2b_128() */ -void precompute_mac_key(uint8_t out_mac_key[CRYPTO_SYMMETRIC_KEY_SIZE], - const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], - const uint8_t label[CRYPTO_COOKIE_LABEL_SIZE]) -{ - crypto_generichash_blake2b_state state; - - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_SYMMETRIC_KEY_SIZE); - crypto_generichash_blake2b_update(&state, label, CRYPTO_COOKIE_LABEL_SIZE); - crypto_generichash_blake2b_update(&state, public_key, CRYPTO_PUBLIC_KEY_SIZE); - crypto_generichash_blake2b_final(&state, out_mac_key, CRYPTO_SYMMETRIC_KEY_SIZE); -} - -//TODO: Mac(key, input) Keyed-Blake2b(key, input, 16), the keyed MAC variant of the BLAKE2b hash function, returning 16 bytes of output. -void crypto_mac_blake2b_128(uint8_t *out_mac, const uint8_t *key, size_t key_length, const uint8_t *in, size_t in_length) { - crypto_generichash(out_mac, CRYPTO_BLAKE2b_MAC_SIZE, in, in_length, key, key_length); -} - -//TODO: remove if Blake2b +//TODO: remove, unused function /** * cf. Noise sections 4.3 and 5.1 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. @@ -675,25 +654,23 @@ void crypto_mac_blake2b_128(uint8_t *out_mac, const uint8_t *key, size_t key_len * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ -// void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, -// size_t data_length) -// { -// crypto_auth_hmacsha512(auth, data, data_length, key); -// } +void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, + size_t data_length) +{ + crypto_auth_hmacsha512(auth, data, data_length, key); +} /** - * cf. Noise sections 4.3, 5.1 and 12.8: HMAC-BLAKE2b-512 - * HASH(input): BLAKE2b with digest length 64 - * HASHLEN = 64 - * BLOCKLEN = 128 + * cf. Noise sections 4.3 and 5.1 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=BLAKE2b) function. * This function is only called via `crypto_hkdf()`. * Necessary for Noise (cf. sections 4.3 and 12.8) to return 64 bytes (BLAKE2b HASHLEN). * Cf. https://doc.libsodium.org/hashing/generic_hashing - * TODO: key is CRYPTO_BLAKE2b_HASH_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) + * TODO: Still true? + * key is CRYPTO_BLAKE2b_HASH_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ -static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t in_length, const uint8_t *key, +static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_length, const uint8_t *key, size_t key_length) { crypto_generichash_blake2b_state state; @@ -765,14 +742,13 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t crypto_generichash_blake2b_update(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); - memcpy(out_hmac, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(out, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); /* Clear sensitive data from stack */ crypto_memzero(x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); crypto_memzero(i_hash, CRYPTO_BLAKE2b_HASH_SIZE); } -//TODO: remove if Blake2b /* This is Hugo Krawczyk's HKDF (i.e. HKDF-SHA512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 @@ -845,7 +821,7 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t // crypto_memzero(output_temp, CRYPTO_SHA512_SIZE*2); // } -/* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b-512): +/* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 * HKDF(chaining_key, input_key_material, num_outputs): Takes a @@ -863,10 +839,6 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t * length. Also note that the HKDF() function is simply HKDF with the * chaining_key as HKDF salt, and zero-length HKDF info. * - * HASH(input): BLAKE2b with digest length 64. - * HASHLEN = 64 - * BLOCKLEN = 128 - * * Verified using Noise_IK_25519_ChaChaPoly_BLAKE2b test vectors. */ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, @@ -881,13 +853,13 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). Result is a pseudo random key (PRK) = temp_key */ /* data => input_key_material => X25519-DH result in Noise */ - crypto_hmac_blake2b_512(temp_key, data, data_len, chaining_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b512(temp_key, data, data_len, chaining_key, CRYPTO_BLAKE2b_HASH_SIZE); /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ /* Expand first key: key = temp_key, data = 0x1 */ output[0] = 1; - crypto_hmac_blake2b_512(output, output, 1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b512(output, output, 1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(output1, output, first_len); /* Expand both keys in one operation (verified): */ @@ -898,11 +870,11 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* Expand second key: key = secret, data = first-key || 0x2 */ output[CRYPTO_SHA512_SIZE] = 2; - crypto_hmac_blake2b_512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ - /* TODO: urrently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ + /* Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ // output[CRYPTO_SHA512_SIZE] = 3; // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); // memcpy(output3, output, third_len); @@ -946,13 +918,14 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // } /* - * cf. Noise section 5.2: based on HKDF-BLAKE2b + * cf. Noise section 5.2 * Executes the following steps: * - Sets ck, temp_k = HKDF(ck, input_key_material, 2). * - If HASHLEN is 64, then truncates temp_k to 32 bytes * - Calls InitializeKey(temp_k). * input_key_material = DH_X25519(private, public) * + * based on HKDF-BLAKE2b */ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index dc5a96caf3..0196c37678 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -84,12 +84,7 @@ extern "C" { #define CRYPTO_SHA512_SIZE 64 /** - * @brief The number of bytes in a BLAKE2b-128 MAC. - */ -#define CRYPTO_BLAKE2b_MAC_SIZE 16 - -/** - * @brief The number of bytes in a BLAKE2b-512 hash. + * @brief The number of bytes in a BLAKE2b hash. */ #define CRYPTO_BLAKE2b_HASH_SIZE 64 @@ -98,14 +93,6 @@ extern "C" { */ #define CRYPTO_BLAKE2b_BLOCK_SIZE 128 -/** - * @brief The number of bytes in a cookie label. - */ -#define CRYPTO_COOKIE_LABEL_SIZE 8 - -// #define NOISE_MAC1_KEY_LABEL "mac1----" -// #define NOISE_COOKIE_KEY_LABEL "cookie--" - /** @brief Fill a byte array with random bytes. * * This is the key generator callback and as such must be a cryptographically @@ -615,13 +602,6 @@ non_null(1, 2, 3, 5) nullable(6) int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); -//TODO: comment -/* MAC key as input for crypto_mac_blake2b_128() */ -non_null() -void precompute_mac_key(uint8_t out_mac_key[CRYPTO_SYMMETRIC_KEY_SIZE], - const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], - const uint8_t label[CRYPTO_COOKIE_LABEL_SIZE]); - /** * @brief Compute an HMAC-SHA512 authenticator (64 bytes). * diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 3e0452c8b2..994e353fe8 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -170,9 +170,6 @@ struct Net_Crypto { /* The secret key used for cookies */ uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - /* The secret key used for mac1 */ - uint8_t mac1_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; - new_connection_cb *new_connection_callback; void *new_connection_callback_object; @@ -231,9 +228,6 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti #define COOKIE_REQUEST_LENGTH (uint16_t)(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) #define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE) -static const uint8_t noise_mac1_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "mac1----"; -static const uint8_t noise_cookie_key_label[CRYPTO_COOKIE_LABEL_SIZE] = "cookie--"; - /** @brief Create a cookie request packet and put it in packet. * * dht_public_key is the dht public key of the other @@ -273,8 +267,6 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin } return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len; - - } /** @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key @@ -551,7 +543,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise Handshake"); /* Noise INITIATOR: -> e, es, s, ss */ - /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -565,24 +557,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [MAC encrypted payload 16 bytes] => 345 bytes in total */ - /* TODO: New Cookies - Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) - [uint8_t 26] - [session public key of the peer (32 bytes)] => currently in plain - ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 - [encrypted static public key of the INITIATOR (32 bytes)] - [MAC encrypted static pubkey 16 bytes] - ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 - [Encrypted message containing: - ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ - //TODO: EchoID - [current ephemeral dht public key of the peer (32 bytes)] => necessary for the NoiseIK responder - [16 bytes "Other" (i.e. INITIATOR) Cookie (used by the other peer to respond to the handshake packet)] - [MAC encrypted payload 16 bytes] - [MAC1 16 bytes] - [MAC2 16 bytes] - => 177 bytes in total - */ if (noise_handshake->initiator) { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); @@ -660,7 +634,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* Noise RESPONDER: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -671,18 +645,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [MAC encrypted payload 16 bytes] => ~~321~~ 185 bytes in total */ - /* TODO: New Cookies - Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) - [uint8_t 26] - [session public key of the peer (32 bytes)] => currently in plain - ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 - [Encrypted message containing: - ~~[24 bytes base nonce] => WITHOUT base Nonce, not necessary with different symmetric keys for outgoing/incoming packets~~ - [MAC encrypted payload 16 bytes] - [MAC1 16 bytes] - [MAC2 16 bytes] - => 81 bytes in total - */ else { /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); @@ -798,7 +760,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -903,7 +865,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -2424,9 +2386,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* non-Noise handshake */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - /* TODO: NOT necessary only for non-Noise */ - // uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, nullptr, dht_public_key, cookie, + /* necessary only for non-Noise */ + uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, nullptr)) { return -1; } @@ -4060,7 +4022,6 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r new_keys(temp); new_symmetric_key(rng, temp->secret_symmetric_key); - precompute_mac_key(temp->mac1_symmetric_key, dht_get_self_public_key(dht), noise_mac1_key_label); temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; @@ -4117,7 +4078,6 @@ uint32_t crypto_run_interval(const Net_Crypto *c) /** Main loop. */ void do_net_crypto(Net_Crypto *c, void *userdata) { - //TODO: update cookie symmetric key every ~2 minutes (cf. WireGuard)? kill_timedout(c, userdata); do_tcp(c, userdata); send_crypto_packets(c); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 828cab3383..3a9c7b78b7 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -134,7 +134,6 @@ typedef struct New_Connection { uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ // Necessary for Noise - //TODO: refactor to not use struct Noise_Handshake noise_handshake_data; Noise_Handshake *noise_handshake; //TODO: if no struct necessary From d4f7f73550139f68d2f9469be95eee8cb539f75b Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 25 Jan 2025 20:52:50 +0100 Subject: [PATCH 124/150] refactor: minor refactoring and documentation (based on reverted cookie commits). --- toxcore/crypto_core.c | 52 ++++++++++++++++++++++++++----------------- toxcore/crypto_core.h | 2 +- toxcore/net_crypto.c | 51 ++++++++++++++++++++++++------------------ toxcore/net_crypto.h | 1 + 4 files changed, 62 insertions(+), 44 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index bb99b8c7e6..4b53468b16 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -46,6 +46,8 @@ static_assert(CRYPTO_SIGN_PUBLIC_KEY_SIZE == crypto_sign_PUBLICKEYBYTES, static_assert(CRYPTO_SIGN_SECRET_KEY_SIZE == crypto_sign_SECRETKEYBYTES, "CRYPTO_SIGN_SECRET_KEY_SIZE should be equal to crypto_sign_SECRETKEYBYTES"); +//TODO: add static_assert for NoiseIK sizes + bool create_extended_keypair(Extended_Public_Key *pk, Extended_Secret_Key *sk, const Random *rng) { /* create signature key pair */ @@ -641,6 +643,7 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ /* Actually only 32 bytes necessary (but terminator necessary for CI), but test vectors still verify with 33 bytes */ //TODO: Remove if Blake2b // static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; +/* Actually only 33 bytes necessary (but terminator necessary for CI), but test vectors still verify with 34 bytes */ static const uint8_t noise_protocol[34] = "Noise_IK_25519_ChaChaPoly_BLAKE2b"; //TODO: remove, unused function @@ -661,7 +664,10 @@ void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const } /** - * cf. Noise sections 4.3 and 5.1 + * cf. Noise sections 4.3, 5.1 and 12.8: HMAC-BLAKE2b-512 + * HASH(input): BLAKE2b with digest length 64 + * HASHLEN = 64 + * BLOCKLEN = 128 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=BLAKE2b) function. * This function is only called via `crypto_hkdf()`. * Necessary for Noise (cf. sections 4.3 and 12.8) to return 64 bytes (BLAKE2b HASHLEN). @@ -670,7 +676,7 @@ void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const * key is CRYPTO_BLAKE2b_HASH_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ -static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_length, const uint8_t *key, +static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t in_length, const uint8_t *key, size_t key_length) { crypto_generichash_blake2b_state state; @@ -742,13 +748,14 @@ static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_le crypto_generichash_blake2b_update(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); - memcpy(out, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(out_hmac, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); /* Clear sensitive data from stack */ crypto_memzero(x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); crypto_memzero(i_hash, CRYPTO_BLAKE2b_HASH_SIZE); } +//TODO: remove if Blake2b /* This is Hugo Krawczyk's HKDF (i.e. HKDF-SHA512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 @@ -821,7 +828,7 @@ static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_le // crypto_memzero(output_temp, CRYPTO_SHA512_SIZE*2); // } -/* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b): +/* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b-512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 * HKDF(chaining_key, input_key_material, num_outputs): Takes a @@ -839,6 +846,10 @@ static void crypto_hmac_blake2b512(uint8_t *out, const uint8_t *in, size_t in_le * length. Also note that the HKDF() function is simply HKDF with the * chaining_key as HKDF salt, and zero-length HKDF info. * + * HASH(input): BLAKE2b with digest length 64. + * HASHLEN = 64 + * BLOCKLEN = 128 + * * Verified using Noise_IK_25519_ChaChaPoly_BLAKE2b test vectors. */ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, @@ -853,13 +864,13 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). Result is a pseudo random key (PRK) = temp_key */ /* data => input_key_material => X25519-DH result in Noise */ - crypto_hmac_blake2b512(temp_key, data, data_len, chaining_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(temp_key, data, data_len, chaining_key, CRYPTO_BLAKE2b_HASH_SIZE); /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ /* Expand first key: key = temp_key, data = 0x1 */ output[0] = 1; - crypto_hmac_blake2b512(output, output, 1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(output, output, 1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(output1, output, first_len); /* Expand both keys in one operation (verified): */ @@ -869,19 +880,19 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ /* Expand second key: key = secret, data = first-key || 0x2 */ - output[CRYPTO_SHA512_SIZE] = 2; - crypto_hmac_blake2b512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + output[CRYPTO_BLAKE2b_HASH_SIZE] = 2; + crypto_hmac_blake2b_512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ - /* Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ + /* TODO: Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ // output[CRYPTO_SHA512_SIZE] = 3; // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); // memcpy(output3, output, third_len); /* Clear sensitive data from stack */ - crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); - crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); + crypto_memzero(temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_memzero(output, CRYPTO_BLAKE2b_HASH_SIZE + 1); } /* @@ -918,14 +929,13 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // } /* - * cf. Noise section 5.2 + * cf. Noise section 5.2: based on HKDF-BLAKE2b * Executes the following steps: * - Sets ck, temp_k = HKDF(ck, input_key_material, 2). * - If HASHLEN is 64, then truncates temp_k to 32 bytes * - Calls InitializeKey(temp_k). * input_key_material = DH_X25519(private, public) * - * based on HKDF-BLAKE2b */ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], @@ -995,14 +1005,14 @@ void noise_mix_hash(uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE], const uint8_t *data, */ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE]) + uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE]) { static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); int32_t encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, - hash, CRYPTO_SHA512_SIZE); + hash, CRYPTO_BLAKE2b_HASH_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); } @@ -1014,14 +1024,14 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, */ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_SHA512_SIZE]) + uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE]) { static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); int32_t plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, - hash, CRYPTO_SHA512_SIZE); + hash, CRYPTO_BLAKE2b_HASH_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); @@ -1062,11 +1072,11 @@ int noise_handshake_init /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ - uint8_t temp_hash[CRYPTO_SHA512_SIZE]; - memset(temp_hash, 0, CRYPTO_SHA512_SIZE); + uint8_t temp_hash[CRYPTO_BLAKE2b_HASH_SIZE]; + memset(temp_hash, 0, CRYPTO_BLAKE2b_HASH_SIZE); memcpy(temp_hash, noise_protocol, sizeof(noise_protocol)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_SHA512_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_SHA512_SIZE); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_BLAKE2b_HASH_SIZE); /* IMPORTANT needs to be called with (empty/zero-length) prologue! */ noise_mix_hash(noise_handshake->hash, prologue, prologue_length); diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 0196c37678..d5401a891b 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -84,7 +84,7 @@ extern "C" { #define CRYPTO_SHA512_SIZE 64 /** - * @brief The number of bytes in a BLAKE2b hash. + * @brief The number of bytes in a BLAKE2b-512 hash. */ #define CRYPTO_BLAKE2b_HASH_SIZE 64 diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 994e353fe8..b8cf5ae652 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -68,7 +68,7 @@ typedef struct Crypto_Connection { uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. (non-Noise handshake) */ Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ - uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public X25519 key of the peer */ + uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public X25519 key of the peer */ bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ @@ -168,7 +168,7 @@ struct Net_Crypto { uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; /* The secret key used for cookies */ - uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; + uint8_t cookie_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; new_connection_cb *new_connection_callback; void *new_connection_callback_object; @@ -338,7 +338,7 @@ 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->mem, c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { + if (create_cookie(c->mem, c->rng, c->mono_time, plain, cookie_plain, c->cookie_symmetric_key) != 0) { return -1; } @@ -551,13 +551,16 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [MAC encrypted static pubkey 16 bytes] ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: + //TODO: remove base Nonce, not necessary with different symmetric keys for outgoing/incoming packets [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake + //TODO: move Cookie outside of encrypted payload? [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] [MAC encrypted payload 16 bytes] => 345 bytes in total */ if (noise_handshake->initiator) { + LOGGER_DEBUG(c->log, "INITIATOR"); /* set ephemeral private+public */ memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -605,7 +608,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise /* OtherCookie is added to payload */ if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, - cookie_plain, c->secret_symmetric_key) != 0) { + cookie_plain, c->cookie_symmetric_key) != 0) { return -1; } @@ -634,7 +637,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; } /* Noise RESPONDER: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -707,7 +710,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); if (create_cookie(c->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, - cookie_plain, c->secret_symmetric_key) != 0) { + cookie_plain, c->cookie_symmetric_key) != 0) { return -1; } @@ -726,6 +729,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u } } +//TODO: update comment /** @brief Handle a crypto handshake packet of length. * put the base nonce contained in the packet in nonce, * the session public key in session_pk @@ -760,7 +764,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_SHA512) + /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -838,7 +842,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here - if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->cookie_symmetric_key) != 0) { return false; } @@ -865,7 +869,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -920,7 +924,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here - if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->secret_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->cookie_symmetric_key) != 0) { return false; } @@ -954,7 +958,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->cookie_symmetric_key) != 0) { return false; } @@ -2246,7 +2250,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); - if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { + if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { return -1; } } else { @@ -2255,7 +2259,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, } else if (c->noise_compatibility_enabled) { /* non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); - if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) { + if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { return -1; } } @@ -2394,7 +2398,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - if (pk_equal(dht_public_key, conn->dht_public_key)) { + //TODO: adapt for Noise, makes only sense for RESPONDER not initiator + if (pk_equal(dht_public_key, conn->peer_dht_public_key)) { LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); @@ -2727,7 +2732,7 @@ void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_cal * @retval 0 on success. */ non_null(1, 2, 3) nullable(5) -static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length, +static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { //TODO: remove @@ -2762,7 +2767,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, n_c.noise_handshake)) { + n_c.cookie, packet, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; mem_delete(c->mem, n_c.cookie); @@ -2775,7 +2780,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // Necessary for backwards compatibility n_c.noise_handshake = nullptr; if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, - n_c.cookie, data, length, nullptr, nullptr)) { + n_c.cookie, packet, length, nullptr, nullptr)) { mem_delete(c->mem, n_c.cookie); return -1; } @@ -2803,7 +2808,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } - if (!pk_equal(n_c.dht_public_key, conn->dht_public_key)) { + if (!pk_equal(n_c.dht_public_key, conn->peer_dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ LOGGER_DEBUG(c->log, "Noise handshake"); @@ -2981,7 +2986,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - memcpy(conn->dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(conn->peer_dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; @@ -3041,7 +3046,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u 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_PUBLIC_KEY_SIZE); + memcpy(conn->peer_dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; @@ -3052,7 +3057,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u //TODO: remove // LOGGER_DEBUG(c->log, "INITIATOR: BEFORE: create_cookie_request()"); - if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, + if (create_cookie_request(c, cookie_request, conn->peer_dht_public_key, conn->cookie_request_number, conn->shared_key) != sizeof(cookie_request) || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); @@ -4021,7 +4026,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r temp->dht = dht; new_keys(temp); - new_symmetric_key(rng, temp->secret_symmetric_key); + new_symmetric_key(rng, temp->cookie_symmetric_key); temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; @@ -4078,6 +4083,8 @@ uint32_t crypto_run_interval(const Net_Crypto *c) /** Main loop. */ void do_net_crypto(Net_Crypto *c, void *userdata) { + LOGGER_DEBUG(c->log, "do_net_crypto()"); + //TODO: update cookie symmetric key every ~2 minutes (cf. WireGuard)? kill_timedout(c, userdata); do_tcp(c, userdata); send_crypto_packets(c); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 3a9c7b78b7..828cab3383 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -134,6 +134,7 @@ typedef struct New_Connection { uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ // Necessary for Noise + //TODO: refactor to not use struct Noise_Handshake noise_handshake_data; Noise_Handshake *noise_handshake; //TODO: if no struct necessary From 25311c7436ff72d615a6ca24167c85a9091d9316 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sun, 26 Jan 2025 21:10:17 +0100 Subject: [PATCH 125/150] chore: added Noise compatibility option again after master merge. --- toxcore/tox_options.c | 10 ++++++++++ toxcore/tox_options.h | 14 ++++++++++++++ toxcore/util.c | 1 + 3 files changed, 25 insertions(+) diff --git a/toxcore/tox_options.c b/toxcore/tox_options.c index d67a8aebd0..de302eccaa 100644 --- a/toxcore/tox_options.c +++ b/toxcore/tox_options.c @@ -181,6 +181,15 @@ void tox_options_set_experimental_groups_persistence( { options->experimental_groups_persistence = experimental_groups_persistence; } +bool tox_options_get_noise_compatibility_enabled(const Tox_Options *options) +{ + return options->noise_compatibility_enabled; +} +void tox_options_set_noise_compatibility_enabled( + Tox_Options *options, bool noise_compatibility_enabled) +{ + options->noise_compatibility_enabled = noise_compatibility_enabled; +} bool tox_options_get_experimental_disable_dns(const Tox_Options *options) { return options->experimental_disable_dns; @@ -255,6 +264,7 @@ void tox_options_default(Tox_Options *options) tox_options_set_dht_announcements_enabled(options, true); tox_options_set_experimental_thread_safety(options, false); tox_options_set_experimental_groups_persistence(options, false); + tox_options_set_noise_compatibility_enabled(options, true); tox_options_set_experimental_disable_dns(options, false); tox_options_set_experimental_owned_data(options, false); } diff --git a/toxcore/tox_options.h b/toxcore/tox_options.h index 7d8b7aafaa..79bc5ea0e9 100644 --- a/toxcore/tox_options.h +++ b/toxcore/tox_options.h @@ -265,6 +265,16 @@ struct Tox_Options { */ bool experimental_groups_persistence; + /** + * @brief Compatibility for old non-Noise handshake. + * + * If this is set to false, non-Noise handshake + * will not work anymore. + * + * Default: true. + */ + bool noise_compatibility_enabled; + /** * @brief Disable DNS hostname resolution. * @@ -393,6 +403,10 @@ bool tox_options_get_experimental_groups_persistence(const Tox_Options *options) void tox_options_set_experimental_groups_persistence( Tox_Options *options, bool experimental_groups_persistence); +bool tox_options_get_noise_compatibility_enabled(const struct Tox_Options *options); + +void tox_options_set_noise_compatibility_enabled(struct Tox_Options *options, bool noise_compatibility_enabled); + bool tox_options_get_experimental_disable_dns(const Tox_Options *options); void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns); diff --git a/toxcore/util.c b/toxcore/util.c index 8758b9aadd..34471a6571 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -13,6 +13,7 @@ #include "util.h" +#include #include #include "ccompat.h" From 3060956254d3622dac246efd7a62b9c51a46698b Mon Sep 17 00:00:00 2001 From: goldroom Date: Sun, 26 Jan 2025 21:12:30 +0100 Subject: [PATCH 126/150] fix: cannot have const Net_Crypto in handle_packet_crypto_hs() here (was added in master). --- toxcore/net_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index d65e4e3327..8df0922a31 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2280,7 +2280,7 @@ non_null(1, 3) nullable(5) * @return -1 in case of failure * @return 0 if successful */ -static int handle_packet_crypto_hs(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, +static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, void *userdata) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); From 76acc47fcb22dd12ccef97fb00e0d0a71af080e3 Mon Sep 17 00:00:00 2001 From: goldroom Date: Mon, 27 Jan 2025 13:14:44 +0100 Subject: [PATCH 127/150] chore: cleanup and documentation of crypto_core. --- auto_tests/crypto_test.c | 2 +- toxcore/crypto_core.c | 117 ++++++++++++++++++++------------------- toxcore/crypto_core.h | 33 ++++++----- 3 files changed, 77 insertions(+), 75 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index a77319cfe3..42866debcb 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -931,7 +931,7 @@ static void test_noiseik(void) // printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); uint8_t ciphertext4_transport1_initiator[sizeof(init_payload_transport1) + CRYPTO_MAC_SIZE]; - uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; + uint8_t nonce_chacha20_ietf[CRYPTO_NOISE_NONCE_SIZE] = {0}; encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, init_payload_transport1, sizeof(init_payload_transport1), ciphertext4_transport1_initiator, nullptr, 0); ck_assert_msg(memcmp(ciphertext4_transport1_initiator, init_payload_transport1_encrypted, sizeof(init_payload_transport1_encrypted)) == 0, "initiator transport1 ciphertext differ"); diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 0320eee50d..9826bd3ffd 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -27,6 +27,8 @@ static_assert(CRYPTO_MAC_SIZE == crypto_box_MACBYTES, "CRYPTO_MAC_SIZE should be equal to crypto_box_MACBYTES"); static_assert(CRYPTO_NONCE_SIZE == crypto_box_NONCEBYTES, "CRYPTO_NONCE_SIZE should be equal to crypto_box_NONCEBYTES"); +static_assert(CRYPTO_NOISE_NONCE_SIZE == crypto_stream_chacha20_ietf_NONCEBYTES, + "CRYPTO_NOISEIK_NONCE_SIZE should be equal to crypto_stream_chacha20_ietf_NONCEBYTES"); static_assert(CRYPTO_HMAC_SIZE == crypto_auth_BYTES, "CRYPTO_HMAC_SIZE should be equal to crypto_auth_BYTES"); static_assert(CRYPTO_HMAC_KEY_SIZE == crypto_auth_KEYBYTES, @@ -45,7 +47,10 @@ static_assert(CRYPTO_SIGN_PUBLIC_KEY_SIZE == crypto_sign_PUBLICKEYBYTES, static_assert(CRYPTO_SIGN_SECRET_KEY_SIZE == crypto_sign_SECRETKEYBYTES, "CRYPTO_SIGN_SECRET_KEY_SIZE should be equal to crypto_sign_SECRETKEYBYTES"); -//TODO: add static_assert for NoiseIK sizes +/* CRYPTO_BLAKE2b_HASH_SIZE -> crypto_generichash_blake2b_BYTES_MAX (libsodium) */ +static_assert(CRYPTO_NOISE_BLAKE2b_HASH_SIZE == crypto_generichash_blake2b_BYTES_MAX, + "CRYPTO_BLAKE2b_HASH_SIZE should be equal to crypto_generichash_blake2b_BYTES_MAX"); +/* CRYPTO_BLAKE2b_BLOCK_SIZE -> BLAKE2B_BLOCKBYTES (not exposed by libsodium) */ bool create_extended_keypair(Extended_Public_Key *pk, Extended_Secret_Key *sk, const Random *rng) { @@ -538,7 +543,7 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length) /* Necessary functions for Noise, cf. https://noiseprotocol.org/noise.html (Revision 34) */ -int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], +int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISE_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length) { @@ -560,7 +565,7 @@ int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S return (int32_t)(plain_length + crypto_aead_chacha20poly1305_IETF_ABYTES); } -int32_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], +int32_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISE_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length) { @@ -629,8 +634,8 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ } /* -* TODO: Helper function to print hashes, keys, packets, etc. -* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? +* Helper function to print hashes, keys, packets, etc. +* TODO(goldroom): remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? * bytes_to_string() from util.h */ // static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length) @@ -640,12 +645,12 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ // #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" /* Actually only 32 bytes necessary (but terminator necessary for CI), but test vectors still verify with 33 bytes */ -//TODO: Remove if Blake2b +//TODO(goldroom): Remove if Blake2b // static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; /* Actually only 33 bytes necessary (but terminator necessary for CI), but test vectors still verify with 34 bytes */ static const uint8_t noise_protocol[34] = "Noise_IK_25519_ChaChaPoly_BLAKE2b"; -//TODO: remove, unused function +//TODO(goldroom): remove, unused function /** * cf. Noise sections 4.3 and 5.1 * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. @@ -656,11 +661,11 @@ static const uint8_t noise_protocol[34] = "Noise_IK_25519_ChaChaPoly_BLAKE2b"; * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ -void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, - size_t data_length) -{ - crypto_auth_hmacsha512(auth, data, data_length, key); -} +// void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, +// size_t data_length) +// { +// crypto_auth_hmacsha512(auth, data, data_length, key); +// } /** * cf. Noise sections 4.3, 5.1 and 12.8: HMAC-BLAKE2b-512 @@ -671,7 +676,6 @@ void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const * This function is only called via `crypto_hkdf()`. * Necessary for Noise (cf. sections 4.3 and 12.8) to return 64 bytes (BLAKE2b HASHLEN). * Cf. https://doc.libsodium.org/hashing/generic_hashing - * TODO: Still true? * key is CRYPTO_BLAKE2b_HASH_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) * is always HASHLEN bytes. */ @@ -687,7 +691,7 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t * L the byte-length of Blake2b hash output = 64 */ uint8_t x_key[CRYPTO_BLAKE2b_BLOCK_SIZE] = { 0 }; - uint8_t i_hash[CRYPTO_BLAKE2b_HASH_SIZE]; + uint8_t i_hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]; int i; /* @@ -699,7 +703,7 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t * length). */ if (key_length > CRYPTO_BLAKE2b_BLOCK_SIZE) { - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); crypto_generichash_blake2b_update(&state, key, key_length); crypto_generichash_blake2b_final(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); } else { @@ -721,10 +725,10 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t from step (2) (4) apply H to the stream generated in step (3) */ - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); crypto_generichash_blake2b_update(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); crypto_generichash_blake2b_update(&state, in, in_length); - crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); /* * K XOR opad, opad = the byte 0x5C repeated B times @@ -742,19 +746,19 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t (7) apply H to the stream generated in step (6) and output the result */ - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); crypto_generichash_blake2b_update(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); - crypto_generichash_blake2b_update(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); - crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_update(&state, i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); - memcpy(out_hmac, i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(out_hmac, i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); /* Clear sensitive data from stack */ crypto_memzero(x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); - crypto_memzero(i_hash, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_memzero(i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); } -//TODO: remove if Blake2b +//TODO(goldroom): remove if Blake2b /* This is Hugo Krawczyk's HKDF (i.e. HKDF-SHA512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 @@ -853,23 +857,23 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t */ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, size_t second_len, const uint8_t *data, - size_t data_len, const uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE]) + size_t data_len, const uint8_t chaining_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]) { - uint8_t output[CRYPTO_BLAKE2b_HASH_SIZE + 1]; + uint8_t output[CRYPTO_NOISE_BLAKE2b_HASH_SIZE + 1]; // temp_key = secret in WG - uint8_t temp_key[CRYPTO_BLAKE2b_HASH_SIZE]; + uint8_t temp_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]; /* Extract entropy from data into temp_key */ /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). Result is a pseudo random key (PRK) = temp_key */ /* data => input_key_material => X25519-DH result in Noise */ - crypto_hmac_blake2b_512(temp_key, data, data_len, chaining_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(temp_key, data, data_len, chaining_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ /* Expand first key: key = temp_key, data = 0x1 */ output[0] = 1; - crypto_hmac_blake2b_512(output, output, 1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(output, output, 1, temp_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); memcpy(output1, output, first_len); /* Expand both keys in one operation (verified): */ @@ -879,19 +883,19 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ /* Expand second key: key = secret, data = first-key || 0x2 */ - output[CRYPTO_BLAKE2b_HASH_SIZE] = 2; - crypto_hmac_blake2b_512(output, output, CRYPTO_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_BLAKE2b_HASH_SIZE); + output[CRYPTO_NOISE_BLAKE2b_HASH_SIZE] = 2; + crypto_hmac_blake2b_512(output, output, CRYPTO_NOISE_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ - /* TODO: Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ + /* TODO(goldroom): Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ // output[CRYPTO_SHA512_SIZE] = 3; // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); // memcpy(output3, output, third_len); /* Clear sensitive data from stack */ - crypto_memzero(temp_key, CRYPTO_BLAKE2b_HASH_SIZE); - crypto_memzero(output, CRYPTO_BLAKE2b_HASH_SIZE + 1); + crypto_memzero(temp_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_memzero(output, CRYPTO_NOISE_BLAKE2b_HASH_SIZE + 1); } /* @@ -936,7 +940,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * input_key_material = DH_X25519(private, public) * */ -int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], +int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) @@ -951,7 +955,7 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], /* chaining_key is HKDF output1 and shared_key is HKDF output2 => different values/results! */ /* If HASHLEN is 64, then truncates temp_k (= shared_key) to 32 bytes. => done via call to crypto_hkdf() */ - crypto_hkdf(chaining_key, CRYPTO_BLAKE2b_HASH_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, + crypto_hkdf(chaining_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, CRYPTO_SHARED_KEY_SIZE, chaining_key); crypto_memzero(dh_calculation, CRYPTO_SHARED_KEY_SIZE); @@ -959,6 +963,7 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], return 0; } +///TODO(goldroom): remove unused function /* * Noise MixHash(data): Sets h = HASH(h || data). * SHA512 @@ -967,7 +972,6 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], */ // void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) // { -// //TODO: not necessary with Blake2b // VLA(uint8_t, to_hash, CRYPTO_SHA512_SIZE + data_len); // memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); // if (data != nullptr) { @@ -988,13 +992,13 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_BLAKE2b_HASH_SIZE], * * cf. Noise section 5.2 */ -void noise_mix_hash(uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE], const uint8_t *data, size_t data_len) +void noise_mix_hash(uint8_t hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE], const uint8_t *data, size_t data_len) { crypto_generichash_blake2b_state state; - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); - crypto_generichash_blake2b_update(&state, hash, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_update(&state, hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); crypto_generichash_blake2b_update(&state, data, data_len); - crypto_generichash_blake2b_final(&state, hash, CRYPTO_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_final(&state, hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); } /* @@ -1004,14 +1008,14 @@ void noise_mix_hash(uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE], const uint8_t *data, */ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE]) + uint8_t hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]) { - static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; - memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); + static uint8_t nonce_chacha20_ietf[CRYPTO_NOISE_NONCE_SIZE] = {0}; + memset(nonce_chacha20_ietf, 0, CRYPTO_NOISE_NONCE_SIZE); int32_t encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, - hash, CRYPTO_BLAKE2b_HASH_SIZE); + hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); } @@ -1023,14 +1027,14 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, */ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_BLAKE2b_HASH_SIZE]) + uint8_t hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]) { - static uint8_t nonce_chacha20_ietf[CRYPTO_NOISEIK_NONCE_SIZE] = {0}; - memset(nonce_chacha20_ietf, 0, CRYPTO_NOISEIK_NONCE_SIZE); + static uint8_t nonce_chacha20_ietf[CRYPTO_NOISE_NONCE_SIZE] = {0}; + memset(nonce_chacha20_ietf, 0, CRYPTO_NOISE_NONCE_SIZE); int32_t plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, - hash, CRYPTO_BLAKE2b_HASH_SIZE); + hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); @@ -1047,13 +1051,12 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, * Sets the initiator, s, e, rs, and re variables to the corresponding arguments. * Calls MixHash() once for each public key listed in the pre-messages. * - * //TODO: remove Logger Param * @param noise_handshake handshake struct to save the necessary values to * @param self_secret_key static private ID X25519 key of this Tox instance - * @param peer_public_key X25519 static ID public key from peer to connect to + * @param peer_public_key static public ID X25519 key from peer to connect to * @param initiator specifies if this Tox instance is the initiator of this crypto connection - * @param prologue specifies the prologue, used in call to MixHash(prologue) which maybe zero-length - * @param prologue_length length of prologue in bytes + * @param prologue specifies the Noise prologue, used in call to MixHash(prologue) which maybe zero-length + * @param prologue_length length of Noise prologue in bytes * * @return -1 on failure * @return 0 on success @@ -1066,16 +1069,16 @@ int noise_handshake_init // LOGGER_DEBUG(log, "ENTERING"); // } - //TODO: move to handle_packet_crypto_hs()? + //TODO(goldroom): move to handle_packet_crypto_hs()? crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ - uint8_t temp_hash[CRYPTO_BLAKE2b_HASH_SIZE]; - memset(temp_hash, 0, CRYPTO_BLAKE2b_HASH_SIZE); + uint8_t temp_hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]; + memset(temp_hash, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); memcpy(temp_hash, noise_protocol, sizeof(noise_protocol)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_BLAKE2b_HASH_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_BLAKE2b_HASH_SIZE); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); /* IMPORTANT needs to be called with (empty/zero-length) prologue! */ noise_mix_hash(noise_handshake->hash, prologue, prologue_length); diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 7a7b3855dd..6e3052481f 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -69,9 +69,9 @@ extern "C" { #define CRYPTO_NONCE_SIZE 24 /** - * @brief NoiseIK: The number of bytes in a nonce used for encryption/decryption (ChaChaPoly-1305-IETF). + * @brief NoiseIK: The number of bytes in a nonce used for encryption/decryption (ChaChaPoly1305-IETF). */ -#define CRYPTO_NOISEIK_NONCE_SIZE 12 +#define CRYPTO_NOISE_NONCE_SIZE 12 /** * @brief The number of bytes in a SHA256 hash. @@ -84,9 +84,9 @@ extern "C" { #define CRYPTO_SHA512_SIZE 64 /** - * @brief The number of bytes in a BLAKE2b-512 hash. + * @brief The number of bytes in a BLAKE2b-512 hash (as defined for Noise in section 12.8.). */ -#define CRYPTO_BLAKE2b_HASH_SIZE 64 +#define CRYPTO_NOISE_BLAKE2b_HASH_SIZE 64 /** * @brief The number of bytes in a BLAKE2b block. @@ -125,9 +125,8 @@ typedef struct Random { void *obj; } Random; -// TODO: struct necessary? -// TODO: move to crypto_core.h? -/** @brief Necessary Noise handshake state information/values. +// TODO(goldroom): struct necessary? +/** @brief Necessary NoiseIK handshake state information/values. */ typedef struct Noise_Handshake { // TODO: static_private? @@ -548,7 +547,7 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); * @brief Encrypt message with precomputed shared key using ChaCha20-Poly1305-IETF (RFC7539). * * Encrypts plain of plain_length to encrypted of plain_length + @ref CRYPTO_MAC_SIZE - * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NOISEIK_NONCE_SIZE + * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NOISE_NONCE_SIZE * byte nonce. The encrypted message, as well as a tag authenticating both the confidential * message m and adlen bytes of non-confidential data ad, are put into encrypted. * @@ -556,7 +555,7 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); * @return length of encrypted data if everything was fine. */ non_null(1, 2, 3, 5) nullable(6) -int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *plain, size_t plain_length, +int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISE_NONCE_SIZE], const uint8_t *plain, size_t plain_length, uint8_t *encrypted, const uint8_t *ad, size_t ad_length); /** @@ -564,13 +563,13 @@ int32_t encrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_S * * Decrypts encrypted of encrypted_length to plain of length * `length - CRYPTO_MAC_SIZE` using a shared key @ref CRYPTO_SHARED_KEY_SIZE - * big and a @ref CRYPTO_NOISEIK_NONCE_SIZE byte nonce. + * big and a @ref CRYPTO_NOISE_NONCE_SIZE byte nonce. * * @retval -1 if there was a problem (decryption failed). * @return length of plain data if everything was fine. */ non_null(1, 2, 3, 5) nullable(6) -int32_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISEIK_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, +int32_t decrypt_data_symmetric_aead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NOISE_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); /** @@ -602,6 +601,7 @@ non_null(1, 2, 3, 5) nullable(6) int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); +//TODO(goldroom): remove, unused function /** * @brief Compute an HMAC-SHA512 authenticator (64 bytes). * @@ -667,13 +667,12 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * Sets the initiator, s, e, rs, and re variables to the corresponding arguments. * Calls MixHash() once for each public key listed in the pre-messages. * - * //TODO: remove Logger Param - * @param noise_handshake handshake struct to save the necessary values to + * @param noise_handshake Noise handshake struct to save the necessary values to * @param self_secret_key static private ID X25519 key of this Tox instance - * @param peer_public_key X25519 static ID public key from peer to connect to + * @param peer_public_key static public ID X25519 key from the peer to connect to * @param initiator specifies if this Tox instance is the initiator of this crypto connection - * @param prologue specifies the prologue, used in call to MixHash(prologue) which maybe zero-length - * @param prologue_length length of prologue in bytes + * @param prologue specifies the Noise prologue, used in call to MixHash(prologue) which maybe zero-length + * @param prologue_length length of Noise prologue in bytes * * @return -1 on failure * @return 0 on success @@ -695,7 +694,7 @@ int noise_handshake_init * input_key_material = DH_X25519(private, public) * * @param chaining_key 64 byte Noise ck - * @param shared_key 32 byte key to be calculated + * @param shared_key 32 byte secret key to be calculated * @param private_key X25519 private key * @param public_key X25519 public key */ From ee4e7c23cd4c1d648a44aff16b71384bb6293987 Mon Sep 17 00:00:00 2001 From: goldroom Date: Mon, 27 Jan 2025 16:21:31 +0100 Subject: [PATCH 128/150] refactor: removed base nonces from NoiseIK handshake packets to use (only) a counter instead. Due to separate encryption/decryption keys they were unnecessary overhead. --- toxcore/net_crypto.c | 355 +++++++++++++++++++++---------------------- toxcore/net_crypto.h | 16 +- 2 files changed, 179 insertions(+), 192 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 8df0922a31..cfb9d6bc97 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -61,12 +61,13 @@ typedef enum Crypto_Conn_State { typedef struct Crypto_Connection { /* (Currently) all used for both non-Noise and Noise handshakes/connections */ - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real/static identity public X25519 key of the peer. */ - uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ //TODO: Not use in Noise handshake - uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ //TODO: Not use in Noise handshake - uint8_t sessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public ephemeral X25519 key for this session. */ - uint8_t sessionsecret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private ephemeral X25519 key for this session. */ - uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public ephemeral X25519 key of the peer. Not used in Noise handshake. */ + uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real/static identity public X25519 key of the peer. */ + uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce used to decrypt incoming packets after non-Noise and NoiseIK handshake. */ + //TODO(goldroom): Dot not send in NoiseIK handshake + uint8_t send_nonce[CRYPTO_NONCE_SIZE]; /* Nonce used to encrypt outgoing packets after non-Noise and NoiseIK handshake. */ + uint8_t ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public ephemeral X25519 key for this session. */ + uint8_t ephemeral_secret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private ephemeral X25519 key for this session. */ + uint8_t peer_ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public ephemeral X25519 key of the peer. Not used in Noise handshake. */ uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. (non-Noise handshake) */ Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ @@ -166,8 +167,8 @@ struct Net_Crypto { uint32_t crypto_connections_length; /* Length of connections array. */ /* Our public and secret keys. */ - uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; + uint8_t self_id_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t self_id_secret_key[CRYPTO_SECRET_KEY_SIZE]; /* The secret key used for cookies */ uint8_t cookie_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; @@ -186,12 +187,12 @@ struct Net_Crypto { const uint8_t *nc_get_self_public_key(const Net_Crypto *c) { - return c->self_public_key; + return c->self_id_public_key; } const uint8_t *nc_get_self_secret_key(const Net_Crypto *c) { - return c->self_secret_key; + return c->self_id_secret_key; } TCP_Connections *nc_get_tcp_c(const Net_Crypto *c) @@ -250,7 +251,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin //TODO: or different cookie mechanism? E.g. as in WireGuard? uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; - memcpy(plain, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(plain, c->self_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: "Padding is used to maintain backwards-compatibility with previous versions of the protocol." => can this be removed by now? memzero(plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); memcpy(plain + (CRYPTO_PUBLIC_KEY_SIZE * 2), &number, sizeof(uint64_t)); @@ -512,22 +513,22 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte /* Non-noise: Necessary for backwards compatiblity to non-Noise handshake */ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) /* Noise: Necessary for Noise-based handshake */ -#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (CRYPTO_NONCE_SIZE + COOKIE_LENGTH + COOKIE_LENGTH) -#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (CRYPTO_NONCE_SIZE + COOKIE_LENGTH) +#define NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + COOKIE_LENGTH + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER (1 + CRYPTO_PUBLIC_KEY_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR (COOKIE_LENGTH + COOKIE_LENGTH) +#define NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER (COOKIE_LENGTH) /** @brief Create a handshake packet and put it in packet. Currently supports noise-Noise and Noise handshake. * * cf. Noise section 5.3 -> WriteMessage(payload, message_buffer) * - * @param cookie must be COOKIE_LENGTH bytes. + * @param peer_cookie must be COOKIE_LENGTH bytes. Cookie received from the peer. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. - * @param nonce base nonce for this Tox instance, to be used for transport message encryption after handshake - * @param ephemeral_private Ephemeral private X25519 key of this Tox instance for this handshake - * @param ephemeral_public Ephemeral public X25519 key of this Tox instance for this handshake - * @param peer_real_pk X25519 static ID public key from peer to connect to - * @param peer_dht_pubkey X25519 DHT public key from peer to connect to + * @param send_nonce base nonce for this Tox instance, to be used for transport message encryption after non-Noise handshake + * @param ephemeral_private_key Ephemeral private X25519 key of this Tox instance for this handshake + * @param ephemeral_public_key Ephemeral public X25519 key of this Tox instance for this handshake + * @param peer_id_public_key X25519 static ID public key from peer to connect to + * @param peer_dht_public_key X25519 DHT public key from peer to connect to * @param noise_handshake struct containing Noise information/values * * @retval -1 on failure. @@ -536,40 +537,38 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte * @retval NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER if Noise handshake responder * */ -non_null(1, 2, 3, 4, 6, 7, 8) nullable(5, 9) -static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce, const uint8_t *ephemeral_private, - const uint8_t *ephemeral_public, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey, Noise_Handshake *noise_handshake) +non_null(1, 2, 3, 6, 7, 8) nullable(4, 5, 9) +static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t peer_cookie[COOKIE_LENGTH], const uint8_t send_nonce[CRYPTO_NONCE_SIZE], const uint8_t ephemeral_private_key[CRYPTO_SECRET_KEY_SIZE], + const uint8_t ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], Noise_Handshake *noise_handshake) { LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); /* Noise-based handshake */ if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "Noise Handshake"); /* Noise INITIATOR: -> e, es, s, ss */ - /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_SHA512) + /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain - ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 + ~~[24 bytes nonce for static public key encryption]~~ NOT necessary for ChaCha20-Poly1305 [encrypted static public key of the INITIATOR (32 bytes)] - [MAC encrypted static pubkey 16 bytes] + [MAC encrypted static pulic key 16 bytes] ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: - //TODO: remove base Nonce, not necessary with different symmetric keys for outgoing/incoming packets - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - //TODO: move Cookie outside of encrypted payload? - [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD - [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] + ~~[24 bytes base nonce]~~ => WITHOUT base Nonce, just a counter (not necessary with different symmetric keys for outgoing/incoming packets) + [Cookie 112 bytes] => RESPONDER cookie encrypted and authenticated via AEAD + [112 bytes other/INITIATOR cookie] => used by the RESPONDER peer to respond to the handshake packet [MAC encrypted payload 16 bytes] - => 345 bytes in total + => 321 bytes in total */ if (noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR"); /* set ephemeral private+public */ - memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); - memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_private, ephemeral_private_key, CRYPTO_SECRET_KEY_SIZE); + memcpy(noise_handshake->ephemeral_public, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* e */ - memcpy(packet + 1, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(packet + 1, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; @@ -578,7 +577,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_static); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private_key, noise_handshake->remote_static); /* s */ /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ @@ -598,18 +597,17 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; - memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); /* Noise: Cookie from RESPONDER */ - memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + memcpy(handshake_payload_plain, peer_cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain, peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise /* OtherCookie is added to payload */ - if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, + if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + COOKIE_LENGTH, cookie_plain, c->cookie_symmetric_key) != 0) { return -1; } @@ -644,20 +642,20 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD - ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK + ~~[24 bytes base nonce]~~ => WITHOUT base Nonce, just use a counter WITHOUT base Nonce, just a counter (not necessary with different symmetric keys for outgoing/incoming packets) + [Cookie 112 bytes] => INITIATOR cookie encrypted and authenticated via AEAD + ~~[112 bytes other/RESPONDER cookie]~~ NOT necessary for NoiseIK [MAC encrypted payload 16 bytes] - => ~~321~~ 185 bytes in total + => 161 bytes in total */ else { /* set ephemeral private+public */ - memcpy(noise_handshake->ephemeral_private, ephemeral_private, CRYPTO_SECRET_KEY_SIZE); - memcpy(noise_handshake->ephemeral_public, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(noise_handshake->ephemeral_private, ephemeral_private_key, CRYPTO_SECRET_KEY_SIZE); + memcpy(noise_handshake->ephemeral_public, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* e */ - memcpy(packet + 1, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake->hash, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(packet + 1, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove // char log_ck[CRYPTO_SHA512_SIZE*2+1]; @@ -666,7 +664,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* ee */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private, noise_handshake->remote_ephemeral); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private_key, noise_handshake->remote_ephemeral); //TODO: Remove // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; @@ -682,10 +680,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; - memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); /* Noise: Cookie from INITIATOR */ - memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); + memcpy(handshake_payload_plain, peer_cookie, COOKIE_LENGTH); /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, @@ -704,12 +701,12 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u else { LOGGER_DEBUG(c->log, "non-Noise handshake"); uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - memcpy(plain, nonce, CRYPTO_NONCE_SIZE); - memcpy(plain + CRYPTO_NONCE_SIZE, ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - crypto_sha512(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, cookie, COOKIE_LENGTH); + memcpy(plain, send_nonce, CRYPTO_NONCE_SIZE); + memcpy(plain + CRYPTO_NONCE_SIZE, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + crypto_sha512(plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, peer_cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain, peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); if (create_cookie(c->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, cookie_plain, c->cookie_symmetric_key) != 0) { @@ -717,7 +714,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u } random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); - const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), + const int len = encrypt_data(c->mem, peer_id_public_key, c->self_id_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { @@ -725,37 +722,32 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u } packet[0] = NET_PACKET_CRYPTO_HS; - memcpy(packet + 1, cookie, COOKIE_LENGTH); + memcpy(packet + 1, peer_cookie, COOKIE_LENGTH); return HANDSHAKE_PACKET_LENGTH; } } -//TODO: update comment -/** @brief Handle a crypto handshake packet of length. - * put the base nonce contained in the packet in nonce, - * the session public key in session_pk - * the real public key of the peer in peer_real_pk - * the dht public key of the peer in dht_public_key and - * the cookie inside the encrypted part of the packet in cookie. - * Currently supports noise-Noise and Noise handshake - * - * if expected_real_pk isn't NULL it denotes the real public key - * the packet should be from. - * - * nonce must be at least CRYPTO_NONCE_SIZE - * session_pk must be at least CRYPTO_PUBLIC_KEY_SIZE - * peer_real_pk must be at least CRYPTO_PUBLIC_KEY_SIZE - * cookie must be at least COOKIE_LENGTH +/** @brief Handle a handshake packet (of packet_length), recieved cookie(s) and crypto material. + * Currently supports noise-Noise and Noise handshake. * * cf. Noise section 5.3 -> ReadMessage(payload, message_buffer) * + * @param packet received handshake packet. + * @param recv_nonce base nonce of the peers Tox instance to be used for transport message decryption after non-Noise handshake + * @param peer_ephemeral_public_key Ephemeral public X25519 key of the peers Tox instance for this handshake + * @param peer_id_public_key X25519 static ID public key from peer to connect to + * @param peer_dht_public_key X25519 DHT public key from peer to connect to + * @param peer_cookie must be COOKIE_LENGTH bytes. Cookie received from the peer. + * @param noise_handshake struct containing Noise information/values + * * @retval false on failure. * @retval true on success. + * */ -non_null(1, 2, 5, 7) nullable(3, 4, 6, 9, 10) -static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, - uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk, +non_null(1, 5, 7) nullable(2, 3, 4, 6, 9, 10) +static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYPTO_NONCE_SIZE], uint8_t peer_ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE], uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], + uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], uint8_t peer_cookie[COOKIE_LENGTH], const uint8_t *packet, uint16_t packet_length, const uint8_t expected_peer_id_pk[CRYPTO_PUBLIC_KEY_SIZE], Noise_Handshake *noise_handshake) { LOGGER_DEBUG(c->log, "ENTERING"); @@ -766,23 +758,23 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; /* -> e, es, s, ss */ - /* Initiator: Handshake packet structure handled here (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain - ~~[24 bytes nonce for static pub key encryption]~~ NOT necessary for ChaCha20-Poly1305 + ~~[24 bytes nonce for static public key encryption]~~ NOT necessary for ChaCha20-Poly1305 [encrypted static public key of the INITIATOR (32 bytes)] - [MAC encrypted static pubkey 16 bytes] + [MAC encrypted static pulic key 16 bytes] ~~[24 bytes nonce handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => Cookie encrypted and authenticated via AEAD - [112 bytes Other Cookie (used by the other peer to respond to the handshake packet)] + ~~[24 bytes base nonce]~~ => WITHOUT base Nonce, just a counter (not necessary with different symmetric keys for outgoing/incoming packets) + [Cookie 112 bytes] => RESPONDER cookie encrypted and authenticated via AEAD + [112 bytes other/INITIATOR cookie] => used by the RESPONDER peer to respond to the handshake packet [MAC encrypted payload 16 bytes] - => 345 bytes in total + => 321 bytes in total */ if (!noise_handshake->initiator) { LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); - if (length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + if (packet_length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { return false; } @@ -844,24 +836,22 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here - if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->cookie_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain, c->cookie_symmetric_key) != 0) { return false; } /* Compares static identity public keys from the peer */ - if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { + if (expected_peer_id_pk != nullptr && !pk_equal(cookie_plain, expected_peer_id_pk)) { return false; } - /* received base nonce (from INITIATOR) */ - memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ - memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); - /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ + memcpy(peer_cookie, handshake_payload_plain + COOKIE_LENGTH, COOKIE_LENGTH); + /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c:handle_new_connections() */ //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? - memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(peer_id_public_key, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); /* necessary */ - memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); @@ -871,21 +861,21 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 [Encrypted message containing: - [24 bytes base nonce] => WITH base Nonce, to be used for transport message encryption after handshake - [Cookie 112 bytes] => INITIATOR Cookie encrypted and authenticate via XAEAD - ~~[112 bytes Other Cookie (used by the other to respond to the handshake packet)]~~ NOT necessary for NoiseIK + ~~[24 bytes base nonce]~~ => WITHOUT base Nonce, just use a counter WITHOUT base Nonce, just a counter (not necessary with different symmetric keys for outgoing/incoming packets) + [Cookie 112 bytes] => INITIATOR cookie encrypted and authenticated via AEAD + ~~[112 bytes other/RESPONDER cookie]~~ NOT necessary for NoiseIK [MAC encrypted payload 16 bytes] - => ~~321~~ 185 bytes in total + => 161 bytes in total */ else { LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); - if (length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + if (packet_length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { return false; } @@ -919,28 +909,26 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t if (noise_decrypt_and_hash(handshake_payload_plain, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, sizeof(handshake_payload_plain) + CRYPTO_MAC_SIZE, noise_handshake_temp_key, noise_handshake->hash) != sizeof(handshake_payload_plain)) { - LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage remote static decryption failed"); + LOGGER_DEBUG(c->log, "INITIATOR: Noise ReadMessage decryption failed"); return false; } crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here - if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain + CRYPTO_NONCE_SIZE, c->cookie_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain, c->cookie_symmetric_key) != 0) { return false; } /* Compares static identity public keys from the peer */ - if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { + if (expected_peer_id_pk != nullptr && !pk_equal(cookie_plain, expected_peer_id_pk)) { return false; } - /* neccessary, base nonce (from Noise RESPONDER) */ - memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); /* necessary */ - memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const + //TODO: memzero packet, unwanted side effects? TODO: not possible currently because const // crypto_memzero(packet, length); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); @@ -954,7 +942,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - if (length != HANDSHAKE_PACKET_LENGTH) { + if (packet_length != HANDSHAKE_PACKET_LENGTH) { return false; } @@ -965,7 +953,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t } /* Compares static identity public keys from the peer */ - if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) { + if (expected_peer_id_pk != nullptr && !pk_equal(cookie_plain, expected_peer_id_pk)) { return false; } @@ -973,7 +961,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, + const int len = decrypt_data(c->mem, cookie_plain, c->self_id_secret_key, packet + 1 + COOKIE_LENGTH, packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); @@ -985,11 +973,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - memcpy(nonce, plain, CRYPTO_NONCE_SIZE); - memcpy(session_pk, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); - memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(recv_nonce, plain, CRYPTO_NONCE_SIZE); + memcpy(peer_ephemeral_public_key, plain + CRYPTO_NONCE_SIZE, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(peer_cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH); + memcpy(peer_id_public_key, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? // crypto_memzero(packet, length); @@ -1529,7 +1517,7 @@ static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const const uint16_t packet_size = 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE; VLA(uint8_t, packet, packet_size); packet[0] = NET_PACKET_CRYPTO_DATA; - memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); + memcpy(packet + 1, conn->send_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); //TODO: remove // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; @@ -1543,9 +1531,9 @@ static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const int len = 0; if (conn->noise_handshake_enabled) { /* Case NoiseIK handshake */ //TODO: add ad? only packet ID and last two bytes of nonce sent in plain - len = encrypt_data_symmetric_xaead(conn->send_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); + len = encrypt_data_symmetric_xaead(conn->send_key, conn->send_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); } else { /* Case non-Noise handshake */ - len = encrypt_data_symmetric(c->mem, conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + len = encrypt_data_symmetric(c->mem, conn->shared_key, conn->send_nonce, data, length, packet + 1 + sizeof(uint16_t)); } @@ -1554,7 +1542,7 @@ static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const return -1; } - increment_nonce(conn->sent_nonce); + increment_nonce(conn->send_nonce); return send_packet_to(c, crypt_connection_id, packet, packet_size); } @@ -1958,8 +1946,8 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; - if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + if (create_crypto_handshake(c, handshake_packet, cookie, nullptr, conn->ephemeral_secret_key, conn->ephemeral_public_key, + conn->peer_id_public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { return -1; } @@ -1969,8 +1957,8 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c } else { /* Noise RESPONDER */ uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER]; - if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionsecret_key, conn->sessionpublic_key, - conn->public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + if (create_crypto_handshake(c, handshake_packet, cookie, nullptr, conn->ephemeral_secret_key, conn->ephemeral_public_key, + conn->peer_id_public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { return -1; } @@ -1985,8 +1973,8 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; /* ephemeral_private and noise_handshake not necessary for old handshake */ - if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, nullptr, conn->sessionpublic_key, - conn->public_key, dht_public_key, nullptr) != sizeof(handshake_packet)) { + if (create_crypto_handshake(c, handshake_packet, cookie, conn->send_nonce, nullptr, conn->ephemeral_public_key, + conn->peer_id_public_key, dht_public_key, nullptr) != sizeof(handshake_packet)) { return -1; } @@ -2245,7 +2233,7 @@ static int handle_packet_cookie_response(const Net_Crypto *c, int crypt_connecti } /* Noise: only necessary if Cookie response was successful */ - if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { + if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, conn->peer_id_public_key, true, nullptr, 0) != 0) { return -1; } @@ -2316,6 +2304,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: Wipe noise_handshake etc. in this case? } else if (c->noise_compatibility_enabled) { conn->noise_handshake_enabled = false; + random_nonce(c->rng, conn->send_nonce); } else { return -1; } @@ -2326,19 +2315,19 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? - if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, nullptr, dht_public_key, nullptr, - packet, length, conn->public_key, conn->noise_handshake)) { + if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, nullptr, + packet, length, conn->peer_id_public_key, conn->noise_handshake)) { return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); - if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { + if (noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ - if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, + if (!handle_crypto_handshake(c, nullptr, nullptr, conn->peer_id_public_key, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; } @@ -2365,12 +2354,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change; also necessary without change */ - if (noise_handshake_init(conn->noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { + if (noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ - if (!handle_crypto_handshake(c, conn->recv_nonce, nullptr, conn->public_key, dht_public_key, cookie, + if (!handle_crypto_handshake(c, nullptr, nullptr, conn->peer_id_public_key, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; } @@ -2394,8 +2383,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "non-Noise handshake"); /* necessary only for non-Noise */ uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, - packet, length, conn->public_key, nullptr)) { + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peer_ephemeral_public_key, peer_real_pk, dht_public_key, cookie, + packet, length, conn->peer_id_public_key, nullptr)) { return -1; } } @@ -2442,7 +2431,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } // } /* Backwards compatibility: necessary for non-Noise handshake */ - encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + encrypt_precompute(conn->peer_ephemeral_public_key, conn->ephemeral_secret_key, conn->shared_key); //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway /* Backwards compatibility: necessary for non-Noise handshake */ conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -2666,7 +2655,7 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key) continue; } - if (pk_equal(public_key, c->crypto_connections[i].public_key)) { + if (pk_equal(public_key, c->crypto_connections[i].peer_id_public_key)) { return i; } } @@ -2747,7 +2736,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } New_Connection n_c = {{{{0}}}}; - n_c.cookie = cookie; + n_c.peer_cookie = cookie; n_c.source = *source; n_c.cookie_length = COOKIE_LENGTH; @@ -2756,10 +2745,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (length != HANDSHAKE_PACKET_LENGTH) { //TODO: adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; - if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { + if (noise_handshake_init(n_c.noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; - mem_delete(c->mem, n_c.cookie); + mem_delete(c->mem, n_c.peer_cookie); return -1; } @@ -2768,11 +2757,11 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? - if (!handle_crypto_handshake(c, n_c.recv_nonce, nullptr, n_c.public_key, n_c.dht_public_key, - n_c.cookie, packet, length, nullptr, n_c.noise_handshake)) { + if (!handle_crypto_handshake(c, nullptr, nullptr, n_c.peer_id_public_key, n_c.peer_dht_public_key, + n_c.peer_cookie, packet, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; - mem_delete(c->mem, n_c.cookie); + mem_delete(c->mem, n_c.peer_cookie); return -1; } } @@ -2781,9 +2770,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, LOGGER_DEBUG(c->log, "non-Noise handshake"); // Necessary for backwards compatibility n_c.noise_handshake = nullptr; - if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, - n_c.cookie, packet, length, nullptr, nullptr)) { - mem_delete(c->mem, n_c.cookie); + if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peer_ephemeral_public_key, n_c.peer_id_public_key, n_c.peer_dht_public_key, + n_c.peer_cookie, packet, length, nullptr, nullptr)) { + mem_delete(c->mem, n_c.peer_cookie); return -1; } } else { @@ -2798,7 +2787,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // bytes2string(log_cookie, sizeof(log_cookie), n_c.cookie, COOKIE_LENGTH, c->log); // LOGGER_DEBUG(c->log, "RESPONDER: cookie: %s", log_cookie); - const int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); + const int crypt_connection_id = getcryptconnection_id(c, n_c.peer_id_public_key); //TODO: This is only called if new_crypto_connection() was already called in the meantime! Now Noise RESPONDER! //TODO: Does it make sense to handle this case for NoiseIK handshake? @@ -2810,26 +2799,24 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } - if (!pk_equal(n_c.dht_public_key, conn->peer_dht_public_key)) { + if (!pk_equal(n_c.peer_dht_public_key, conn->peer_dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ LOGGER_DEBUG(c->log, "Noise handshake"); conn->noise_handshake_enabled = true; if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - mem_delete(c->mem, n_c.cookie); + mem_delete(c->mem, n_c.peer_cookie); return -1; } /* there is already something in conn->noise_handshake -> necessary to memzero in this case! */ crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(Noise_Handshake)); - memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); - crypto_connection_add_source(c, crypt_connection_id, source); - if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { - mem_delete(c->mem, n_c.cookie); + if (create_send_handshake(c, crypt_connection_id, n_c.peer_cookie, n_c.peer_dht_public_key) != 0) { + mem_delete(c->mem, n_c.peer_cookie); return -1; } @@ -2844,7 +2831,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; - mem_delete(c->mem, n_c.cookie); + mem_delete(c->mem, n_c.peer_cookie); return 0; } /* case non-Noise handshake */ @@ -2852,29 +2839,29 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, LOGGER_DEBUG(c->log, "non-Noise handshake"); conn->noise_handshake_enabled = false; if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - mem_delete(c->mem, n_c.cookie); + mem_delete(c->mem, n_c.peer_cookie); return -1; } memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); - memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE); - encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); + memcpy(conn->peer_ephemeral_public_key, n_c.peer_ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + encrypt_precompute(conn->peer_ephemeral_public_key, conn->ephemeral_secret_key, conn->shared_key); crypto_connection_add_source(c, crypt_connection_id, source); - if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { - mem_delete(c->mem, n_c.cookie); + if (create_send_handshake(c, crypt_connection_id, n_c.peer_cookie, n_c.peer_dht_public_key) != 0) { + mem_delete(c->mem, n_c.peer_cookie); return -1; } conn->status = CRYPTO_CONN_NOT_CONFIRMED; - mem_delete(c->mem, n_c.cookie); + mem_delete(c->mem, n_c.peer_cookie); return 0; } } const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); - mem_delete(c->mem, n_c.cookie); + mem_delete(c->mem, n_c.peer_cookie); //TODO: remove; ret value is from friend_connection.c:handle_new_connections() // LOGGER_DEBUG(c->log, "ret (!= 0?): %d", ret); return ret; @@ -2891,7 +2878,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); - if (getcryptconnection_id(c, n_c->public_key) != -1) { + if (getcryptconnection_id(c, n_c->peer_id_public_key) != -1) { //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: Crypto Connection already exists"); return -1; @@ -2915,7 +2902,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id); + const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->peer_dht_public_key, crypt_connection_id); if (connection_number_tcp == -1) { wipe_crypto_connection(c, crypt_connection_id); @@ -2936,16 +2923,15 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); // necessary -> TODO: duplicated code necessary? - memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE); - random_nonce(c->rng, conn->sent_nonce); - crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); + memcpy(conn->peer_id_public_key, n_c->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memset(conn->send_nonce, 0, CRYPTO_NONCE_SIZE); + crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); /* IMPORTANT: in this case here/before create_send_handshake(), otherwise get_crypto_connection() in create_send_handshake() returns a nullptr */ conn->status = CRYPTO_CONN_NOT_CONFIRMED; - if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { + if (create_send_handshake(c, crypt_connection_id, n_c->peer_cookie, n_c->peer_dht_public_key) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); return -1; @@ -2969,15 +2955,15 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) else if (c->noise_compatibility_enabled) { //TODO: remove LOGGER_DEBUG(c->log, "non-Noise handshake"); - memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(conn->peer_id_public_key, n_c->peer_id_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(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); + memcpy(conn->peer_ephemeral_public_key, n_c->peer_ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + random_nonce(c->rng, conn->send_nonce); + crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); + encrypt_precompute(conn->peer_ephemeral_public_key, conn->ephemeral_secret_key, conn->shared_key); conn->status = CRYPTO_CONN_NOT_CONFIRMED; - if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { + if (create_send_handshake(c, crypt_connection_id, n_c->peer_cookie, n_c->peer_dht_public_key) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); return -1; @@ -2988,7 +2974,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - memcpy(conn->peer_dht_public_key, n_c->dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(conn->peer_dht_public_key, n_c->peer_dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; @@ -3040,9 +3026,10 @@ 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(c->rng, conn->sent_nonce); - crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key); + memcpy(conn->peer_id_public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE); + /* Base nonce is a counter in transport phase after Noise-based handshake */ + memset(conn->send_nonce, 0, CRYPTO_NONCE_SIZE); + crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); conn->status = CRYPTO_CONN_COOKIE_REQUESTING; conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; @@ -3967,7 +3954,7 @@ void new_keys(Net_Crypto *c) { //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); - crypto_new_keypair(c->rng, c->self_public_key, c->self_secret_key); + crypto_new_keypair(c->rng, c->self_id_public_key, c->self_id_secret_key); } /** @brief Save the public and private keys to the keys array. @@ -3977,8 +3964,8 @@ void new_keys(Net_Crypto *c) */ void save_keys(const Net_Crypto *c, uint8_t *keys) { - memcpy(keys, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - memcpy(keys + CRYPTO_PUBLIC_KEY_SIZE, c->self_secret_key, CRYPTO_SECRET_KEY_SIZE); + memcpy(keys, c->self_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(keys + CRYPTO_PUBLIC_KEY_SIZE, c->self_id_secret_key, CRYPTO_SECRET_KEY_SIZE); } /** @brief Load the secret key. @@ -3986,8 +3973,8 @@ void save_keys(const Net_Crypto *c, uint8_t *keys) */ void load_secret_key(Net_Crypto *c, const uint8_t *sk) { - memcpy(c->self_secret_key, sk, CRYPTO_SECRET_KEY_SIZE); - crypto_derive_public_key(c->self_public_key, c->self_secret_key); + memcpy(c->self_id_secret_key, sk, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(c->self_id_public_key, c->self_id_secret_key); } /** @brief Create new instance of Net_Crypto. diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index ba93b1053a..6e7817a63c 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -127,22 +127,22 @@ non_null() DHT *nc_get_dht(const Net_Crypto *c); typedef struct New_Connection { IP_Port source; // Necessary for non-Noise handshake - uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ - uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer. */ - uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ - uint8_t peersessionpublic_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ + uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ + uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer. */ + uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce to decrypt received packets. */ + uint8_t peer_ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ // Necessary for Noise - //TODO: refactor to not use struct + //TODO(goldroom): refactor to not use struct Noise_Handshake noise_handshake_data; Noise_Handshake *noise_handshake; - //TODO: if no struct necessary + //TODO(goldroom): if no struct necessary // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_SHARED_KEY_SIZE]; // uint8_t noise_recv_key[CRYPTO_SHARED_KEY_SIZE]; // bool initiator; - uint8_t *cookie; + uint8_t *peer_cookie; uint8_t cookie_length; } New_Connection; @@ -427,7 +427,7 @@ void do_net_crypto(Net_Crypto *c, void *userdata); nullable(1) void kill_net_crypto(Net_Crypto *c); -//TODO: necessary? +//TODO(goldroom): necessary? //static void handshake_zero(struct noise_handshake *handshake); From 0ecbd3ba2277c1a356d2824354079cb6c1c1a204 Mon Sep 17 00:00:00 2001 From: goldroom Date: Mon, 27 Jan 2025 16:26:48 +0100 Subject: [PATCH 129/150] fix: fixed friend_connection after New_Connection refactoring. --- toxcore/friend_connection.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index 78c6d4acdc..22e7c54625 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c @@ -569,7 +569,7 @@ non_null() static int handle_new_connections(void *object, const New_Connection *n_c) { Friend_Connections *const fr_c = (Friend_Connections *)object; - const int friendcon_id = getfriend_conn_id_pk(fr_c, n_c->public_key); + const int friendcon_id = getfriend_conn_id_pk(fr_c, n_c->peer_id_public_key); Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id); if (friend_con == nullptr) { @@ -598,8 +598,8 @@ static int handle_new_connections(void *object, const New_Connection *n_c) friend_con->dht_ip_port_lastrecv = mono_time_get(fr_c->mono_time); } - if (!pk_equal(friend_con->dht_temp_pk, n_c->dht_public_key)) { - change_dht_pk(fr_c, friendcon_id, n_c->dht_public_key); + if (!pk_equal(friend_con->dht_temp_pk, n_c->peer_dht_public_key)) { + change_dht_pk(fr_c, friendcon_id, n_c->peer_dht_public_key); } nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id); From 34b931ca56e61d121888ed05539a4c0d254d8055 Mon Sep 17 00:00:00 2001 From: goldroom Date: Mon, 27 Jan 2025 20:55:32 +0100 Subject: [PATCH 130/150] chore: cleanup and documentation. --- toxcore/crypto_core.c | 14 +++---- toxcore/crypto_core.h | 9 ++--- toxcore/net_crypto.c | 93 ++++++++++++++++++++++--------------------- 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 9826bd3ffd..5c473029ef 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -1062,7 +1062,7 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, * @return 0 on success */ int noise_handshake_init -(Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length) +(Noise_Handshake *noise_handshake, const uint8_t self_id_secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], bool initiator, const uint8_t *prologue, size_t prologue_length) { //TODO: remove // if (log != nullptr) { @@ -1092,9 +1092,9 @@ int noise_handshake_init /* Sets the initiator, s => ephemeral keys are set afterwards */ noise_handshake->initiator = initiator; - if (self_secret_key != nullptr) { - memcpy(noise_handshake->static_private, self_secret_key, CRYPTO_SECRET_KEY_SIZE); - crypto_derive_public_key(noise_handshake->static_public, self_secret_key); + if (self_id_secret_key != nullptr) { + memcpy(noise_handshake->static_private, self_id_secret_key, CRYPTO_SECRET_KEY_SIZE); + crypto_derive_public_key(noise_handshake->static_public, self_id_secret_key); //TODO: remove // if (log != nullptr) { @@ -1110,8 +1110,8 @@ int noise_handshake_init } /* <- s: pre-message from responder to initiator => sets rs (only initiator) */ if (initiator) { - if (peer_public_key != nullptr) { - memcpy(noise_handshake->remote_static, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + if (peer_id_public_key != nullptr) { + memcpy(noise_handshake->remote_static, peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove // if (log != nullptr) { @@ -1121,7 +1121,7 @@ int noise_handshake_init // } /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ - noise_mix_hash(noise_handshake->hash, peer_public_key, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove // if (log != nullptr) { diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 6e3052481f..3041c2dabb 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -129,7 +129,6 @@ typedef struct Random { /** @brief Necessary NoiseIK handshake state information/values. */ typedef struct Noise_Handshake { - // TODO: static_private? uint8_t static_private[CRYPTO_SECRET_KEY_SIZE]; uint8_t static_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t ephemeral_private[CRYPTO_SECRET_KEY_SIZE]; @@ -137,7 +136,7 @@ typedef struct Noise_Handshake { uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; //TODO(goldroom): precompute static static? cf. WireGuard struct noise_handshake - // uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; + // uint8_t precomputed_static_static[CRYPTO_SHARED_KEY_SIZE]; uint8_t hash[CRYPTO_SHA512_SIZE]; uint8_t chaining_key[CRYPTO_SHA512_SIZE]; @@ -668,8 +667,8 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * Calls MixHash() once for each public key listed in the pre-messages. * * @param noise_handshake Noise handshake struct to save the necessary values to - * @param self_secret_key static private ID X25519 key of this Tox instance - * @param peer_public_key static public ID X25519 key from the peer to connect to + * @param self_id_secret_key static private ID X25519 key of this Tox instance + * @param peer_id_public_key static public ID X25519 key from the peer to connect to * @param initiator specifies if this Tox instance is the initiator of this crypto connection * @param prologue specifies the Noise prologue, used in call to MixHash(prologue) which maybe zero-length * @param prologue_length length of Noise prologue in bytes @@ -679,7 +678,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, */ non_null(1, 2) nullable(3, 5) int noise_handshake_init -(Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); +(Noise_Handshake *noise_handshake, const uint8_t self_id_secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], bool initiator, const uint8_t *prologue, size_t prologue_length); //TODO: remove // int noise_handshake_init // (const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index cfb9d6bc97..19ed67393b 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -60,32 +60,31 @@ typedef enum Crypto_Conn_State { } Crypto_Conn_State; typedef struct Crypto_Connection { - /* (Currently) all used for both non-Noise and Noise handshakes/connections */ + //TODO(goldroom): kept for backwards compatibility in NoiseIK, to be removed at some point. Not used in NoiseIK handshake. uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real/static identity public X25519 key of the peer. */ + uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce used to decrypt incoming packets after non-Noise and NoiseIK handshake. */ - //TODO(goldroom): Dot not send in NoiseIK handshake - uint8_t send_nonce[CRYPTO_NONCE_SIZE]; /* Nonce used to encrypt outgoing packets after non-Noise and NoiseIK handshake. */ + uint8_t send_nonce[CRYPTO_NONCE_SIZE]; /* Nonce used to encrypt outgoing packets after non-Noise and NoiseIK handshake. */ + + //TODO(goldroom): currently in use for backwards compatibility in NoiseIK, to be removed at some point. uint8_t ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public ephemeral X25519 key for this session. */ uint8_t ephemeral_secret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private ephemeral X25519 key for this session. */ - uint8_t peer_ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public ephemeral X25519 key of the peer. Not used in Noise handshake. */ - uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; /* The precomputed shared key from encrypt_precompute. (non-Noise handshake) */ + + //TODO(goldroom): kept for backwards compatibility in NoiseIK, to be removed at some point. Not used in NoiseIK handshake. + uint8_t peer_ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public ephemeral X25519 key of the peer. */ + + /* The precomputed shared key from encrypt_precompute. + Used for cookie requests/responses in non-Noise and NoiseIK handshake: and for transport payload encryption (non-Noise only). */ + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; + Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ - uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public X25519 key of the peer */ + uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The DHT public X25519 key of the peer. */ bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ - uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to encrypt outgoing packets after NoiseIK handshake */ - uint8_t recv_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to decrypt incoming packets after NoiseIK handshake */ - //TODO: remove - // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; - // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; - // uint8_t niose_send_key[CRYPTO_PUBLIC_KEY_SIZE]; - // uint8_t noise_recv_key[CRYPTO_PUBLIC_KEY_SIZE]; - //TODO: necessary? - // uint16_t handshake_send_interval; - // bool initiator; - // uint8_t precomputed_static_static[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to encrypt outgoing packets after NoiseIK handshake. */ + uint8_t recv_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to decrypt incoming packets after NoiseIK handshake. */ uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ uint16_t temp_packet_length; @@ -247,12 +246,11 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); - //TODO: adapt for new Noise-cookie mechanism _only_ - //TODO: or different cookie mechanism? E.g. as in WireGuard? + //TODO(goldroom): adapt for new Noise-cookie mechanism _only_ or different cookie mechanism? E.g. as in WireGuard? uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; memcpy(plain, c->self_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: "Padding is used to maintain backwards-compatibility with previous versions of the protocol." => can this be removed by now? + //TODO(goldroom): "Padding is used to maintain backwards-compatibility with previous versions of the protocol." => can this be removed by now? memzero(plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); memcpy(plain + (CRYPTO_PUBLIC_KEY_SIZE * 2), &number, sizeof(uint64_t)); const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key); @@ -605,8 +603,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain, peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: Send/Receive cookies again outside of handshake payload encryption? Double encrypted otherwise - /* OtherCookie is added to payload */ + /* Cookies are currently double-encrypted, but decryption also necessary if they would be authenticated via AD */ + /* INITIATOR OtherCookie is added to payload */ if (create_cookie(c->mem, c->rng, c->mono_time, handshake_payload_plain + COOKIE_LENGTH, cookie_plain, c->cookie_symmetric_key) != 0) { return -1; @@ -783,7 +781,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); // LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); - //TODO: Check here if remote_ephemeral is already the same ephemeral key? + //TODO(goldroom): Check here if remote_ephemeral is already the same ephemeral key? /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); @@ -835,7 +833,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here + /* Cookie is verified later than in non-Noise handshake, but this should be acceptable */ if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain, c->cookie_symmetric_key) != 0) { return false; } @@ -848,11 +846,12 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ memcpy(peer_cookie, handshake_payload_plain + COOKIE_LENGTH, COOKIE_LENGTH); /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c:handle_new_connections() */ - //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? - memcpy(peer_id_public_key, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); + if (peer_id_public_key != nullptr) { + memcpy(peer_id_public_key, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); + } /* necessary */ memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const + //TODO(goldroom): memzero packet, unwatend side effects? Currently not possible currently because const // crypto_memzero(packet, length); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); @@ -915,7 +914,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - //TODO: Send/Receive cookies again outside of handshake payload encryption? Late check here + /* Cookie is verified later than in non-Noise handshake, but this should be acceptable */ if (open_cookie(c->mem, c->mono_time, cookie_plain, handshake_payload_plain, c->cookie_symmetric_key) != 0) { return false; } @@ -928,12 +927,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP /* necessary */ memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: memzero packet, unwanted side effects? TODO: not possible currently because const + //TODO(goldroom): memzero packet, unwanted side effects? Currently not possible currently because const // crypto_memzero(packet, length); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); - LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); return true; } @@ -979,7 +977,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP memcpy(peer_id_public_key, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: memzero packet, unwatend side effects? + //TODO(goldroom): memzero packet, unwanted side effects? Currently not possible currently because const // crypto_memzero(packet, length); return true; @@ -1527,15 +1525,14 @@ static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const // bytes2string(nonce_print, sizeof(nonce_print), conn->sent_nonce, CRYPTO_NONCE_SIZE, c->log); // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); - //TODO: len was const + //TODO(goldroom): const len when backwards compatiblity removed int len = 0; if (conn->noise_handshake_enabled) { /* Case NoiseIK handshake */ - //TODO: add ad? only packet ID and last two bytes of nonce sent in plain + //TODO(goldroom): no data authenticated as AD (also none in WireGuard) len = encrypt_data_symmetric_xaead(conn->send_key, conn->send_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); } else { /* Case non-Noise handshake */ len = encrypt_data_symmetric(c->mem, conn->shared_key, conn->send_nonce, data, length, packet + 1 + sizeof(uint16_t)); } - if (len + 1 + sizeof(uint16_t) != packet_size) { LOGGER_ERROR(c->log, "encryption failed: %d", len); @@ -1718,10 +1715,10 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint // bytes2string(nonce_print, sizeof(nonce_print), nonce, CRYPTO_NONCE_SIZE, c->log); // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); - //TODO: len was const + //TODO(goldroom): const len when backwards compatiblity removed int len = 0; if (conn->noise_handshake_enabled) { /* case NoiseIK handshake */ - //TODO: add ad? only packet ID and last two bytes of nonce sent in plain + //TODO(goldroom): no data authenticated as AD (also none in WireGuard) len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, nullptr, 0); } else { /* case non-Noise handshake */ @@ -1947,7 +1944,7 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; if (create_crypto_handshake(c, handshake_packet, cookie, nullptr, conn->ephemeral_secret_key, conn->ephemeral_public_key, - conn->peer_id_public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + conn->noise_handshake->remote_static, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { return -1; } @@ -1958,7 +1955,7 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER]; if (create_crypto_handshake(c, handshake_packet, cookie, nullptr, conn->ephemeral_secret_key, conn->ephemeral_public_key, - conn->peer_id_public_key, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { + conn->noise_handshake->remote_static, dht_public_key, conn->noise_handshake) != sizeof(handshake_packet)) { return -1; } @@ -2059,7 +2056,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (len <= (int)(sizeof(uint32_t) * 2)) { LOGGER_DEBUG(c->log, "connection_kill() because data packet decryption failure, crypt_connection_id: %d", crypt_connection_id); - //TODO: unwanted side effects? leave here? + //TODO(goldroom): unwanted side effects? leave here? connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2119,7 +2116,12 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, conn->noise_handshake); conn->noise_handshake = nullptr; - //TODO: non-Noise: also crypto_memzero() values from conn? + + /* also crypto_memzero() non-Noise values from crypto connection */ + crypto_memzero(conn->ephemeral_secret_key, CRYPTO_SECRET_KEY_SIZE); + crypto_memzero(conn->ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + crypto_memzero(conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); + crypto_memzero(conn->peer_ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); if (conn->connection_status_callback != nullptr) { conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, @@ -2232,11 +2234,6 @@ static int handle_packet_cookie_response(const Net_Crypto *c, int crypt_connecti return -1; } - /* Noise: only necessary if Cookie response was successful */ - if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, conn->peer_id_public_key, true, nullptr, 0) != 0) { - return -1; - } - if (conn->noise_handshake != nullptr) { if (conn->noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake"); @@ -3026,6 +3023,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u } conn->connection_number_tcp = connection_number_tcp; + //TODO: Can this be removed? memcpy(conn->peer_id_public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* Base nonce is a counter in transport phase after Noise-based handshake */ memset(conn->send_nonce, 0, CRYPTO_NONCE_SIZE); @@ -3040,6 +3038,11 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; + /* TODO(goldroom): Noise: only necessary if Cookie response was successful, but moved here to avoid saving peer_id_public_key twice (to remove it a some point from struct Crypto_Connection) */ + if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, real_public_key, true, nullptr, 0) != 0) { + return -1; + } + conn->cookie_request_number = random_u64(c->rng); uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; From cbf09c58c75d857e732fff6f65e4271e56ff6600 Mon Sep 17 00:00:00 2001 From: goldroom Date: Mon, 27 Jan 2025 21:08:02 +0100 Subject: [PATCH 131/150] fix: fix for CI --- toxcore/crypto_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 5c473029ef..7e4c44240b 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -1052,8 +1052,8 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, * Calls MixHash() once for each public key listed in the pre-messages. * * @param noise_handshake handshake struct to save the necessary values to - * @param self_secret_key static private ID X25519 key of this Tox instance - * @param peer_public_key static public ID X25519 key from peer to connect to + * @param self_id_secret_key static private ID X25519 key of this Tox instance + * @param peer_id_public_key static public ID X25519 key from peer to connect to * @param initiator specifies if this Tox instance is the initiator of this crypto connection * @param prologue specifies the Noise prologue, used in call to MixHash(prologue) which maybe zero-length * @param prologue_length length of Noise prologue in bytes From e2e65c249ee825dbe0dabb96c717441cb18456a6 Mon Sep 17 00:00:00 2001 From: goldroom Date: Tue, 28 Jan 2025 20:26:12 +0100 Subject: [PATCH 132/150] cleanup: minor cleanup --- toxcore/net_crypto.c | 48 +++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 19ed67393b..989301ab3d 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -839,7 +839,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP } /* Compares static identity public keys from the peer */ - if (expected_peer_id_pk != nullptr && !pk_equal(cookie_plain, expected_peer_id_pk)) { + if (!pk_equal(cookie_plain, noise_handshake->remote_static)) { return false; } @@ -851,8 +851,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP } /* necessary */ memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO(goldroom): memzero packet, unwatend side effects? Currently not possible currently because const - // crypto_memzero(packet, length); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); @@ -927,9 +925,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP /* necessary */ memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO(goldroom): memzero packet, unwanted side effects? Currently not possible currently because const - // crypto_memzero(packet, length); - crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); @@ -977,9 +972,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP memcpy(peer_id_public_key, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(peer_dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); - //TODO(goldroom): memzero packet, unwanted side effects? Currently not possible currently because const - // crypto_memzero(packet, length); - return true; } } @@ -2296,11 +2288,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* necessary for Noise RESPONDER and non-Noise */ uint8_t cookie[COOKIE_LENGTH]; + //TODO: does this make sense this way? if (length != HANDSHAKE_PACKET_LENGTH) { conn->noise_handshake_enabled = true; - //TODO: Wipe noise_handshake etc. in this case? } else if (c->noise_compatibility_enabled) { + //TODO: Wipe noise_handshake etc. in this case? conn->noise_handshake_enabled = false; + /* Random nonce needed in non-Noise handshake */ random_nonce(c->rng, conn->send_nonce); } else { return -1; @@ -2311,20 +2305,23 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); - //TODO: fails if peer receives two handshake packets.. check for send_key/recv_key? + //TODO(goldroom): fails if peer receives two handshake packets.. check for send_key/recv_key? + //TODO(goldroom): Update 28.01.2025 not sure if that is still a problem, not happening in auto_tox_many_test if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, nullptr, - packet, length, conn->peer_id_public_key, conn->noise_handshake)) { + packet, length, nullptr, conn->noise_handshake)) { return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { + /* At least in auto tests this only happens for UDP connections */ LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); if (noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } - /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() + /* Noise: peer_id_public_key (=conn->peer_id_public_key) not necessary for NoiseIK, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ - if (!handle_crypto_handshake(c, nullptr, nullptr, conn->peer_id_public_key, dht_public_key, cookie, + //TODO: is this true in this case? => Removed from here, check if tests fail + if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; } @@ -2386,13 +2383,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - //TODO: adapt for Noise, makes only sense for RESPONDER not initiator + //TODO: adapt for NoiseIK, makes only sense for RESPONDER not initiator if (pk_equal(dht_public_key, conn->peer_dht_public_key)) { LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "Noise handshake"); + LOGGER_DEBUG(c->log, "Noise handshake: CRYPTO_CONN_NOT_CONFIRMED"); conn->status = CRYPTO_CONN_NOT_CONFIRMED; if (conn->noise_handshake->initiator) { //TODO: remove @@ -2787,7 +2784,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.peer_id_public_key); //TODO: This is only called if new_crypto_connection() was already called in the meantime! Now Noise RESPONDER! - //TODO: Does it make sense to handle this case for NoiseIK handshake? + //TODO: Does it make sense to handle this case for NoiseIK handshake? => yes, happens in auto_tox_many_test if (crypt_connection_id != -1) { LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING"); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -3040,6 +3037,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u /* TODO(goldroom): Noise: only necessary if Cookie response was successful, but moved here to avoid saving peer_id_public_key twice (to remove it a some point from struct Crypto_Connection) */ if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, real_public_key, true, nullptr, 0) != 0) { + kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); + wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -3060,18 +3059,6 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u //TODO: remove // LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); - //TODO: here? - // only necessary if Cookie request was successful - // if (noise_handshake_init(c->log, conn->noise_handshake, c->self_secret_key, real_public_key, true) != 0) { - // // crypto_memzero(conn->noise_handshake, sizeof(struct noise_handshake)); - // mem_delete(c->mem, conn->noise_handshake); - // pthread_mutex_lock(&c->tcp_mutex); - // kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - // pthread_mutex_unlock(&c->tcp_mutex); - // wipe_crypto_connection(c, crypt_connection_id); - // return -1; - // } - //TODO: remove LOGGER_DEBUG(c->log, "INITIATOR: END"); @@ -4075,7 +4062,8 @@ uint32_t crypto_run_interval(const Net_Crypto *c) /** Main loop. */ void do_net_crypto(Net_Crypto *c, void *userdata) { - LOGGER_DEBUG(c->log, "do_net_crypto()"); + //TODO: remove + // LOGGER_DEBUG(c->log, "do_net_crypto()"); //TODO: update cookie symmetric key every ~2 minutes (cf. WireGuard)? kill_timedout(c, userdata); do_tcp(c, userdata); From 5a825837d8f5c3a0aec934906dc13ab50c913b3e Mon Sep 17 00:00:00 2001 From: goldroom Date: Thu, 30 Jan 2025 20:43:24 +0100 Subject: [PATCH 133/150] cleanup: minor cleanup --- toxcore/net_crypto.c | 50 +++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 989301ab3d..1189bdb4a1 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -82,6 +82,7 @@ typedef struct Crypto_Connection { uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The DHT public X25519 key of the peer. */ bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ + //TODO(goldroom): Can this be moved out of struct Crypto_Connection? Not necessary after handshake is finished Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to encrypt outgoing packets after NoiseIK handshake. */ uint8_t recv_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to decrypt incoming packets after NoiseIK handshake. */ @@ -600,7 +601,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(handshake_payload_plain, peer_cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - memcpy(cookie_plain, peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(cookie_plain, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* Cookies are currently double-encrypted, but decryption also necessary if they would be authenticated via AD */ @@ -2104,10 +2105,12 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); - /* Noise: noise_handshake not necessary anymore => memzero and free */ - crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); - mem_delete(c->mem, conn->noise_handshake); - conn->noise_handshake = nullptr; + /* Noise: noise_handshake not necessary anymore => memzero and free */ + if (conn->noise_handshake != nullptr) { + crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + mem_delete(c->mem, conn->noise_handshake); + conn->noise_handshake = nullptr; + } /* also crypto_memzero() non-Noise values from crypto connection */ crypto_memzero(conn->ephemeral_secret_key, CRYPTO_SECRET_KEY_SIZE); @@ -2288,20 +2291,22 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* necessary for Noise RESPONDER and non-Noise */ uint8_t cookie[COOKIE_LENGTH]; - //TODO: does this make sense this way? - if (length != HANDSHAKE_PACKET_LENGTH) { - conn->noise_handshake_enabled = true; - } else if (c->noise_compatibility_enabled) { - //TODO: Wipe noise_handshake etc. in this case? + /* necessary for compatiblity to non-Noise */ + if (length == HANDSHAKE_PACKET_LENGTH && c->noise_compatibility_enabled) { + /* non-Noise: noise_handshake not necessary anymore => memzero and free */ + crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + mem_delete(c->mem, conn->noise_handshake); + conn->noise_handshake = nullptr; conn->noise_handshake_enabled = false; /* Random nonce needed in non-Noise handshake */ random_nonce(c->rng, conn->send_nonce); - } else { - return -1; } - if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { + if (conn->noise_handshake_enabled) { LOGGER_DEBUG(c->log, "Noise handshake"); + if (conn->noise_handshake == nullptr) { + return -1; + } if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); @@ -2353,7 +2358,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() -> otherwise not working (call via friend_connection.c) */ - if (!handle_crypto_handshake(c, nullptr, nullptr, conn->peer_id_public_key, dht_public_key, cookie, + //TODO: is this true in this case? => Removed from here, check if tests fail + if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; } @@ -2376,8 +2382,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const else { LOGGER_DEBUG(c->log, "non-Noise handshake"); /* necessary only for non-Noise */ - uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; - if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peer_ephemeral_public_key, peer_real_pk, dht_public_key, cookie, + uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE]; + if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peer_ephemeral_public_key, peer_id_public_key, dht_public_key, cookie, packet, length, conn->peer_id_public_key, nullptr)) { return -1; } @@ -2916,9 +2922,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //NOT possible here, need content afterwards! // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); - // necessary -> TODO: duplicated code necessary? - memcpy(conn->peer_id_public_key, n_c->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); + //TODO: only necessary if NoiseIK handshake finished memset(conn->send_nonce, 0, CRYPTO_NONCE_SIZE); + //TODO: why did I move that here? crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); /* IMPORTANT: in this case here/before create_send_handshake(), otherwise get_crypto_connection() in @@ -2996,7 +3002,6 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u if (crypt_connection_id != -1) { //TODO: remove - //TODO: Print pub key? LOGGER_DEBUG(c->log, "Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); return crypt_connection_id; } @@ -3020,10 +3025,12 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u } conn->connection_number_tcp = connection_number_tcp; - //TODO: Can this be removed? + /* Necessary for backwards compatibility to switch to non-Noise handshake */ memcpy(conn->peer_id_public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* Base nonce is a counter in transport phase after Noise-based handshake */ + //TODO: only necessary if handshake finished memset(conn->send_nonce, 0, CRYPTO_NONCE_SIZE); + //TODO: move to create_send_handshake? crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); conn->status = CRYPTO_CONN_COOKIE_REQUESTING; conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; @@ -3035,7 +3042,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; - /* TODO(goldroom): Noise: only necessary if Cookie response was successful, but moved here to avoid saving peer_id_public_key twice (to remove it a some point from struct Crypto_Connection) */ + /* TODO(goldroom): Noise: only necessary if Cookie response was successful, but moved here to avoid saving peer_id_public_key twice + (to remove it a some point from struct Crypto_Connection) */ if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, real_public_key, true, nullptr, 0) != 0) { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); wipe_crypto_connection(c, crypt_connection_id); From 8bdcac41cffb9bf5ea752b1bf40396d3668565e9 Mon Sep 17 00:00:00 2001 From: goldroom Date: Fri, 31 Jan 2025 14:09:40 +0100 Subject: [PATCH 134/150] fix: fixed two issues because of noise_handshake memzero in backwards compatiblity case. Moved ephemeral key pair generation to create_crypto_handshake(). Fixed setting of recv_nonce in NoiseIK handshake. --- toxcore/net_crypto.c | 62 +++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1189bdb4a1..bffa606ba9 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -524,8 +524,8 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte * @param peer_cookie must be COOKIE_LENGTH bytes. Cookie received from the peer. * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. * @param send_nonce base nonce for this Tox instance, to be used for transport message encryption after non-Noise handshake - * @param ephemeral_private_key Ephemeral private X25519 key of this Tox instance for this handshake - * @param ephemeral_public_key Ephemeral public X25519 key of this Tox instance for this handshake + * @param ephemeral_private_key Ephemeral private X25519 key of this non-Noise handshake + * @param ephemeral_public_key Ephemeral public X25519 key of this non-Noise handshake * @param peer_id_public_key X25519 static ID public key from peer to connect to * @param peer_dht_public_key X25519 DHT public key from peer to connect to * @param noise_handshake struct containing Noise information/values @@ -536,7 +536,7 @@ static void bytes2string(char *string, size_t string_length, const uint8_t *byte * @retval NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER if Noise handshake responder * */ -non_null(1, 2, 3, 6, 7, 8) nullable(4, 5, 9) +non_null(1, 2, 3, 8) nullable(4, 5, 6, 7, 9) static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t peer_cookie[COOKIE_LENGTH], const uint8_t send_nonce[CRYPTO_NONCE_SIZE], const uint8_t ephemeral_private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], Noise_Handshake *noise_handshake) { @@ -561,13 +561,12 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u */ if (noise_handshake->initiator) { LOGGER_DEBUG(c->log, "INITIATOR"); - /* set ephemeral private+public */ - memcpy(noise_handshake->ephemeral_private, ephemeral_private_key, CRYPTO_SECRET_KEY_SIZE); - memcpy(noise_handshake->ephemeral_public, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + /* Noise: create and set ephemeral private+public */ + crypto_new_keypair(c->rng, noise_handshake->ephemeral_public, noise_handshake->ephemeral_private); /* e */ - memcpy(packet + 1, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake->hash, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(packet + 1, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: remove from production code // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; @@ -576,7 +575,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private_key, noise_handshake->remote_static); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); /* s */ /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ @@ -648,13 +647,12 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u => 161 bytes in total */ else { - /* set ephemeral private+public */ - memcpy(noise_handshake->ephemeral_private, ephemeral_private_key, CRYPTO_SECRET_KEY_SIZE); - memcpy(noise_handshake->ephemeral_public, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + /* Noise: create and set ephemeral private+public */ + crypto_new_keypair(c->rng, noise_handshake->ephemeral_public, noise_handshake->ephemeral_private); /* e */ - memcpy(packet + 1, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); - noise_mix_hash(noise_handshake->hash, ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); + memcpy(packet + 1, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); + noise_mix_hash(noise_handshake->hash, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); //TODO: Remove // char log_ck[CRYPTO_SHA512_SIZE*2+1]; @@ -663,7 +661,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u /* ee */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; - noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, ephemeral_private_key, noise_handshake->remote_ephemeral); + noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); //TODO: Remove // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; @@ -1928,11 +1926,10 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c return -1; } - LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); - /* Noise-based handshake */ if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "NoiseIK handshake"); + LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; @@ -2293,11 +2290,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* necessary for compatiblity to non-Noise */ if (length == HANDSHAKE_PACKET_LENGTH && c->noise_compatibility_enabled) { - /* non-Noise: noise_handshake not necessary anymore => memzero and free */ - crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); - mem_delete(c->mem, conn->noise_handshake); - conn->noise_handshake = nullptr; + if (conn->noise_handshake != nullptr) { + /* non-Noise: noise_handshake not necessary anymore => memzero and free */ + crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + mem_delete(c->mem, conn->noise_handshake); + conn->noise_handshake = nullptr; + } + conn->noise_handshake_enabled = false; + /* Ephemeral key pair needed in non-Noise handshake */ + crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); /* Random nonce needed in non-Noise handshake */ random_nonce(c->rng, conn->send_nonce); } @@ -2349,6 +2351,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary => TODO: need info in conn or noise_handshake //TODO: Or add new connection state? /* Case where RESPONDER with and without change from INITIATOR */ + //TODO: I think this cannot happen else { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); @@ -2922,11 +2925,6 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //NOT possible here, need content afterwards! // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); - //TODO: only necessary if NoiseIK handshake finished - memset(conn->send_nonce, 0, CRYPTO_NONCE_SIZE); - //TODO: why did I move that here? - crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); - /* IMPORTANT: in this case here/before create_send_handshake(), otherwise get_crypto_connection() in create_send_handshake() returns a nullptr */ conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -2937,6 +2935,9 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } + /* NoiseIK handshake finished */ + memset(conn->send_nonce, 0, CRYPTO_NONCE_SIZE); + memset(conn->recv_nonce, 0, CRYPTO_NONCE_SIZE); /* Noise Split(), base nonces already set */ crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); @@ -3027,11 +3028,12 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u conn->connection_number_tcp = connection_number_tcp; /* Necessary for backwards compatibility to switch to non-Noise handshake */ memcpy(conn->peer_id_public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE); - /* Base nonce is a counter in transport phase after Noise-based handshake */ - //TODO: only necessary if handshake finished + + /* Base nonces are a counter in transport phase after NoiseIK handshake */ + /* Only necessary after handshake is finished, but would need to set in multiple different places */ memset(conn->send_nonce, 0, CRYPTO_NONCE_SIZE); - //TODO: move to create_send_handshake? - crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); + memset(conn->recv_nonce, 0, CRYPTO_NONCE_SIZE); + conn->status = CRYPTO_CONN_COOKIE_REQUESTING; conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE; From 5f0553391945abf045abb81996c483f8bf06adf0 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 1 Feb 2025 12:39:09 +0100 Subject: [PATCH 135/150] cleanup: moved crypto_memzero() out of noise_handshake_init() to cases where it's actually necessary. --- toxcore/crypto_core.c | 3 --- toxcore/net_crypto.c | 59 ++++++++++++++++++++----------------------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 7e4c44240b..b989096383 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -1069,9 +1069,6 @@ int noise_handshake_init // LOGGER_DEBUG(log, "ENTERING"); // } - //TODO(goldroom): move to handle_packet_crypto_hs()? - crypto_memzero(noise_handshake, sizeof(Noise_Handshake)); - /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ uint8_t temp_hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]; diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index bffa606ba9..7be1507867 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2045,7 +2045,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const int len = handle_data_packet(c, crypt_connection_id, data, packet, length); if (len <= (int)(sizeof(uint32_t) * 2)) { - LOGGER_DEBUG(c->log, "connection_kill() because data packet decryption failure, crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "connection_kill() -> data packet decryption failure in crypt_connection_id: %d", crypt_connection_id); //TODO(goldroom): unwanted side effects? leave here? connection_kill(c, crypt_connection_id, userdata); return -1; @@ -2100,7 +2100,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const clear_temp_packet(c, crypt_connection_id); conn->status = CRYPTO_CONN_ESTABLISHED; - LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); + LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED->crypt_connection_id: %d", crypt_connection_id); /* Noise: noise_handshake not necessary anymore => memzero and free */ if (conn->noise_handshake != nullptr) { @@ -2271,17 +2271,21 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet[0], conn->status); - //TODO: what if I remove CRYPTO_CONN_NOT_CONFIRMED from here? => doesn't work together with connection_kill() after decrypting failure (after new handshake) - if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING + if (conn->noise_handshake != nullptr) { + //TODO(goldroom): removed CRYPTO_CONN_NOT_CONFIRMED -> test for possible side effects + if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING + && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { + LOGGER_DEBUG(c->log, "NoiseIK: already handled handshake packet"); + return -1; + } + } else { + if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT && conn->status != CRYPTO_CONN_NOT_CONFIRMED) { - return -1; + return -1; + } } - //TODO: unwanted side effects? => yes, see above - // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING - // && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - // return -1; - // } + /* necessary for Noise and non-Noise */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -2306,28 +2310,24 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake_enabled) { LOGGER_DEBUG(c->log, "Noise handshake"); - if (conn->noise_handshake == nullptr) { + if (conn->noise_handshake == nullptr) { //TODO(goldroom): Is this check necessary? return -1; } if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); - //TODO(goldroom): fails if peer receives two handshake packets.. check for send_key/recv_key? - //TODO(goldroom): Update 28.01.2025 not sure if that is still a problem, not happening in auto_tox_many_test if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, nullptr, packet, length, nullptr, conn->noise_handshake)) { return -1; } - } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - /* At least in auto tests this only happens for UDP connections */ + } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { /* At least in auto tests this only happens for UDP connections */ LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); + crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); if (noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } - /* Noise: peer_id_public_key (=conn->peer_id_public_key) not necessary for NoiseIK, but for call in handle_new_connection_handshake() - -> otherwise not working (call via friend_connection.c) */ - //TODO: is this true in this case? => Removed from here, check if tests fail + /* Noise: peer_id_public_key (=conn->peer_id_public_key) not necessary for NoiseIK */ if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; @@ -2342,7 +2342,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } - //TODO: here? + conn->status = CRYPTO_CONN_HANDSHAKE_SENT; } else { return -1; @@ -2356,12 +2356,11 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change; also necessary without change */ + crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); if (noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } - /* Noise: peer_real_pk (=conn->public_key) not necessary here, but for call in handle_new_connection_handshake() - -> otherwise not working (call via friend_connection.c) */ - //TODO: is this true in this case? => Removed from here, check if tests fail + /* Noise: peer_real_pk (=conn->public_key) not necessary here */ if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { return -1; @@ -2746,7 +2745,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { - //TODO: adapt static allocation? + //TODO(goldroom): adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(n_c.noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); @@ -2793,9 +2792,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.peer_id_public_key); //TODO: This is only called if new_crypto_connection() was already called in the meantime! Now Noise RESPONDER! - //TODO: Does it make sense to handle this case for NoiseIK handshake? => yes, happens in auto_tox_many_test + /* happens NoiseIK handshake (e.g. auto_tox_many_test) */ if (crypt_connection_id != -1) { - LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING"); + LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING -> crypt_connection_id: %d", crypt_connection_id); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -2806,13 +2805,11 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, connection_kill(c, crypt_connection_id, userdata); } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ LOGGER_DEBUG(c->log, "Noise handshake"); - conn->noise_handshake_enabled = true; if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { mem_delete(c->mem, n_c.peer_cookie); return -1; } - /* there is already something in conn->noise_handshake -> necessary to memzero in this case! */ - crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + /* Data from new_crypto_connection():conn->noise_handshake is overwritten here */ memcpy(conn->noise_handshake, n_c.noise_handshake, sizeof(Noise_Handshake)); crypto_connection_add_source(c, crypt_connection_id, source); @@ -2826,7 +2823,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, conn->status = CRYPTO_CONN_NOT_CONFIRMED; /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ - //TODO: remove here? crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); @@ -3010,13 +3006,14 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u crypt_connection_id = create_crypto_connection(c); //TODO: remove - LOGGER_DEBUG(c->log, "AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + // LOGGER_DEBUG(c->log, "AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { return -1; } Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; + LOGGER_DEBUG(c->log, "crypt_connection_id: %d", crypt_connection_id); const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id); @@ -3070,7 +3067,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); //TODO: remove - LOGGER_DEBUG(c->log, "INITIATOR: END"); + // LOGGER_DEBUG(c->log, "INITIATOR: END"); return crypt_connection_id; } From 54e04718286cb45431719a2288a8d00d28dfcf89 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 1 Feb 2025 20:39:51 +0100 Subject: [PATCH 136/150] chore: adapted logging. Need to test connection_kill() in L2054 and behavior of non-Noise handle_new_connection_handshake(). --- toxcore/net_crypto.c | 172 +++++++++++++++++++++++-------------------- 1 file changed, 94 insertions(+), 78 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 7be1507867..97d605020f 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -367,7 +367,7 @@ non_null() static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d", packet[0], length); if (length != COOKIE_REQUEST_LENGTH) { return -1; } @@ -394,7 +394,7 @@ static int udp_handle_cookie_request(void *object, const IP_Port *source, const const Net_Crypto *c = (const Net_Crypto *)object; //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d", packet[0], length); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; @@ -422,7 +422,7 @@ non_null() static int tcp_handle_cookie_request(const Net_Crypto *c, int connections_number, const uint8_t *packet, uint16_t length) { - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d", packet[0], length); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -446,7 +446,7 @@ non_null() static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) { - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d", packet[0], length); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t dht_public_key_temp[CRYPTO_PUBLIC_KEY_SIZE]; @@ -540,10 +540,13 @@ non_null(1, 2, 3, 8) nullable(4, 5, 6, 7, 9) static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t peer_cookie[COOKIE_LENGTH], const uint8_t send_nonce[CRYPTO_NONCE_SIZE], const uint8_t ephemeral_private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], Noise_Handshake *noise_handshake) { - LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); + //TODO: remove + // LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); /* Noise-based handshake */ if (noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "Noise Handshake"); + //TODO: remove + // LOGGER_DEBUG(c->log, "Noise Handshake"); + /* Noise INITIATOR: -> e, es, s, ss */ /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] @@ -560,7 +563,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u => 321 bytes in total */ if (noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "INITIATOR"); + LOGGER_DEBUG(c->log, "Noise: INITIATOR"); /* Noise: create and set ephemeral private+public */ crypto_new_keypair(c->rng, noise_handshake->ephemeral_public, noise_handshake->ephemeral_private); @@ -586,9 +589,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); - char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); + // char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; + // bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); /* ss */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); @@ -647,6 +650,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u => 161 bytes in total */ else { + LOGGER_DEBUG(c->log, "Noise: RESPONDER"); /* Noise: create and set ephemeral private+public */ crypto_new_keypair(c->rng, noise_handshake->ephemeral_public, noise_handshake->ephemeral_private); @@ -747,10 +751,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], uint8_t peer_cookie[COOKIE_LENGTH], const uint8_t *packet, uint16_t packet_length, const uint8_t expected_peer_id_pk[CRYPTO_PUBLIC_KEY_SIZE], Noise_Handshake *noise_handshake) { - LOGGER_DEBUG(c->log, "ENTERING"); + //TODO: remove + // LOGGER_DEBUG(c->log, "ENTERING"); /* Noise-based handshake */ if (noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "NOISE handshake => INITIATOR or RESPONDER: %d", noise_handshake->initiator); + LOGGER_DEBUG(c->log, "noise_handshake->initiator: %d", noise_handshake->initiator); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; @@ -770,10 +775,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP => 321 bytes in total */ if (!noise_handshake->initiator) { - LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); - if (packet_length != NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { - return false; - } + //TODO: remove + // LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); //TODO: remove from production code // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; @@ -853,7 +856,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); - LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); + //TODO: remove + // LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ @@ -869,11 +873,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP => 161 bytes in total */ else { - LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); - - if (packet_length != NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { - return false; - } + //TODO: remove + // LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -926,7 +927,8 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); - LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); + //TODO: remove + // LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); return true; } } @@ -1916,7 +1918,8 @@ non_null() static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { - LOGGER_DEBUG(c->log, "ENTERING"); + //TODO: remove + // LOGGER_DEBUG(c->log, "ENTERING"); const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -1928,7 +1931,6 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c /* Noise-based handshake */ if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "NoiseIK handshake"); LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); if (conn->noise_handshake->initiator) { uint8_t handshake_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR]; @@ -2029,7 +2031,8 @@ non_null(1, 3) nullable(6) static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { - LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d", packet[0]); + //TODO: remove + // LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d", packet[0]); if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) { return -1; @@ -2045,9 +2048,10 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const int len = handle_data_packet(c, crypt_connection_id, data, packet, length); if (len <= (int)(sizeof(uint32_t) * 2)) { - LOGGER_DEBUG(c->log, "connection_kill() -> data packet decryption failure in crypt_connection_id: %d", crypt_connection_id); - //TODO(goldroom): unwanted side effects? leave here? - connection_kill(c, crypt_connection_id, userdata); + LOGGER_DEBUG(c->log, "decryption failure/crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); + //TODO(goldroom): unwanted side effects? => yes, kills connection if new handshake before timeout + //TODO: maybe this was better? Connections now slower? + // connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2091,7 +2095,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const // LOGGER_DEBUG(c->log, "DATA ID after PADDING: %d", real_data[0]); if (real_data[0] == PACKET_ID_KILL) { - LOGGER_DEBUG(c->log, "KILL PACKET RECEIVED"); + LOGGER_DEBUG(c->log, "KILL PACKET RECEIVED crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); connection_kill(c, crypt_connection_id, userdata); return 0; } @@ -2100,11 +2104,12 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const clear_temp_packet(c, crypt_connection_id); conn->status = CRYPTO_CONN_ESTABLISHED; - LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED->crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); /* Noise: noise_handshake not necessary anymore => memzero and free */ if (conn->noise_handshake != nullptr) { crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + //TODO: remove? leads to nullptr in handle_new_connection_handshake()? mem_delete(c->mem, conn->noise_handshake); conn->noise_handshake = nullptr; } @@ -2206,10 +2211,8 @@ static int handle_packet_cookie_response(const Net_Crypto *c, int crypt_connecti return -1; } - LOGGER_DEBUG(c->log, "ENTERING: crypto_connection_id: %d => PACKET: %d => CRYPTO CONN STATE: %d", - crypt_connection_id, - packet[0], - conn->status); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypto_connection_id: %d/conn->status: %d", + packet[0], length, crypt_connection_id, conn->status); if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING) { return -1; @@ -2266,10 +2269,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } - LOGGER_DEBUG(c->log, "ENTERING: crypt_connection_id: %d | PACKET: %d | CRYPTO CONN STATE: %d", - crypt_connection_id, - packet[0], - conn->status); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d", + packet[0], length, crypt_connection_id, conn->status); if (conn->noise_handshake != nullptr) { //TODO(goldroom): removed CRYPTO_CONN_NOT_CONFIRMED -> test for possible side effects @@ -2300,28 +2301,28 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const mem_delete(c->mem, conn->noise_handshake); conn->noise_handshake = nullptr; } - conn->noise_handshake_enabled = false; /* Ephemeral key pair needed in non-Noise handshake */ crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); /* Random nonce needed in non-Noise handshake */ random_nonce(c->rng, conn->send_nonce); + LOGGER_DEBUG(c->log, "Switch to non-Noise handshake"); } if (conn->noise_handshake_enabled) { - LOGGER_DEBUG(c->log, "Noise handshake"); + LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); if (conn->noise_handshake == nullptr) { //TODO(goldroom): Is this check necessary? return -1; } if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { - LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); + LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> normal"); if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, nullptr, packet, length, nullptr, conn->noise_handshake)) { return -1; } } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { /* At least in auto tests this only happens for UDP connections */ - LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGED TO RESPONDER"); + LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> CHANGE TO RESPONDER"); crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); if (noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; @@ -2372,6 +2373,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: here? conn->status = CRYPTO_CONN_HANDSHAKE_SENT; } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + //TODO: Does this even happen? LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); /* cannot chagne to INITIATOR here, connection broken */ //TODO: leave here? @@ -2393,12 +2395,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const //TODO: adapt for NoiseIK, makes only sense for RESPONDER not initiator if (pk_equal(dht_public_key, conn->peer_dht_public_key)) { - - LOGGER_DEBUG(c->log, "Crypto Conn Status: %d", conn->status); - if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { - LOGGER_DEBUG(c->log, "Noise handshake: CRYPTO_CONN_NOT_CONFIRMED"); conn->status = CRYPTO_CONN_NOT_CONFIRMED; + LOGGER_DEBUG(c->log, "conn->status: set to CRYPTO_CONN_NOT_CONFIRMED (%d)", conn->status); if (conn->noise_handshake->initiator) { //TODO: remove // char ck_print[CRYPTO_SHA512_SIZE*2+1]; @@ -2458,9 +2457,8 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con } //TODO: remove from prod code - LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d | CRYPTO CONN STATE: %d", - packet[0], - conn->status); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d", + packet[0], length, crypt_connection_id, conn->status); if (conn->status != CRYPTO_CONN_NOT_CONFIRMED && conn->status != CRYPTO_CONN_ESTABLISHED) { @@ -2480,7 +2478,7 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons bool udp, void *userdata) { //TODO: remove from prod code - LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d", packet[0]); + // LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d", packet[0]); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; @@ -2551,7 +2549,7 @@ static int create_crypto_connection(Net_Crypto *c) if (c->crypto_connections[i].status == CRYPTO_CONN_FREE) { id = i; //TODO: remove - LOGGER_DEBUG(c->log, "NO realloc"); + // LOGGER_DEBUG(c->log, "NO realloc"); break; } } @@ -2562,7 +2560,7 @@ static int create_crypto_connection(Net_Crypto *c) ++c->crypto_connections_length; c->crypto_connections[id] = empty_crypto_connection; //TODO: remove - LOGGER_DEBUG(c->log, "DONE realloc"); + // LOGGER_DEBUG(c->log, "DONE realloc"); } } @@ -2616,11 +2614,13 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) return -1; } - LOGGER_DEBUG(c->log, "valid id provided, free()'ing"); + //TODO: remove + // LOGGER_DEBUG(c->log, "valid id provided, free()'ing"); uint32_t i; - /* Noise: necessary for backwards compatibility and because after CRYPTO_CONN_ESTABLISHED noise_handshake is already memzeroed/freed */ + /* NoiseIK: necessary for backwards compatibility and because after CRYPTO_CONN_ESTABLISHED noise_handshake is already memzeroed/freed */ + //TODO(goldroom): refactor if backwards compatiblity removed if (c->crypto_connections[crypt_connection_id].noise_handshake != nullptr) { crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].noise_handshake); @@ -2729,7 +2729,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, void *userdata) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + // LOGGER_DEBUG(c->log, "ENTERING"); uint8_t *cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH); @@ -2755,7 +2755,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } //TODO: remove - LOGGER_DEBUG(c->log, "RESPONDER: After Handshake init"); + LOGGER_DEBUG(c->log, "Noise RESPONDER: After Handshake init"); /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? @@ -2804,7 +2804,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!pk_equal(n_c.peer_dht_public_key, conn->peer_dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ - LOGGER_DEBUG(c->log, "Noise handshake"); + //TODO: remove + // LOGGER_DEBUG(c->log, "Noise handshake"); if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { mem_delete(c->mem, n_c.peer_cookie); return -1; @@ -2825,7 +2826,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); //TODO: remove - LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); + LOGGER_DEBUG(c->log, "Noise RESPONDER crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; @@ -2837,10 +2838,24 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, else { LOGGER_DEBUG(c->log, "non-Noise handshake"); conn->noise_handshake_enabled = false; - if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - mem_delete(c->mem, n_c.peer_cookie); - return -1; - } + //TODO: need to do the same here as in handle_crypto_hs() to switch? otherwise still think this is a Noise connection? (toxic_01022025_4.log) + //TODO: not sure if that fixed something, connections taking way longer now in toxic + // if (conn->noise_handshake != nullptr) { + // /* non-Noise: noise_handshake not necessary anymore => memzero and free */ + // crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + // mem_delete(c->mem, conn->noise_handshake); + // conn->noise_handshake = nullptr; + // } + // conn->noise_handshake_enabled = false; + // /* Ephemeral key pair needed in non-Noise handshake */ + // crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); + // /* Random nonce needed in non-Noise handshake */ + // random_nonce(c->rng, conn->send_nonce); + // LOGGER_DEBUG(c->log, "Switch to non-Noise handshake"); + // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { + // mem_delete(c->mem, n_c.peer_cookie); + // return -1; + // } memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peer_ephemeral_public_key, n_c.peer_ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2875,7 +2890,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + // LOGGER_DEBUG(c->log, "ENTERING"); if (getcryptconnection_id(c, n_c->peer_id_public_key) != -1) { //TODO: remove @@ -2887,7 +2902,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: remove //TODO: Print pub key of peer? - LOGGER_DEBUG(c->log, "RESPONDER: AFTER: create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "RESPONDER: AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { LOGGER_ERROR(c->log, "Could not create new crypto connection"); @@ -2915,7 +2930,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) if (!n_c->noise_handshake->initiator) { conn->noise_handshake_enabled = true; //TODO: remove - LOGGER_DEBUG(c->log, "Responder: Noise handshake -> Noise WriteMessage"); + LOGGER_DEBUG(c->log, "Responder: Noise WriteMessage"); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(Noise_Handshake)); //NOT possible here, need content afterwards! @@ -2938,7 +2953,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); //TODO: remove - LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); + LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()/conn->status: %d", conn->status); //TODO: here correct? crypto_memzero(n_c->noise_handshake, sizeof(Noise_Handshake)); } else { @@ -2993,7 +3008,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + // LOGGER_DEBUG(c->log, "ENTERING"); int crypt_connection_id = getcryptconnection_id(c, real_public_key); @@ -3108,9 +3123,6 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ { Net_Crypto *c = (Net_Crypto *)object; - //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", packet[0]); - if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; } @@ -3121,6 +3133,10 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ return -1; } + //TODO: remove + LOGGER_DEBUG(c->log, "Packet ID: %d/length: %d/crypt_connection_id: %d/conn->status: %d", + packet[0], length, crypt_connection_id, conn->status); + if (packet[0] == NET_PACKET_COOKIE_REQUEST) { return tcp_handle_cookie_request(c, conn->connection_number_tcp, packet, length); } @@ -3142,7 +3158,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in Net_Crypto *c = (Net_Crypto *)object; //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", packet[0]); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d", packet[0], length); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; @@ -3330,7 +3346,7 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + // LOGGER_DEBUG(c->log, "ENTERING"); if (conn == nullptr) { return -1; @@ -3357,7 +3373,7 @@ int connection_lossy_data_handler(const Net_Crypto *c, int crypt_connection_id, Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + // LOGGER_DEBUG(c->log, "ENTERING"); if (conn == nullptr) { return -1; @@ -3423,15 +3439,15 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t { Net_Crypto *c = (Net_Crypto *)object; - //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING => PACKET: %d", packet[0]); - if (length <= CRYPTO_MIN_PACKET_SIZE || length > MAX_CRYPTO_PACKET_SIZE) { return 1; } const int crypt_connection_id = crypto_id_ip_port(c, source); + //TODO: remove + LOGGER_DEBUG(c->log, "Packet ID: %d/length: %d/crypt_connection_id: %d", packet[0], length, crypt_connection_id); + /* No crypto connection yet = RESPONDER case */ if (crypt_connection_id == -1) { if (packet[0] != NET_PACKET_CRYPTO_HS) { @@ -3898,7 +3914,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "ENTERING: crypto conn: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "crypt_connection_id: %d", crypt_connection_id); int ret = -1; From 387835c8f70eb8577c93a893065a43133f3e3c3a Mon Sep 17 00:00:00 2001 From: goldroom Date: Fri, 7 Feb 2025 19:43:17 +0100 Subject: [PATCH 137/150] fix: fixed issues in real-world backwards-compatible handshake behavior. --- toxcore/net_crypto.c | 61 +++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 97d605020f..1ca07d76d8 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2110,8 +2110,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake != nullptr) { crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); //TODO: remove? leads to nullptr in handle_new_connection_handshake()? - mem_delete(c->mem, conn->noise_handshake); - conn->noise_handshake = nullptr; + // mem_delete(c->mem, conn->noise_handshake); + // conn->noise_handshake = nullptr; } /* also crypto_memzero() non-Noise values from crypto connection */ @@ -2211,7 +2211,7 @@ static int handle_packet_cookie_response(const Net_Crypto *c, int crypt_connecti return -1; } - LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypto_connection_id: %d/conn->status: %d", + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d", packet[0], length, crypt_connection_id, conn->status); if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING) { @@ -2294,7 +2294,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t cookie[COOKIE_LENGTH]; /* necessary for compatiblity to non-Noise */ - if (length == HANDSHAKE_PACKET_LENGTH && c->noise_compatibility_enabled) { + //TODO: check for conn->noise_handshake_enabled => to not switch again after handle_new_connection_handshake() + if (length == HANDSHAKE_PACKET_LENGTH && c->noise_compatibility_enabled && conn->noise_handshake_enabled) { if (conn->noise_handshake != nullptr) { /* non-Noise: noise_handshake not necessary anymore => memzero and free */ crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); @@ -2785,6 +2786,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // char log_spub[CRYPTO_PUBLIC_KEY_SIZE*2+1]; // bytes2string(log_spub, sizeof(log_spub), n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "RESPONDER: session pub: %s", log_spub); + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), n_c.peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, ": peer_id_public_key: %s", log_id_public); // char log_cookie[COOKIE_LENGTH*2+1]; // bytes2string(log_cookie, sizeof(log_cookie), n_c.cookie, COOKIE_LENGTH, c->log); // LOGGER_DEBUG(c->log, "RESPONDER: cookie: %s", log_cookie); @@ -2792,6 +2796,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.peer_id_public_key); //TODO: This is only called if new_crypto_connection() was already called in the meantime! Now Noise RESPONDER! + //TODO: why is this called twice in row via tcp_oob_callback() ?! /* happens NoiseIK handshake (e.g. auto_tox_many_test) */ if (crypt_connection_id != -1) { LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING -> crypt_connection_id: %d", crypt_connection_id); @@ -2838,29 +2843,34 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, else { LOGGER_DEBUG(c->log, "non-Noise handshake"); conn->noise_handshake_enabled = false; + //TODO: need to do the same here as in handle_crypto_hs() to switch? otherwise still think this is a Noise connection? (toxic_01022025_4.log) //TODO: not sure if that fixed something, connections taking way longer now in toxic - // if (conn->noise_handshake != nullptr) { - // /* non-Noise: noise_handshake not necessary anymore => memzero and free */ - // crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); - // mem_delete(c->mem, conn->noise_handshake); - // conn->noise_handshake = nullptr; - // } - // conn->noise_handshake_enabled = false; - // /* Ephemeral key pair needed in non-Noise handshake */ - // crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); - // /* Random nonce needed in non-Noise handshake */ - // random_nonce(c->rng, conn->send_nonce); - // LOGGER_DEBUG(c->log, "Switch to non-Noise handshake"); - // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - // mem_delete(c->mem, n_c.peer_cookie); - // return -1; - // } + if (conn->noise_handshake != nullptr) { + /* non-Noise: noise_handshake not necessary anymore => memzero and free */ + crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); + mem_delete(c->mem, conn->noise_handshake); + conn->noise_handshake = nullptr; + } + + uint8_t zeros[CRYPTO_PUBLIC_KEY_SIZE]; + memset(zeros, 0, CRYPTO_PUBLIC_KEY_SIZE); + /* Need to check here, values overwritten if handle_new_connection_handshake() is called twice (happened in tests) */ + if (memcmp(conn->ephemeral_public_key, zeros, CRYPTO_PUBLIC_KEY_SIZE) == 0 + && memcmp(conn->ephemeral_secret_key, zeros, CRYPTO_SECRET_KEY_SIZE) == 0 + && memcmp(conn->send_nonce, zeros, CRYPTO_NONCE_SIZE) == 0) { + /* Ephemeral key pair needed in non-Noise handshake */ + crypto_new_keypair(c->rng, conn->ephemeral_public_key, conn->ephemeral_secret_key); + /* Random nonce needed in non-Noise handshake */ + random_nonce(c->rng, conn->send_nonce); + LOGGER_DEBUG(c->log, "Switch to non-Noise handshake"); + } memcpy(conn->recv_nonce, n_c.recv_nonce, CRYPTO_NONCE_SIZE); memcpy(conn->peer_ephemeral_public_key, n_c.peer_ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); encrypt_precompute(conn->peer_ephemeral_public_key, conn->ephemeral_secret_key, conn->shared_key); + crypto_connection_add_source(c, crypt_connection_id, source); if (create_send_handshake(c, crypt_connection_id, n_c.peer_cookie, n_c.peer_dht_public_key) != 0) { @@ -2925,6 +2935,10 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->connection_number_tcp = connection_number_tcp; + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), n_c->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "peer_id_public_key: %s", log_id_public); + // NoiseIK: only happening for RESPONDER if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { @@ -3040,6 +3054,10 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u conn->connection_number_tcp = connection_number_tcp; /* Necessary for backwards compatibility to switch to non-Noise handshake */ memcpy(conn->peer_id_public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE); + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + LOGGER_DEBUG(c->log, "peer_id_public_key: %s", log_id_public); + /* Base nonces are a counter in transport phase after NoiseIK handshake */ /* Only necessary after handshake is finished, but would need to set in multiple different places */ @@ -3055,6 +3073,9 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u /* Necessary for backwards compatibility to switch to non-Noise handshake (only if enabled with option noise_compatibility_enabled) */ conn->noise_handshake_enabled = true; + /* Need to set for check in handle_new_connection_handshake() */ + memset(conn->ephemeral_public_key, 0, CRYPTO_PUBLIC_KEY_SIZE); + memset(conn->ephemeral_secret_key, 0, CRYPTO_SECRET_KEY_SIZE); /* TODO(goldroom): Noise: only necessary if Cookie response was successful, but moved here to avoid saving peer_id_public_key twice (to remove it a some point from struct Crypto_Connection) */ From fda81b648b16a5823511c3b6ba0b48f2b9fe2490 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 8 Feb 2025 15:47:23 +0100 Subject: [PATCH 138/150] fix: moved creation of new ephemeral key pair after noise_handshake_init() to avoid multiple calls. --- toxcore/net_crypto.c | 45 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1ca07d76d8..8ea5290e90 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -564,8 +564,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u */ if (noise_handshake->initiator) { LOGGER_DEBUG(c->log, "Noise: INITIATOR"); - /* Noise: create and set ephemeral private+public */ - crypto_new_keypair(c->rng, noise_handshake->ephemeral_public, noise_handshake->ephemeral_private); /* e */ memcpy(packet + 1, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -651,8 +649,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u */ else { LOGGER_DEBUG(c->log, "Noise: RESPONDER"); - /* Noise: create and set ephemeral private+public */ - crypto_new_keypair(c->rng, noise_handshake->ephemeral_public, noise_handshake->ephemeral_private); /* e */ memcpy(packet + 1, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -783,7 +779,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); // LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); - //TODO(goldroom): Check here if remote_ephemeral is already the same ephemeral key? + //TODO(goldroom): Check here if remote_ephemeral is already the same ephemeral key? => should not be possible to call it twice /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); @@ -845,7 +841,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP return false; } - /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ + /* Cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ memcpy(peer_cookie, handshake_payload_plain + COOKIE_LENGTH, COOKIE_LENGTH); /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c:handle_new_connections() */ if (peer_id_public_key != nullptr) { @@ -2049,9 +2045,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (len <= (int)(sizeof(uint32_t) * 2)) { LOGGER_DEBUG(c->log, "decryption failure/crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); - //TODO(goldroom): unwanted side effects? => yes, kills connection if new handshake before timeout - //TODO: maybe this was better? Connections now slower? - // connection_kill(c, crypt_connection_id, userdata); + //TODO(goldroom): unwanted side effects? + connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2109,9 +2104,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const /* Noise: noise_handshake not necessary anymore => memzero and free */ if (conn->noise_handshake != nullptr) { crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); - //TODO: remove? leads to nullptr in handle_new_connection_handshake()? - // mem_delete(c->mem, conn->noise_handshake); - // conn->noise_handshake = nullptr; + /* mem_delete(c->mem, conn->noise_handshake)/conn->noise_handshake = nullptr: + not possible here, memory possibly needed in handle_new_connection_handshake() */ } /* also crypto_memzero() non-Noise values from crypto connection */ @@ -2293,8 +2287,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* necessary for Noise RESPONDER and non-Noise */ uint8_t cookie[COOKIE_LENGTH]; - /* necessary for compatiblity to non-Noise */ - //TODO: check for conn->noise_handshake_enabled => to not switch again after handle_new_connection_handshake() + /* necessary for compatiblity to non-Noise handshake; + check for conn->noise_handshake_enabled necessary to not switch again after handle_new_connection_handshake() + and create new crypto material. */ if (length == HANDSHAKE_PACKET_LENGTH && c->noise_compatibility_enabled && conn->noise_handshake_enabled) { if (conn->noise_handshake != nullptr) { /* non-Noise: noise_handshake not necessary anymore => memzero and free */ @@ -2329,6 +2324,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } + /* Noise: create and set ephemeral private+public */ + crypto_new_keypair(c->rng, conn->noise_handshake->ephemeral_public, conn->noise_handshake->ephemeral_private); + /* Noise: peer_id_public_key (=conn->peer_id_public_key) not necessary for NoiseIK */ if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { @@ -2362,6 +2360,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (noise_handshake_init(conn->noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { return -1; } + + /* Noise: create and set ephemeral private+public */ + crypto_new_keypair(c->rng, conn->noise_handshake->ephemeral_public, conn->noise_handshake->ephemeral_private); + /* Noise: peer_real_pk (=conn->public_key) not necessary here */ if (!handle_crypto_handshake(c, nullptr, nullptr, nullptr, dht_public_key, cookie, packet, length, nullptr, conn->noise_handshake)) { @@ -2376,7 +2378,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { //TODO: Does this even happen? LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); - /* cannot chagne to INITIATOR here, connection broken */ + /* cannot change to INITIATOR here, connection broken */ //TODO: leave here? connection_kill(c, crypt_connection_id, userdata); return -1; @@ -2755,6 +2757,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } + /* Noise: create and set ephemeral private+public */ + crypto_new_keypair(c->rng, n_c.noise_handshake->ephemeral_public, n_c.noise_handshake->ephemeral_private); + //TODO: remove LOGGER_DEBUG(c->log, "Noise RESPONDER: After Handshake init"); @@ -2795,9 +2800,9 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int crypt_connection_id = getcryptconnection_id(c, n_c.peer_id_public_key); - //TODO: This is only called if new_crypto_connection() was already called in the meantime! Now Noise RESPONDER! - //TODO: why is this called twice in row via tcp_oob_callback() ?! - /* happens NoiseIK handshake (e.g. auto_tox_many_test) */ + /* This is only called if a crypto_connection already exists (e.g. new_crypto_connection() was already called)! Now Noise RESPONDER! */ + /* happens NoiseIK handshake (e.g. auto_tox_many_test) */ + //TODO(goldroom): why is this called twice in row via tcp_oob_callback()? if (crypt_connection_id != -1) { LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING -> crypt_connection_id: %d", crypt_connection_id); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -3085,6 +3090,10 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u return -1; } + /* Noise: create and set ephemeral private+public */ + crypto_new_keypair(c->rng, conn->noise_handshake->ephemeral_public, conn->noise_handshake->ephemeral_private); + + conn->cookie_request_number = random_u64(c->rng); uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; From 83674b6e8cb632cd85ac6cd2cc5e8b11b5998a0e Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 8 Feb 2025 16:50:17 +0100 Subject: [PATCH 139/150] chore: cleanup of documentation/comments --- auto_tests/crypto_test.c | 28 ++++++++-------------------- toxcore/net_crypto.c | 30 ++++++++++++------------------ 2 files changed, 20 insertions(+), 38 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 42866debcb..57f2f0e6a8 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -6,7 +6,7 @@ #include "../toxcore/crypto_core.h" #include "../toxcore/net_crypto.h" #include "check_compat.h" -//TODO: necessary to print bytes +//TODO(goldroom): necessary to print bytes // #include "../other/fun/create_common.h" static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) @@ -373,7 +373,7 @@ static void test_memzero(void) } } -//TODO: Remove if Blake2b? +//TODO(goldroom): Remove if Blake2b? // /* Noise_IK_25519_ChaChaPoly_SHA512 test vectors from here: https://github.com/rweather/noise-c/blob/cfe25410979a87391bb9ac8d4d4bef64e9f268c6/tests/vector/noise-c-basic.txt */ // /* "init_prologue": "50726f6c6f677565313233" (same as `resp_prologue`) */ // static const uint8_t prologue[11] = { @@ -523,7 +523,7 @@ static void test_memzero(void) // 0xc1, 0x4c, 0xbd, 0x4f, 0x14, 0xcc, 0xd1, 0xe1 // }; -/* TODO: Currently unused */ +/* TODO(goldroom): Currently unused */ // // 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 // static const uint8_t init_payload_transport2[17] = { // 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, @@ -686,11 +686,11 @@ static const uint8_t handshake_hash[CRYPTO_SHA512_SIZE] = { 0xf1, 0xfe, 0x5a, 0x7f, 0x0c, 0x55, 0xc0, 0x78 }; -//TODO: "payload": "4a65616e2d426170746973746520536179", -//TODO: "ciphertext": "49063084b2c51f098337cb8a13739ac848f907e67cfb2cc8a8b60586467aa02fc7" +//TODO(goldroom): "payload": "4a65616e2d426170746973746520536179", +//TODO(goldroom): "ciphertext": "49063084b2c51f098337cb8a13739ac848f907e67cfb2cc8a8b60586467aa02fc7" -//TODO: "payload": "457567656e2042f6686d20766f6e2042617765726b", -//TODO: "ciphertext": "8b9709d23b47e4639df7678d7a21741eba4ef1e9c60383001c7435549c20f9d56f30e935d3" +//TODO(goldroom): "payload": "457567656e2042f6686d20766f6e2042617765726b", +//TODO(goldroom): "ciphertext": "8b9709d23b47e4639df7678d7a21741eba4ef1e9c60383001c7435549c20f9d56f30e935d3" static void test_noiseik(void) { @@ -749,11 +749,6 @@ static void test_noiseik(void) // printf("noise_handshake_temp_key (after es): %s\n", key_print); /* s */ - //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 - /*Nonce provided as parameter is the base nonce! -> This adds nonce for static pub key encryption to packet (XChaCha20-Poly1305) */ - // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); - // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, - // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE); /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ uint8_t ciphertext1[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; @@ -768,7 +763,7 @@ static void test_noiseik(void) ck_assert_msg(memcmp(ciphertext1, init_encrypted_static_public, CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE) == 0, "initiator encrypted static public keys differ"); - //TODO: remove from production code + //TODO(goldroom): remove from production code // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); @@ -784,13 +779,6 @@ static void test_noiseik(void) // uint8_t handshake_payload_plain[15]; uint8_t ciphertext2[sizeof(init_payload_hs) + CRYPTO_MAC_SIZE]; - //TODO: remove; not necessary to due change to ChaCha20-Poly1305 instead of XChaCha20-Poly1305 - /* Add Handshake payload nonce */ - // random_nonce(c->rng, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - // noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE, - // handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, - // noise_handshake->hash, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); - /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ noise_encrypt_and_hash(ciphertext2, init_payload_hs, sizeof(init_payload_hs), noise_handshake_temp_key, diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 8ea5290e90..5f21b7d833 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2348,10 +2348,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } } - //TODO: Differentiate between change and not change? if not changed, no call to noise_handshake_init() necessary => TODO: need info in conn or noise_handshake - //TODO: Or add new connection state? /* Case where RESPONDER with and without change from INITIATOR */ - //TODO: I think this cannot happen + //TODO(goldroom): this doesn't seem to happen, wether in auto_tests nor in real-world tests => remove? else { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); @@ -2373,13 +2371,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } - //TODO: here? + //TODO(goldroom): here? conn->status = CRYPTO_CONN_HANDSHAKE_SENT; } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { - //TODO: Does this even happen? + //TODO(goldroom): Does this even happen? LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); /* cannot change to INITIATOR here, connection broken */ - //TODO: leave here? + //TODO(goldroom): leave here? connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2396,7 +2394,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - //TODO: adapt for NoiseIK, makes only sense for RESPONDER not initiator + //TODO(goldroom): adapt for NoiseIK, makes only sense for RESPONDER not initiator? if (pk_equal(dht_public_key, conn->peer_dht_public_key)) { if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { conn->status = CRYPTO_CONN_NOT_CONFIRMED; @@ -2429,14 +2427,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* Backwards compatibility: non-Noise handshake case */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - // if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { //TODO: doesn't work if Noise handshake packet was sent before + // if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { //TODO(goldroom): doesn't work if Noise handshake packet was sent before if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } // } /* Backwards compatibility: necessary for non-Noise handshake */ encrypt_precompute(conn->peer_ephemeral_public_key, conn->ephemeral_secret_key, conn->shared_key); - //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway /* Backwards compatibility: necessary for non-Noise handshake */ conn->status = CRYPTO_CONN_NOT_CONFIRMED; } @@ -2763,8 +2760,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, //TODO: remove LOGGER_DEBUG(c->log, "Noise RESPONDER: After Handshake init"); - /* Noise: peer_real_pk (=n_c.public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ - //TODO: adapt peer_real_pk (=n_c.public_key) for Noise? + /* Noise: peer_id_public_key (=n_c.peer_id_public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ + //TODO(goldroom): adapt peer_id_public_key (=n_c.peer_id_public_key) for Noise? if (!handle_crypto_handshake(c, nullptr, nullptr, n_c.peer_id_public_key, n_c.peer_dht_public_key, n_c.peer_cookie, packet, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); @@ -2849,8 +2846,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, LOGGER_DEBUG(c->log, "non-Noise handshake"); conn->noise_handshake_enabled = false; - //TODO: need to do the same here as in handle_crypto_hs() to switch? otherwise still think this is a Noise connection? (toxic_01022025_4.log) - //TODO: not sure if that fixed something, connections taking way longer now in toxic + /* necessary for compatiblity to non-Noise handshake; */ if (conn->noise_handshake != nullptr) { /* non-Noise: noise_handshake not necessary anymore => memzero and free */ crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); @@ -3491,8 +3487,6 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t return 0; } - //TODO: return -1 if RESPONDER? - if (handle_packet_connection(c, crypt_connection_id, packet, length, true, userdata) != 0) { return 1; } @@ -3546,13 +3540,13 @@ static void send_crypto_packets(Net_Crypto *c) continue; } - //TODO: remove TODO: interesting if want to adapt interval + //TODO(goldroom): remove? interesting if want to adapt interval // LOGGER_DEBUG(c->log, "conn->handshake_send_interval: %d", conn->handshake_send_interval); // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); // LOGGER_DEBUG(c->log, "(conn->handshake_send_interval + conn->temp_packet_sent_time): %lu", (conn->handshake_send_interval + conn->temp_packet_sent_time)); // LOGGER_DEBUG(c->log, "temp_time: %lu", temp_time); - //TODO: Use again? / TODO: adapt interval? + //TODO(goldroom): Use again? / adapt interval? if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { //TODO: remove //LOGGER_DEBUG(c->log, "=> call send_temp_packet() => random_backoff: %d", random_backoff); @@ -4117,7 +4111,7 @@ void do_net_crypto(Net_Crypto *c, void *userdata) { //TODO: remove // LOGGER_DEBUG(c->log, "do_net_crypto()"); - //TODO: update cookie symmetric key every ~2 minutes (cf. WireGuard)? + //TODO(goldroom) update cookie symmetric key every ~2 minutes (cf. WireGuard)? kill_timedout(c, userdata); do_tcp(c, userdata); send_crypto_packets(c); From 7f12a5428fe951e5157f659914742c56c6ec51d3 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 8 Feb 2025 16:56:18 +0100 Subject: [PATCH 140/150] chore: removed unused SHA512 functions --- toxcore/crypto_core.c | 150 ------------------------------------------ toxcore/crypto_core.h | 24 +------ 2 files changed, 1 insertion(+), 173 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index b989096383..401850ee27 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -643,30 +643,9 @@ int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_ // bytes_to_string(bytes, bytes_length, string, string_length); // } -// #define NOISE_PROTOCOL_NAME "Noise_IK_25519_ChaChaPoly_SHA512" -/* Actually only 32 bytes necessary (but terminator necessary for CI), but test vectors still verify with 33 bytes */ -//TODO(goldroom): Remove if Blake2b -// static const uint8_t noise_protocol[33] = "Noise_IK_25519_ChaChaPoly_SHA512"; /* Actually only 33 bytes necessary (but terminator necessary for CI), but test vectors still verify with 34 bytes */ static const uint8_t noise_protocol[34] = "Noise_IK_25519_ChaChaPoly_BLAKE2b"; -//TODO(goldroom): remove, unused function -/** - * cf. Noise sections 4.3 and 5.1 - * Applies HMAC from RFC2104 (https://www.ietf.org/rfc/rfc2104.txt) using the HASH() (=SHA512) function. - * This function is only called via `crypto_hkdf()`. - * HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of - * `crypto_hmac*()` in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of - * of 32 bytes (SHA512-256 HASHLEN). Cf. https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512 - * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) - * is always HASHLEN bytes. - */ -// void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, -// size_t data_length) -// { -// crypto_auth_hmacsha512(auth, data, data_length, key); -// } - /** * cf. Noise sections 4.3, 5.1 and 12.8: HMAC-BLAKE2b-512 * HASH(input): BLAKE2b with digest length 64 @@ -758,79 +737,6 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t crypto_memzero(i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); } -//TODO(goldroom): remove if Blake2b -/* This is Hugo Krawczyk's HKDF (i.e. HKDF-SHA512): - * - https://eprint.iacr.org/2010/264.pdf - * - https://tools.ietf.org/html/rfc5869 - * HKDF(chaining_key, input_key_material, num_outputs): Takes a - * chaining_key byte sequence of length HASHLEN, and an input_key_material - * byte sequence with length either zero bytes, 32 bytes, or DHLEN bytes. - * Returns a pair or triple of byte sequences each of length HASHLEN, - * depending on whether num_outputs is two or three: - * – Sets temp_key = HMAC-HASH(chaining_key, input_key_material). - * – Sets output1 = HMAC-HASH(temp_key, byte(0x01)). - * – Sets output2 = HMAC-HASH(temp_key, output1 || byte(0x02)). - * – If num_outputs == 2 then returns the pair (output1, output2). - * – Sets output3 = HMAC-HASH(temp_key, output2 || byte(0x03)). - * – Returns the triple (output1, output2, output3). - * Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in - * length. Also note that the HKDF() function is simply HKDF with the - * chaining_key as HKDF salt, and zero-length HKDF info. - */ -// void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, -// size_t second_len, const uint8_t *data, -// size_t data_len, const uint8_t chaining_key[CRYPTO_SHA512_SIZE]) -// { -// /* Implementing HKDF-SHA512 based on libsodium `crypto_auth_hmacsha512()` and WireGuard leads to wrong results. -// Verified using Noise_IK_25519_ChaChaPoly_SHA512 test vectors. Keeping for documentation purposes. */ -// // uint8_t output[CRYPTO_SHA512_SIZE + 1]; -// // temp_key = secret in WG -// uint8_t temp_key[CRYPTO_SHA512_SIZE]; - -// /* Extract entropy from data into temp_key */ -// /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). -// Result is a pseudo random key (PRK) = temp_key */ -// /* data => input_key_material => X25519-DH result in Noise */ -// /* TODO: This is correct, same result as libsodium `crypto_kdf_hkdf_sha512_extract()` */ -// // crypto_hmac512(temp_key, chaining_key, data, data_len); -// /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. -// Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ -// crypto_kdf_hkdf_sha512_extract(temp_key, chaining_key, CRYPTO_SHA512_SIZE, data, data_len); - -// /* Expand first key: key = temp_key, data = 0x1 */ -// /* TODO: Result not correct, unsure why */ -// // output[0] = 1; -// // crypto_hmac512(output, temp_key, output, 1); -// // memcpy(output1, output, first_len); - -// /* Expand both keys in one operation (verified): */ -// /* HKDF-Expand(PRK, info, L) -> OKM, where PRK = temp_key, zero-length HKDF info (ctx) -// and L (length of output keying material in octets) = 2*64 byte (i.e. 2x HashLen) */ -// /* OKM = HKDF -> T(0) + T(1); cf. RFC5869: https://datatracker.ietf.org/doc/html/rfc5869#section-2.3 */ -// /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ -// uint8_t output_temp[CRYPTO_SHA512_SIZE*2]; -// crypto_kdf_hkdf_sha512_expand(output_temp, CRYPTO_SHA512_SIZE*2, nullptr, 0, temp_key); -// memcpy(output1, output_temp, first_len); -// memcpy(output2, output_temp + CRYPTO_SHA512_SIZE, second_len); - -// /* Expand second key: key = secret, data = first-key || 0x2 */ -// /* TODO: Not correct, unsure why */ -// // output[CRYPTO_SHA512_SIZE] = 2; -// // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); -// // memcpy(output2, output, second_len); - -// /* Expand third key: key = temp_key, data = second-key || 0x3 */ -// /* Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ -// // output[CRYPTO_SHA512_SIZE] = 3; -// // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); -// // memcpy(output3, output, third_len); - -// /* Clear sensitive data from stack */ -// crypto_memzero(temp_key, CRYPTO_SHA512_SIZE); -// // crypto_memzero(output, CRYPTO_SHA512_SIZE + 1); -// crypto_memzero(output_temp, CRYPTO_SHA512_SIZE*2); -// } - /* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b-512): * - https://eprint.iacr.org/2010/264.pdf * - https://tools.ietf.org/html/rfc5869 @@ -898,39 +804,6 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, crypto_memzero(output, CRYPTO_NOISE_BLAKE2b_HASH_SIZE + 1); } -/* - * cf. Noise section 5.2 - * Executes the following steps: - * - Sets ck, temp_k = HKDF(ck, input_key_material, 2). - * - If HASHLEN is 64, then truncates temp_k to 32 bytes - * - Calls InitializeKey(temp_k). - * input_key_material = DH_X25519(private, public) - * - * based on HKDF-SHA512 - */ -// int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_SHA512_SIZE], -// uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], -// const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], -// const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) -// { -// uint8_t dh_calculation[CRYPTO_SHARED_KEY_SIZE]; -// memset(dh_calculation, 0, CRYPTO_SHARED_KEY_SIZE); - -// /* X25519: returns plain DH result, afterwards hashed with HKDF (necessary for NoiseIK) */ -// if (crypto_scalarmult_curve25519(dh_calculation, private_key, public_key) != 0) { -// return -1; -// } - -// /* chaining_key is HKDF output1 and shared_key is HKDF output2 => different values/results! */ -// /* If HASHLEN is 64, then truncates temp_k (= shared_key) to 32 bytes. => done via call to crypto_hkdf() */ -// crypto_hkdf(chaining_key, CRYPTO_SHA512_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, -// CRYPTO_SHARED_KEY_SIZE, chaining_key); - -// crypto_memzero(dh_calculation, CRYPTO_SHARED_KEY_SIZE); - -// return 0; -// } - /* * cf. Noise section 5.2: based on HKDF-BLAKE2b * Executes the following steps: @@ -963,29 +836,6 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE], return 0; } -///TODO(goldroom): remove unused function -/* - * Noise MixHash(data): Sets h = HASH(h || data). - * SHA512 - * - * cf. Noise section 5.2 - */ -// void noise_mix_hash(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t data_len) -// { -// VLA(uint8_t, to_hash, CRYPTO_SHA512_SIZE + data_len); -// memcpy(to_hash, hash, CRYPTO_SHA512_SIZE); -// if (data != nullptr) { -// memcpy(to_hash + CRYPTO_SHA512_SIZE, data, data_len); -// } -// // crypto_sha512(hash, to_hash, CRYPTO_SHA512_SIZE + data_len); - -// crypto_generichash_blake2b_state state; -// crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_BLAKE2b_HASH_SIZE); -// crypto_generichash_blake2b_update(&state, hash, CRYPTO_BLAKE2b_HASH_SIZE); -// crypto_generichash_blake2b_update(&state, data, data_len); -// crypto_generichash_blake2b_final(&state, hash, CRYPTO_BLAKE2b_HASH_SIZE); -// } - /* * Noise MixHash(data): Sets h = HASH(h || data). * Blake2b diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 3041c2dabb..4aada3c612 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -600,26 +600,6 @@ non_null(1, 2, 3, 5) nullable(6) int32_t decrypt_data_symmetric_xaead(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t encrypted_length, uint8_t *plain, const uint8_t *ad, size_t ad_length); -//TODO(goldroom): remove, unused function -/** - * @brief Compute an HMAC-SHA512 authenticator (64 bytes). - * - * cf. Noise sections 4.3 and 5.1 - * Applies HMAC from RFC2104 (https://tools.ietf.org/html/rfc2104) using the HASH() (=SHA512) function. - * This function is only called via `crypto_hkdf()`. - * HMAC-SHA-512 instead of HMAC-SHA512-256 as used by `crypto_auth_*()` (libsodium) which is underlying function of - * `crypto_hmac*() in crypto_core. Necessary for Noise (cf. section 4.3) to return 64 bytes (SHA512 HASHLEN) instead of - * of 32 bytes (SHA512-256 HASHLEN). Cf. https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512 - * key is CRYPTO_SHA512_SIZE bytes because this function is only called via crypto_hkdf() where the key (ck, temp_key) - * is always HASHLEN bytes. - * - * @param auth Resulting authenticator. - * @param key Secret key - */ -non_null(1, 2) nullable(3) -void crypto_hmac512(uint8_t *auth, const uint8_t key[CRYPTO_SHA512_SIZE], const uint8_t *data, - size_t data_length); - /** * @brief Computes the number of provides outputs (=keys) with HKDF-SHA512. * @@ -679,9 +659,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, non_null(1, 2) nullable(3, 5) int noise_handshake_init (Noise_Handshake *noise_handshake, const uint8_t self_id_secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], bool initiator, const uint8_t *prologue, size_t prologue_length); -//TODO: remove -// int noise_handshake_init -// (const Logger *log, Noise_Handshake *noise_handshake, const uint8_t *self_secret_key, const uint8_t *peer_public_key, bool initiator, const uint8_t *prologue, size_t prologue_length); + /** * @brief Noise MixKey(input_key_material) * From 0011691b3e91a81d77ff625cf9fd0f115b65cad7 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 8 Feb 2025 17:16:56 +0100 Subject: [PATCH 141/150] fix: changed constant names to all upper case --- toxcore/crypto_core.c | 82 +++++++++++++++++++++---------------------- toxcore/crypto_core.h | 4 +-- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 401850ee27..8f159cd83d 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -48,7 +48,7 @@ static_assert(CRYPTO_SIGN_SECRET_KEY_SIZE == crypto_sign_SECRETKEYBYTES, "CRYPTO_SIGN_SECRET_KEY_SIZE should be equal to crypto_sign_SECRETKEYBYTES"); /* CRYPTO_BLAKE2b_HASH_SIZE -> crypto_generichash_blake2b_BYTES_MAX (libsodium) */ -static_assert(CRYPTO_NOISE_BLAKE2b_HASH_SIZE == crypto_generichash_blake2b_BYTES_MAX, +static_assert(CRYPTO_NOISE_BLAKE2B_HASH_SIZE == crypto_generichash_blake2b_BYTES_MAX, "CRYPTO_BLAKE2b_HASH_SIZE should be equal to crypto_generichash_blake2b_BYTES_MAX"); /* CRYPTO_BLAKE2b_BLOCK_SIZE -> BLAKE2B_BLOCKBYTES (not exposed by libsodium) */ @@ -669,8 +669,8 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t * B = Blake2b block length = 128 * L the byte-length of Blake2b hash output = 64 */ - uint8_t x_key[CRYPTO_BLAKE2b_BLOCK_SIZE] = { 0 }; - uint8_t i_hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]; + uint8_t x_key[CRYPTO_BLAKE2B_BLOCK_SIZE] = { 0 }; + uint8_t i_hash[CRYPTO_NOISE_BLAKE2B_HASH_SIZE]; int i; /* @@ -681,10 +681,10 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t * In any case the minimal recommended length for K is L bytes (as the hash output * length). */ - if (key_length > CRYPTO_BLAKE2b_BLOCK_SIZE) { - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + if (key_length > CRYPTO_BLAKE2B_BLOCK_SIZE) { + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); crypto_generichash_blake2b_update(&state, key, key_length); - crypto_generichash_blake2b_final(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); + crypto_generichash_blake2b_final(&state, x_key, CRYPTO_BLAKE2B_BLOCK_SIZE); } else { memcpy(x_key, key, key_length); } @@ -694,7 +694,7 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t * (2) XOR (bitwise exclusive-OR) the B byte string computed in step * (1) with ipad */ - for (i = 0; i < CRYPTO_BLAKE2b_BLOCK_SIZE; ++i) { + for (i = 0; i < CRYPTO_BLAKE2B_BLOCK_SIZE; ++i) { x_key[i] ^= 0x36; } @@ -704,17 +704,17 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t from step (2) (4) apply H to the stream generated in step (3) */ - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); - crypto_generichash_blake2b_update(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); + crypto_generichash_blake2b_update(&state, x_key, CRYPTO_BLAKE2B_BLOCK_SIZE); crypto_generichash_blake2b_update(&state, in, in_length); - crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); /* * K XOR opad, opad = the byte 0x5C repeated B times * (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad */ - for (i = 0; i < CRYPTO_BLAKE2b_BLOCK_SIZE; ++i) { + for (i = 0; i < CRYPTO_BLAKE2B_BLOCK_SIZE; ++i) { x_key[i] ^= 0x5c ^ 0x36; } @@ -725,16 +725,16 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t (7) apply H to the stream generated in step (6) and output the result */ - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); - crypto_generichash_blake2b_update(&state, x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); - crypto_generichash_blake2b_update(&state, i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); - crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); + crypto_generichash_blake2b_update(&state, x_key, CRYPTO_BLAKE2B_BLOCK_SIZE); + crypto_generichash_blake2b_update(&state, i_hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); + crypto_generichash_blake2b_final(&state, i_hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); - memcpy(out_hmac, i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + memcpy(out_hmac, i_hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); /* Clear sensitive data from stack */ - crypto_memzero(x_key, CRYPTO_BLAKE2b_BLOCK_SIZE); - crypto_memzero(i_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_memzero(x_key, CRYPTO_BLAKE2B_BLOCK_SIZE); + crypto_memzero(i_hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); } /* This is Hugo Krawczyk's HKDF (i.e. HKDF-BLAKE2b-512): @@ -763,23 +763,23 @@ static void crypto_hmac_blake2b_512(uint8_t *out_hmac, const uint8_t *in, size_t */ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, size_t second_len, const uint8_t *data, - size_t data_len, const uint8_t chaining_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]) + size_t data_len, const uint8_t chaining_key[CRYPTO_NOISE_BLAKE2B_HASH_SIZE]) { - uint8_t output[CRYPTO_NOISE_BLAKE2b_HASH_SIZE + 1]; + uint8_t output[CRYPTO_NOISE_BLAKE2B_HASH_SIZE + 1]; // temp_key = secret in WG - uint8_t temp_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]; + uint8_t temp_key[CRYPTO_NOISE_BLAKE2B_HASH_SIZE]; /* Extract entropy from data into temp_key */ /* HKDF-Extract(salt, IKM) -> PRK, where chaining_key is HKDF salt, DH result (data) is input keying material (IKM) (and zero-length HKDF info in expand). Result is a pseudo random key (PRK) = temp_key */ /* data => input_key_material => X25519-DH result in Noise */ - crypto_hmac_blake2b_512(temp_key, data, data_len, chaining_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(temp_key, data, data_len, chaining_key, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); /* Noise spec: Note that temp_key, output1, output2, and output3 are all HASHLEN bytes in length. Also note that the HKDF() function is simply HKDF from [4] with the chaining_key as HKDF salt, and zero-length HKDF info. */ /* Expand first key: key = temp_key, data = 0x1 */ output[0] = 1; - crypto_hmac_blake2b_512(output, output, 1, temp_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_hmac_blake2b_512(output, output, 1, temp_key, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); memcpy(output1, output, first_len); /* Expand both keys in one operation (verified): */ @@ -789,8 +789,8 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, /* ctx parameter = RFC5869 info -> i.e. optional context and application specific information (can be a zero-length string) */ /* Expand second key: key = secret, data = first-key || 0x2 */ - output[CRYPTO_NOISE_BLAKE2b_HASH_SIZE] = 2; - crypto_hmac_blake2b_512(output, output, CRYPTO_NOISE_BLAKE2b_HASH_SIZE +1, temp_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + output[CRYPTO_NOISE_BLAKE2B_HASH_SIZE] = 2; + crypto_hmac_blake2b_512(output, output, CRYPTO_NOISE_BLAKE2B_HASH_SIZE +1, temp_key, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ @@ -800,8 +800,8 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, // memcpy(output3, output, third_len); /* Clear sensitive data from stack */ - crypto_memzero(temp_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); - crypto_memzero(output, CRYPTO_NOISE_BLAKE2b_HASH_SIZE + 1); + crypto_memzero(temp_key, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); + crypto_memzero(output, CRYPTO_NOISE_BLAKE2B_HASH_SIZE + 1); } /* @@ -813,7 +813,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, * input_key_material = DH_X25519(private, public) * */ -int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE], +int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_NOISE_BLAKE2B_HASH_SIZE], uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) @@ -828,7 +828,7 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE], /* chaining_key is HKDF output1 and shared_key is HKDF output2 => different values/results! */ /* If HASHLEN is 64, then truncates temp_k (= shared_key) to 32 bytes. => done via call to crypto_hkdf() */ - crypto_hkdf(chaining_key, CRYPTO_NOISE_BLAKE2b_HASH_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, + crypto_hkdf(chaining_key, CRYPTO_NOISE_BLAKE2B_HASH_SIZE, shared_key, CRYPTO_SHARED_KEY_SIZE, dh_calculation, CRYPTO_SHARED_KEY_SIZE, chaining_key); crypto_memzero(dh_calculation, CRYPTO_SHARED_KEY_SIZE); @@ -842,13 +842,13 @@ int32_t noise_mix_key(uint8_t chaining_key[CRYPTO_NOISE_BLAKE2b_HASH_SIZE], * * cf. Noise section 5.2 */ -void noise_mix_hash(uint8_t hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE], const uint8_t *data, size_t data_len) +void noise_mix_hash(uint8_t hash[CRYPTO_NOISE_BLAKE2B_HASH_SIZE], const uint8_t *data, size_t data_len) { crypto_generichash_blake2b_state state; - crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); - crypto_generichash_blake2b_update(&state, hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_init(&state, NULL, 0, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); + crypto_generichash_blake2b_update(&state, hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); crypto_generichash_blake2b_update(&state, data, data_len); - crypto_generichash_blake2b_final(&state, hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + crypto_generichash_blake2b_final(&state, hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); } /* @@ -858,14 +858,14 @@ void noise_mix_hash(uint8_t hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE], const uint8_t */ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, size_t plain_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]) + uint8_t hash[CRYPTO_NOISE_BLAKE2B_HASH_SIZE]) { static uint8_t nonce_chacha20_ietf[CRYPTO_NOISE_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISE_NONCE_SIZE); int32_t encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, - hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); } @@ -877,14 +877,14 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, */ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, size_t encrypted_length, uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], - uint8_t hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]) + uint8_t hash[CRYPTO_NOISE_BLAKE2B_HASH_SIZE]) { static uint8_t nonce_chacha20_ietf[CRYPTO_NOISE_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISE_NONCE_SIZE); int32_t plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, - hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); noise_mix_hash(hash, ciphertext, encrypted_length); @@ -921,11 +921,11 @@ int noise_handshake_init /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ - uint8_t temp_hash[CRYPTO_NOISE_BLAKE2b_HASH_SIZE]; - memset(temp_hash, 0, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + uint8_t temp_hash[CRYPTO_NOISE_BLAKE2B_HASH_SIZE]; + memset(temp_hash, 0, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); memcpy(temp_hash, noise_protocol, sizeof(noise_protocol)); - memcpy(noise_handshake->hash, temp_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); - memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_NOISE_BLAKE2b_HASH_SIZE); + memcpy(noise_handshake->hash, temp_hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); + memcpy(noise_handshake->chaining_key, temp_hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); /* IMPORTANT needs to be called with (empty/zero-length) prologue! */ noise_mix_hash(noise_handshake->hash, prologue, prologue_length); diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 4aada3c612..578003b124 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -86,12 +86,12 @@ extern "C" { /** * @brief The number of bytes in a BLAKE2b-512 hash (as defined for Noise in section 12.8.). */ -#define CRYPTO_NOISE_BLAKE2b_HASH_SIZE 64 +#define CRYPTO_NOISE_BLAKE2B_HASH_SIZE 64 /** * @brief The number of bytes in a BLAKE2b block. */ -#define CRYPTO_BLAKE2b_BLOCK_SIZE 128 +#define CRYPTO_BLAKE2B_BLOCK_SIZE 128 /** @brief Fill a byte array with random bytes. * From 59906f907462c4d6ab71d1a8187ee21105919a90 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 8 Feb 2025 18:33:42 +0100 Subject: [PATCH 142/150] chore: cleanup documentation and logging --- auto_tests/crypto_test.c | 285 +------------------------------- toxcore/crypto_core.c | 49 +----- toxcore/crypto_core.h | 2 +- toxcore/net_crypto.c | 343 ++++++--------------------------------- toxcore/net_crypto.h | 8 +- 5 files changed, 64 insertions(+), 623 deletions(-) diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 57f2f0e6a8..ac6c595b82 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -6,7 +6,7 @@ #include "../toxcore/crypto_core.h" #include "../toxcore/net_crypto.h" #include "check_compat.h" -//TODO(goldroom): necessary to print bytes +// TODO(goldroom): necessary to print bytes // #include "../other/fun/create_common.h" static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) @@ -373,169 +373,6 @@ static void test_memzero(void) } } -//TODO(goldroom): Remove if Blake2b? -// /* Noise_IK_25519_ChaChaPoly_SHA512 test vectors from here: https://github.com/rweather/noise-c/blob/cfe25410979a87391bb9ac8d4d4bef64e9f268c6/tests/vector/noise-c-basic.txt */ -// /* "init_prologue": "50726f6c6f677565313233" (same as `resp_prologue`) */ -// static const uint8_t prologue[11] = { -// 0x50, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x75, 0x65, -// 0x31, 0x32, 0x33 -// }; - -// /* Initiator static private key -// "init_static": "e61ef9919cde45dd5f82166404bd08e38bceb5dfdfded0a34c8df7ed542214d1" */ -// static const uint8_t init_static[CRYPTO_SECRET_KEY_SIZE] = { -// 0xe6, 0x1e, 0xf9, 0x91, 0x9c, 0xde, 0x45, 0xdd, -// 0x5f, 0x82, 0x16, 0x64, 0x04, 0xbd, 0x08, 0xe3, -// 0x8b, 0xce, 0xb5, 0xdf, 0xdf, 0xde, 0xd0, 0xa3, -// 0x4c, 0x8d, 0xf7, 0xed, 0x54, 0x22, 0x14, 0xd1 -// }; - -// /* Initiator ephemeral private key -// "init_ephemeral": "893e28b9dc6ca8d611ab664754b8ceb7bac5117349a4439a6b0569da977c464a" */ -// static const uint8_t init_ephemeral[CRYPTO_SECRET_KEY_SIZE] = { -// 0x89, 0x3e, 0x28, 0xb9, 0xdc, 0x6c, 0xa8, 0xd6, -// 0x11, 0xab, 0x66, 0x47, 0x54, 0xb8, 0xce, 0xb7, -// 0xba, 0xc5, 0x11, 0x73, 0x49, 0xa4, 0x43, 0x9a, -// 0x6b, 0x05, 0x69, 0xda, 0x97, 0x7c, 0x46, 0x4a -// }; - -// /* Responder static public key -// "init_remote_static": "31e0303fd6418d2f8c0e78b91f22e8caed0fbe48656dcf4767e4834f701b8f62" */ -// static const uint8_t init_remote_static[CRYPTO_PUBLIC_KEY_SIZE] = { -// 0x31, 0xe0, 0x30, 0x3f, 0xd6, 0x41, 0x8d, 0x2f, -// 0x8c, 0x0e, 0x78, 0xb9, 0x1f, 0x22, 0xe8, 0xca, -// 0xed, 0x0f, 0xbe, 0x48, 0x65, 0x6d, 0xcf, 0x47, -// 0x67, 0xe4, 0x83, 0x4f, 0x70, 0x1b, 0x8f, 0x62 -// }; - -// /* Responder static private key -// "resp_static": "4a3acbfdb163dec651dfa3194dece676d437029c62a408b4c5ea9114246e4893" */ -// static const uint8_t resp_static[CRYPTO_SECRET_KEY_SIZE] = { -// 0x4a, 0x3a, 0xcb, 0xfd, 0xb1, 0x63, 0xde, 0xc6, -// 0x51, 0xdf, 0xa3, 0x19, 0x4d, 0xec, 0xe6, 0x76, -// 0xd4, 0x37, 0x02, 0x9c, 0x62, 0xa4, 0x08, 0xb4, -// 0xc5, 0xea, 0x91, 0x14, 0x24, 0x6e, 0x48, 0x93 -// }; - -// /* Responder ephermal private key -// "resp_ephemeral": "bbdb4cdbd309f1a1f2e1456967fe288cadd6f712d65dc7b7793d5e63da6b375b" */ -// static const uint8_t resp_ephemeral[CRYPTO_SECRET_KEY_SIZE] = { -// 0xbb, 0xdb, 0x4c, 0xdb, 0xd3, 0x09, 0xf1, 0xa1, -// 0xf2, 0xe1, 0x45, 0x69, 0x67, 0xfe, 0x28, 0x8c, -// 0xad, 0xd6, 0xf7, 0x12, 0xd6, 0x5d, 0xc7, 0xb7, -// 0x79, 0x3d, 0x5e, 0x63, 0xda, 0x6b, 0x37, 0x5b -// }; - -// /* Payload for initiator handshake message -// "payload": "4c756477696720766f6e204d69736573" */ -// static const uint8_t init_payload_hs[16] = { -// 0x4c, 0x75, 0x64, 0x77, 0x69, 0x67, 0x20, 0x76, -// 0x6f,0x6e, 0x20, 0x4d, 0x69, 0x73, 0x65, 0x73 -// }; -// /* "ciphertext": is actually three values for initiator handshake message: -// Initiator ephemeral public key in plaintext: ca35def5ae56cec33dc2036731ab14896bc4c75dbb07a61f879f8e3afa4c7944 -// Encrypted static public key (of initiator): 7a2281c0f1aee0c48c41333a1abbb349ee4bf12e09f8c4fd66635aabbb7dad345826d359e4bd6ebee659f5c6cb3d2d4e -// Encrypted payload: d12f7c7ffc9fe5513818d9cf9b8778d1502f90649c42ab4a1e3df7199a3d6a13 */ -// static const uint8_t init_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { -// 0xca, 0x35, 0xde, 0xf5, 0xae, 0x56, 0xce, 0xc3, -// 0x3d, 0xc2, 0x03, 0x67, 0x31, 0xab, 0x14, 0x89, -// 0x6b, 0xc4, 0xc7, 0x5d, 0xbb, 0x07, 0xa6, 0x1f, -// 0x87, 0x9f, 0x8e, 0x3a, 0xfa, 0x4c, 0x79, 0x44 -// }; -// static const uint8_t init_encrypted_static_public[CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE] = { -// 0x7a, 0x22, 0x81, 0xc0, 0xf1, 0xae, 0xe0, 0xc4, -// 0x8c, 0x41, 0x33, 0x3a, 0x1a, 0xbb, 0xb3, 0x49, -// 0xee, 0x4b, 0xf1, 0x2e, 0x09, 0xf8, 0xc4, 0xfd, -// 0x66, 0x63, 0x5a, 0xab, 0xbb, 0x7d, 0xad, 0x34, -// 0x58, 0x26, 0xd3, 0x59, 0xe4, 0xbd, 0x6e, 0xbe, -// 0xe6, 0x59, 0xf5, 0xc6, 0xcb, 0x3d, 0x2d, 0x4e -// }; -// static const uint8_t init_payload_hs_encrypted[sizeof(init_payload_hs)+CRYPTO_MAC_SIZE] = { -// 0xd1, 0x2f, 0x7c, 0x7f, 0xfc, 0x9f, 0xe5, 0x51, -// 0x38, 0x18, 0xd9, 0xcf, 0x9b, 0x87, 0x78, 0xd1, -// 0x50, 0x2f, 0x90, 0x64, 0x9c, 0x42, 0xab, 0x4a, -// 0x1e, 0x3d, 0xf7, 0x19, 0x9a, 0x3d, 0x6a, 0x13 -// }; - -// /* Payload for responder handshake message -// "payload": "4d757272617920526f746862617264", */ -// static const uint8_t resp_payload_hs[15] = { -// 0x4d, 0x75, 0x72, 0x72, 0x61, 0x79, 0x20, 0x52, -// 0x6f, 0x74, 0x68, 0x62, 0x61, 0x72, 0x64 -// }; -// /* "ciphertext": is actually two values for responder handshake message: -// Responder ephemeral public key in plaintext: 95ebc60d2b1fa672c1f46a8aa265ef51bfe38e7ccb39ec5be34069f144808843 -// Encrypted payload: f58050451a0edd2a40bb8b0f6b51ea63e1f1f429f1afd583e5d6e53f44da1e */ -// static const uint8_t resp_ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE] = { -// 0x95, 0xeb, 0xc6, 0x0d, 0x2b, 0x1f, 0xa6, 0x72, -// 0xc1, 0xf4, 0x6a, 0x8a, 0xa2, 0x65, 0xef, 0x51, -// 0xbf, 0xe3, 0x8e, 0x7c, 0xcb, 0x39, 0xec, 0x5b, -// 0xe3, 0x40, 0x69, 0xf1, 0x44, 0x80, 0x88, 0x43 -// }; -// static const uint8_t resp_payload_hs_encrypted[sizeof(resp_payload_hs)+CRYPTO_MAC_SIZE] = { -// 0xf5, 0x80, 0x50, 0x45, 0x1a, 0x0e, 0xdd, 0x2a, -// 0x40, 0xbb, 0x8b, 0x0f, 0x6b, 0x51, 0xea, 0x63, -// 0xe1, 0xf1, 0xf4, 0x29, 0xf1, 0xaf, 0xd5, 0x83, -// 0xe5, 0xd6, 0xe5, 0x3f, 0x44, 0xda, 0x1e -// }; - -// /* Payload for initiator transport message 1 -// "payload": "462e20412e20486179656b" */ -// static const uint8_t init_payload_transport1[11] = { -// 0x46, 0x2e, 0x20, 0x41, 0x2e, 0x20, 0x48, 0x61, -// 0x79, -// 0x65, 0x6b -// }; -// /* Payload ciphertext for initiator transport message 1 -// "ciphertext": "cae0b6af5460d026e80e22c27572a92048176872538f91a056a8df" */ -// static const uint8_t init_payload_transport1_encrypted[sizeof(init_payload_transport1)+CRYPTO_MAC_SIZE] = { -// 0xca, 0xe0, 0xb6, 0xaf, 0x54, 0x60, 0xd0, 0x26, -// 0xe8, 0x0e, 0x22, 0xc2, 0x75, 0x72, 0xa9, 0x20, -// 0x48, 0x17, 0x68, 0x72, 0x53, 0x8f, 0x91, 0xa0, -// 0x56, 0xa8, 0xdf -// }; - -// /* Payload for responder transport message 1 -// "payload": "4361726c204d656e676572" */ -// static const uint8_t resp_payload_transport1[11] = { -// 0x43, 0x61, 0x72, 0x6c, 0x20, 0x4d, 0x65, 0x6e, -// 0x67, 0x65, 0x72 -// }; -// /* Payload ciphertext for responder transport message 1 -// "ciphertext": "ab1440d2b5892c638a11a7fa6412beaea5cee62342147f02d75a68" */ -// static const uint8_t resp_payload_transport1_encrypted[sizeof(resp_payload_transport1)+CRYPTO_MAC_SIZE] = { -// 0xab, 0x14 , 0x40 , 0xd2, 0xb5, 0x89, 0x2c, 0x63, -// 0x8a, 0x11, 0xa7, 0xfa, 0x64, 0x12, 0xbe, 0xae, -// 0xa5, 0xce, 0xe6, 0x23, 0x42, 0x14, 0x7f, 0x02, -// 0xd7, 0x5a, 0x68 -// }; - -// /* Final handshake hash value (MUST be the same for both initiator and responder) -// "handshake_hash": "48d8b650f042c4767cf1f3c26b22ccdd4bc8cff341166603109954eab8a9bd20915d284b6b618a325e93a8e949a23f4b62ba3094aad0b640c14cbd4f14ccd1e1" */ -// static const uint8_t handshake_hash[CRYPTO_SHA512_SIZE] = { -// 0x48 ,0xd8, 0xb6, 0x50, 0xf0, 0x42, 0xc4, 0x76, -// 0x7c, 0xf1, 0xf3, 0xc2, 0x6b, 0x22, 0xcc, 0xdd, -// 0x4b, 0xc8, 0xcf, 0xf3, 0x41, 0x16, 0x66, 0x03, -// 0x10, 0x99, 0x54, 0xea, 0xb8, 0xa9, 0xbd, 0x20, -// 0x91, 0x5d, 0x28, 0x4b, 0x6b, 0x61, 0x8a, 0x32, -// 0x5e, 0x93, 0xa8, 0xe9, 0x49, 0xa2, 0x3f, 0x4b, -// 0x62, 0xba, 0x30, 0x94, 0xaa, 0xd0, 0xb6, 0x40, -// 0xc1, 0x4c, 0xbd, 0x4f, 0x14, 0xcc, 0xd1, 0xe1 -// }; - -/* TODO(goldroom): Currently unused */ -// // 4a 65 61 6e 2d 42 61 70 74 69 73 74 65 20 53 61 79 -// static const uint8_t init_payload_transport2[17] = { -// 0x4a, 0x65, 0x61, 0x6e, 0x2d, 0x42, 0x61, 0x70, 0x74, 0x69, 0x73, -// 0x74, 0x65, 0x20, 0x53, 0x61, 0x79 -// }; - -// // 45 75 67 65 6e 20 42 f6 68 6d 20 76 6f 6e 20 42 61 77 65 72 6b -// static const uint8_t payload_transport_responder2[21] = { -// 0x45, 0x75, 0x67, 0x65, 0x6e, 0x20, 0x42, 0xf6, 0x68, 0x6d, 0x20, -// 0x76, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x77, 0x65, 0x72, 0x6b -// }; - /* Noise_IK_25519_ChaChaPoly_BLAKE2b test vectors from here: https://github.com/rweather/noise-c/blob/cfe25410979a87391bb9ac8d4d4bef64e9f268c6/tests/vector/noise-c-basic.txt */ /* "init_prologue": "50726f6c6f677565313233" (same as `resp_prologue`) */ static const uint8_t prologue[11] = { @@ -686,68 +523,36 @@ static const uint8_t handshake_hash[CRYPTO_SHA512_SIZE] = { 0xf1, 0xfe, 0x5a, 0x7f, 0x0c, 0x55, 0xc0, 0x78 }; -//TODO(goldroom): "payload": "4a65616e2d426170746973746520536179", -//TODO(goldroom): "ciphertext": "49063084b2c51f098337cb8a13739ac848f907e67cfb2cc8a8b60586467aa02fc7" +/* TODO(goldroom): Currently unused */ +// TODO(goldroom): "payload": "4a65616e2d426170746973746520536179", +// TODO(goldroom): "ciphertext": "49063084b2c51f098337cb8a13739ac848f907e67cfb2cc8a8b60586467aa02fc7" -//TODO(goldroom): "payload": "457567656e2042f6686d20766f6e2042617765726b", -//TODO(goldroom): "ciphertext": "8b9709d23b47e4639df7678d7a21741eba4ef1e9c60383001c7435549c20f9d56f30e935d3" +// TODO(goldroom): "payload": "457567656e2042f6686d20766f6e2042617765726b", +// TODO(goldroom): "ciphertext": "8b9709d23b47e4639df7678d7a21741eba4ef1e9c60383001c7435549c20f9d56f30e935d3" static void test_noiseik(void) { /* INITIATOR: Create handshake packet for responder */ Noise_Handshake *noise_handshake_initiator = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); - /* Troubleshooting info, intermediary values */ - // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->hash: %s\n", h_print); - // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->chaining_key: %s\n", ck_print); - noise_handshake_init(noise_handshake_initiator, init_static, init_remote_static, true, prologue, sizeof(prologue)); - /* Troubleshooting info, intermediary values */ - // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->hash: %s\n", h_print); - // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->chaining_key: %s\n", ck_print); - memcpy(noise_handshake_initiator->ephemeral_private, init_ephemeral, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(noise_handshake_initiator->ephemeral_public, init_ephemeral); ck_assert_msg(memcmp(noise_handshake_initiator->ephemeral_public, init_ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE) == 0, "initiator ephemeral public keys differ"); - /* Troubleshooting info, intermediary values */ - // char ephemeral_public_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bin2hex_toupper(ephemeral_public_print, sizeof(ephemeral_public_print), noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - // printf("ephemeral_public_print: %s\n", ephemeral_public_print); - uint8_t resp_static_pub[CRYPTO_PUBLIC_KEY_SIZE]; crypto_derive_public_key(resp_static_pub, resp_static); ck_assert_msg(memcmp(resp_static_pub, init_remote_static, CRYPTO_PUBLIC_KEY_SIZE) == 0, "responder static public keys differ"); - /* Troubleshooting info, intermediary values */ - // char resp_static_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bin2hex_toupper(resp_static_print, sizeof(resp_static_print), resp_static_pub, CRYPTO_PUBLIC_KEY_SIZE); - // printf("resp_static_pub: %s\n", resp_static_print); - /* e */ noise_mix_hash(noise_handshake_initiator->hash, noise_handshake_initiator->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - /* Troubleshooting info, intermediary values */ - // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); - /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key, noise_handshake_initiator->ephemeral_private, noise_handshake_initiator->remote_static); - /* Troubleshooting info, intermediary values */ - // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->chaining_key (after es): %s\n", ck_print); - // bin2hex_toupper(key_print, sizeof(key_print), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); - // printf("noise_handshake_temp_key (after es): %s\n", key_print); - /* s */ /* Nonce for static pub key encryption is _always_ 0 in case of ChaCha20-Poly1305 */ @@ -755,28 +560,13 @@ static void test_noiseik(void) noise_encrypt_and_hash(ciphertext1, noise_handshake_initiator->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake_initiator->hash); - /* Troubleshooting info, intermediary values */ - // char ciphertext1_print[sizeof(ciphertext1) * 2 + 1]; - // bin2hex_toupper(ciphertext1_print, sizeof(ciphertext1_print), ciphertext1, sizeof(ciphertext1)); - // printf("Initiator: HS ciphertext static pub key: %s\n", ciphertext1_print); - ck_assert_msg(memcmp(ciphertext1, init_encrypted_static_public, CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_MAC_SIZE) == 0, "initiator encrypted static public keys differ"); - - //TODO(goldroom): remove from production code - // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); - // char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); - /* ss */ noise_mix_key(noise_handshake_initiator->chaining_key, noise_handshake_temp_key, noise_handshake_initiator->static_private, noise_handshake_initiator->remote_static); /* Noise Handshake Payload */ - // uint8_t handshake_payload_plain[15]; uint8_t ciphertext2[sizeof(init_payload_hs) + CRYPTO_MAC_SIZE]; /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ @@ -786,31 +576,14 @@ static void test_noiseik(void) ck_assert_msg(memcmp(ciphertext2, init_payload_hs_encrypted, sizeof(init_payload_hs_encrypted)) == 0, "initiator encrypted handshake payloads differ"); - /* Troubleshooting info, intermediary values */ - // char ciphertext2_print[sizeof(ciphertext2) * 2 + 1]; - // bin2hex_toupper(ciphertext2_print, sizeof(ciphertext2_print), ciphertext2, sizeof(ciphertext2)); - // printf("Initiator: HS ciphertext payload: %s\n", ciphertext2_print); - // INITIATOR: END Create handshake packet for responder /* RESPONDER: Consume handshake packet from initiator */ Noise_Handshake *noise_handshake_responder = (Noise_Handshake *) calloc(1, sizeof(Noise_Handshake)); - - /* Troubleshooting info, intermediary values */ - // bin2hex_toupper(h_print, sizeof(h_print), noise_handshake->hash, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->hash: %s\n", h_print); - // bin2hex_toupper(ck_print, sizeof(ck_print), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE); - // printf("noise_handshake->chaining_key: %s\n", ck_print); - uint8_t init_static_pub[CRYPTO_PUBLIC_KEY_SIZE]; crypto_derive_public_key(init_static_pub, init_static); - /* Troubleshooting info, intermediary values */ - // char init_static_print[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bin2hex_toupper(init_static_print, sizeof(init_static_print), init_static_pub, CRYPTO_PUBLIC_KEY_SIZE); - // printf("init_static_pub: %s\n", init_static_print); - noise_handshake_init(noise_handshake_responder, resp_static, nullptr, false, prologue, sizeof(prologue)); /* e */ @@ -844,11 +617,6 @@ static void test_noiseik(void) ck_assert_msg(memcmp(noise_handshake_responder->ephemeral_public, resp_ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE) == 0, "responder ephemeral public keys differ"); - /* Troubleshooting info, intermediary values */ - // char ephemeral_public_print_responder[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bin2hex_toupper(ephemeral_public_print_responder, sizeof(ephemeral_public_print_responder), noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - // printf("Responder ephemeral public: %s\n", ephemeral_public_print_responder); - /* e */ noise_mix_hash(noise_handshake_responder->hash, noise_handshake_responder->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); @@ -870,11 +638,6 @@ static void test_noiseik(void) ck_assert_msg(memcmp(ciphertext3_hs_responder, resp_payload_hs_encrypted, sizeof(resp_payload_hs_encrypted)) == 0, "responder encrypted handshake payloads differ"); - /* Troubleshooting info, intermediary values */ - // char ciphertext3_print[sizeof(ciphertext3_hs_responder) * 2 + 1]; - // bin2hex_toupper(ciphertext3_print, sizeof(ciphertext3_print), ciphertext3_hs_responder, sizeof(ciphertext3_hs_responder)); - // printf("Responder: HS ciphertext payload: %s\n", ciphertext3_print); - /* RESPONDER: END create handshake packet for initiator */ /* INITIATOR: Consume handshake packet from responder */ @@ -905,30 +668,12 @@ static void test_noiseik(void) ck_assert_msg(memcmp(noise_handshake_initiator->hash, handshake_hash, CRYPTO_SHA512_SIZE) == 0, "initiator handshake hash differ"); - /* Troubleshooting info, intermediary values */ - // char handshake_hash_initiator_print[sizeof(noise_handshake_initiator->hash) * 2 + 1]; - // bin2hex_toupper(handshake_hash_initiator_print, sizeof(handshake_hash_initiator_print), noise_handshake_initiator->hash, sizeof(noise_handshake_initiator->hash)); - // printf("Initiator: final handshake hash: %s\n", handshake_hash_initiator_print); - - /* Troubleshooting info, intermediary values */ - // char initiator_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // char initiator_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // bin2hex_toupper(initiator_send_key_print, sizeof(initiator_send_key_print), initiator_send_key, CRYPTO_SHARED_KEY_SIZE); - // printf("initiator_send_key_print: %s\n", initiator_send_key_print); - // bin2hex_toupper(initiator_recv_key_print, sizeof(initiator_recv_key_print), initiator_recv_key, CRYPTO_SHARED_KEY_SIZE); - // printf("initiator_recv_key_print: %s\n", initiator_recv_key_print); - uint8_t ciphertext4_transport1_initiator[sizeof(init_payload_transport1) + CRYPTO_MAC_SIZE]; uint8_t nonce_chacha20_ietf[CRYPTO_NOISE_NONCE_SIZE] = {0}; encrypt_data_symmetric_aead(initiator_send_key, nonce_chacha20_ietf, init_payload_transport1, sizeof(init_payload_transport1), ciphertext4_transport1_initiator, nullptr, 0); ck_assert_msg(memcmp(ciphertext4_transport1_initiator, init_payload_transport1_encrypted, sizeof(init_payload_transport1_encrypted)) == 0, "initiator transport1 ciphertext differ"); - /* Troubleshooting info, intermediary values */ - // char ciphertext4_transport1_initiator_print[sizeof(ciphertext4_transport1_initiator) * 2 + 1]; - // bin2hex_toupper(ciphertext4_transport1_initiator_print, sizeof(ciphertext4_transport1_initiator_print), ciphertext4_transport1_initiator, sizeof(ciphertext4_transport1_initiator)); - // printf("Initiator: Transport1 ciphertext: (length: %d) %s\n", length, ciphertext4_transport1_initiator_print); - /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ uint8_t responder_send_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t responder_recv_key[CRYPTO_SHARED_KEY_SIZE]; @@ -936,30 +681,12 @@ static void test_noiseik(void) ck_assert_msg(memcmp(noise_handshake_responder->hash, handshake_hash, CRYPTO_SHA512_SIZE) == 0, "responder handshake hash differ"); - /* Troubleshooting info, intermediary values */ - // char handshake_hash_responder_print[sizeof(noise_handshake_responder->hash) * 2 + 1]; - // bin2hex_toupper(handshake_hash_responder_print, sizeof(handshake_hash_responder_print), noise_handshake_responder->hash, sizeof(noise_handshake_responder->hash)); - // printf("Responder: final handshake hash: %s\n", handshake_hash_responder_print); - - /* Troubleshooting info, intermediary values */ - // char responder_send_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // char responder_recv_key_print[CRYPTO_SHARED_KEY_SIZE * 2 + 1]; - // bin2hex_toupper(responder_send_key_print, sizeof(responder_send_key_print), responder_send_key, CRYPTO_SHARED_KEY_SIZE); - // printf("responder_send_key_print: %s\n", responder_send_key_print); - // bin2hex_toupper(responder_recv_key_print, sizeof(responder_recv_key_print), responder_recv_key, CRYPTO_SHARED_KEY_SIZE); - // printf("responder_recv_key_print: %s\n", responder_recv_key_print); - uint8_t ciphertext5_transport1_responder[sizeof(resp_payload_transport1) + CRYPTO_MAC_SIZE]; encrypt_data_symmetric_aead(responder_send_key, nonce_chacha20_ietf, resp_payload_transport1, sizeof(resp_payload_transport1), ciphertext5_transport1_responder, nullptr, 0); ck_assert_msg(memcmp(ciphertext5_transport1_responder, resp_payload_transport1_encrypted, sizeof(resp_payload_transport1_encrypted)) == 0, "responder transport1 ciphertext differ"); - /* Troubleshooting info, intermediary values */ - // char ciphertext5_transport1_responder_print[sizeof(ciphertext5_transport1_responder) * 2 + 1]; - // bin2hex_toupper(ciphertext5_transport1_responder_print, sizeof(ciphertext5_transport1_responder_print), ciphertext5_transport1_responder, sizeof(ciphertext5_transport1_responder)); - // printf("Responder: Transport1 ciphertext: (length: %d) %s\n", length_ciphertext5_transport1_responder, ciphertext5_transport1_responder_print); - free(noise_handshake_initiator); free(noise_handshake_responder); } diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 8f159cd83d..dbfd1c0929 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -794,7 +794,7 @@ void crypto_hkdf(uint8_t *output1, size_t first_len, uint8_t *output2, memcpy(output2, output, second_len); /* Expand third key: key = temp_key, data = second-key || 0x3 */ - /* TODO(goldroom): Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec )*/ + /* TODO(goldroom): Currently output3 is not used in Tox, maybe necessary in future for pre-shared symmetric keys (cf. Noise spec) */ // output[CRYPTO_SHA512_SIZE] = 3; // crypto_hmac512(output, temp_key, output, CRYPTO_SHA512_SIZE + 1); // memcpy(output3, output, third_len); @@ -863,7 +863,7 @@ void noise_encrypt_and_hash(uint8_t *ciphertext, const uint8_t *plaintext, static uint8_t nonce_chacha20_ietf[CRYPTO_NOISE_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISE_NONCE_SIZE); - int32_t encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, + const int32_t encrypted_length = encrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, plaintext, plain_length, ciphertext, hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); @@ -882,7 +882,7 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, static uint8_t nonce_chacha20_ietf[CRYPTO_NOISE_NONCE_SIZE] = {0}; memset(nonce_chacha20_ietf, 0, CRYPTO_NOISE_NONCE_SIZE); - int32_t plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, + const int32_t plaintext_length = decrypt_data_symmetric_aead(shared_key, nonce_chacha20_ietf, ciphertext, encrypted_length, plaintext, hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); @@ -914,11 +914,6 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, int noise_handshake_init (Noise_Handshake *noise_handshake, const uint8_t self_id_secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], bool initiator, const uint8_t *prologue, size_t prologue_length) { - //TODO: remove - // if (log != nullptr) { - // LOGGER_DEBUG(log, "ENTERING"); - // } - /* IntializeSymmetric(protocol_name) => set h to NOISE_PROTOCOL_NAME and append zero bytes to make 64 bytes, sets ck = h Nothing gets hashed in Tox case because NOISE_PROTOCOL_NAME < CRYPTO_SHA512_SIZE */ uint8_t temp_hash[CRYPTO_NOISE_BLAKE2B_HASH_SIZE]; @@ -930,26 +925,11 @@ int noise_handshake_init /* IMPORTANT needs to be called with (empty/zero-length) prologue! */ noise_mix_hash(noise_handshake->hash, prologue, prologue_length); - //TODO: remove - // char log_ck[CRYPTO_SHA512_SIZE*2+1]; - // if (log != nullptr) { - // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "ck: %s", log_ck); - // } - /* Sets the initiator, s => ephemeral keys are set afterwards */ noise_handshake->initiator = initiator; if (self_id_secret_key != nullptr) { memcpy(noise_handshake->static_private, self_id_secret_key, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(noise_handshake->static_public, self_id_secret_key); - - //TODO: remove - // if (log != nullptr) { - // char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bytes2string(log_spub, sizeof(log_spub), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, log); - // LOGGER_DEBUG(log, "static pub: %s", log_spub); - // } - } else { // fprintf(stderr, "Local static private key required, but not provided.\n"); // LOGGER_DEBUG(log, "Local static private key required, but not provided."); @@ -960,21 +940,8 @@ int noise_handshake_init if (peer_id_public_key != nullptr) { memcpy(noise_handshake->remote_static, peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: Remove - // if (log != nullptr) { - // char log_spub[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bytes2string(log_spub, sizeof(log_spub), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, log); - // LOGGER_DEBUG(log, "INITIATOR remote static: %s", log_spub); - // } - /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ noise_mix_hash(noise_handshake->hash, peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); - - //TODO: remove - // if (log != nullptr) { - // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "INITIATOR hash: %s", log_hash); - // } } else { // fprintf(stderr, "Remote peer static public key required, but not provided.\n"); // LOGGER_DEBUG(log, "Remote peer static public key required, but not provided."); @@ -986,20 +953,14 @@ int noise_handshake_init /* Calls MixHash() once for each public key listed in the pre-messages from Noise IK */ noise_mix_hash(noise_handshake->hash, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE); - //TODO(goldroom): precompute static static here (ss)? cf. WireGuard wg_noise_handshake_init() - - //TODO: remove - // if (log != nullptr) { - // bytes2string(log_hash, sizeof(log_hash), noise_handshake->hash, CRYPTO_SHA512_SIZE, log); - // LOGGER_DEBUG(log, "RESPONDER hash: %s", log_hash); - // } + // TODO(goldroom): precompute static static here (ss)? cf. WireGuard wg_noise_handshake_init() } /* Ready to go */ return 0; } -//TODO(goldroom): abstract creation and handling of NoiseIK handshake packets from net_crypto (_after_ cookie adaption) +// TODO(goldroom): abstract creation and handling of NoiseIK handshake packets from net_crypto (_after_ cookie adaption) // /* Noise create INITIATOR: -> e, es, s, ss */ // int noise_handshake_create_initiator() // /* Noise handle INITIATOR: -> e, es, s, ss */ diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 578003b124..5041e18c40 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -135,7 +135,7 @@ typedef struct Noise_Handshake { uint8_t ephemeral_public[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_static[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t remote_ephemeral[CRYPTO_PUBLIC_KEY_SIZE]; - //TODO(goldroom): precompute static static? cf. WireGuard struct noise_handshake + // TODO(goldroom): precompute static static? cf. WireGuard struct noise_handshake // uint8_t precomputed_static_static[CRYPTO_SHARED_KEY_SIZE]; uint8_t hash[CRYPTO_SHA512_SIZE]; diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 5f21b7d833..7f391bdd0b 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -60,17 +60,17 @@ typedef enum Crypto_Conn_State { } Crypto_Conn_State; typedef struct Crypto_Connection { - //TODO(goldroom): kept for backwards compatibility in NoiseIK, to be removed at some point. Not used in NoiseIK handshake. + // TODO(goldroom): kept for backwards compatibility in NoiseIK, to be removed at some point. Not used in NoiseIK handshake. uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real/static identity public X25519 key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce used to decrypt incoming packets after non-Noise and NoiseIK handshake. */ uint8_t send_nonce[CRYPTO_NONCE_SIZE]; /* Nonce used to encrypt outgoing packets after non-Noise and NoiseIK handshake. */ - //TODO(goldroom): currently in use for backwards compatibility in NoiseIK, to be removed at some point. + // TODO(goldroom): currently in use for backwards compatibility in NoiseIK, to be removed at some point. uint8_t ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* Our public ephemeral X25519 key for this session. */ uint8_t ephemeral_secret_key[CRYPTO_SECRET_KEY_SIZE]; /* Our private ephemeral X25519 key for this session. */ - //TODO(goldroom): kept for backwards compatibility in NoiseIK, to be removed at some point. Not used in NoiseIK handshake. + // TODO(goldroom): kept for backwards compatibility in NoiseIK, to be removed at some point. Not used in NoiseIK handshake. uint8_t peer_ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public ephemeral X25519 key of the peer. */ /* The precomputed shared key from encrypt_precompute. @@ -82,7 +82,7 @@ typedef struct Crypto_Connection { uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The DHT public X25519 key of the peer. */ bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ - //TODO(goldroom): Can this be moved out of struct Crypto_Connection? Not necessary after handshake is finished + // TODO(goldroom): Can this be moved out of struct Crypto_Connection? Not necessary after handshake is finished Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to encrypt outgoing packets after NoiseIK handshake. */ uint8_t recv_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to decrypt incoming packets after NoiseIK handshake. */ @@ -244,14 +244,13 @@ non_null() static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uint8_t *dht_public_key, uint64_t number, uint8_t *shared_key) { - //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); - //TODO(goldroom): adapt for new Noise-cookie mechanism _only_ or different cookie mechanism? E.g. as in WireGuard? + // TODO(goldroom): adapt for new Noise-cookie mechanism _only_ or different cookie mechanism? E.g. as in WireGuard? uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; memcpy(plain, c->self_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); - //TODO(goldroom): "Padding is used to maintain backwards-compatibility with previous versions of the protocol." => can this be removed by now? + // TODO(goldroom): "Padding is used to maintain backwards-compatibility with previous versions of the protocol." => can this be removed by now? memzero(plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); memcpy(plain + (CRYPTO_PUBLIC_KEY_SIZE * 2), &number, sizeof(uint64_t)); const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key); @@ -393,7 +392,6 @@ static int udp_handle_cookie_request(void *object, const IP_Port *source, const { const Net_Crypto *c = (const Net_Crypto *)object; - //TODO: remove LOGGER_DEBUG(c->log, "Packet: %d/length: %d", packet[0], length); uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; @@ -500,8 +498,8 @@ static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t * } /* -* TODO: Helper function to print hashes, keys, packets, etc. -* TODO: remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? +* TODO(goldroom): Helper function to print hashes, keys, packets, etc. +* TODO(goldroom): remove from production code or make dependent on MIN_LOGGER_LEVEL=DEBUG? * bytes_to_string() from util.h */ static void bytes2string(char *string, size_t string_length, const uint8_t *bytes, size_t bytes_length, const Logger *log) @@ -540,13 +538,8 @@ non_null(1, 2, 3, 8) nullable(4, 5, 6, 7, 9) static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t peer_cookie[COOKIE_LENGTH], const uint8_t send_nonce[CRYPTO_NONCE_SIZE], const uint8_t ephemeral_private_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], Noise_Handshake *noise_handshake) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING: create_crypto_handshake()"); /* Noise-based handshake */ if (noise_handshake != nullptr) { - //TODO: remove - // LOGGER_DEBUG(c->log, "Noise Handshake"); - /* Noise INITIATOR: -> e, es, s, ss */ /* Initiator: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] @@ -569,11 +562,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(packet + 1, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: remove from production code - // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "hash1 INITIATOR: %s", log_hash1); - /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); @@ -583,14 +571,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u noise_encrypt_and_hash(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, noise_handshake_temp_key, noise_handshake->hash); - //TODO: remove from production code - // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "hash2 INITIATOR: %s", log_hash2); - // char log_ephemeral[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bytes2string(log_ephemeral, sizeof(log_ephemeral), noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "ephemeral public: %s", log_ephemeral); - /* ss */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); @@ -616,20 +596,8 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u handshake_payload_plain, sizeof(handshake_payload_plain), noise_handshake_temp_key, noise_handshake->hash); - //TODO: remove from production code - // LOGGER_DEBUG(c->log, "AFTER noise_encrypt_and_hash()"); - // char log_ciphertext[(sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE)*2+1]; - // bytes2string(log_ciphertext, sizeof(log_ciphertext), (packet + 1 + COOKIE_LENGTH + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE + CRYPTO_NONCE_SIZE), - // (sizeof(handshake_payload_plain)+CRYPTO_MAC_SIZE), c->log); - // LOGGER_DEBUG(c->log, "Ciphertext INITIATOR: %s", log_ciphertext); - packet[0] = NET_PACKET_CRYPTO_HS; - //TODO: remove from production code - // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; - // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); - // LOGGER_DEBUG(c->log, "HS Packet I: %s", log_packet); - crypto_memzero(noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE); crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); @@ -654,27 +622,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(packet + 1, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->ephemeral_public, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: Remove - // char log_ck[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "RESPONDER pre ee ck: %s", log_ck); - /* ee */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); - //TODO: Remove - // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; - // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "RESPONDER ee temp_key: %s", log_temp_key); - /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_static); - //TODO: Remove - // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "RESPONDER es temp_key: %s", log_temp_key); - /* Create Noise Handshake Payload */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; @@ -747,8 +701,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP uint8_t peer_dht_public_key[CRYPTO_PUBLIC_KEY_SIZE], uint8_t peer_cookie[COOKIE_LENGTH], const uint8_t *packet, uint16_t packet_length, const uint8_t expected_peer_id_pk[CRYPTO_PUBLIC_KEY_SIZE], Noise_Handshake *noise_handshake) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); /* Noise-based handshake */ if (noise_handshake != nullptr) { LOGGER_DEBUG(c->log, "noise_handshake->initiator: %d", noise_handshake->initiator); @@ -771,30 +723,11 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP => 321 bytes in total */ if (!noise_handshake->initiator) { - //TODO: remove - // LOGGER_DEBUG(c->log, "RESPONDER: Noise HS handle/ReadMessage"); - - //TODO: remove from production code - // char log_packet[NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR*2+1]; - // bytes2string(log_packet, sizeof(log_packet), packet, NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR, c->log); - // LOGGER_DEBUG(c->log, "HS Packet I (R): %s", log_packet); - - //TODO(goldroom): Check here if remote_ephemeral is already the same ephemeral key? => should not be possible to call it twice - + // TODO(goldroom): Check here if remote_ephemeral is already the same ephemeral key? => should not be possible to call it twice /* e */ memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: remove from production code - // char log_hash1[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_hash1, sizeof(log_hash1), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash1); - // char log_static[CRYPTO_PUBLIC_KEY_SIZE * 2 + 1]; - // bytes2string(log_static, sizeof(log_static), noise_handshake->static_public, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "local static pub: %s", log_static); - // bytes2string(log_static, sizeof(log_static), noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "remote ephemeral: %s", log_static); - /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); @@ -807,15 +740,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP return false; } - //TODO: remove - // bytes2string(log_static, sizeof(log_static), noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "local remote pub: %s", log_static); - - //TODO: remove from production code - // char log_hash2[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_hash2, sizeof(log_hash2), noise_handshake->hash, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "hash1 RESPONDER: %s", log_hash2); - /* ss */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_static); /* Payload decryption */ @@ -852,8 +776,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); - //TODO: remove - // LOGGER_DEBUG(c->log, "RESPONDER: END Noise HS handle/ReadMessage"); return true; } /* Noise ReadMessage() if initiator: <- e, ee, se */ @@ -869,31 +791,15 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP => 161 bytes in total */ else { - //TODO: remove - // LOGGER_DEBUG(c->log, "INITIATOR: Noise HS handle/ReadMessage"); - memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); - //TODO: Remove - // char log_ck[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(log_ck, sizeof(log_ck), noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "INITIATOR pre ee ck: %s", log_ck); - /* ee */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->ephemeral_private, noise_handshake->remote_ephemeral); - //TODO: Remove - // char log_temp_key[CRYPTO_SHARED_KEY_SIZE*2+1]; - // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "INITIATOR ee temp_key: %s", log_temp_key); - /* se */ noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); - //TODO: Remove - // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); /* Payload decryption */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; @@ -923,8 +829,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER); - //TODO: remove - // LOGGER_DEBUG(c->log, "INITIATOR: END Noise HS handle/ReadMessage"); return true; } } @@ -1095,9 +999,6 @@ static int send_packet_to(const Net_Crypto *c, int crypt_connection_id, const ui return -1; } - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING: send_packet_to()"); - bool direct_send_attempt = false; const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); @@ -1484,9 +1385,6 @@ static int handle_request_packet(const Memory *mem, const Mono_Time *mono_time, non_null() static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE); if (length == 0 || length > max_length) { @@ -1506,18 +1404,10 @@ static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const packet[0] = NET_PACKET_CRYPTO_DATA; memcpy(packet + 1, conn->send_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); - //TODO: remove - // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; - // bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "send_key: %s", key); - // char nonce_print[CRYPTO_NONCE_SIZE*2+1]; - // bytes2string(nonce_print, sizeof(nonce_print), conn->sent_nonce, CRYPTO_NONCE_SIZE, c->log); - // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); - - //TODO(goldroom): const len when backwards compatiblity removed + // TODO(goldroom): const len when backwards compatiblity removed int len = 0; if (conn->noise_handshake_enabled) { /* Case NoiseIK handshake */ - //TODO(goldroom): no data authenticated as AD (also none in WireGuard) + // TODO(goldroom): no data authenticated as AD (also none in WireGuard) len = encrypt_data_symmetric_xaead(conn->send_key, conn->send_nonce, data, length, packet + 1 + sizeof(uint16_t), nullptr, 0); } else { /* Case non-Noise handshake */ len = encrypt_data_symmetric(c->mem, conn->shared_key, conn->send_nonce, data, length, packet + 1 + sizeof(uint16_t)); @@ -1696,18 +1586,10 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint const uint16_t diff = num - num_cur_nonce; increment_nonce_number(nonce, diff); - //TODO: remove - // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; - // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "recv_key: %s", key); - // char nonce_print[CRYPTO_NONCE_SIZE*2+1]; - // bytes2string(nonce_print, sizeof(nonce_print), nonce, CRYPTO_NONCE_SIZE, c->log); - // LOGGER_DEBUG(c->log, "nonce: %s", nonce_print); - - //TODO(goldroom): const len when backwards compatiblity removed + // TODO(goldroom): const len when backwards compatiblity removed int len = 0; if (conn->noise_handshake_enabled) { /* case NoiseIK handshake */ - //TODO(goldroom): no data authenticated as AD (also none in WireGuard) + // TODO(goldroom): no data authenticated as AD (also none in WireGuard) len = decrypt_data_symmetric_xaead(conn->recv_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data, nullptr, 0); } else { /* case non-Noise handshake */ @@ -1715,11 +1597,6 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint length - (1 + sizeof(uint16_t)), data); } - - - //TODO: remove - // LOGGER_DEBUG(c->log, "data packet decrypt len: %d", len); - if ((unsigned int)len != length - crypto_packet_overhead) { return -1; } @@ -1841,8 +1718,6 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u conn->temp_packet = temp_packet; conn->temp_packet_length = length; conn->temp_packet_sent_time = 0; - //TODO: remove - // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time = 0"); conn->temp_packet_num_sent = 0; return 0; } @@ -1880,9 +1755,6 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id) non_null() static int send_temp_packet(const Net_Crypto *c, int crypt_connection_id) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -1898,7 +1770,6 @@ static int send_temp_packet(const Net_Crypto *c, int crypt_connection_id) } conn->temp_packet_sent_time = current_time_monotonic(c->mono_time); - // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); ++conn->temp_packet_num_sent; return 0; } @@ -1914,14 +1785,9 @@ non_null() static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { - //TODO: remove - // LOGGER_DEBUG(c->log, "nullptr"); return -1; } @@ -1991,8 +1857,7 @@ static int send_kill_packet(const Net_Crypto *c, int crypt_connection_id) const uint8_t kill_packet[1] = {PACKET_ID_KILL}; - //TODO: remove - LOGGER_DEBUG(c->log, "KILL PACKET"); + LOGGER_DEBUG(c->log, ""); return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end, kill_packet, sizeof(kill_packet)); @@ -2003,8 +1868,7 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - //TODO: remove - LOGGER_DEBUG(c->log, "CONNECTION KILL"); + LOGGER_DEBUG(c->log, ""); if (conn == nullptr) { return; @@ -2027,9 +1891,6 @@ non_null(1, 3) nullable(6) static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d", packet[0]); - if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) { return -1; } @@ -2045,7 +1906,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const if (len <= (int)(sizeof(uint32_t) * 2)) { LOGGER_DEBUG(c->log, "decryption failure/crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); - //TODO(goldroom): unwanted side effects? + // TODO(goldroom): unwanted side effects? connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -2074,9 +1935,6 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const uint8_t *real_data = data + (sizeof(uint32_t) * 2); uint16_t real_length = len - (sizeof(uint32_t) * 2); - //TODO: remove - // LOGGER_DEBUG(c->log, "DATA ID: %d", real_data[0]); - while (real_data[0] == 0) { /* Remove Padding */ ++real_data; --real_length; @@ -2086,9 +1944,6 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } } - //TODO: remove - // LOGGER_DEBUG(c->log, "DATA ID after PADDING: %d", real_data[0]); - if (real_data[0] == PACKET_ID_KILL) { LOGGER_DEBUG(c->log, "KILL PACKET RECEIVED crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); connection_kill(c, crypt_connection_id, userdata); @@ -2267,7 +2122,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet[0], length, crypt_connection_id, conn->status); if (conn->noise_handshake != nullptr) { - //TODO(goldroom): removed CRYPTO_CONN_NOT_CONFIRMED -> test for possible side effects + // TODO(goldroom): removed CRYPTO_CONN_NOT_CONFIRMED -> test for possible side effects if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { LOGGER_DEBUG(c->log, "NoiseIK: already handled handshake packet"); @@ -2306,10 +2161,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } if (conn->noise_handshake_enabled) { - LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); - if (conn->noise_handshake == nullptr) { //TODO(goldroom): Is this check necessary? + if (conn->noise_handshake == nullptr) { // TODO(goldroom): Is this check necessary? return -1; } + LOGGER_DEBUG(c->log, "conn->noise_handshake->initiator: %d", conn->noise_handshake->initiator); if (conn->noise_handshake->initiator) { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { LOGGER_DEBUG(c->log, "INITIATOR: Noise handshake -> normal"); @@ -2333,11 +2188,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } - //TODO: remove - // char ck_print[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "ck: %s", ck_print); - /* Noise RESPONDER needs to send handshake packet, afterwards finished */ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; @@ -2349,7 +2199,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } /* Case where RESPONDER with and without change from INITIATOR */ - //TODO(goldroom): this doesn't seem to happen, wether in auto_tests nor in real-world tests => remove? + // TODO(goldroom): this doesn't seem to happen, wether in auto_tests nor in real-world tests => remove? else { if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); @@ -2371,14 +2221,13 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } - //TODO(goldroom): here? + // TODO(goldroom): here? conn->status = CRYPTO_CONN_HANDSHAKE_SENT; - } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { - //TODO(goldroom): Does this even happen? + } + /* cannot change to INITIATOR here, connection broken */ + else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { // TODO(goldroom): Does this even happen? LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); - /* cannot change to INITIATOR here, connection broken */ - //TODO(goldroom): leave here? - connection_kill(c, crypt_connection_id, userdata); + connection_kill(c, crypt_connection_id, userdata); // TODO(goldroom): leave here? return -1; } } @@ -2394,40 +2243,28 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } } - //TODO(goldroom): adapt for NoiseIK, makes only sense for RESPONDER not initiator? + // TODO(goldroom): adapt for NoiseIK, makes only sense for RESPONDER not initiator? if (pk_equal(dht_public_key, conn->peer_dht_public_key)) { if (conn->noise_handshake_enabled && conn->noise_handshake != nullptr) { conn->status = CRYPTO_CONN_NOT_CONFIRMED; LOGGER_DEBUG(c->log, "conn->status: set to CRYPTO_CONN_NOT_CONFIRMED (%d)", conn->status); if (conn->noise_handshake->initiator) { - //TODO: remove - // char ck_print[CRYPTO_SHA512_SIZE*2+1]; - // bytes2string(ck_print, sizeof(ck_print), conn->noise_handshake->chaining_key, CRYPTO_SHA512_SIZE, c->log); - // LOGGER_DEBUG(c->log, "ck: %s", ck_print); /* INITIATOR Noise Split(), nonces already set in crypto connection */ crypto_hkdf(conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); - - //TODO: remove - // char key[CRYPTO_SECRET_KEY_SIZE*2+1]; - // bytes2string(key, sizeof(key), conn->send_key, CRYPTO_SECRET_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "send_key: %s", key); - // bytes2string(key, sizeof(key), conn->recv_key, CRYPTO_SECRET_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "recv_key: %s", key); } /* Noise RESPONDER */ else { /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); - //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } } /* Backwards compatibility: non-Noise handshake case */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - // if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { //TODO(goldroom): doesn't work if Noise handshake packet was sent before + // if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { // TODO(goldroom): doesn't work if Noise handshake packet was sent before if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { return -1; } @@ -2456,7 +2293,6 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con return -1; } - //TODO: remove from prod code LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d", packet[0], length, crypt_connection_id, conn->status); @@ -2477,9 +2313,6 @@ non_null(1, 3) nullable(6) static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length, bool udp, void *userdata) { - //TODO: remove from prod code - // LOGGER_DEBUG(c->log, "ENTERING: PACKET: %d", packet[0]); - if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { return -1; } @@ -2507,14 +2340,9 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons non_null() static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING: NUM: %d", num); - if (num == 0) { mem_delete(c->mem, c->crypto_connections); c->crypto_connections = nullptr; - //TODO: remove - // LOGGER_DEBUG(c->log, "FREE crypto_connections"); return 0; } @@ -2527,8 +2355,6 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) c->crypto_connections = newcrypto_connections; - //TODO: remove - // LOGGER_DEBUG(c->log, "END: realloc done"); return 0; } @@ -2540,16 +2366,13 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) non_null() static int create_crypto_connection(Net_Crypto *c) { - //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, ""); int id = -1; for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { if (c->crypto_connections[i].status == CRYPTO_CONN_FREE) { id = i; - //TODO: remove - // LOGGER_DEBUG(c->log, "NO realloc"); break; } } @@ -2559,8 +2382,6 @@ static int create_crypto_connection(Net_Crypto *c) id = c->crypto_connections_length; ++c->crypto_connections_length; c->crypto_connections[id] = empty_crypto_connection; - //TODO: remove - // LOGGER_DEBUG(c->log, "DONE realloc"); } } @@ -2583,9 +2404,6 @@ static int create_crypto_connection(Net_Crypto *c) c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; } - //TODO: Remove - // c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 800); - // LOGGER_DEBUG(c->log, "handshake_send_interval: %d", c->crypto_connections[id].handshake_send_interval); return id; } @@ -2597,8 +2415,7 @@ static int create_crypto_connection(Net_Crypto *c) non_null() static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) { - //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, ""); if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) { return -1; @@ -2614,13 +2431,10 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) return -1; } - //TODO: remove - // LOGGER_DEBUG(c->log, "valid id provided, free()'ing"); - uint32_t i; /* NoiseIK: necessary for backwards compatibility and because after CRYPTO_CONN_ESTABLISHED noise_handshake is already memzeroed/freed */ - //TODO(goldroom): refactor if backwards compatiblity removed + // TODO(goldroom): refactor if backwards compatiblity removed if (c->crypto_connections[crypt_connection_id].noise_handshake != nullptr) { crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].noise_handshake); @@ -2728,9 +2542,6 @@ non_null(1, 2, 3) nullable(5) static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - uint8_t *cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH); if (cookie == nullptr) { @@ -2745,7 +2556,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { - //TODO(goldroom): adapt static allocation? + // TODO(goldroom): adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(n_c.noise_handshake, c->self_id_secret_key, nullptr, false, nullptr, 0) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); @@ -2757,11 +2568,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Noise: create and set ephemeral private+public */ crypto_new_keypair(c->rng, n_c.noise_handshake->ephemeral_public, n_c.noise_handshake->ephemeral_private); - //TODO: remove LOGGER_DEBUG(c->log, "Noise RESPONDER: After Handshake init"); /* Noise: peer_id_public_key (=n_c.peer_id_public_key) not necessary for Noise, but need to include -> otherwise not working (call via friend_connection.c) */ - //TODO(goldroom): adapt peer_id_public_key (=n_c.peer_id_public_key) for Noise? + // TODO(goldroom): adapt peer_id_public_key (=n_c.peer_id_public_key) for Noise? if (!handle_crypto_handshake(c, nullptr, nullptr, n_c.peer_id_public_key, n_c.peer_dht_public_key, n_c.peer_cookie, packet, length, nullptr, n_c.noise_handshake)) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); @@ -2773,7 +2583,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* case non-Noise handshake */ else if (c->noise_compatibility_enabled) { LOGGER_DEBUG(c->log, "non-Noise handshake"); - // Necessary for backwards compatibility + /* Necessary for backwards compatibility */ n_c.noise_handshake = nullptr; if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peer_ephemeral_public_key, n_c.peer_id_public_key, n_c.peer_dht_public_key, n_c.peer_cookie, packet, length, nullptr, nullptr)) { @@ -2784,22 +2594,15 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, return -1; } - //TODO: remove - // char log_spub[CRYPTO_PUBLIC_KEY_SIZE*2+1]; - // bytes2string(log_spub, sizeof(log_spub), n_c.peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // LOGGER_DEBUG(c->log, "RESPONDER: session pub: %s", log_spub); char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; bytes2string(log_id_public, sizeof(log_id_public), n_c.peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, ": peer_id_public_key: %s", log_id_public); - // char log_cookie[COOKIE_LENGTH*2+1]; - // bytes2string(log_cookie, sizeof(log_cookie), n_c.cookie, COOKIE_LENGTH, c->log); - // LOGGER_DEBUG(c->log, "RESPONDER: cookie: %s", log_cookie); const int crypt_connection_id = getcryptconnection_id(c, n_c.peer_id_public_key); /* This is only called if a crypto_connection already exists (e.g. new_crypto_connection() was already called)! Now Noise RESPONDER! */ /* happens NoiseIK handshake (e.g. auto_tox_many_test) */ - //TODO(goldroom): why is this called twice in row via tcp_oob_callback()? + // TODO(goldroom): why is this called twice in row via tcp_oob_callback()? if (crypt_connection_id != -1) { LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING -> crypt_connection_id: %d", crypt_connection_id); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -2811,8 +2614,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!pk_equal(n_c.peer_dht_public_key, conn->peer_dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ - //TODO: remove - // LOGGER_DEBUG(c->log, "Noise handshake"); if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { mem_delete(c->mem, n_c.peer_cookie); return -1; @@ -2822,7 +2623,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, crypto_connection_add_source(c, crypt_connection_id, source); - if (create_send_handshake(c, crypt_connection_id, n_c.peer_cookie, n_c.peer_dht_public_key) != 0) { mem_delete(c->mem, n_c.peer_cookie); return -1; @@ -2832,7 +2632,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); - //TODO: remove + LOGGER_DEBUG(c->log, "Noise RESPONDER crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); @@ -2871,7 +2671,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, memcpy(conn->peer_ephemeral_public_key, n_c.peer_ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); encrypt_precompute(conn->peer_ephemeral_public_key, conn->ephemeral_secret_key, conn->shared_key); - crypto_connection_add_source(c, crypt_connection_id, source); if (create_send_handshake(c, crypt_connection_id, n_c.peer_cookie, n_c.peer_dht_public_key) != 0) { @@ -2887,8 +2686,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); mem_delete(c->mem, n_c.peer_cookie); - //TODO: remove; ret value is from friend_connection.c:handle_new_connections() - // LOGGER_DEBUG(c->log, "ret (!= 0?): %d", ret); return ret; } @@ -2899,20 +2696,13 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, */ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) { - - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - if (getcryptconnection_id(c, n_c->peer_id_public_key) != -1) { - //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: Crypto Connection already exists"); return -1; } const int crypt_connection_id = create_crypto_connection(c); - //TODO: remove - //TODO: Print pub key of peer? LOGGER_DEBUG(c->log, "RESPONDER: AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { @@ -2940,15 +2730,14 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) bytes2string(log_id_public, sizeof(log_id_public), n_c->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, "peer_id_public_key: %s", log_id_public); - // NoiseIK: only happening for RESPONDER + /* NoiseIK: only happening for RESPONDER */ if (n_c->noise_handshake != nullptr) { if (!n_c->noise_handshake->initiator) { conn->noise_handshake_enabled = true; - //TODO: remove LOGGER_DEBUG(c->log, "Responder: Noise WriteMessage"); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(Noise_Handshake)); - //NOT possible here, need content afterwards! + /* TODO(goldroom): NOT possible here, need content afterwards! */ // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); /* IMPORTANT: in this case here/before create_send_handshake(), otherwise get_crypto_connection() in @@ -2967,9 +2756,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) /* Noise Split(), base nonces already set */ crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); - //TODO: remove LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()/conn->status: %d", conn->status); - //TODO: here correct? + // TODO(goldroom): here correct? crypto_memzero(n_c->noise_handshake, sizeof(Noise_Handshake)); } else { kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); @@ -2980,7 +2768,6 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) } /* non-Noise handshake */ else if (c->noise_compatibility_enabled) { - //TODO: remove LOGGER_DEBUG(c->log, "non-Noise handshake"); memcpy(conn->peer_id_public_key, n_c->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE); @@ -3008,7 +2795,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->rtt_time = DEFAULT_PING_CONNECTION; crypto_connection_add_source(c, crypt_connection_id, &n_c->source); - //TODO: here correct? => nope, crashes backwards compatbility + // TODO(goldroom): here correct? => nope, crashes backwards compatbility // crypto_memzero(n_c->noise_handshake, sizeof(Noise_Handshake)); return crypt_connection_id; @@ -3022,22 +2809,15 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) */ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) { - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - int crypt_connection_id = getcryptconnection_id(c, real_public_key); if (crypt_connection_id != -1) { - //TODO: remove LOGGER_DEBUG(c->log, "Crypto connection already exists => crypt_connection_id: %d", crypt_connection_id); return crypt_connection_id; } crypt_connection_id = create_crypto_connection(c); - //TODO: remove - // LOGGER_DEBUG(c->log, "AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); - if (crypt_connection_id == -1) { return -1; } @@ -3055,6 +2835,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u conn->connection_number_tcp = connection_number_tcp; /* Necessary for backwards compatibility to switch to non-Noise handshake */ memcpy(conn->peer_id_public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // TODO(goldroom): remove before merge char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); LOGGER_DEBUG(c->log, "peer_id_public_key: %s", log_id_public); @@ -3089,13 +2870,9 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u /* Noise: create and set ephemeral private+public */ crypto_new_keypair(c->rng, conn->noise_handshake->ephemeral_public, conn->noise_handshake->ephemeral_private); - conn->cookie_request_number = random_u64(c->rng); uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; - //TODO: remove - // LOGGER_DEBUG(c->log, "INITIATOR: BEFORE: create_cookie_request()"); - if (create_cookie_request(c, cookie_request, conn->peer_dht_public_key, conn->cookie_request_number, conn->shared_key) != sizeof(cookie_request) || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { @@ -3104,12 +2881,6 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u return -1; } - //TODO: remove - // LOGGER_DEBUG(c->log, "AFTER: create_cookie_request()"); - - //TODO: remove - // LOGGER_DEBUG(c->log, "INITIATOR: END"); - return crypt_connection_id; } @@ -3159,7 +2930,6 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ return -1; } - //TODO: remove LOGGER_DEBUG(c->log, "Packet ID: %d/length: %d/crypt_connection_id: %d/conn->status: %d", packet[0], length, crypt_connection_id, conn->status); @@ -3183,7 +2953,6 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in { Net_Crypto *c = (Net_Crypto *)object; - //TODO: remove LOGGER_DEBUG(c->log, "Packet: %d/length: %d", packet[0], length); if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) { @@ -3371,9 +3140,6 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - if (conn == nullptr) { return -1; } @@ -3398,9 +3164,6 @@ int connection_lossy_data_handler(const Net_Crypto *c, int crypt_connection_id, { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - if (conn == nullptr) { return -1; } @@ -3425,8 +3188,7 @@ int nc_dht_pk_callback(const Net_Crypto *c, int crypt_connection_id, dht_pk_cb * { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, ""); if (conn == nullptr) { return -1; @@ -3471,7 +3233,6 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t const int crypt_connection_id = crypto_id_ip_port(c, source); - //TODO: remove LOGGER_DEBUG(c->log, "Packet ID: %d/length: %d/crypt_connection_id: %d", packet[0], length, crypt_connection_id); /* No crypto connection yet = RESPONDER case */ @@ -3540,21 +3301,21 @@ static void send_crypto_packets(Net_Crypto *c) continue; } - //TODO(goldroom): remove? interesting if want to adapt interval + // TODO(goldroom): remove? interesting if want to adapt interval // LOGGER_DEBUG(c->log, "conn->handshake_send_interval: %d", conn->handshake_send_interval); // LOGGER_DEBUG(c->log, "conn->temp_packet_sent_time: %lu", conn->temp_packet_sent_time); // LOGGER_DEBUG(c->log, "(conn->handshake_send_interval + conn->temp_packet_sent_time): %lu", (conn->handshake_send_interval + conn->temp_packet_sent_time)); // LOGGER_DEBUG(c->log, "temp_time: %lu", temp_time); - //TODO(goldroom): Use again? / adapt interval? + // TODO(goldroom): Use again? / adapt interval? if ((CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time) < temp_time) { - //TODO: remove + // TODO(goldroom): remove //LOGGER_DEBUG(c->log, "=> call send_temp_packet() => random_backoff: %d", random_backoff); // c_sleep(random_backoff); send_temp_packet(c, i); } - //TODO: remove? where to add? + // TODO(goldroom): remove? where to add? // if ((conn->handshake_send_interval + conn->temp_packet_sent_time) < temp_time) { // send_temp_packet(c, i); // } @@ -3882,9 +3643,6 @@ int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - //TODO: remove - // LOGGER_DEBUG(c->log, "ENTERING"); - if (conn == nullptr) { return -1; } @@ -3989,8 +3747,7 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool void new_keys(Net_Crypto *c) { - //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, ""); crypto_new_keypair(c->rng, c->self_id_public_key, c->self_id_secret_key); } @@ -4084,7 +3841,6 @@ static void kill_timedout(Net_Crypto *c, void *userdata) continue; } - //TODO: remove LOGGER_DEBUG(c->log, "connection_kill"); connection_kill(c, i, userdata); } @@ -4109,9 +3865,7 @@ uint32_t crypto_run_interval(const Net_Crypto *c) /** Main loop. */ void do_net_crypto(Net_Crypto *c, void *userdata) { - //TODO: remove - // LOGGER_DEBUG(c->log, "do_net_crypto()"); - //TODO(goldroom) update cookie symmetric key every ~2 minutes (cf. WireGuard)? + // TODO(goldroom) update cookie symmetric key every ~2 minutes (cf. WireGuard)? kill_timedout(c, userdata); do_tcp(c, userdata); send_crypto_packets(c); @@ -4123,8 +3877,7 @@ void kill_net_crypto(Net_Crypto *c) return; } - //TODO: remove - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, ""); const Memory *mem = c->mem; diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index dfce4f848a..9420b469a8 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -136,10 +136,10 @@ typedef struct New_Connection { uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce to decrypt received packets. */ uint8_t peer_ephemeral_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The public key of the peer. */ // Necessary for Noise - //TODO(goldroom): refactor to not use struct + // TODO(goldroom): refactor to not use struct Noise_Handshake noise_handshake_data; Noise_Handshake *noise_handshake; - //TODO(goldroom): if no struct necessary + // TODO(goldroom): if no struct necessary // uint8_t noise_hash[CRYPTO_SHA512_SIZE]; // uint8_t noise_chaining_key[CRYPTO_SHA512_SIZE]; // uint8_t niose_send_key[CRYPTO_SHARED_KEY_SIZE]; @@ -418,7 +418,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk); */ non_null() Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns, - Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info, const bool noise_compatibility_enabled); + Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info, bool noise_compatibility_enabled); /** return the optimal interval in ms for running do_net_crypto. */ non_null() @@ -431,7 +431,7 @@ void do_net_crypto(Net_Crypto *c, void *userdata); nullable(1) void kill_net_crypto(Net_Crypto *c); -//TODO(goldroom): necessary? +// TODO(goldroom): necessary? //static void handshake_zero(struct noise_handshake *handshake); From a96f5ae8e51750fc239e459ee985e69c7a785e60 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 8 Feb 2025 18:55:22 +0100 Subject: [PATCH 143/150] fix: fixed logging for CI --- toxcore/net_crypto.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 7f391bdd0b..02d5e6c09b 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1857,7 +1857,7 @@ static int send_kill_packet(const Net_Crypto *c, int crypt_connection_id) const uint8_t kill_packet[1] = {PACKET_ID_KILL}; - LOGGER_DEBUG(c->log, ""); + LOGGER_DEBUG(c->log, ">"); return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end, kill_packet, sizeof(kill_packet)); @@ -1868,7 +1868,7 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, ""); + LOGGER_DEBUG(c->log, ">"); if (conn == nullptr) { return; @@ -2366,7 +2366,7 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) non_null() static int create_crypto_connection(Net_Crypto *c) { - LOGGER_DEBUG(c->log, ""); + LOGGER_DEBUG(c->log, ">"); int id = -1; @@ -2415,7 +2415,7 @@ static int create_crypto_connection(Net_Crypto *c) non_null() static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) { - LOGGER_DEBUG(c->log, ""); + LOGGER_DEBUG(c->log, ">"); if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) { return -1; @@ -3188,7 +3188,7 @@ int nc_dht_pk_callback(const Net_Crypto *c, int crypt_connection_id, dht_pk_cb * { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, ""); + LOGGER_DEBUG(c->log, ">"); if (conn == nullptr) { return -1; @@ -3747,7 +3747,7 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool void new_keys(Net_Crypto *c) { - LOGGER_DEBUG(c->log, ""); + LOGGER_DEBUG(c->log, ">"); crypto_new_keypair(c->rng, c->self_id_public_key, c->self_id_secret_key); } @@ -3877,7 +3877,7 @@ void kill_net_crypto(Net_Crypto *c) return; } - LOGGER_DEBUG(c->log, ""); + LOGGER_DEBUG(c->log, ">"); const Memory *mem = c->mem; From ac15cc04a2758495c35813c0a99d09b720cf66c5 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 8 Feb 2025 19:21:44 +0100 Subject: [PATCH 144/150] fix: possible fix for failing auto_reconnect_test in bazel-asan --- toxcore/logger.c | 2 +- toxcore/net_crypto.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/toxcore/logger.c b/toxcore/logger.c index df66d2bcaf..5db75775fd 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -83,7 +83,7 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, uint3 #endif /* WIN32 */ // Format message - // TODO: changed from 1024 to 4096 + // TODO(goldroom): changed from 1024 to 4096 char msg[4096]; va_list args; va_start(args, format); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 02d5e6c09b..0cf953802a 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2123,11 +2123,17 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake != nullptr) { // TODO(goldroom): removed CRYPTO_CONN_NOT_CONFIRMED -> test for possible side effects + // TODO(goldroom): seems to break auto_reconnect_test in bazel-asan + // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING + // && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { + // LOGGER_DEBUG(c->log, "NoiseIK: already handled handshake packet"); + // return -1; + // } if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING - && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - LOGGER_DEBUG(c->log, "NoiseIK: already handled handshake packet"); + && conn->status != CRYPTO_CONN_HANDSHAKE_SENT + && conn->status != CRYPTO_CONN_NOT_CONFIRMED) { return -1; - } + } } else { if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT @@ -2135,7 +2141,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } } - /* necessary for Noise and non-Noise */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -2249,7 +2254,6 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const conn->status = CRYPTO_CONN_NOT_CONFIRMED; LOGGER_DEBUG(c->log, "conn->status: set to CRYPTO_CONN_NOT_CONFIRMED (%d)", conn->status); if (conn->noise_handshake->initiator) { - /* INITIATOR Noise Split(), nonces already set in crypto connection */ crypto_hkdf(conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); @@ -2260,9 +2264,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); } - } - /* Backwards compatibility: non-Noise handshake case */ - else { + } else { /* Backwards compatibility: non-Noise handshake case */ LOGGER_DEBUG(c->log, "non-Noise handshake"); // if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { // TODO(goldroom): doesn't work if Noise handshake packet was sent before if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) { From fc432081bdf77b5ff1feb415eb85b2f032690d9d Mon Sep 17 00:00:00 2001 From: goldroom Date: Sat, 8 Feb 2025 19:47:11 +0100 Subject: [PATCH 145/150] fix: fixes for ccplint CI check --- toxcore/net_crypto.c | 69 +++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 0cf953802a..9a076de350 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -602,9 +602,9 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); return NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR; - } - /* Noise RESPONDER: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + } else { + /* Noise RESPONDER: <- e, ee, se */ + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -615,7 +615,6 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u [MAC encrypted payload 16 bytes] => 161 bytes in total */ - else { LOGGER_DEBUG(c->log, "Noise: RESPONDER"); /* e */ @@ -647,9 +646,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u return NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER; } - } - /* non-Noise handshake, check for enabled backwards compatibility happens in create_send_handshake() */ - else { + } else { /* non-Noise handshake, check for enabled backwards compatibility happens in create_send_handshake() */ LOGGER_DEBUG(c->log, "non-Noise handshake"); uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; memcpy(plain, send_nonce, CRYPTO_NONCE_SIZE); @@ -777,9 +774,9 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP crypto_memzero(handshake_payload_plain, NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR); return true; - } - /* Noise ReadMessage() if initiator: <- e, ee, se */ - /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) + } else { + /* Noise ReadMessage() if initiator: <- e, ee, se */ + /* Responder: Handshake packet structure (Noise_IK_25519_ChaChaPoly_BLAKE2b) [uint8_t 26] [session public key of the peer (32 bytes)] => currently in plain ~~[24 bytes nonce for handshake payload encryption]~~ NOT necessary for ChaCha20-Poly1305 @@ -790,7 +787,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP [MAC encrypted payload 16 bytes] => 161 bytes in total */ - else { memcpy(noise_handshake->remote_ephemeral, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); noise_mix_hash(noise_handshake->hash, noise_handshake->remote_ephemeral, CRYPTO_PUBLIC_KEY_SIZE); @@ -831,9 +827,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t recv_nonce[CRYP return true; } - } - /* non-Noise handshake, check for enabled backwards compatibility happens in calling functions */ - else { + } else { /* non-Noise handshake, check for enabled backwards compatibility happens in calling functions */ LOGGER_DEBUG(c->log, "non-Noise handshake"); if (packet_length != HANDSHAKE_PACKET_LENGTH) { @@ -1817,9 +1811,7 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c return -1; } } - } - /* non-Noise handshake*/ - else if(c->noise_compatibility_enabled) { + } else if(c->noise_compatibility_enabled) { /* non-Noise handshake*/ LOGGER_DEBUG(c->log, "non-Noise handshake"); uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; @@ -1832,8 +1824,7 @@ static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, c if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) { return -1; } - } - else { + } else { return -1; } @@ -2093,8 +2084,7 @@ static int handle_packet_cookie_response(const Net_Crypto *c, int crypt_connecti if (create_send_handshake(c, crypt_connection_id, cookie, conn->peer_dht_public_key) != 0) { return -1; } - } - else { + } else { return -1; } @@ -2122,8 +2112,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const packet[0], length, crypt_connection_id, conn->status); if (conn->noise_handshake != nullptr) { - // TODO(goldroom): removed CRYPTO_CONN_NOT_CONFIRMED -> test for possible side effects - // TODO(goldroom): seems to break auto_reconnect_test in bazel-asan + // TODO(goldroom): removing CRYPTO_CONN_NOT_CONFIRMED breaks auto_reconnect_test in bazel-asan // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING // && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { // LOGGER_DEBUG(c->log, "NoiseIK: already handled handshake packet"); @@ -2202,10 +2191,8 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } else { return -1; } - } - /* Case where RESPONDER with and without change from INITIATOR */ - // TODO(goldroom): this doesn't seem to happen, wether in auto_tests nor in real-world tests => remove? - else { + } else { /* Case where RESPONDER with and without change from INITIATOR */ + // TODO(goldroom): if status CRYPTO_CONN_NOT_CONFIRMED is handled this does happen (which is necessary for auto_reconnect_test) if (length == NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR) { LOGGER_DEBUG(c->log, "RESPONDER: Noise handshake -> NOISE_HANDSHAKE_PACKET_LENGTH_INITIATOR"); /* necessary, otherwise broken after INITIATOR to RESPONDER change; also necessary without change */ @@ -2228,17 +2215,15 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const } // TODO(goldroom): here? conn->status = CRYPTO_CONN_HANDSHAKE_SENT; - } - /* cannot change to INITIATOR here, connection broken */ - else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { // TODO(goldroom): Does this even happen? + } else if (length == NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER) { + /* cannot change to INITIATOR here, connection broken */ + // TODO(goldroom): if status CRYPTO_CONN_NOT_CONFIRMED is handled this does happen (which is necessary for auto_reconnect_test) LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); connection_kill(c, crypt_connection_id, userdata); // TODO(goldroom): leave here? return -1; } } - } - /* non-Noise handshake */ - else { + } else { /* non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); /* necessary only for non-Noise */ uint8_t peer_id_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -2257,9 +2242,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* INITIATOR Noise Split(), nonces already set in crypto connection */ crypto_hkdf(conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); LOGGER_DEBUG(c->log, "INITIATOR: After Noise Split()"); - } - /* Noise RESPONDER */ - else { + } else { /* Noise RESPONDER */ /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); LOGGER_DEBUG(c->log, "RESPONDER: After Noise Split()"); @@ -2581,9 +2564,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, mem_delete(c->mem, n_c.peer_cookie); return -1; } - } - /* case non-Noise handshake */ - else if (c->noise_compatibility_enabled) { + } else if (c->noise_compatibility_enabled) { /* case non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); /* Necessary for backwards compatibility */ n_c.noise_handshake = nullptr; @@ -2615,7 +2596,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!pk_equal(n_c.peer_dht_public_key, conn->peer_dht_public_key)) { connection_kill(c, crypt_connection_id, userdata); - } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ + } else if(length != HANDSHAKE_PACKET_LENGTH) { /* case NoiseIK handshake */ if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { mem_delete(c->mem, n_c.peer_cookie); return -1; @@ -2642,9 +2623,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, mem_delete(c->mem, n_c.peer_cookie); return 0; - } - /* case non-Noise handshake */ - else { + } else { /* case non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); conn->noise_handshake_enabled = false; @@ -2767,9 +2746,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - } - /* non-Noise handshake */ - else if (c->noise_compatibility_enabled) { + } else if (c->noise_compatibility_enabled) { /* non-Noise handshake */ LOGGER_DEBUG(c->log, "non-Noise handshake"); memcpy(conn->peer_id_public_key, n_c->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE); From 4af0b03b319a6fbb065a329e8956f9e8a903b145 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sun, 16 Feb 2025 18:09:09 +0100 Subject: [PATCH 146/150] test: added further debug logging for real-world tests. Removed connection_kill() from handle_data_packet_core() and also from handle_packet_crypto_hs(). Using conn->peer_id_public_key also in Noise for testing/debugging purposes. --- toxcore/crypto_core.c | 2 + toxcore/net_crypto.c | 100 +++++++++++++++++++++++++++++++----------- 2 files changed, 76 insertions(+), 26 deletions(-) diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index dbfd1c0929..09e1ebd45d 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -886,6 +886,8 @@ int noise_decrypt_and_hash(uint8_t *plaintext, const uint8_t *ciphertext, ciphertext, encrypted_length, plaintext, hash, CRYPTO_NOISE_BLAKE2B_HASH_SIZE); + // TODO(goldroom): add condition for plaintext_length? (if decrypt failed mix_hash is unnecessary) + // TODO(goldroom): or instead fix all cases that lead to decrypt failed noise_mix_hash(hash, ciphertext, encrypted_length); return plaintext_length; diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 9a076de350..e8e6345250 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -244,7 +244,7 @@ non_null() static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uint8_t *dht_public_key, uint64_t number, uint8_t *shared_key) { - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, "Packet: %d/NET_PACKET_COOKIE_REQUEST", NET_PACKET_COOKIE_REQUEST); // TODO(goldroom): adapt for new Noise-cookie mechanism _only_ or different cookie mechanism? E.g. as in WireGuard? uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; @@ -333,7 +333,7 @@ non_null() static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain, const uint8_t *shared_key, const uint8_t *dht_public_key) { - LOGGER_DEBUG(c->log, "ENTERING"); + LOGGER_DEBUG(c->log, "Packet: %d/NET_PACKET_COOKIE_REQUEST", NET_PACKET_COOKIE_REQUEST); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; memcpy(cookie_plain, request_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -1896,9 +1896,14 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const int len = handle_data_packet(c, crypt_connection_id, data, packet, length); if (len <= (int)(sizeof(uint32_t) * 2)) { - LOGGER_DEBUG(c->log, "decryption failure/crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); - // TODO(goldroom): unwanted side effects? - connection_kill(c, crypt_connection_id, userdata); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "decryption failure/crypt_connection_id: %d/conn->status: %d/peer_id_public_key: %s", crypt_connection_id, conn->status, conn->peer_id_public_key); + // TODO(goldroom): unwanted side effects? => yes, happens in practice => but why? + // TODO(goldroom): Enables DoS attacks? + // connection_kill(c, crypt_connection_id, userdata); return -1; } @@ -1945,7 +1950,11 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const clear_temp_packet(c, crypt_connection_id); conn->status = CRYPTO_CONN_ESTABLISHED; - LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED/crypt_connection_id: %d/conn->status: %d/peer_id_public_key: %s", crypt_connection_id, conn->status, log_id_public); /* Noise: noise_handshake not necessary anymore => memzero and free */ if (conn->noise_handshake != nullptr) { @@ -1957,7 +1966,8 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const /* also crypto_memzero() non-Noise values from crypto connection */ crypto_memzero(conn->ephemeral_secret_key, CRYPTO_SECRET_KEY_SIZE); crypto_memzero(conn->ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); - crypto_memzero(conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); + // TODO(goldroom): no memzero for testing purposes, memzero for merge? + // crypto_memzero(conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); crypto_memzero(conn->peer_ephemeral_public_key, CRYPTO_PUBLIC_KEY_SIZE); if (conn->connection_status_callback != nullptr) { @@ -2051,8 +2061,12 @@ static int handle_packet_cookie_response(const Net_Crypto *c, int crypt_connecti return -1; } - LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d", - packet[0], length, crypt_connection_id, conn->status); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d/peer_id_public_key: %s", + packet[0], length, crypt_connection_id, conn->status, log_id_public); if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING) { return -1; @@ -2108,8 +2122,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } - LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d", - packet[0], length, crypt_connection_id, conn->status); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d/peer_id_public_key: %s", + packet[0], length, crypt_connection_id, conn->status, log_id_public); if (conn->noise_handshake != nullptr) { // TODO(goldroom): removing CRYPTO_CONN_NOT_CONFIRMED breaks auto_reconnect_test in bazel-asan @@ -2219,7 +2237,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* cannot change to INITIATOR here, connection broken */ // TODO(goldroom): if status CRYPTO_CONN_NOT_CONFIRMED is handled this does happen (which is necessary for auto_reconnect_test) LOGGER_DEBUG(c->log, "RESPONDER: NOISE_HANDSHAKE_PACKET_LENGTH_RESPONDER"); - connection_kill(c, crypt_connection_id, userdata); // TODO(goldroom): leave here? + // connection_kill(c, crypt_connection_id, userdata); // TODO(goldroom): leave here? leads to weird behavior in real-world tests return -1; } } @@ -2278,8 +2296,12 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con return -1; } - LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d", - packet[0], length, crypt_connection_id, conn->status); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d/peer_id_public_key: %s", + packet[0], length, crypt_connection_id, conn->status, log_id_public); if (conn->status != CRYPTO_CONN_NOT_CONFIRMED && conn->status != CRYPTO_CONN_ESTABLISHED) { @@ -2387,6 +2409,8 @@ static int create_crypto_connection(Net_Crypto *c) // TODO(Green-Sky): This enum is likely unneeded and the same as FREE. c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; + + LOGGER_DEBUG(c->log, "crypt_connection_id: %d", id); } return id; @@ -2540,6 +2564,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ + // TODO(goldroom): In tests this also happens for Noise INITIATOR => how to handle this case? if (length != HANDSHAKE_PACKET_LENGTH) { // TODO(goldroom): adapt static allocation? n_c.noise_handshake = &n_c.noise_handshake_data; @@ -2587,7 +2612,11 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* happens NoiseIK handshake (e.g. auto_tox_many_test) */ // TODO(goldroom): why is this called twice in row via tcp_oob_callback()? if (crypt_connection_id != -1) { - LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING -> crypt_connection_id: %d", crypt_connection_id); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), n_c.peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING -> crypt_connection_id: %d/peer_id_public_key: %s", crypt_connection_id, log_id_public); Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); if (conn == nullptr) { @@ -2616,7 +2645,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, /* RESPONDER Noise Split(): vice-verse keys in comparison to initiator */ crypto_hkdf(conn->recv_key, CRYPTO_SYMMETRIC_KEY_SIZE, conn->send_key, CRYPTO_SYMMETRIC_KEY_SIZE, nullptr, 0, conn->noise_handshake->chaining_key); - LOGGER_DEBUG(c->log, "Noise RESPONDER crypt_connection_id: %d/conn->status: %d", crypt_connection_id, conn->status); + LOGGER_DEBUG(c->log, "Noise RESPONDER crypt_connection_id: %d/conn->status: %d/peer_id_public_key: %s", crypt_connection_id, conn->status, log_id_public); crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; @@ -2684,7 +2713,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) const int crypt_connection_id = create_crypto_connection(c); - LOGGER_DEBUG(c->log, "RESPONDER: AFTER create_crypto_connection() => crypt_connection_id: %d", crypt_connection_id); + LOGGER_DEBUG(c->log, "crypt_connection_id: %d", crypt_connection_id); if (crypt_connection_id == -1) { LOGGER_ERROR(c->log, "Could not create new crypto connection"); @@ -2709,7 +2738,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; bytes2string(log_id_public, sizeof(log_id_public), n_c->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "peer_id_public_key: %s", log_id_public); + LOGGER_DEBUG(c->log, "crypt_connection_id: %d/peer_id_public_key: %s", crypt_connection_id, log_id_public); /* NoiseIK: only happening for RESPONDER */ if (n_c->noise_handshake != nullptr) { @@ -2717,6 +2746,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->noise_handshake_enabled = true; LOGGER_DEBUG(c->log, "Responder: Noise WriteMessage"); memcpy(conn->noise_handshake, n_c->noise_handshake, sizeof(Noise_Handshake)); + // TODO(goldroom): not necessary for Noise, added for debugging/testing purposes + memcpy(conn->peer_id_public_key, n_c->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE); /* TODO(goldroom): NOT possible here, need content afterwards! */ // crypto_memzero(n_c->noise_handshake, sizeof(struct noise_handshake)); @@ -2817,7 +2848,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u // TODO(goldroom): remove before merge char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); - LOGGER_DEBUG(c->log, "peer_id_public_key: %s", log_id_public); + LOGGER_DEBUG(c->log, "crypt_connection_id: %d/peer_id_public_key: %s", crypt_connection_id, log_id_public); /* Base nonces are a counter in transport phase after NoiseIK handshake */ @@ -2909,8 +2940,12 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ return -1; } - LOGGER_DEBUG(c->log, "Packet ID: %d/length: %d/crypt_connection_id: %d/conn->status: %d", - packet[0], length, crypt_connection_id, conn->status); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d/conn->status: %d/peer_id_public_key: %s", + packet[0], length, crypt_connection_id, conn->status, log_id_public); if (packet[0] == NET_PACKET_COOKIE_REQUEST) { return tcp_handle_cookie_request(c, conn->connection_number_tcp, packet, length); @@ -3167,12 +3202,16 @@ int nc_dht_pk_callback(const Net_Crypto *c, int crypt_connection_id, dht_pk_cb * { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, ">"); - if (conn == nullptr) { return -1; } + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "crypt_connection_id: %d/peer_id_public_key: %s", crypt_connection_id, log_id_public); + conn->dht_pk_callback = function; conn->dht_pk_callback_object = object; conn->dht_pk_callback_number = number; @@ -3212,7 +3251,7 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t const int crypt_connection_id = crypto_id_ip_port(c, source); - LOGGER_DEBUG(c->log, "Packet ID: %d/length: %d/crypt_connection_id: %d", packet[0], length, crypt_connection_id); + LOGGER_DEBUG(c->log, "Packet: %d/length: %d/crypt_connection_id: %d", packet[0], length, crypt_connection_id); /* No crypto connection yet = RESPONDER case */ if (crypt_connection_id == -1) { @@ -3675,11 +3714,16 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - LOGGER_DEBUG(c->log, "crypt_connection_id: %d", crypt_connection_id); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "crypt_connection_id: %d/peer_id_public_key: %s", crypt_connection_id, log_id_public); int ret = -1; if (conn != nullptr) { + // TODO(goldroom): Add CRYPTO_CONN_NOT_CONFIRMED for broken Noise handshakes? => removed connection_kill() for now from handle_packet_crypto_hs() if (conn->status == CRYPTO_CONN_ESTABLISHED) { send_kill_packet(c, crypt_connection_id); } @@ -3726,8 +3770,12 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool void new_keys(Net_Crypto *c) { - LOGGER_DEBUG(c->log, ">"); crypto_new_keypair(c->rng, c->self_id_public_key, c->self_id_secret_key); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), c->self_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "self_id_public_key: %s", log_id_public); } /** @brief Save the public and private keys to the keys array. From 7ccf4e8bff8d34f55f5602e08d11d354fefd8943 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sun, 16 Feb 2025 18:14:30 +0100 Subject: [PATCH 147/150] fix: double declaration --- toxcore/net_crypto.c | 1 - 1 file changed, 1 deletion(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index e8e6345250..247e181e33 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2613,7 +2613,6 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, // TODO(goldroom): why is this called twice in row via tcp_oob_callback()? if (crypt_connection_id != -1) { // TODO(goldroom): remove before merge? - char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; bytes2string(log_id_public, sizeof(log_id_public), n_c.peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); // TODO(goldroom): remove print of static id public key before merge? LOGGER_DEBUG(c->log, "RESPONDER: CRYPTO CONN EXISTING -> crypt_connection_id: %d/peer_id_public_key: %s", crypt_connection_id, log_id_public); From 97d99105167eaab30a5c09db4799da1366a8b0ed Mon Sep 17 00:00:00 2001 From: goldroom Date: Sun, 16 Feb 2025 18:46:23 +0100 Subject: [PATCH 148/150] fix: possible fix for CI --- toxcore/net_crypto.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 247e181e33..015ec58225 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -3770,11 +3770,6 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool void new_keys(Net_Crypto *c) { crypto_new_keypair(c->rng, c->self_id_public_key, c->self_id_secret_key); - // TODO(goldroom): remove before merge? - char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; - bytes2string(log_id_public, sizeof(log_id_public), c->self_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // TODO(goldroom): remove print of static id public key before merge? - LOGGER_DEBUG(c->log, "self_id_public_key: %s", log_id_public); } /** @brief Save the public and private keys to the keys array. @@ -3836,6 +3831,11 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r new_keys(temp); new_symmetric_key(rng, temp->cookie_symmetric_key); + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), temp->self_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, temp->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(temp->log, "self_id_public_key: %s", log_id_public); temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL; From d258c45c20156c58d37d91d8a082c904f8fb1f63 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sun, 16 Feb 2025 19:10:13 +0100 Subject: [PATCH 149/150] fix: possible fix for asan --- toxcore/net_crypto.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 015ec58225..027a2d3559 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -3713,15 +3713,15 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); - // TODO(goldroom): remove before merge? - char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; - bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); - // TODO(goldroom): remove print of static id public key before merge? - LOGGER_DEBUG(c->log, "crypt_connection_id: %d/peer_id_public_key: %s", crypt_connection_id, log_id_public); - int ret = -1; if (conn != nullptr) { + // TODO(goldroom): remove before merge? + char log_id_public[CRYPTO_PUBLIC_KEY_SIZE*2+1]; + bytes2string(log_id_public, sizeof(log_id_public), conn->peer_id_public_key, CRYPTO_PUBLIC_KEY_SIZE, c->log); + // TODO(goldroom): remove print of static id public key before merge? + LOGGER_DEBUG(c->log, "crypt_connection_id: %d/peer_id_public_key: %s", crypt_connection_id, log_id_public); + // TODO(goldroom): Add CRYPTO_CONN_NOT_CONFIRMED for broken Noise handshakes? => removed connection_kill() for now from handle_packet_crypto_hs() if (conn->status == CRYPTO_CONN_ESTABLISHED) { send_kill_packet(c, crypt_connection_id); From b1bf78246cc7189ba1173b0fc6f521834eb0db69 Mon Sep 17 00:00:00 2001 From: goldroom Date: Sun, 16 Feb 2025 20:22:21 +0100 Subject: [PATCH 150/150] test: testing if auto_reconnect_test fails --- toxcore/net_crypto.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 027a2d3559..86aace912f 100755 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -333,7 +333,7 @@ non_null() static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain, const uint8_t *shared_key, const uint8_t *dht_public_key) { - LOGGER_DEBUG(c->log, "Packet: %d/NET_PACKET_COOKIE_REQUEST", NET_PACKET_COOKIE_REQUEST); + LOGGER_DEBUG(c->log, "Packet: %d/NET_PACKET_COOKIE_RESPONSE", NET_PACKET_COOKIE_RESPONSE); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; memcpy(cookie_plain, request_plain, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -2131,16 +2131,16 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const if (conn->noise_handshake != nullptr) { // TODO(goldroom): removing CRYPTO_CONN_NOT_CONFIRMED breaks auto_reconnect_test in bazel-asan - // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING - // && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - // LOGGER_DEBUG(c->log, "NoiseIK: already handled handshake packet"); - // return -1; - // } if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING - && conn->status != CRYPTO_CONN_HANDSHAKE_SENT - && conn->status != CRYPTO_CONN_NOT_CONFIRMED) { + && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { + LOGGER_DEBUG(c->log, "NoiseIK: already handled handshake packet"); return -1; - } + } + // if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING + // && conn->status != CRYPTO_CONN_HANDSHAKE_SENT + // && conn->status != CRYPTO_CONN_NOT_CONFIRMED) { + // return -1; + // } } else { if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT @@ -2576,6 +2576,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, } /* Noise: create and set ephemeral private+public */ + // TODO(goldroom): can this be moved to accept_crypto_connection()? crypto_new_keypair(c->rng, n_c.noise_handshake->ephemeral_public, n_c.noise_handshake->ephemeral_private); LOGGER_DEBUG(c->log, "Noise RESPONDER: After Handshake init");