Browse Source

generate sipkeys for data pahse of NTCP2

pull/1200/head
orignal 7 years ago
parent
commit
5b29592174
  1. 62
      libi2pd/NTCP2.cpp
  2. 12
      libi2pd/NTCP2.h

62
libi2pd/NTCP2.cpp

@ -19,7 +19,8 @@ namespace transport
TransportSession (in_RemoteRouter, 30), TransportSession (in_RemoteRouter, 30),
m_Server (server), m_Socket (m_Server.GetService ()), m_Server (server), m_Socket (m_Server.GetService ()),
m_IsEstablished (false), m_IsTerminated (false), m_IsEstablished (false), m_IsTerminated (false),
m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr) m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr),
m_NextReceivedBuffer (nullptr)
{ {
auto addr = in_RemoteRouter->GetNTCPAddress (); auto addr = in_RemoteRouter->GetNTCPAddress ();
if (addr->ntcp2) if (addr->ntcp2)
@ -36,6 +37,7 @@ namespace transport
delete[] m_SessionRequestBuffer; delete[] m_SessionRequestBuffer;
delete[] m_SessionCreatedBuffer; delete[] m_SessionCreatedBuffer;
delete[] m_SessionConfirmedBuffer; delete[] m_SessionConfirmedBuffer;
delete[] m_NextReceivedBuffer;
} }
void NTCP2Session::Terminate () void NTCP2Session::Terminate ()
@ -130,13 +132,13 @@ namespace transport
void NTCP2Session::KeyDerivationFunctionDataPhase () void NTCP2Session::KeyDerivationFunctionDataPhase ()
{ {
char buf[100];
uint8_t tempKey[32]; unsigned int len; uint8_t tempKey[32]; unsigned int len;
HMAC(EVP_sha256(), m_CK, 32, nullptr, 0, tempKey, &len); // temp_key = HMAC-SHA256(ck, zerolen) HMAC(EVP_sha256(), m_CK, 32, nullptr, 0, tempKey, &len); // temp_key = HMAC-SHA256(ck, zerolen)
static uint8_t one[1] = { 1 }; static uint8_t one[1] = { 1 };
HMAC(EVP_sha256(), tempKey, 32, one, 1, m_Kab, &len); // k_ab = HMAC-SHA256(temp_key, byte(0x01)). HMAC(EVP_sha256(), tempKey, 32, one, 1, m_Kab, &len); // k_ab = HMAC-SHA256(temp_key, byte(0x01)).
m_Kab[32] = 2; m_Kab[32] = 2;
HMAC(EVP_sha256(), tempKey, 32, m_Kab, 33, m_Kba, &len); // k_ba = HMAC-SHA256(temp_key, k_ab || byte(0x02)). HMAC(EVP_sha256(), tempKey, 32, m_Kab, 33, m_Kba, &len); // k_ba = HMAC-SHA256(temp_key, k_ab || byte(0x02))
static uint8_t ask[4] = { 'a', 's', 'k', 1 }, master[32]; static uint8_t ask[4] = { 'a', 's', 'k', 1 }, master[32];
HMAC(EVP_sha256(), tempKey, 32, ask, 4, master, &len); // ask_master = HMAC-SHA256(temp_key, "ask" || byte(0x01)) HMAC(EVP_sha256(), tempKey, 32, ask, 4, master, &len); // ask_master = HMAC-SHA256(temp_key, "ask" || byte(0x01))
uint8_t h[39]; uint8_t h[39];
@ -145,9 +147,9 @@ namespace transport
HMAC(EVP_sha256(), master, 32, h, 39, tempKey, &len); // temp_key = HMAC-SHA256(ask_master, h || "siphash") HMAC(EVP_sha256(), master, 32, h, 39, tempKey, &len); // temp_key = HMAC-SHA256(ask_master, h || "siphash")
HMAC(EVP_sha256(), tempKey, 32, one, 1, master, &len); // sip_master = HMAC-SHA256(temp_key, byte(0x01)) HMAC(EVP_sha256(), tempKey, 32, one, 1, master, &len); // sip_master = HMAC-SHA256(temp_key, byte(0x01))
HMAC(EVP_sha256(), master, 32, nullptr, 0, tempKey, &len); // temp_key = HMAC-SHA256(sip_master, zerolen) HMAC(EVP_sha256(), master, 32, nullptr, 0, tempKey, &len); // temp_key = HMAC-SHA256(sip_master, zerolen)
HMAC(EVP_sha256(), tempKey, 32, one, 1, m_Siphashab, &len); // sipkeys_ab = HMAC-SHA256(temp_key, byte(0x01)). HMAC(EVP_sha256(), tempKey, 32, one, 1, m_Sipkeysab, &len); // sipkeys_ab = HMAC-SHA256(temp_key, byte(0x01)).
m_Siphashab[32] = 2; m_Sipkeysab[32] = 2;
HMAC(EVP_sha256(), tempKey, 32, m_Siphashab, 33, m_Siphashba, &len); // sipkeys_ba = HMAC-SHA256(temp_key, sipkeys_ab || byte(0x02)) HMAC(EVP_sha256(), tempKey, 32, m_Sipkeysab, 33, m_Sipkeysba, &len); // sipkeys_ba = HMAC-SHA256(temp_key, sipkeys_ab || byte(0x02))
} }
void NTCP2Session::CreateEphemeralKey (uint8_t * pub) void NTCP2Session::CreateEphemeralKey (uint8_t * pub)
@ -394,6 +396,11 @@ namespace transport
KeyDerivationFunction3 (i2p::context.GetNTCP2StaticPrivateKey (), key); KeyDerivationFunction3 (i2p::context.GetNTCP2StaticPrivateKey (), key);
memset (nonce, 0, 12); // set nonce to 0 again memset (nonce, 0, 12); // set nonce to 0 again
i2p::crypto::AEADChaCha20Poly1305 (buf.data (), m3p2Len - 16, m_H, 32, key, nonce, m_SessionConfirmedBuffer + 48, m3p2Len, true); // encrypt i2p::crypto::AEADChaCha20Poly1305 (buf.data (), m3p2Len - 16, m_H, 32, key, nonce, m_SessionConfirmedBuffer + 48, m3p2Len, true); // encrypt
uint8_t tmp[48];
memcpy (tmp, m_SessionConfirmedBuffer, 48);
memcpy (m_SessionConfirmedBuffer + 16, m_H, 32); // h || ciphertext
SHA256 (m_SessionConfirmedBuffer + 16, m3p2Len + 32, m_H); //h = SHA256(h || ciphertext);
memcpy (m_SessionConfirmedBuffer, tmp, 48);
// send message // send message
boost::asio::async_write (m_Socket, boost::asio::buffer (m_SessionConfirmedBuffer, m3p2Len + 48), boost::asio::transfer_all (), boost::asio::async_write (m_Socket, boost::asio::buffer (m_SessionConfirmedBuffer, m3p2Len + 48), boost::asio::transfer_all (),
@ -404,7 +411,8 @@ namespace transport
{ {
LogPrint (eLogDebug, "NTCP2: SessionConfirmed sent"); LogPrint (eLogDebug, "NTCP2: SessionConfirmed sent");
KeyDerivationFunctionDataPhase (); KeyDerivationFunctionDataPhase ();
Terminate (); // TODO memcpy (m_IV, m_Sipkeysba + 16, 8); //Alice
ReceiveLength ();
} }
void NTCP2Session::HandleSessionCreatedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) void NTCP2Session::HandleSessionCreatedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
@ -426,6 +434,46 @@ namespace transport
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} }
void NTCP2Session::ReceiveLength ()
{
boost::asio::async_read (m_Socket, boost::asio::buffer(&m_NextReceivedLen, 2), boost::asio::transfer_all (),
std::bind(&NTCP2Session::HandleReceivedLength, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
}
void NTCP2Session::HandleReceivedLength (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint (eLogWarning, "NTCP2: receive length read error: ", ecode.message ());
Terminate ();
}
else
{
i2p::crypto::Siphash<8> (m_ReceiveIV, m_ReceiveIV, 8, m_Kba); // assume Alice TODO:
m_NextReceivedLen = be16toh (m_NextReceivedLen ^ buf16toh(m_ReceiveIV));
LogPrint (eLogDebug, "NTCP2: received length ", m_NextReceivedLen);
delete[] m_NextReceivedBuffer;
m_NextReceivedBuffer = new uint8_t[m_NextReceivedLen];
Receive ();
}
}
void NTCP2Session::Receive ()
{
boost::asio::async_read (m_Socket, boost::asio::buffer(m_NextReceivedBuffer, m_NextReceivedLen), boost::asio::transfer_all (),
std::bind(&NTCP2Session::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
}
void NTCP2Session::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint (eLogWarning, "NTCP2: receive read error: ", ecode.message ());
Terminate ();
}
Terminate (); // TODO
}
NTCP2Server::NTCP2Server (): NTCP2Server::NTCP2Server ():
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service) m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service)
{ {

12
libi2pd/NTCP2.h

@ -36,6 +36,7 @@ namespace transport
void KeyDerivationFunction3 (const uint8_t * staticPrivKey, uint8_t * derived); // for SessionConfirmed part 2 void KeyDerivationFunction3 (const uint8_t * staticPrivKey, uint8_t * derived); // for SessionConfirmed part 2
void KeyDerivationFunctionDataPhase (); void KeyDerivationFunctionDataPhase ();
// establish
void CreateEphemeralKey (uint8_t * pub); void CreateEphemeralKey (uint8_t * pub);
void SendSessionRequest (); void SendSessionRequest ();
void SendSessionCreated (); void SendSessionCreated ();
@ -49,6 +50,12 @@ namespace transport
void HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleSessionConfirmedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionConfirmedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
// data
void ReceiveLength ();
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);
private: private:
NTCP2Server& m_Server; NTCP2Server& m_Server;
@ -60,7 +67,10 @@ namespace transport
uint8_t * m_SessionRequestBuffer, * m_SessionCreatedBuffer, * m_SessionConfirmedBuffer; uint8_t * m_SessionRequestBuffer, * m_SessionCreatedBuffer, * m_SessionConfirmedBuffer;
size_t m_SessionRequestBufferLen, m_SessionCreatedBufferLen; size_t m_SessionRequestBufferLen, m_SessionCreatedBufferLen;
// data phase // data phase
uint8_t m_Kab[33], m_Kba[32], m_Siphashab[33], m_Siphashba[32]; 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];
}; };
class NTCP2Server class NTCP2Server

Loading…
Cancel
Save