separate X25519Keys

pull/1243/head
orignal 6 years ago
parent 50399e5194
commit 1babd3a5a2

@ -12,9 +12,8 @@
#if LEGACY_OPENSSL
#include "ChaCha20.h"
#include "Poly1305.h"
#else
#include <openssl/evp.h>
#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)
{

@ -13,11 +13,23 @@
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/engine.h>
#include <openssl/opensslv.h>
#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 <openssl/opensslv.h>
#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)

@ -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 ()

@ -20,6 +20,7 @@
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <boost/asio.hpp>
#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;

Loading…
Cancel
Save