diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 2f10e91d..ea2cd675 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1323,6 +1323,21 @@ namespace crypto #endif } + void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len) + { + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, m_H, 32); + SHA256_Update (&ctx, buf, len); + SHA256_Final (m_H, &ctx); + } + + void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret) + { + HKDF (m_CK, sharedSecret, 32, "", m_CK); + // new ck is m_CK[0:31], key is m_CK[32:63] + } + // init and terminate /* std::vector > m_OpenSSLMutexes; @@ -1336,8 +1351,7 @@ namespace crypto m_OpenSSLMutexes[type]->unlock (); } }*/ - - + void InitCrypto (bool precomputation) { i2p::cpu::Detect (); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index ab84e56a..205be44d 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -311,6 +311,16 @@ namespace crypto void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32 +// Noise + + struct NoiseSymmetricState + { + uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/; + + void MixHash (const uint8_t * buf, size_t len); + void MixKey (const uint8_t * sharedSecret); + }; + // init and terminate void InitCrypto (bool precomputation); void TerminateCrypto (); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index cdf660b7..7a88e4d8 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -39,21 +39,6 @@ namespace transport delete[] m_SessionConfirmedBuffer; } - void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial) - { - i2p::crypto::HKDF (m_CK, inputKeyMaterial, 32, "", m_CK); - // ck is m_CK[0:31], k is m_CK[32:63] - } - - void NTCP2Establisher::MixHash (const uint8_t * buf, size_t len) - { - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, buf, len); - SHA256_Final (m_H, &ctx); - } - void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) { static const uint8_t protocolNameHash[] = diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index df72fed0..351f17b5 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -74,7 +74,7 @@ namespace transport // RouterInfo flags const uint8_t NTCP2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01; - struct NTCP2Establisher + struct NTCP2Establisher: private i2p::crypto::NoiseSymmetricState { NTCP2Establisher (); ~NTCP2Establisher (); @@ -94,8 +94,6 @@ namespace transport void KDF3Alice (); // for SessionConfirmed part 2 void KDF3Bob (); - void MixKey (const uint8_t * inputKeyMaterial); - void MixHash (const uint8_t * buf, size_t len); void KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH void KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate void CreateEphemeralKey (); @@ -112,7 +110,7 @@ namespace transport std::shared_ptr m_EphemeralKeys; uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 - uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[64] /* [ck, k]*/; + uint8_t m_RemoteStaticKey[32], m_IV[16]; i2p::data::IdentHash m_RemoteIdentHash; uint16_t m3p2Len; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index bfe466e3..a74c8c91 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -124,7 +124,7 @@ namespace tunnel uint8_t nonce[12]; memset (nonce, 0, 12); if (!i2p::crypto::AEADChaCha20Poly1305 (record, TUNNEL_BUILD_RECORD_SIZE - 16, - hop->h, 32, hop->ck, nonce, record, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + hop->m_H, 32, hop->m_CK, nonce, record, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 5c2cbd53..61e878d4 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -10,7 +10,6 @@ #include #include #include -#include "Crypto.h" #include "Log.h" #include "Transports.h" #include "Timestamp.h" @@ -129,8 +128,8 @@ namespace tunnel const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) { static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars - memcpy (ck, protocolName, 32); // ck = h = protocol_name || 0 - SHA256 (ck, 32, h); // h = SHA256(h); + memcpy (m_CK, protocolName, 32); // ck = h = protocol_name || 0 + SHA256 (m_CK, 32, m_H); // h = SHA256(h); uint8_t hepk[32]; encryptor->Encrypt (nullptr, hepk, nullptr, false); MixHash (hepk, 32); // h = SHA256(h || hepk) @@ -140,27 +139,16 @@ namespace tunnel encrypted += 32; uint8_t sharedSecret[32]; ephemeralKeys->Agree (hepk, sharedSecret); // x25519(sesk, hepk) - uint8_t keydata[64]; - i2p::crypto::HKDF (ck, sharedSecret, 32, "", keydata); - memcpy (ck, keydata, 32); + MixKey (sharedSecret); uint8_t nonce[12]; memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, h, 32, - keydata + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, m_H, 32, + m_CK + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16, true)) // encrypt { LogPrint (eLogWarning, "Tunnel: Plaintext AEAD encryption failed"); return; } MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) } - - void TunnelHopConfig::MixHash (const uint8_t * buf, size_t len) - { - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, h, 32); - SHA256_Update (&ctx, buf, len); - SHA256_Final (h, &ctx); - } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 0e757071..261394b4 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -12,12 +12,13 @@ #include #include "Identity.h" #include "RouterContext.h" +#include "Crypto.h" namespace i2p { namespace tunnel { - struct TunnelHopConfig + struct TunnelHopConfig: public i2p::crypto::NoiseSymmetricState { std::shared_ptr ident; i2p::data::IdentHash nextIdent; @@ -30,7 +31,6 @@ namespace tunnel TunnelHopConfig * next, * prev; int recordIndex; // record # in tunnel build message - uint8_t ck[32], h[32]; // for ECIES TunnelHopConfig (std::shared_ptr r); @@ -43,7 +43,6 @@ namespace tunnel void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); void EncryptECIES (std::shared_ptr& encryptor, const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); - void MixHash (const uint8_t * buf, size_t len); }; class TunnelConfig