mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 11:04:00 +01:00
handle out of order NSR
This commit is contained in:
parent
c0de9455bb
commit
3d9c844dca
|
@ -482,13 +482,18 @@ namespace garlic
|
||||||
}
|
}
|
||||||
buf += 32; len -= 32;
|
buf += 32; len -= 32;
|
||||||
// KDF for Reply Key Section
|
// KDF for Reply Key Section
|
||||||
|
uint8_t h[32]; memcpy (h, m_H, 32); // save m_H
|
||||||
MixHash (tag, 8); // h = SHA256(h || tag)
|
MixHash (tag, 8); // h = SHA256(h || tag)
|
||||||
MixHash (bepk, 32); // h = SHA256(h || bepk)
|
MixHash (bepk, 32); // h = SHA256(h || bepk)
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk)
|
if (m_State == eSessionStateNewSessionSent)
|
||||||
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_RATCHET); // x25519 (ask, bepk)
|
// only fist time, we assume ephemeral keys the same
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
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_RATCHET); // x25519 (ask, bepk)
|
||||||
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||||
|
}
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (0, nonce);
|
CreateNonce (0, nonce);
|
||||||
// calulate hash for zero length
|
// calulate hash for zero length
|
||||||
|
@ -502,14 +507,17 @@ namespace garlic
|
||||||
// KDF for payload
|
// KDF for payload
|
||||||
uint8_t keydata[64];
|
uint8_t keydata[64];
|
||||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||||
// k_ab = keydata[0:31], k_ba = keydata[32:63]
|
if (m_State == eSessionStateNewSessionSent)
|
||||||
m_SendTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
{
|
||||||
m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab)
|
// k_ab = keydata[0:31], k_ba = keydata[32:63]
|
||||||
m_SendTagset->NextSessionTagRatchet ();
|
m_SendTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||||
auto receiveTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab)
|
||||||
receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
m_SendTagset->NextSessionTagRatchet ();
|
||||||
receiveTagset->NextSessionTagRatchet ();
|
auto receiveTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||||
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS);
|
receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
||||||
|
receiveTagset->NextSessionTagRatchet ();
|
||||||
|
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS);
|
||||||
|
}
|
||||||
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
||||||
// decrypt payload
|
// decrypt payload
|
||||||
std::vector<uint8_t> payload (len - 16);
|
std::vector<uint8_t> payload (len - 16);
|
||||||
|
@ -518,9 +526,13 @@ namespace garlic
|
||||||
LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed");
|
LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_State = eSessionStateEstablished;
|
if (m_State == eSessionStateNewSessionSent)
|
||||||
GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ());
|
{
|
||||||
|
m_State = eSessionStateEstablished;
|
||||||
|
GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ());
|
||||||
|
}
|
||||||
|
memcpy (m_H, h, 32); // restore m_H
|
||||||
HandlePayload (payload.data (), len - 16, nullptr, 0);
|
HandlePayload (payload.data (), len - 16, nullptr, 0);
|
||||||
|
|
||||||
// we have received reply to NS with LeaseSet in it
|
// we have received reply to NS with LeaseSet in it
|
||||||
|
@ -587,7 +599,15 @@ namespace garlic
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
#endif
|
#endif
|
||||||
case eSessionStateEstablished:
|
case eSessionStateEstablished:
|
||||||
return HandleExistingSessionMessage (buf, len, receiveTagset, index);
|
if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true;
|
||||||
|
if (index < ECIESX25519_NSR_NUM_GENERATED_TAGS)
|
||||||
|
{
|
||||||
|
// check NSR just in case
|
||||||
|
LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index);
|
||||||
|
return HandleNewOutgoingSessionReply (buf, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
case eSessionStateNew:
|
case eSessionStateNew:
|
||||||
return HandleNewIncomingSession (buf, len);
|
return HandleNewIncomingSession (buf, len);
|
||||||
case eSessionStateNewSessionSent:
|
case eSessionStateNewSessionSent:
|
||||||
|
|
Loading…
Reference in a new issue