From 1babd3a5a2b0e3c8f670d4f41f99b41c6b3315fc Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 8 Sep 2018 16:52:42 -0400 Subject: [PATCH] separate X25519Keys --- libi2pd/Crypto.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++-- libi2pd/Crypto.h | 50 +++++++++++++++++++++++++++++++---------- libi2pd/NTCP2.cpp | 34 +++++----------------------- libi2pd/NTCP2.h | 11 +++++----- 4 files changed, 101 insertions(+), 49 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 7a947d34..0a7c56ed 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -12,9 +12,8 @@ #if LEGACY_OPENSSL #include "ChaCha20.h" #include "Poly1305.h" -#else -#include #endif +#include "Ed25519.h" #include "I2PEndian.h" #include "Log.h" @@ -278,6 +277,58 @@ namespace crypto BN_free (pk); } +// x25519 + X25519Keys::X25519Keys () + { +#if OPENSSL_X25519 + m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL); +#else + m_Ctx = BN_CTX_new (); +#endif + } + + X25519Keys::~X25519Keys () + { +#if OPENSSL_X25519 + EVP_PKEY_CTX_free (m_Ctx); + if (m_Pkey) + EVP_PKEY_free (m_Pkey); +#else + BN_CTX_free (m_Ctx); +#endif + } + + void X25519Keys::GenerateKeys () + { +#if OPENSSL_X25519 + m_Pkey = nullptr; + EVP_PKEY_keygen_init (m_Ctx); + EVP_PKEY_keygen (m_Ctx, &m_Pkey); + 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); +#else + RAND_bytes (m_PrivateKey, 32); + GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); +#endif + } + + void X25519Keys::Agree (const uint8_t * pub, uint8_t * shared) + { +#if OPENSSL_X25519 + EVP_PKEY_derive_init (m_Ctx); + auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32); + EVP_PKEY_derive_set_peer (m_Ctx, pkey); + size_t len = 32; + EVP_PKEY_derive (m_Ctx, shared, &len); + EVP_PKEY_free (pkey); +#else + GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx); +#endif + } + // ElGamal void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 30d00d76..353a8165 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -13,11 +13,23 @@ #include #include #include +#include #include "Base.h" #include "Tag.h" #include "CPU.h" +// recognize openssl version and features +#if ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL +# define LEGACY_OPENSSL 1 +#else +# define LEGACY_OPENSSL 0 +# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 +# define OPENSSL_EDDSA 1 +# define OPENSSL_X25519 1 +# endif +#endif + namespace i2p { namespace crypto @@ -48,6 +60,31 @@ namespace crypto uint8_t m_PublicKey[256]; }; + // x25519 + class X25519Keys + { + public: + + X25519Keys (); + ~X25519Keys (); + + void GenerateKeys (); + const uint8_t * GetPublicKey () const { return m_PublicKey; }; + const uint8_t * GetPrivateKey () const { return m_PrivateKey; }; // TODO: remove + void Agree (const uint8_t * pub, uint8_t * shared); + + private: + + uint8_t m_PublicKey[32]; + uint8_t m_PrivateKey[32]; // TODO: move to #else +#if OPENSSL_X25519 + EVP_PKEY_CTX * m_Ctx; + EVP_PKEY * m_Pkey; +#else + BN_CTX * m_Ctx; +#endif + }; + // ElGamal void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); @@ -260,18 +297,7 @@ namespace crypto } } -// take care about openssl version -#include -#if ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL -# define LEGACY_OPENSSL 1 -#else -# define LEGACY_OPENSSL 0 -# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 -# define OPENSSL_EDDSA 1 -# define OPENSSL_X25519 1 -# endif -#endif - +// take care about openssl below 1.1.0 #if LEGACY_OPENSSL // define getters and setters introduced in 1.1.0 inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 6a319115..d0e16d90 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -120,20 +120,10 @@ namespace transport SHA256_Update (&ctx, epub, 32); SHA256_Final (m_H, &ctx); - // x25519 between remote pub and priv + // x25519 between remote pub and ephemaral priv uint8_t inputKeyMaterial[32]; -#if OPENSSL_X25519 - auto pctx = EVP_PKEY_CTX_new (m_EphemeralPkey, NULL); - EVP_PKEY_derive_init (pctx); - auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, GetRemotePub (), 32); - EVP_PKEY_derive_set_peer (pctx, pkey); - size_t len = 32; - EVP_PKEY_derive (pctx, inputKeyMaterial, &len); - EVP_PKEY_free (pkey); - EVP_PKEY_CTX_free (pctx); -#else - i2p::crypto::GetEd25519 ()->ScalarMul (GetRemotePub (), GetPriv (), inputKeyMaterial, m_Ctx); -#endif + m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial); + MixKey (inputKeyMaterial, m_K); } @@ -157,27 +147,13 @@ namespace transport void NTCP2Establisher::KDF3Bob () { uint8_t inputKeyMaterial[32]; - i2p::crypto::GetEd25519 ()->ScalarMul (m_RemoteStaticKey, m_EphemeralPrivateKey, inputKeyMaterial, m_Ctx); + i2p::crypto::GetEd25519 ()->ScalarMul (m_RemoteStaticKey, GetPriv (), inputKeyMaterial, m_Ctx); MixKey (inputKeyMaterial, m_K); } void NTCP2Establisher::CreateEphemeralKey () { -#if OPENSSL_X25519 - m_EphemeralPkey = nullptr; - EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL); - EVP_PKEY_keygen_init (pctx); - EVP_PKEY_keygen (pctx, &m_EphemeralPkey); - EVP_PKEY_CTX_free (pctx); - // TODO: remove, after switch to m_EphemeralPkey - size_t len = 32; - EVP_PKEY_get_raw_public_key (m_EphemeralPkey, m_EphemeralPublicKey, &len); - len = 32; - EVP_PKEY_get_raw_private_key (m_EphemeralPkey, m_EphemeralPrivateKey, &len); -#else - RAND_bytes (m_EphemeralPrivateKey, 32); - i2p::crypto::GetEd25519 ()->ScalarMulB (m_EphemeralPrivateKey, m_EphemeralPublicKey, m_Ctx); -#endif + m_EphemeralKeys.GenerateKeys (); } void NTCP2Establisher::CreateSessionRequestMessage () diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 10874abb..73001fc2 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -20,6 +20,7 @@ #include #include #include +#include "Crypto.h" #include "util.h" #include "RouterInfo.h" #include "TransportSession.h" @@ -78,8 +79,8 @@ namespace transport NTCP2Establisher (); ~NTCP2Establisher (); - const uint8_t * GetPub () const { return m_EphemeralPublicKey; }; - const uint8_t * GetPriv () const { return m_EphemeralPrivateKey; }; + 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 @@ -110,10 +111,8 @@ namespace transport bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf); BN_CTX * m_Ctx; - uint8_t m_EphemeralPrivateKey[32], m_EphemeralPublicKey[32], m_RemoteEphemeralPublicKey[32]; // x25519 -#if OPENSSL_X25519 - EVP_PKEY * m_EphemeralPkey; -#endif + 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*/; i2p::data::IdentHash m_RemoteIdentHash; uint16_t m3p2Len;