diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index df5dd38f..9881ebef 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -151,11 +151,9 @@ namespace crypto memcpy (m_PublicKey, pub, 32); } - void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t * epriv, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) + void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) { - X25519Keys ep; - ep.SetPrivateKey (epriv); - ep.Agree (m_PublicKey, sharedSecret); + memcpy (pub, m_PublicKey, 32); } ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv) diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 6412f4d3..701e9482 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -125,8 +125,8 @@ namespace crypto ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; - void Encrypt (const uint8_t * epriv, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); - // agree with ephemeral priv and return in sharedSecret (32 bytes) + void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool); + // copies m_PublicKey to pub private: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 56b97635..2f18ada2 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -74,6 +74,7 @@ namespace garlic if (isStatic) { // static key, fs is apk + memcpy (m_StaticKey, fs, 32); GetOwner ()->Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index fa9a960e..b273f2fd 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -33,6 +33,7 @@ namespace garlic std::shared_ptr WrapSingleMessage (std::shared_ptr msg); bool NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove); + const uint8_t * GetStaticKey () const { return m_StaticKey; }; private: @@ -42,7 +43,7 @@ namespace garlic private: - uint8_t m_H[32], m_CK[32]; + uint8_t m_H[32], m_CK[32], m_StaticKey[32]; }; } } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 965ccdb4..f865d8f9 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -655,21 +655,35 @@ namespace garlic std::shared_ptr GarlicDestination::GetRoutingSession ( std::shared_ptr destination, bool attachLeaseSet) { - ElGamalAESSessionPtr session; - { - std::unique_lock l(m_SessionsMutex); - auto it = m_Sessions.find (destination->GetIdentHash ()); - if (it != m_Sessions.end ()) - session = it->second; - } - if (!session) - { - session = std::make_shared (this, destination, - attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests - std::unique_lock l(m_SessionsMutex); - m_Sessions[destination->GetIdentHash ()] = session; - } - return session; + if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + { + ECIESX25519AEADRatchetSessionPtr session; + uint8_t staticKey[32]; + destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key + auto it = m_ECIESx25519Sessions.find (staticKey); + if (it != m_ECIESx25519Sessions.end ()) + session = it->second; + // TODO: Alice + return session; + } + else + { + ElGamalAESSessionPtr session; + { + std::unique_lock l(m_SessionsMutex); + auto it = m_Sessions.find (destination->GetIdentHash ()); + if (it != m_Sessions.end ()) + session = it->second; + } + if (!session) + { + session = std::make_shared (this, destination, + attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests + std::unique_lock l(m_SessionsMutex); + m_Sessions[destination->GetIdentHash ()] = session; + } + return session; + } } void GarlicDestination::CleanupExpiredTags () @@ -841,9 +855,14 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { - ECIESX25519AEADRatchetSession session (this); - session.NewIncomingSession (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, - this, std::placeholders::_1, std::placeholders::_2)); + auto session = std::make_shared (this); + if (session->NewIncomingSession (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, + this, std::placeholders::_1, std::placeholders::_2))) + { + m_ECIESx25519Sessions.emplace (session->GetStaticKey (), session); + } + else + LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session"); } void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index cd8c48ed..727b4a8d 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -196,6 +196,9 @@ namespace garlic }; typedef std::shared_ptr ElGamalAESSessionPtr; + class ECIESX25519AEADRatchetSession; + typedef std::shared_ptr ECIESX25519AEADRatchetSessionPtr; + class GarlicDestination: public i2p::data::LocalDestination { public: @@ -249,6 +252,7 @@ namespace garlic int m_NumTags; std::mutex m_SessionsMutex; std::map m_Sessions; + std::map, ECIESX25519AEADRatchetSessionPtr > m_ECIESx25519Sessions; // static key -> session // incoming std::map > m_Tags; // DeliveryStatus