From 5bc157eb190e5b64a087d56bdd24cef1778cc7f2 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 Jun 2018 12:28:07 -0400 Subject: [PATCH] send data frame for NTCP2 --- libi2pd/NTCP2.cpp | 44 +++++++++++++++++++++++++++++++++++++++++--- libi2pd/NTCP2.h | 10 +++++++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 4551a8cd..594f4a93 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -20,7 +20,8 @@ namespace transport m_Server (server), m_Socket (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr), - m_NextReceivedBuffer (nullptr), m_ReceiveSequenceNumber (0) + m_NextReceivedBuffer (nullptr), m_NextSendBuffer (nullptr), + m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0) { auto addr = in_RemoteRouter->GetNTCPAddress (); if (addr->ntcp2) @@ -38,6 +39,7 @@ namespace transport delete[] m_SessionCreatedBuffer; delete[] m_SessionConfirmedBuffer; delete[] m_NextReceivedBuffer; + delete[] m_NextSendBuffer; } void NTCP2Session::Terminate () @@ -69,6 +71,12 @@ namespace transport HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, derived, &len); } + void NTCP2Session::CreateNonce (uint64_t seqn, uint8_t * nonce) + { + memset (nonce, 0, 4); + htole64buf (nonce + 4, seqn); + } + void NTCP2Session::KeyDerivationFunction1 (const uint8_t * rs, const uint8_t * priv, const uint8_t * pub, uint8_t * derived) { static const uint8_t protocolNameHash[] = @@ -378,7 +386,7 @@ namespace transport // part1 48 bytes m_SessionConfirmedBuffer = new uint8_t[2048]; // TODO: actual size uint8_t nonce[12]; - memset (nonce, 0, 4); htole64buf (nonce + 4, 1); // set nonce to 1 + CreateNonce (1, nonce); i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, h, 32, m_K, nonce, m_SessionConfirmedBuffer, 48, true); // encrypt // part 2 // update AD again @@ -411,7 +419,16 @@ namespace transport LogPrint (eLogDebug, "NTCP2: SessionConfirmed sent"); KeyDerivationFunctionDataPhase (); memcpy (m_ReceiveIV, m_Sipkeysba + 16, 8); //Alice + memcpy (m_SendIV, m_Sipkeysab + 16, 8); //Alice ReceiveLength (); + + // TODO: remove + uint8_t pad[1024]; + auto paddingLength = rand () % 1000; + RAND_bytes (pad + 3, paddingLength); + pad[0] = 254; + htobe16buf (pad + 1, paddingLength); + SendNextFrame (pad, paddingLength + 3); } void NTCP2Session::HandleSessionCreatedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) @@ -473,7 +490,7 @@ namespace transport else { uint8_t nonce[12]; - memset (nonce, 0, 4); htole64buf (nonce + 4, m_ReceiveSequenceNumber); m_ReceiveSequenceNumber++; + CreateNonce (m_ReceiveSequenceNumber, nonce); m_ReceiveSequenceNumber++; uint8_t * decrypted = new uint8_t[m_NextReceivedLen]; if (i2p::crypto::AEADChaCha20Poly1305 (m_NextReceivedBuffer, m_NextReceivedLen-16, nullptr, 0, m_Kba, nonce, decrypted, m_NextReceivedLen, false)) // decrypt. assume Alice TODO: { @@ -509,6 +526,27 @@ namespace transport } } + void NTCP2Session::SendNextFrame (const uint8_t * payload, size_t len) + { + uint8_t nonce[12]; + CreateNonce (m_SendSequenceNumber, nonce); m_SendSequenceNumber++; + m_NextSendBuffer = new uint8_t[len + 16 + 2]; + i2p::crypto::AEADChaCha20Poly1305 (payload, len, nullptr, 0, m_Kab, nonce, m_NextSendBuffer + 2, len + 16, true); // encrypt. assume Alice TODO: + i2p::crypto::Siphash<8> (m_SendIV, m_SendIV, 8, m_Sipkeysab); // assume Alice TODO: + htobuf16 (m_NextSendBuffer, bufbe16toh (m_SendIV) ^ htobe16(len + 16)); + LogPrint (eLogDebug, "NTCP2: sent length ", len + 16); + + // send message + boost::asio::async_write (m_Socket, boost::asio::buffer (m_NextSendBuffer, len + 16 + 2), boost::asio::transfer_all (), + std::bind(&NTCP2Session::HandleNextFrameSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } + + void NTCP2Session::HandleNextFrameSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) + { + delete[] m_NextSendBuffer; m_NextSendBuffer = nullptr; + LogPrint (eLogDebug, "NTCP2: Next frame sent"); + } + NTCP2Server::NTCP2Server (): m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service) { diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 744b3375..6ee76aad 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -31,6 +31,7 @@ namespace transport private: void MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived); + void CreateNonce (uint64_t seqn, uint8_t * nonce); void KeyDerivationFunction1 (const uint8_t * rs, const uint8_t * priv, const uint8_t * pub, uint8_t * derived); // for SessionRequest void KeyDerivationFunction2 (const uint8_t * priv, const uint8_t * pub, const uint8_t * sessionRequest, size_t sessionRequestLen, uint8_t * derived); // for SessionCreate void KeyDerivationFunction3 (const uint8_t * staticPrivKey, uint8_t * derived); // for SessionConfirmed part 2 @@ -57,6 +58,9 @@ namespace transport void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void ProcessNextFrame (const uint8_t * frame, size_t len); + void SendNextFrame (const uint8_t * payload, size_t len); + void HandleNextFrameSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); + private: NTCP2Server& m_Server; @@ -70,9 +74,9 @@ namespace transport // data phase uint8_t m_Kab[33], m_Kba[32], m_Sipkeysab[33], m_Sipkeysba[32]; uint16_t m_NextReceivedLen; - uint8_t * m_NextReceivedBuffer; - uint8_t m_ReceiveIV[8]; - uint64_t m_ReceiveSequenceNumber; + uint8_t * m_NextReceivedBuffer, * m_NextSendBuffer; + uint8_t m_ReceiveIV[8], m_SendIV[8]; + uint64_t m_ReceiveSequenceNumber, m_SendSequenceNumber; }; class NTCP2Server