mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-10 05:11:10 +00:00
new session reply
This commit is contained in:
parent
80373623cd
commit
62e39ddfbd
@ -34,7 +34,16 @@ namespace garlic
|
|||||||
SHA256_Update (&ctx, buf, len);
|
SHA256_Update (&ctx, buf, len);
|
||||||
SHA256_Final (m_H, &ctx);
|
SHA256_Final (m_H, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ECIESX25519AEADRatchetSession::DHInitialize (const uint8_t * rootKey, const uint8_t * k, uint8_t * nextRootKey, uint8_t * ck)
|
||||||
|
{
|
||||||
|
uint8_t keydata[64];
|
||||||
|
i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64)
|
||||||
|
memcpy (nextRootKey, keydata, 32); // nextRootKey = keydata[0:31]
|
||||||
|
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", ck);
|
||||||
|
// ck = [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64)
|
||||||
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove)
|
bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove)
|
||||||
{
|
{
|
||||||
if (!GetOwner ()) return false;
|
if (!GetOwner ()) return false;
|
||||||
@ -165,11 +174,66 @@ namespace garlic
|
|||||||
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
|
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext)
|
MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||||
|
{
|
||||||
|
m_EphemeralKeys.GenerateKeys ();
|
||||||
|
// we are Bob
|
||||||
|
uint8_t tagsetKey[32], ck[64];
|
||||||
|
i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32)
|
||||||
|
DHInitialize (m_CK, tagsetKey, tagsetKey, ck); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey), nextRootKey?
|
||||||
|
// Session Tag Ratchet
|
||||||
|
uint8_t keydata[64];
|
||||||
|
i2p::crypto::HKDF (ck, nullptr, 0, "STInitialization", keydata); // keydata = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64)
|
||||||
|
// sessTag_chainKey = keydata[0:31], SESSTAG_CONSTANT = keydata[32:63]
|
||||||
|
i2p::crypto::HKDF (keydata, keydata + 32, 32, "SessionTagKeyGen", keydata); // keydata_0 = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64)
|
||||||
|
// tag_0 = keydata_0[32:39]
|
||||||
|
uint8_t * tag = keydata + 32;
|
||||||
|
|
||||||
|
size_t offset = 0;
|
||||||
|
memcpy (out + offset, tag, 8);
|
||||||
|
offset += 8;
|
||||||
|
if (!i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), out + offset)) // bepk
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Garlic: Can't encode elligator");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
offset += 32;
|
||||||
|
// KDF for Reply Key Section
|
||||||
|
MixHash (tag, 8); // h = SHA256(h || tag)
|
||||||
|
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk)
|
||||||
|
uint8_t sharedSecret[32];
|
||||||
|
m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, aepk)
|
||||||
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||||
|
uint8_t nonce[12];
|
||||||
|
memset (nonce, 0, 12); // n = 0
|
||||||
|
// calulate hash for zero length
|
||||||
|
if (!i2p::crypto::AEADChaCha20Poly1305 (sharedSecret /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
|
||||||
|
out += 16;
|
||||||
|
// KDF for payload
|
||||||
|
i2p::crypto::HKDF (m_CK, nullptr, 0, "STInitialization", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||||
|
// k_ab = keydata[0:31], k_ba = keydata[32:63]
|
||||||
|
// tagset_ab = DH_INITIALIZE(chainKey, k_ab), tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
||||||
|
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
||||||
|
// encrypt payload
|
||||||
|
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
auto m = NewI2NPMessage ();
|
auto m = NewI2NPMessage ();
|
||||||
@ -185,6 +249,11 @@ namespace garlic
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
len += 96;
|
len += 96;
|
||||||
break;
|
break;
|
||||||
|
case eSessionStateNewSessionReceived:
|
||||||
|
if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||||
|
return nullptr;
|
||||||
|
len += 72;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,12 @@ namespace garlic
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
void MixHash (const uint8_t * buf, size_t len);
|
void MixHash (const uint8_t * buf, size_t len);
|
||||||
|
void DHInitialize (const uint8_t * rootKey, const uint8_t * k, uint8_t * nextRootKey, uint8_t * ck); // ck is 64 buytes
|
||||||
|
|
||||||
void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove);
|
void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove);
|
||||||
|
|
||||||
bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
|
bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg);
|
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user