From d3812786fa9a035380ecec14c4ae5c23f62dbcec Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 May 2014 22:49:22 -0400 Subject: [PATCH] session key decryption --- SSU.cpp | 41 ++++++++++++++++++++++++++++++----------- SSU.h | 11 +++++++---- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/SSU.cpp b/SSU.cpp index 9711ecef..c6fc81d3 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -29,7 +29,7 @@ namespace ssu delete m_DHKeysPair; } - void SSUSession::CreateAESandMacKey (const uint8_t * pubKey, uint8_t * aesKey, uint8_t * macKey) + void SSUSession::CreateAESandMacKey (const uint8_t * pubKey) { CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); uint8_t sharedKey[256]; @@ -41,14 +41,14 @@ namespace ssu if (sharedKey[0] & 0x80) { - aesKey[0] = 0; - memcpy (aesKey + 1, sharedKey, 31); - memcpy (macKey, sharedKey + 31, 32); + m_SessionKey[0] = 0; + memcpy (m_SessionKey + 1, sharedKey, 31); + memcpy (m_MacKey, sharedKey + 31, 32); } else if (sharedKey[0]) { - memcpy (aesKey, sharedKey, 32); - memcpy (macKey, sharedKey + 32, 32); + memcpy (m_SessionKey, sharedKey, 32); + memcpy (m_MacKey, sharedKey + 32, 32); } else { @@ -64,10 +64,11 @@ namespace ssu } } - memcpy (aesKey, nonZero, 32); - CryptoPP::SHA256().CalculateDigest(macKey, nonZero, 64 - (nonZero - sharedKey)); + memcpy (m_SessionKey, nonZero, 32); + CryptoPP::SHA256().CalculateDigest(m_MacKey, nonZero, 64 - (nonZero - sharedKey)); } m_IsSessionKey = true; + m_SessionKeyDecryption.SetKey (m_SessionKey); } void SSUSession::ProcessNextMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) @@ -83,7 +84,7 @@ namespace ssu { ScheduleTermination (); if (m_IsSessionKey && Validate (buf, len, m_MacKey)) // try session key first - Decrypt (buf, len, m_SessionKey); + DecryptSessionKey (buf, len); else { // try intro key depending on side @@ -164,7 +165,7 @@ namespace ssu m_State = eSessionStateRequestReceived; LogPrint ("Session request received"); m_RemoteEndpoint = senderEndpoint; - CreateAESandMacKey (buf + sizeof (SSUHeader), m_SessionKey, m_MacKey); + CreateAESandMacKey (buf + sizeof (SSUHeader)); SendSessionCreated (buf + sizeof (SSUHeader)); } @@ -182,7 +183,7 @@ namespace ssu uint8_t signedData[532]; // x,y, our IP, our port, remote IP, remote port, relayTag, signed on time uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * y = payload; - CreateAESandMacKey (y, m_SessionKey, m_MacKey); + CreateAESandMacKey (y); memcpy (signedData, m_DHKeysPair->publicKey, 256); // x memcpy (signedData + 256, y, 256); // y payload += 256; @@ -523,6 +524,24 @@ namespace ssu m_Decryption.ProcessData (encrypted, encrypted, encryptedLen); } + void SSUSession::DecryptSessionKey (uint8_t * buf, size_t len) + { + if (len < sizeof (SSUHeader)) + { + LogPrint ("Unexpected SSU packet length ", len); + return; + } + SSUHeader * header = (SSUHeader *)buf; + uint8_t * encrypted = &header->flag; + uint16_t encryptedLen = len - (encrypted - buf); + encryptedLen = (encryptedLen>>4)<<4; // make sure 16 bytes boundary + if (encryptedLen > 0) + { + m_SessionKeyDecryption.SetIV (header->iv); + m_SessionKeyDecryption.Decrypt (encrypted, encryptedLen, encrypted); + } + } + bool SSUSession::Validate (uint8_t * buf, size_t len, const uint8_t * macKey) { if (len < sizeof (SSUHeader)) diff --git a/SSU.h b/SSU.h index 16236a38..d44e23f6 100644 --- a/SSU.h +++ b/SSU.h @@ -9,6 +9,7 @@ #include #include #include +#include "aes.h" #include "I2PEndian.h" #include "Identity.h" #include "RouterInfo.h" @@ -85,7 +86,7 @@ namespace ssu private: - void CreateAESandMacKey (const uint8_t * pubKey, uint8_t * aesKey, uint8_t * macKey); + void CreateAESandMacKey (const uint8_t * pubKey); void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); @@ -112,7 +113,8 @@ namespace ssu void Send (uint8_t type, const uint8_t * payload, size_t len); // with session key void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey); - void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey); + void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey); + void DecryptSessionKey (uint8_t * buf, size_t len); bool Validate (uint8_t * buf, size_t len, const uint8_t * macKey); const uint8_t * GetIntroKey () const; @@ -132,8 +134,9 @@ namespace ssu bool m_IsSessionKey; uint32_t m_RelayTag; std::set m_PeerTestNonces; - CryptoPP::CBC_Mode::Encryption m_Encryption; - CryptoPP::CBC_Mode::Decryption m_Decryption; + CryptoPP::CBC_Mode::Encryption m_Encryption; // TODO: remove + CryptoPP::CBC_Mode::Decryption m_Decryption; // TODO: remove + i2p::crypto::CBCDecryption m_SessionKeyDecryption; uint8_t m_SessionKey[32], m_MacKey[32]; std::list m_DelayedMessages; SSUData m_Data;