Browse Source

decrypt short request record

pull/1660/head
orignal 4 years ago
parent
commit
8e3e35a36d
  1. 3
      libi2pd/I2NPProtocol.h
  2. 64
      libi2pd/RouterContext.cpp
  3. 5
      libi2pd/RouterContext.h

3
libi2pd/I2NPProtocol.h

@ -100,6 +100,9 @@ namespace i2p
// ECIES BuildResponseRecord // ECIES BuildResponseRecord
const size_t ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET = 0; const size_t ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET = 0;
const size_t ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET = 511; const size_t ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET = 511;
// ShortRequestRecordClearText
const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 172;
enum I2NPMessageType enum I2NPMessageType
{ {

64
libi2pd/RouterContext.cpp

@ -875,34 +875,11 @@ namespace i2p
bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data)
{ {
if (!m_TunnelDecryptor) return false;
if (IsECIES ()) if (IsECIES ())
{ return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE);
if (!m_InitialNoiseState) return false;
// m_InitialNoiseState is h = SHA256(h || hepk)
m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState));
m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk)
uint8_t sharedSecret[32];
if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false))
{
LogPrint (eLogWarning, "Router: Incorrect ephemeral public key");
return false;
}
m_CurrentNoiseState->MixKey (sharedSecret);
encrypted += 32;
uint8_t nonce[12];
memset (nonce, 0, 12);
if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE,
m_CurrentNoiseState->m_H, 32, m_CurrentNoiseState->m_CK + 32, nonce, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, false)) // decrypt
{
LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed");
return false;
}
m_CurrentNoiseState->MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext)
return true;
}
else else
{ {
if (!m_TunnelDecryptor) return false;
BN_CTX * ctx = BN_CTX_new (); BN_CTX * ctx = BN_CTX_new ();
bool success = m_TunnelDecryptor->Decrypt (encrypted, data, ctx, false); bool success = m_TunnelDecryptor->Decrypt (encrypted, data, ctx, false);
BN_CTX_free (ctx); BN_CTX_free (ctx);
@ -910,6 +887,43 @@ namespace i2p
} }
} }
bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize)
{
if (!m_InitialNoiseState || !m_TunnelDecryptor) return false;
// m_InitialNoiseState is h = SHA256(h || hepk)
m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState));
m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk)
uint8_t sharedSecret[32];
if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false))
{
LogPrint (eLogWarning, "Router: Incorrect ephemeral public key");
return false;
}
m_CurrentNoiseState->MixKey (sharedSecret);
encrypted += 32;
uint8_t nonce[12];
memset (nonce, 0, 12);
if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState->m_H, 32,
m_CurrentNoiseState->m_CK + 32, nonce, data, clearTextSize, false)) // decrypt
{
LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed");
return false;
}
m_CurrentNoiseState->MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext)
return true;
}
bool RouterContext::DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data)
{
if (IsECIES ())
return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE);
else
{
LogPrint (eLogWarning, "Router: Can't decrypt short request record on non-ECIES router");
return false;
}
}
i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () i2p::crypto::X25519Keys& RouterContext::GetStaticKeys ()
{ {
if (!m_StaticKeys) if (!m_StaticKeys)

5
libi2pd/RouterContext.h

@ -97,7 +97,8 @@ namespace garlic
int GetNetID () const { return m_NetID; }; int GetNetID () const { return m_NetID; };
void SetNetID (int netID) { m_NetID = netID; }; void SetNetID (int netID) { m_NetID = netID; };
bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data); bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data);
bool DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data);
void UpdatePort (int port); // called from Daemon void UpdatePort (int port); // called from Daemon
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg); void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg);
@ -164,6 +165,8 @@ namespace garlic
bool Load (); bool Load ();
void SaveKeys (); void SaveKeys ();
bool DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize);
private: private:
i2p::data::RouterInfo m_RouterInfo; i2p::data::RouterInfo m_RouterInfo;

Loading…
Cancel
Save