-
Notifications
You must be signed in to change notification settings - Fork 291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: WIP NoiseIK handshake based on libsodium #2450
base: master
Are you sure you want to change the base?
Conversation
…bsodium in crypto core, which is to be used during the Noise-based handshake.
…ise in crypto_core. Added noise_handshake struct to net_crypto.h. Started Noise-based handshake implementation.
…r issues in crypto_core.c. Started handshake_init in net_crypto.c, added Noise functions MixKey(), MixHash(), EncryptAndHash(), DecryptAndHash().
…cf. Noise Spec WriteMessage(). Started to adapt handle_crypto_handshake() for Noise, cf. Noise Spec ReadMessage().
…reate_crypto_handshake(). Adapted handle?crypto_handshake() for Noise - initiator and responder cases.
… and noise_handle_crypto_handshake() into handle_crypto_handshake() for backwards compatibility.
…ebugging statements.
…tion #2 fails on the handshake packet from INITIATOR to RESPONDER. Adapted encryption/decryption functions, but not fixed yet.
…O_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.
…og whole handshake packet.
…nection structs from being dynamically allocated to statically allocated to fix memory leaks. Minor cleanup in regard to debug logging.
…o_connection() via correct free in wipe_crypto_connection().
…e via new_crypto_connection().
…nitiator to responder change case (relevant for reconnect test).
…ITIATOR case. memzero noise_handshake before every init. Further minor adaptions, e.g. Crypto Conn Status changes. Minor logging/debug adaptions.
…o of n_c.noise_handshake.
…end_handshake() because of a nullptr.
…) - status needs to be set _before_ create_send_handshake(). Cleaned up/adapted debug logging.
…* functions to crypto_core. Use function based on libsodium bin2hex() to print bytes for debugging (instead of custom func).
Implemented Blake2b is faster than SHA512, optimized for 64-bit systems and at least as secure as the latest standard SHA-3 (cf. here https://www.blake2.net/ ). This also removes usage of libsodium HKDF-SHA512, therefore requires no new libsodium version for CI (which was added in libsodium v1.0.19, cf. https://github.com/jedisct1/libsodium/releases/tag/1.0.19-RELEASE ) and therefore most CI checks are passing now. HMAC-BLAKE2b-512 and HKDF-BLAKE2b-512 added based on BLAKE2b primitive functions of libsodium since these are not provided at the high level API (cf. jedisct1/libsodium#788 , jedisct1/libsodium#531 ). |
…en because both peers are Noise-responder.
…s. 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 5ac12e7.
…on 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 7ec460f.
…tly broken because both peers are Noise-responder." This reverts commit 44e58f7.
This reverts commit 3440302.
This reverts commit fdb0163.
This reverts commit b3d73e2.
…nality." This reverts commit fa59b7b.
Reverted commits of possible new cookie mechanism/functionality. Aim is to cleanup this PR, get it merged and test it. |
…was added in master).
…only) a counter instead. Due to separate encryption/decryption keys they were unnecessary overhead.
This PR adds a NoiseIK implementation for a new KCI-resistant crypto handshake. The implemented Noise protocol is:
Noise_IK_25519_ChaChaPoly_SHA512
Noise_IK_25519_ChaChaPoly_BLAKE2b
(update 11.12.2024 ). This resolves #426.NoiseIK is working, tested and passes all auto/CI tests. There is also an auto test added which verifies the cryptographic correctness of
Noise_IK_25519_ChaChaPoly_BLAKE2b
(and also of formerNoise_IK_25519_ChaChaPoly_SHA512
) with test vectors provided by Noise-C.Backwards compatibility for NoiseIK handshake to non-Noise handshake is implemented (though possibly still subject to change). This enables clients using NoiseIK-toxcore to communicate with non-NoiseIK-toxcore clients. Backwards compatibility can be disabled by setting
noise_compatibility_enabled
tofalse
(default:true
) viatox_options_set_noise_compatibility_enabled
.Enabled and disabled backwards compatibility was tested successfully with toxic and minitox clients.
Status 14.06.2024: Currently most failing CI tests/checks fail due to missing functions released with libsodium 1.0.19 (i.e.crypto_kdf_hkdf_*()
which are necessary for NoiseIK; besides the linting stuff).Side effect of using libsodium >=1.0.19: Slightly faster 25519 operations.
Update 11.12.2024: Implemented HKDF-BLAKE2b-512 in crypto_core based on libsodium BLAKE2b primitive functions (since it's not exposed on the high-level API9. Therefore only the linting CI checks are failing (and do not require a newer libsodium version). See update 11.12.2024 for more info.
Further testing, reviews, feedback etc. highly appreciated.
This PR also changes symmetric encryption during the Noise handshake to ChaCha20-Poly1305 and data transport phase (based on
net_crypto
/struct Crypto_Connection
) to XChaCha20-Poly1305, both instead of XSalsa20-Poly1305.This change is necessary because XSalsa20-Poly1305 from libsodium doesn't provide Authenticated Encryption with Associated Data (AEAD), but only Authenticated Encryption (AE). AEAD is a requirement for NoiseIK. Further, the Noise specification/framework only considers ChaCha20-Poly1305 and AES256-GCM as symmetric ciphers. This means, that existing security proofs and cryptographic test vectors only exist and verify with these two ciphers. By adopting ChaCha20-Poly1305 in Tox' NoiseIK handshakes, correctness can and is verified using existing test vectors.
By utilizing XChaCha20 during data transport phase (instead of ChaCha20) it is still possible to use random 24 byte (base) nonces as this is already the case with XSalsa20 (in
net_crypto
/toxcore in general) and further using the existing handling of out-of-order message functionality (same as with old/non-Noise XSalsa20-Poly1305 encryption).Some necessary functions for NoiseIK were added to
crypto_core
:encrypt_data_symmetric_aead()
anddecrypt_data_symmetric_aead()
.encrypt_data_symmetric_xaead()
anddecrypt_data_symmetric_xaead()
.HKDF-SHA512 (crypto_hkdf()
incrypto_core
) is implemented based oncrypto_kdf_hkdf_*()
functions from libsodium 1.0.19 release (HMAC-SHA512 ().crypto_hmac512()
See: https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512crypto_hkdf()
incrypto_core
)noise_mix_key()
noise_mix_hash()
noise_decrypt_and_hash()
noise_handshake_init()
Added functions to
net_crypto
:Noise_Handshake
to and adapted structNew_Connection
innet_crypto.h
Crypto_Connection
innet_crypto.c
was moved tonoise_handshake_init()
to initialize a Noise handshake statecrypto_core
for testing/crypto verification purposesAdded option to enable/disable backwards compatibility to non-Noise handshakes/toxcore versions/clients:
bool noise_compatibility_enabled
intox.h
: default istrue
(i.e. backwards compatibility is enabled) and can be disabled by setting tofalse
viatox_options_set_noise_compatibility_enabled()
For backwards compatibility additionally these functions were adapted (all net_crypto):
create_crypto_handshake()
handle_crypto_handshake()
send_data_packet()
: to support both XSalsa20-Poly1305 (i.e.encrypt_data_symmetric()
) and XChaCha20-Poly1305 (i.e.encrypt_data_symmetric_xaead()
)handle_data_packet()
: to support both XSalsa20-Poly1305 (i.e.decrypt_data_symmetric()
) and XChaCha20-Poly1305 (i.e.decrypt_data_symmetric_xaead()
)create_send_handshake()
handle_packet_cookie_response()
handle_packet_crypto_hs()
handle_new_connection_handshake()
accept_crypto_connection()
new_crypto_connection()
Verification of
Noise_IK_25519_ChaChaPoly_BLAKE2b
andNoise_IK_25519_ChaChaPoly_SHA512
cryptographic correctness:Noise_IK_25519_ChaChaPoly_SHA512
test vectors from Noise-C tocrypto_test.c
auto testtest_noiseik()
functionThe most notable changes to the non-Noise handshake are:
encrypt_precompute()
calls crypto_box_beforenm() which hashes the X25519 result with HSalsa20 (cf. Tox Handshake Vulnerable to KCI #426 (comment) and https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c#L45).Security Audit / Cryptographic Analysis Report
to discuss the security guarantees provided with this new handshake. The analysis also included an inspection of the
implementation's code.
3report_ngir-tox.pdf
Changes/recommendations from the security analysis where incorporated:
CRYPTO_PUBLIC_KEY_SIZE
toCRYPTO_SECRET_KEY_SIZE
MixHash(prologue)
innoise_handshake_init()
even if the prologue is zero-length in ToxNoise_IK_25519_ChaChaPoly_SHA512
instead ofNoise_IK_25519_XChaChaPoly_SHA512
to be compliant with Noise specification/framework after discussion with ROS reviewer. This further reduced handshake packet size for initiator and responder (i.e. removed unnecessary random nonces from handshake packets).NoiseIK provides formally-verified security properties (similar to WireGuard®; cf. https://noiseexplorer.com/):
11.06.2024: Update on the work performed in this pull request:
Noise_IK_25519_XChaChaPoly_SHA512
toNoise_IK_25519_ChaChaPoly_SHA512
; i.e. ChaCha20-Poly1305 is used during the handshake instead of XChaCha20. This means that a compliant Noise protocol with existing test vectors is used. The implementation was verified with test vectors from Noise-C [1] by adding atest_noiseik()
function toauto_tests/crypto_test.c
.noise_mix_hash()
with an empty/zero-length prologue was discoveredcrypto_kdf_hkdf_*()
from 1.0.19 release which are necessary for NoiseIK) besides the linting stuff. (@iphydf )Update 11.12.2024 (comment)
Open:
Contact Information
Tobi/goldroom is available in Tox/TokTok development channel (
360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
) and in Matrix (@tobi_fh:matrix.org) and ready for any input, questions, remarks, discussions or complaints.Resources:
See fore more information:
This project was funded through the NGI Assure Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 957073.
This change is