diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 299ca438..632edc03 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -79,7 +79,8 @@ set (LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/Gost.cpp" "${LIBI2PD_SRC_DIR}/ChaCha20.cpp" "${LIBI2PD_SRC_DIR}/Poly1305.cpp" - "${LIBI2PD_SRC_DIR}/Ed25519.cpp" + "${LIBI2PD_SRC_DIR}/Ed25519.cpp" + "${LIBI2PD_SRC_DIR}/NTCP2.cpp" ) if (WITH_WEBSOCKETS) diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp index 956f52fc..e921bada 100644 --- a/libi2pd/Ed25519.cpp +++ b/libi2pd/Ed25519.cpp @@ -411,6 +411,14 @@ namespace crypto } } + void Ed25519::ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey) + { + SHA512 (key, EDDSA25519_PRIVATE_KEY_LENGTH, expandedKey); + expandedKey[0] &= 0xF8; // drop last 3 bits + expandedKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] &= 0x3F; // drop first 2 bits + expandedKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] |= 0x40; // set second bit + } + static std::unique_ptr g_Ed25519; std::unique_ptr& GetEd25519 () { diff --git a/libi2pd/Ed25519.h b/libi2pd/Ed25519.h index 9222edb4..c3b162a7 100644 --- a/libi2pd/Ed25519.h +++ b/libi2pd/Ed25519.h @@ -79,6 +79,8 @@ namespace crypto bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const; void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const; + static void ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey); // key - 32 bytes, expandedKey - 64 bytes + private: EDDSAPoint Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const; diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp new file mode 100644 index 00000000..907e1fd8 --- /dev/null +++ b/libi2pd/NTCP2.cpp @@ -0,0 +1,44 @@ +#include +#include "Crypto.h" +#include "Ed25519.h" +#include "ChaCha20.h" +#include "Poly1305.h" +#include "NTCP2.h" + +namespace i2p +{ +namespace transport +{ + NTCP2Session::NTCP2Session (std::shared_ptr in_RemoteRouter): + TransportSession (in_RemoteRouter, 30) + { + } + + NTCP2Session::~NTCP2Session () + { + } + + void NTCP2Session::CreateEphemeralKey (uint8_t * pub) + { + uint8_t key[32]; + RAND_bytes (key, 32); + i2p::crypto::Ed25519::ExpandPrivateKey (key, m_ExpandedPrivateKey); + BN_CTX * ctx = BN_CTX_new (); + auto publicKey = i2p::crypto::GetEd25519 ()->GeneratePublicKey (m_ExpandedPrivateKey, ctx); + i2p::crypto::GetEd25519 ()->EncodePublicKey (publicKey, pub, ctx); + BN_CTX_free (ctx); + } + + void NTCP2Session::SendSessionRequest (const uint8_t * iv) + { + i2p::crypto::AESAlignedBuffer<32> x; + CreateEphemeralKey (x); + // encrypt X + i2p::crypto::CBCEncryption encryption; + encryption.SetKey (GetRemoteIdentity ()->GetIdentHash ()); + encryption.SetIV (iv); + encryption.Encrypt (2, x.GetChipherBlock (), x.GetChipherBlock ()); + } +} +} + diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h new file mode 100644 index 00000000..6dfea8ae --- /dev/null +++ b/libi2pd/NTCP2.h @@ -0,0 +1,32 @@ +#ifndef NTCP2_H__ +#define NTCP2_H__ + +#include +#include +#include "RouterInfo.h" +#include "TransportSession.h" + +namespace i2p +{ +namespace transport +{ + class NTCP2Session: public TransportSession, public std::enable_shared_from_this + { + public: + + NTCP2Session (std::shared_ptr in_RemoteRouter = nullptr); // TODO + ~NTCP2Session (); + + private: + + void CreateEphemeralKey (uint8_t * pub); + void SendSessionRequest (const uint8_t * iv); + + private: + + uint8_t m_ExpandedPrivateKey[64]; // x25519 ephemeral key + }; +} +} + +#endif diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index f9b7aebd..baa265bc 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -30,11 +30,7 @@ namespace crypto EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) { // expand key - SHA512 (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH, m_ExpandedPrivateKey); - m_ExpandedPrivateKey[0] &= 0xF8; // drop last 3 bits - m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] &= 0x3F; // drop first 2 bits - m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] |= 0x40; // set second bit - + Ed25519::ExpandPrivateKey (signingPrivateKey, m_ExpandedPrivateKey); // generate and encode public key BN_CTX * ctx = BN_CTX_new (); auto publicKey = GetEd25519 ()->GeneratePublicKey (m_ExpandedPrivateKey, ctx);