From 61897ae16c151f67e73bb3f13c3c0e513acb05e9 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jun 2020 20:42:54 -0400 Subject: [PATCH] crypto.ratchet.inboundTags --- libi2pd/Destination.cpp | 3 +++ libi2pd/Destination.h | 2 ++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 31 +++++++++++++++++------ libi2pd/Garlic.cpp | 3 ++- libi2pd/Garlic.h | 3 +++ libi2pd_client/ClientContext.cpp | 2 ++ 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 6d5fb916..a764224c 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -56,6 +56,9 @@ namespace client if (it != params->end ()) numTags = std::stoi(it->second); LogPrint (eLogInfo, "Destination: parameters for tunnel set to: ", inQty, " inbound (", inLen, " hops), ", outQty, " outbound (", outLen, " hops), ", numTags, " tags"); + it = params->find (I2CP_PARAM_RATCHET_INBOUND_TAGS); + if (it != params->end ()) + SetNumRatchetInboundTags (std::stoi(it->second)); it = params->find (I2CP_PARAM_EXPLICIT_PEERS); if (it != params->end ()) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 139423c6..1d5c0a55 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -57,6 +57,8 @@ namespace client const int STREAM_REQUEST_TIMEOUT = 60; //in seconds const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend"; const int DEFAULT_TAGS_TO_SEND = 40; + const char I2CP_PARAM_RATCHET_INBOUND_TAGS[] = "crypto.ratchet.inboundTags"; + const char I2CP_PARAM_RATCHET_OUTBOUND_TAGS[] = "crypto.ratchet.outboundTags"; // not used yet const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname"; const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname"; const char I2CP_PARAM_LEASESET_TYPE[] = "i2cp.leaseSetType"; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a578131d..ad91382f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -341,7 +341,8 @@ namespace garlic newTagset->SetTagSetID (tagsetID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (newTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MAX_NUM_GENERATED_TAGS); receiveTagset->Expire (); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } @@ -459,7 +460,8 @@ namespace garlic m_SendTagset = std::make_shared(shared_from_this ()); m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (receiveTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt @@ -548,7 +550,8 @@ namespace garlic auto receiveTagset = std::make_shared(shared_from_this ()); receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) receiveTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (receiveTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS); } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload @@ -610,11 +613,23 @@ namespace garlic return false; } HandlePayload (payload, len - 16, receiveTagset, index); - int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 - if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; - moreTags -= (receiveTagset->GetNextIndex () - index); - if (moreTags > 0 && GetOwner ()) - GenerateMoreReceiveTags (receiveTagset, moreTags); + if (GetOwner ()) + { + int moreTags = 0; + if (GetOwner ()->GetNumRatchetInboundTags () > 0) // override in settings? + { + if (receiveTagset->GetNextIndex () - index < GetOwner ()->GetNumRatchetInboundTags ()/2) + moreTags = GetOwner ()->GetNumRatchetInboundTags (); + } + else + { + moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 + if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; + moreTags -= (receiveTagset->GetNextIndex () - index); + } + if (moreTags > 0) + GenerateMoreReceiveTags (receiveTagset, moreTags); + } return true; } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 1170634d..84a0519e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -432,7 +432,8 @@ namespace garlic return ret; } - GarlicDestination::GarlicDestination (): m_NumTags (32) // 32 tags by default + GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default + m_NumRatchetInboundTags (0) // 0 means standard { m_Ctx = BN_CTX_new (); } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 6b34231a..70893bec 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -232,6 +232,8 @@ namespace garlic void CleanUp (); void SetNumTags (int numTags) { m_NumTags = numTags; }; int GetNumTags () const { return m_NumTags; }; + void SetNumRatchetInboundTags (int numTags) { m_NumRatchetInboundTags = numTags; }; + int GetNumRatchetInboundTags () const { return m_NumRatchetInboundTags; }; std::shared_ptr GetRoutingSession (std::shared_ptr destination, bool attachLeaseSet); void CleanupExpiredTags (); void RemoveDeliveryStatusSession (uint32_t msgID); @@ -278,6 +280,7 @@ namespace garlic std::unordered_map m_Sessions; std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming + int m_NumRatchetInboundTags; std::unordered_map, std::hash > > m_Tags; std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 54007c95..0348aeeb 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -461,6 +461,8 @@ namespace client } std::string explicitPeers = GetI2CPStringOption(section, I2CP_PARAM_EXPLICIT_PEERS, ""); if (explicitPeers.length () > 0) options[I2CP_PARAM_EXPLICIT_PEERS] = explicitPeers; + std::string ratchetInboundTags = GetI2CPStringOption(section, I2CP_PARAM_RATCHET_INBOUND_TAGS, ""); + if (ratchetInboundTags.length () > 0) options[I2CP_PARAM_RATCHET_INBOUND_TAGS] = ratchetInboundTags; } void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const