From 8b49a5544284562a2a1082ae332ecb58578182c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 20 Jan 2020 15:17:38 -0500 Subject: [PATCH] ratchet tagsets --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 52 ++++++++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 15 ++++++- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 36d8af43..7548603c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -12,6 +12,29 @@ namespace i2p namespace garlic { + void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k) + { + // DH_INITIALIZE(rootKey, k) + uint8_t keydata[64]; + i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) + // nextRootKey = keydata[0:31] + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_CK); + // ck = [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) + } + + void RatchetTagSet::NextSessionTagRatchet () + { + i2p::crypto::HKDF (m_CK, nullptr, 0, "STInitialization", m_CK); // [ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) + memcpy (m_SessTagConstant, m_CK + 32, 32); + } + + const uint8_t * RatchetTagSet::GetNextSessionTag () + { + i2p::crypto::HKDF (m_CK, m_SessTagConstant, 32, "SessionTagKeyGen", m_CK); // [ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + return m_CK + 32; + } + + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): GarlicRoutingSession (owner, true) { @@ -35,15 +58,6 @@ namespace garlic 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) { if (!GetOwner ()) return false; @@ -183,16 +197,14 @@ namespace garlic { m_EphemeralKeys.GenerateKeys (); // we are Bob - uint8_t tagsetKey[32], ck[64]; + uint8_t tagsetKey[32]; 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; + RatchetTagSet tagsetNsr; + tagsetNsr.DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) + tagsetNsr.NextSessionTagRatchet (); + auto tag = tagsetNsr.GetNextSessionTag (); size_t offset = 0; memcpy (out + offset, tag, 8); @@ -220,9 +232,11 @@ namespace garlic 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) + uint8_t keydata[64]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "", 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) + m_TagsetAB.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_TagsetBA.DHInitialize (m_CK, keydata + 32); // 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 diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 4ff6623f..b449c0e5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -13,6 +13,19 @@ namespace i2p { namespace garlic { + class RatchetTagSet + { + public: + + void DHInitialize (const uint8_t * rootKey, const uint8_t * k); + void NextSessionTagRatchet (); + const uint8_t * GetNextSessionTag (); + + private: + + uint8_t m_CK[64], m_SessTagConstant[32]; + }; + enum ECIESx25519BlockType { eECIESx25519BlkDateTime = 0, @@ -48,7 +61,6 @@ namespace garlic private: 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); @@ -61,6 +73,7 @@ namespace garlic uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; + RatchetTagSet m_TagsetAB, m_TagsetBA; }; } }