From a8b1a86bd71c9b5d76f39c5d6e74a084f2aeabc5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 8 Sep 2018 22:08:08 -0400 Subject: [PATCH] X25519Keys for static key --- libi2pd/Crypto.cpp | 17 ++++++++++++++++- libi2pd/Crypto.h | 1 + libi2pd/NTCP2.cpp | 19 +++++++------------ libi2pd/NTCP2.h | 4 +--- libi2pd/RouterContext.cpp | 10 ++++++++++ libi2pd/RouterContext.h | 2 ++ 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 0a7c56ed..cc424515 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -286,6 +286,19 @@ namespace crypto m_Ctx = BN_CTX_new (); #endif } + + X25519Keys::X25519Keys (const uint8_t * priv, const uint8_t * pub) + { +#if OPENSSL_X25519 + m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); + m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); + memcpy (m_PublicKey, pub, 32); // TODO: verify against m_Pkey +#else + memcpy (m_PrivateKey, priv, 32); + memcpy (m_PublicKey, pub, 32); + m_Ctx = BN_CTX_new (); +#endif + } X25519Keys::~X25519Keys () { @@ -304,11 +317,13 @@ namespace crypto m_Pkey = nullptr; EVP_PKEY_keygen_init (m_Ctx); EVP_PKEY_keygen (m_Ctx, &m_Pkey); + EVP_PKEY_CTX_free (m_Ctx); + m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); // TODO: do we really need to re-create m_Ctx? size_t len = 32; EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); // TODO: remove len = 32; - EVP_PKEY_get_raw_private_key (m_EphemeralPkey, m_PrivateKey, &len); + EVP_PKEY_get_raw_private_key (m_Pkey, m_PrivateKey, &len); #else RAND_bytes (m_PrivateKey, 32); GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 353a8165..b02db36c 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -66,6 +66,7 @@ namespace crypto public: X25519Keys (); + X25519Keys (const uint8_t * priv, const uint8_t * pub); // for RouterContext ~X25519Keys (); void GenerateKeys (); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index d0e16d90..5c4cc9ce 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -31,19 +31,14 @@ namespace transport NTCP2Establisher::NTCP2Establisher (): m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr) { - m_Ctx = BN_CTX_new (); CreateEphemeralKey (); } NTCP2Establisher::~NTCP2Establisher () { - BN_CTX_free (m_Ctx); delete[] m_SessionRequestBuffer; delete[] m_SessionCreatedBuffer; delete[] m_SessionConfirmedBuffer; -#if OPENSSL_X25519 - EVP_PKEY_free (m_EphemeralPkey); -#endif } void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived) @@ -59,7 +54,7 @@ namespace transport HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, derived, &len); } - void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, const uint8_t * priv, const uint8_t * rs, const uint8_t * epub) + void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) { static const uint8_t protocolNameHash[] = { @@ -83,20 +78,20 @@ namespace transport SHA256_Update (&ctx, m_H, 32); SHA256_Update (&ctx, epub, 32); SHA256_Final (m_H, &ctx); - // x25519 between rs and priv + // x25519 between pub and priv uint8_t inputKeyMaterial[32]; - i2p::crypto::GetEd25519 ()->ScalarMul (pub, priv, inputKeyMaterial, m_Ctx); // rs*priv + priv.Agree (pub, inputKeyMaterial); MixKey (inputKeyMaterial, m_K); } void NTCP2Establisher::KDF1Alice () { - KeyDerivationFunction1 (m_RemoteStaticKey, GetPriv (), m_RemoteStaticKey, GetPub ()); + KeyDerivationFunction1 (m_RemoteStaticKey, m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); } void NTCP2Establisher::KDF1Bob () { - KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetNTCP2StaticPrivateKey (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); + KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetStaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); } void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) @@ -140,14 +135,14 @@ namespace transport void NTCP2Establisher::KDF3Alice () { uint8_t inputKeyMaterial[32]; - i2p::crypto::GetEd25519 ()->ScalarMul (GetRemotePub (), i2p::context.GetNTCP2StaticPrivateKey (), inputKeyMaterial, m_Ctx); + i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); MixKey (inputKeyMaterial, m_K); } void NTCP2Establisher::KDF3Bob () { uint8_t inputKeyMaterial[32]; - i2p::crypto::GetEd25519 ()->ScalarMul (m_RemoteStaticKey, GetPriv (), inputKeyMaterial, m_Ctx); + m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial); MixKey (inputKeyMaterial, m_K); } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 73001fc2..07f44371 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -80,7 +80,6 @@ namespace transport ~NTCP2Establisher (); const uint8_t * GetPub () const { return m_EphemeralKeys.GetPublicKey (); }; - const uint8_t * GetPriv () const { return m_EphemeralKeys.GetPrivateKey (); }; const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set @@ -96,7 +95,7 @@ namespace transport void KDF3Bob (); void MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived); - void KeyDerivationFunction1 (const uint8_t * pub, const uint8_t * priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH + 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 (); @@ -110,7 +109,6 @@ namespace transport bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce); bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf); - BN_CTX * m_Ctx; i2p::crypto::X25519Keys m_EphemeralKeys; uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /*k*/; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 6ad3d159..d8ef4c4a 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -620,4 +620,14 @@ namespace i2p { return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, false) : false; } + + i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () + { + if (!m_StaticKeys) + { + if (!m_NTCP2Keys) NewNTCP2Keys (); + m_StaticKeys.reset (new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey)); + } + return *m_StaticKeys; + } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 3f3a18c5..0b88ea82 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -62,6 +62,7 @@ namespace i2p const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; }; const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; }; const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; }; + i2p::crypto::X25519Keys& GetStaticKeys (); uint32_t GetUptime () const; uint32_t GetStartupTime () const { return m_StartupTime; }; @@ -143,6 +144,7 @@ namespace i2p int m_NetID; std::mutex m_GarlicMutex; std::unique_ptr m_NTCP2Keys; + std::unique_ptr m_StaticKeys; }; extern RouterContext context;