From 34939f9381a24d8dae855bf25ee517b495627a2a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 19 Jan 2017 22:00:02 -0500 Subject: [PATCH] calculate shared key in separate therad --- NTCPSession.cpp | 65 +++++++++++++++++++++++++++++++------------------ NTCPSession.h | 1 + 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 8f31e246..d50ccfe5 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "I2PEndian.h" #include "Base.h" @@ -38,7 +39,7 @@ namespace transport void NTCPSession::CreateAESKey (uint8_t * pubKey, i2p::crypto::AESKey& key) { uint8_t sharedKey[256]; - m_DHKeysPair->Agree (pubKey, sharedKey); + m_DHKeysPair->Agree (pubKey, sharedKey); // time consuming operation uint8_t * aesKey = key; if (sharedKey[0] & 0x80) @@ -229,32 +230,48 @@ namespace transport } else { - i2p::crypto::AESKey aesKey; - CreateAESKey (m_Establisher->phase2.pubKey, aesKey); - m_Decryption.SetKey (aesKey); - m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240); - m_Encryption.SetKey (aesKey); - m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16); - - m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); - // verify - uint8_t xy[512]; - memcpy (xy, m_DHKeysPair->GetPublicKey (), 256); - memcpy (xy + 256, m_Establisher->phase2.pubKey, 256); - uint8_t digest[32]; - SHA256 (xy, 512, digest); - if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32)) - { - LogPrint (eLogError, "NTCP: Phase 2 process error: incorrect hash"); - transports.ReuseDHKeysPair (m_DHKeysPair); - m_DHKeysPair = nullptr; - Terminate (); - return ; - } - SendPhase3 (); + auto s = shared_from_this (); + // create AES key in separate thread + auto createKey = std::async (std::launch::async, [s] ()->i2p::crypto::AESKey + { + i2p::crypto::AESKey aesKey; + s->CreateAESKey (s->m_Establisher->phase2.pubKey, aesKey); + return std::move (aesKey); + }).share (); // TODO: use move capture in C++ 14 instead shared_future + // let other operations execute while a key gets created + m_Server.GetService ().post ([s, createKey]() + { + auto aesKey = createKey.get (); // we might wait if no more pending operations + s->HandlePhase2 (aesKey); + }); } } + void NTCPSession::HandlePhase2 (const i2p::crypto::AESKey& aesKey) + { + m_Decryption.SetKey (aesKey); + m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240); + m_Encryption.SetKey (aesKey); + m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16); + + m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); + // verify + uint8_t xy[512]; + memcpy (xy, m_DHKeysPair->GetPublicKey (), 256); + memcpy (xy + 256, m_Establisher->phase2.pubKey, 256); + uint8_t digest[32]; + SHA256 (xy, 512, digest); + if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32)) + { + LogPrint (eLogError, "NTCP: Phase 2 process error: incorrect hash"); + transports.ReuseDHKeysPair (m_DHKeysPair); + m_DHKeysPair = nullptr; + Terminate (); + return ; + } + SendPhase3 (); + } + void NTCPSession::SendPhase3 () { auto& keys = i2p::context.GetPrivateKeys (); diff --git a/NTCPSession.h b/NTCPSession.h index a5d6f99f..60a7b6c1 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -73,6 +73,7 @@ namespace transport void SendPhase3 (); void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void HandlePhase2 (const i2p::crypto::AESKey& aesKey); void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);