mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-23 17:36:37 +02:00
X25519Keys for static key
This commit is contained in:
parent
1babd3a5a2
commit
a8b1a86bd7
6 changed files with 37 additions and 16 deletions
|
@ -286,6 +286,19 @@ namespace crypto
|
||||||
m_Ctx = BN_CTX_new ();
|
m_Ctx = BN_CTX_new ();
|
||||||
#endif
|
#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 ()
|
X25519Keys::~X25519Keys ()
|
||||||
{
|
{
|
||||||
|
@ -304,11 +317,13 @@ namespace crypto
|
||||||
m_Pkey = nullptr;
|
m_Pkey = nullptr;
|
||||||
EVP_PKEY_keygen_init (m_Ctx);
|
EVP_PKEY_keygen_init (m_Ctx);
|
||||||
EVP_PKEY_keygen (m_Ctx, &m_Pkey);
|
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;
|
size_t len = 32;
|
||||||
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
|
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
len = 32;
|
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
|
#else
|
||||||
RAND_bytes (m_PrivateKey, 32);
|
RAND_bytes (m_PrivateKey, 32);
|
||||||
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
|
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
|
||||||
|
|
|
@ -66,6 +66,7 @@ namespace crypto
|
||||||
public:
|
public:
|
||||||
|
|
||||||
X25519Keys ();
|
X25519Keys ();
|
||||||
|
X25519Keys (const uint8_t * priv, const uint8_t * pub); // for RouterContext
|
||||||
~X25519Keys ();
|
~X25519Keys ();
|
||||||
|
|
||||||
void GenerateKeys ();
|
void GenerateKeys ();
|
||||||
|
|
|
@ -31,19 +31,14 @@ namespace transport
|
||||||
NTCP2Establisher::NTCP2Establisher ():
|
NTCP2Establisher::NTCP2Establisher ():
|
||||||
m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr)
|
m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr)
|
||||||
{
|
{
|
||||||
m_Ctx = BN_CTX_new ();
|
|
||||||
CreateEphemeralKey ();
|
CreateEphemeralKey ();
|
||||||
}
|
}
|
||||||
|
|
||||||
NTCP2Establisher::~NTCP2Establisher ()
|
NTCP2Establisher::~NTCP2Establisher ()
|
||||||
{
|
{
|
||||||
BN_CTX_free (m_Ctx);
|
|
||||||
delete[] m_SessionRequestBuffer;
|
delete[] m_SessionRequestBuffer;
|
||||||
delete[] m_SessionCreatedBuffer;
|
delete[] m_SessionCreatedBuffer;
|
||||||
delete[] m_SessionConfirmedBuffer;
|
delete[] m_SessionConfirmedBuffer;
|
||||||
#if OPENSSL_X25519
|
|
||||||
EVP_PKEY_free (m_EphemeralPkey);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived)
|
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);
|
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[] =
|
static const uint8_t protocolNameHash[] =
|
||||||
{
|
{
|
||||||
|
@ -83,20 +78,20 @@ namespace transport
|
||||||
SHA256_Update (&ctx, m_H, 32);
|
SHA256_Update (&ctx, m_H, 32);
|
||||||
SHA256_Update (&ctx, epub, 32);
|
SHA256_Update (&ctx, epub, 32);
|
||||||
SHA256_Final (m_H, &ctx);
|
SHA256_Final (m_H, &ctx);
|
||||||
// x25519 between rs and priv
|
// x25519 between pub and priv
|
||||||
uint8_t inputKeyMaterial[32];
|
uint8_t inputKeyMaterial[32];
|
||||||
i2p::crypto::GetEd25519 ()->ScalarMul (pub, priv, inputKeyMaterial, m_Ctx); // rs*priv
|
priv.Agree (pub, inputKeyMaterial);
|
||||||
MixKey (inputKeyMaterial, m_K);
|
MixKey (inputKeyMaterial, m_K);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCP2Establisher::KDF1Alice ()
|
void NTCP2Establisher::KDF1Alice ()
|
||||||
{
|
{
|
||||||
KeyDerivationFunction1 (m_RemoteStaticKey, GetPriv (), m_RemoteStaticKey, GetPub ());
|
KeyDerivationFunction1 (m_RemoteStaticKey, m_EphemeralKeys, m_RemoteStaticKey, GetPub ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCP2Establisher::KDF1Bob ()
|
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)
|
void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub)
|
||||||
|
@ -140,14 +135,14 @@ namespace transport
|
||||||
void NTCP2Establisher::KDF3Alice ()
|
void NTCP2Establisher::KDF3Alice ()
|
||||||
{
|
{
|
||||||
uint8_t inputKeyMaterial[32];
|
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);
|
MixKey (inputKeyMaterial, m_K);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCP2Establisher::KDF3Bob ()
|
void NTCP2Establisher::KDF3Bob ()
|
||||||
{
|
{
|
||||||
uint8_t inputKeyMaterial[32];
|
uint8_t inputKeyMaterial[32];
|
||||||
i2p::crypto::GetEd25519 ()->ScalarMul (m_RemoteStaticKey, GetPriv (), inputKeyMaterial, m_Ctx);
|
m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial);
|
||||||
MixKey (inputKeyMaterial, m_K);
|
MixKey (inputKeyMaterial, m_K);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,6 @@ namespace transport
|
||||||
~NTCP2Establisher ();
|
~NTCP2Establisher ();
|
||||||
|
|
||||||
const uint8_t * GetPub () const { return m_EphemeralKeys.GetPublicKey (); };
|
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
|
const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob
|
||||||
uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set
|
uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set
|
||||||
|
|
||||||
|
@ -96,7 +95,7 @@ namespace transport
|
||||||
void KDF3Bob ();
|
void KDF3Bob ();
|
||||||
|
|
||||||
void MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived);
|
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 KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate
|
||||||
void CreateEphemeralKey ();
|
void CreateEphemeralKey ();
|
||||||
|
|
||||||
|
@ -110,7 +109,6 @@ namespace transport
|
||||||
bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce);
|
bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce);
|
||||||
bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf);
|
bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf);
|
||||||
|
|
||||||
BN_CTX * m_Ctx;
|
|
||||||
i2p::crypto::X25519Keys m_EphemeralKeys;
|
i2p::crypto::X25519Keys m_EphemeralKeys;
|
||||||
uint8_t m_RemoteEphemeralPublicKey[32]; // x25519
|
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*/;
|
uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /*k*/;
|
||||||
|
|
|
@ -620,4 +620,14 @@ namespace i2p
|
||||||
{
|
{
|
||||||
return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, false) : false;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ namespace i2p
|
||||||
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
|
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 * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
|
||||||
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
|
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
|
||||||
|
i2p::crypto::X25519Keys& GetStaticKeys ();
|
||||||
|
|
||||||
uint32_t GetUptime () const;
|
uint32_t GetUptime () const;
|
||||||
uint32_t GetStartupTime () const { return m_StartupTime; };
|
uint32_t GetStartupTime () const { return m_StartupTime; };
|
||||||
|
@ -143,6 +144,7 @@ namespace i2p
|
||||||
int m_NetID;
|
int m_NetID;
|
||||||
std::mutex m_GarlicMutex;
|
std::mutex m_GarlicMutex;
|
||||||
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
|
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
|
||||||
|
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RouterContext context;
|
extern RouterContext context;
|
||||||
|
|
Loading…
Add table
Reference in a new issue