From 2fc16ee13ddc7c7016ee6d81ba6b03b80c94ac7f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Apr 2020 20:00:19 -0400 Subject: [PATCH] indetification of incoming garlic messages --- libi2pd/Destination.cpp | 4 ++-- libi2pd/Destination.h | 7 ++++++- libi2pd/ECIESX25519AEADRatchetSession.cpp | 12 ++++++------ libi2pd/Garlic.cpp | 24 +++++++++++------------ libi2pd/Identity.cpp | 6 +++--- libi2pd/Identity.h | 2 +- 6 files changed, 30 insertions(+), 25 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 98c4b323..796b0438 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -824,8 +824,8 @@ namespace client i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const { - if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) - return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET; + if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) + return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 83a38816..c19c3f16 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -229,7 +229,12 @@ namespace client // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const + { + return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? + m_EncryptionKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET : + m_EncryptionKeyType < i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; + } const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { return m_EncryptionPublicKey; }; protected: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4371124e..35ccbd34 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -127,7 +127,7 @@ namespace garlic if (!GetOwner ()) return false; // we are Bob // KDF1 - MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET), 32); // h = SHA256(h || bpk) + MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk) if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) { @@ -138,7 +138,7 @@ namespace garlic MixHash (m_Aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519(bsk, aepk) + GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // decrypt flags/static @@ -160,7 +160,7 @@ namespace garlic { // static key, fs is apk memcpy (m_RemoteStaticKey, fs, 32); - GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519(bsk, apk) + GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) } else // all zeros flags @@ -242,7 +242,7 @@ namespace garlic // encrypt static key section uint8_t nonce[12]; CreateNonce (0, nonce); - if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); return false; @@ -250,7 +250,7 @@ namespace garlic MixHash (out + offset, 48); // h = SHA256(h || ciphertext) offset += 48; // KDF2 - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519 (ask, bpk) + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt @@ -355,7 +355,7 @@ namespace garlic uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519 (ask, bepk) + GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; CreateNonce (0, nonce); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index fd6e8fee..d1eaa9f3 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -466,8 +466,9 @@ namespace garlic LogPrint (eLogWarning, "Garlic: message length ", length, " exceeds I2NP message length ", msg->GetLength ()); return; } + auto mod = length & 0x0f; // %16 buf += 4; // length - auto it = m_Tags.find (SessionTag(buf)); + auto it = !mod ? m_Tags.find (SessionTag(buf)) : m_Tags.end (); // AES block is multiple of 16 // AES tag might be used even if encryption type is not ElGamal/AES if (it != m_Tags.end ()) { @@ -487,15 +488,11 @@ namespace garlic } else { - // tag not found. Handle depending on encryption type - if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) - { - HandleECIESx25519 (buf, length); - return; - } - // otherwise assume ElGamal/AES + // AES tag not found. Handle depending on encryption type + // try ElGamal/AES first if leading block is 514 ElGamalBlock elGamal; - if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) + if (mod == 2 && length >= 514 && SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) && + Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) { auto decryption = std::make_shared(elGamal.sessionKey); uint8_t iv[32]; // IV is first 16 bytes @@ -504,8 +501,11 @@ namespace garlic decryption->Decrypt(buf + 514, length - 514, buf + 514); HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } + else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) + // otherwise ECIESx25519 + HandleECIESx25519 (buf, length); // TODO: check tag first else - LogPrint (eLogError, "Garlic: Failed to decrypt message"); + LogPrint (eLogError, "Garlic: Failed to decrypt message"); } } @@ -679,8 +679,8 @@ namespace garlic std::shared_ptr GarlicDestination::GetRoutingSession ( std::shared_ptr destination, bool attachLeaseSet) { - if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET && - SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) + if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && + SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) { ECIESX25519AEADRatchetSessionPtr session; uint8_t staticKey[32]; diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 1026eb02..0c2dc50e 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -412,7 +412,7 @@ namespace data case CRYPTO_KEY_TYPE_ELGAMAL: return std::make_shared(key); break; - case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET: + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET: return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: @@ -672,7 +672,7 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC: return std::make_shared(key); break; - case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET: + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET: return std::make_shared(key); break; default: @@ -754,7 +754,7 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC: i2p::crypto::CreateECIESGOSTR3410RandomKeys (priv, pub); break; - case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET: + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET: i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub); break; default: diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 663f46b5..da14e141 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -56,7 +56,7 @@ namespace data const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1; - const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET = 4; + const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET = 4; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280; // TODO: remove later const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES