From e587513cfcdc111af8871d0d0a0022602ae59f30 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 27 Dec 2025 11:42:19 -0500 Subject: [PATCH] apply MixHash right after Encrypt/Decrypt operations --- libi2pd/NTCP2.cpp | 27 +++++++++++++++++---------- libi2pd/NTCP2.h | 2 +- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index a30b8257..aad28956 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -94,13 +94,8 @@ namespace transport return KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetNTCP2StaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); } - bool NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) + bool NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * epub) { - MixHash (sessionRequest + 32, 32); // encrypted payload - - int paddingLength = sessionRequestLen - 64; - if (paddingLength > 0) - MixHash (sessionRequest + 64, paddingLength); MixHash (epub, 32); // x25519 between remote pub and ephemaral priv @@ -112,12 +107,17 @@ namespace transport bool NTCP2Establisher::KDF2Alice () { - return KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetRemotePub ()); + return KeyDerivationFunction2 (GetRemotePub ()); } bool NTCP2Establisher::KDF2Bob () { - return KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ()); + // padding is not known in ProcessSessionRequestMessage + int paddingLength = m_SessionRequestBufferLen - 64; + if (paddingLength > 0) + MixHash (m_SessionRequestBuffer + 64, paddingLength); + + return KeyDerivationFunction2 (GetPub ()); } bool NTCP2Establisher::KDF3Alice () @@ -209,9 +209,14 @@ namespace transport LogPrint (eLogWarning, "NTCP2: SessionRequest options frame AEAD encryption failed"); return false; } + MixHash (m_SessionRequestBuffer + offset, 32); offset += 32; // padding - RAND_bytes (m_SessionRequestBuffer + offset, paddingLength); + if (paddingLength) + { + RAND_bytes (m_SessionRequestBuffer + offset, paddingLength); + MixHash (m_SessionRequestBuffer + offset, paddingLength); + } m_SessionRequestBufferLen = offset + paddingLength; // create m3p2 payload (RouterInfo block) for SessionConfirmed m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes @@ -301,6 +306,7 @@ namespace transport uint8_t options[16]; if (Decrypt (m_SessionRequestBuffer + 32, options, 16)) { + MixHash (m_SessionRequestBuffer + 32, 32); // options if (options[0] && options[0] != i2p::context.GetNetID ()) { @@ -311,6 +317,7 @@ namespace transport { paddingLen = bufbe16toh (options + 2); m_SessionRequestBufferLen = paddingLen + 64; + // actual padding is not known yet, apply MixHash later in KDF2Bob m3p2Len = bufbe16toh (options + 4); if (m3p2Len < 16) { @@ -652,7 +659,7 @@ namespace transport } else { - boost::asio::post (m_Server.GetEstablisherService (), + boost::asio::post (m_Server.GetEstablisherService (), [s = shared_from_this ()] () { s->SendSessionCreated (); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index dd3baa28..3b84bd4a 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -105,7 +105,7 @@ namespace transport bool KDF3Bob (); bool KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH - bool KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate + bool KeyDerivationFunction2 (const uint8_t * epub); // for SessionCreate void CreateEphemeralKey (); bool CreateSessionRequestMessage (std::mt19937& rng);