diff --git a/Garlic.cpp b/Garlic.cpp index 3afde6a8..34ed84b3 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -365,23 +365,34 @@ namespace garlic { uint8_t * buf = msg->GetPayload (); uint32_t length = bufbe32toh (buf); + if (length > msg->GetLength ()) + { + LogPrint (eLogError, "Garlic message length ", length, " exceeds I2NP message length ", msg->GetLength ()); + DeleteI2NPMessage (msg); + return; + } buf += 4; // length auto it = m_Tags.find (SessionTag(buf)); if (it != m_Tags.end ()) { // tag found. Use AES - uint8_t iv[32]; // IV is first 16 bytes - CryptoPP::SHA256().CalculateDigest(iv, buf, 32); - it->second->SetIV (iv); - it->second->Decrypt (buf + 32, length - 32, buf + 32); - HandleAESBlock (buf + 32, length - 32, it->second, msg->from); - m_Tags.erase (it); // tag might be used only once + if (length >= 32) + { + uint8_t iv[32]; // IV is first 16 bytes + CryptoPP::SHA256().CalculateDigest(iv, buf, 32); + it->second->SetIV (iv); + it->second->Decrypt (buf + 32, length - 32, buf + 32); + HandleAESBlock (buf + 32, length - 32, it->second, msg->from); + } + else + LogPrint (eLogError, "Garlic message length ", length, " is less than 32 bytes"); + m_Tags.erase (it); // tag might be used only once } else { // tag not found. Use ElGamal ElGamalBlock elGamal; - if (i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, true)) + if (length >= 514 && i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, true)) { auto decryption = std::make_shared(); decryption->SetKey (elGamal.sessionKey); @@ -392,7 +403,7 @@ namespace garlic HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } else - LogPrint ("Failed to decrypt garlic"); + LogPrint (eLogError, "Failed to decrypt garlic"); } DeleteI2NPMessage (msg);