From 0aa618b938bd76f0fac8f5ca07b594649a23f6c8 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 22 Jun 2018 15:02:49 -0400 Subject: [PATCH] process AEAD/Chacha20/Poly1305 frame for data phase of NTCP2 --- libi2pd/Crypto.cpp | 22 +++++++++++++--------- libi2pd/NTCP2.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- libi2pd/NTCP2.h | 2 ++ 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 7e320888..6d859342 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1081,19 +1081,23 @@ namespace crypto chacha20 (buf, msgLen, nonce, key, 1); // create Poly1305 message + if (!ad) adLen = 0; std::vector polyMsg(adLen + msgLen + 3*16); - size_t offset = 0; + size_t offset = 0; uint8_t padding[16]; memset (padding, 0, 16); - memcpy (polyMsg.data (), ad, adLen); offset += adLen; // additional authenticated data - auto rem = adLen & 0x0F; // %16 - if (rem) - { - // padding1 - rem = 16 - rem; - memcpy (polyMsg.data () + offset, padding, rem); offset += rem; + if (ad) + { + memcpy (polyMsg.data (), ad, adLen); offset += adLen; // additional authenticated data + auto rem = adLen & 0x0F; // %16 + if (rem) + { + // padding1 + rem = 16 - rem; + memcpy (polyMsg.data () + offset, padding, rem); offset += rem; + } } memcpy (polyMsg.data () + offset, encrypt ? buf : msg, msgLen); offset += msgLen; // encrypted data - rem = msgLen & 0x0F; // %16 + auto rem = msgLen & 0x0F; // %16 if (rem) { // padding2 diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index f7e5e796..4551a8cd 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -20,7 +20,7 @@ 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_NextReceivedBuffer (nullptr), m_ReceiveSequenceNumber (0) { auto addr = in_RemoteRouter->GetNTCPAddress (); if (addr->ntcp2) @@ -470,7 +470,43 @@ namespace transport LogPrint (eLogWarning, "NTCP2: receive read error: ", ecode.message ()); Terminate (); } - Terminate (); // TODO + else + { + uint8_t nonce[12]; + memset (nonce, 0, 4); htole64buf (nonce + 4, m_ReceiveSequenceNumber); 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: + { + LogPrint (eLogInfo, "NTCP2: received message decrypted"); + ProcessNextFrame (decrypted, m_NextReceivedLen-16); + ReceiveLength (); + } + else + { + LogPrint (eLogWarning, "NTCP2: Received MAC verification failed "); + Terminate (); + } + delete[] decrypted; + } + } + + void NTCP2Session::ProcessNextFrame (const uint8_t * frame, size_t len) + { + size_t offset = 0; + while (offset < len) + { + uint8_t blk = frame[offset]; + offset++; + auto size = bufbe16toh (frame + offset); + offset += 2; + LogPrint (eLogDebug, "NTCP2: Block type ", (int)blk, " of size ", size); + if (size > len) + { + LogPrint (eLogError, "NTCP2: Unexpected block length ", size); + break; + } + offset += size; + } } NTCP2Server::NTCP2Server (): diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 5f8d116d..744b3375 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -55,6 +55,7 @@ namespace transport void HandleReceivedLength (const boost::system::error_code& ecode, std::size_t bytes_transferred); void Receive (); void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void ProcessNextFrame (const uint8_t * frame, size_t len); private: @@ -71,6 +72,7 @@ namespace transport uint16_t m_NextReceivedLen; uint8_t * m_NextReceivedBuffer; uint8_t m_ReceiveIV[8]; + uint64_t m_ReceiveSequenceNumber; }; class NTCP2Server