mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-25 23:44:18 +00:00
check if x25519 key is valid
This commit is contained in:
parent
ce9640773c
commit
726bd0d63b
@ -351,11 +351,13 @@ namespace crypto
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void X25519Keys::Agree (const uint8_t * pub, uint8_t * shared)
|
bool X25519Keys::Agree (const uint8_t * pub, uint8_t * shared)
|
||||||
{
|
{
|
||||||
|
if (pub[31] & 0x80) return false; // not x25519 key
|
||||||
#if OPENSSL_X25519
|
#if OPENSSL_X25519
|
||||||
EVP_PKEY_derive_init (m_Ctx);
|
EVP_PKEY_derive_init (m_Ctx);
|
||||||
auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32);
|
auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32);
|
||||||
|
if (!pkey) return false;
|
||||||
EVP_PKEY_derive_set_peer (m_Ctx, pkey);
|
EVP_PKEY_derive_set_peer (m_Ctx, pkey);
|
||||||
size_t len = 32;
|
size_t len = 32;
|
||||||
EVP_PKEY_derive (m_Ctx, shared, &len);
|
EVP_PKEY_derive (m_Ctx, shared, &len);
|
||||||
@ -363,6 +365,7 @@ namespace crypto
|
|||||||
#else
|
#else
|
||||||
GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx);
|
GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx);
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X25519Keys::GetPrivateKey (uint8_t * priv) const
|
void X25519Keys::GetPrivateKey (uint8_t * priv) const
|
||||||
|
@ -89,7 +89,7 @@ namespace crypto
|
|||||||
const uint8_t * GetPublicKey () const { return m_PublicKey; };
|
const uint8_t * GetPublicKey () const { return m_PublicKey; };
|
||||||
void GetPrivateKey (uint8_t * priv) const;
|
void GetPrivateKey (uint8_t * priv) const;
|
||||||
void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false);
|
void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false);
|
||||||
void Agree (const uint8_t * pub, uint8_t * shared);
|
bool Agree (const uint8_t * pub, uint8_t * shared);
|
||||||
|
|
||||||
bool IsElligatorIneligible () const { return m_IsElligatorIneligible; }
|
bool IsElligatorIneligible () const { return m_IsElligatorIneligible; }
|
||||||
void SetElligatorIneligible () { m_IsElligatorIneligible = true; }
|
void SetElligatorIneligible () { m_IsElligatorIneligible = true; }
|
||||||
|
@ -173,8 +173,7 @@ namespace crypto
|
|||||||
|
|
||||||
bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding)
|
bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
m_StaticKeys.Agree (epub, sharedSecret);
|
return m_StaticKeys.Agree (epub, sharedSecret);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub)
|
void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub)
|
||||||
|
@ -231,7 +231,11 @@ namespace garlic
|
|||||||
MixHash (m_Aepk, 32); // h = SHA256(h || aepk)
|
MixHash (m_Aepk, 32); // h = SHA256(h || aepk)
|
||||||
|
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, aepk)
|
if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
|
|
||||||
// decrypt flags/static
|
// decrypt flags/static
|
||||||
@ -251,7 +255,11 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
// static key, fs is apk
|
// static key, fs is apk
|
||||||
memcpy (m_RemoteStaticKey, fs, 32);
|
memcpy (m_RemoteStaticKey, fs, 32);
|
||||||
GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, apk)
|
if (!GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect Alice static key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
}
|
}
|
||||||
else // all zeros flags
|
else // all zeros flags
|
||||||
@ -448,7 +456,11 @@ namespace garlic
|
|||||||
i2p::crypto::InitNoiseIKState (*this, m_RemoteStaticKey); // bpk
|
i2p::crypto::InitNoiseIKState (*this, m_RemoteStaticKey); // bpk
|
||||||
MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk)
|
MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk)
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk)
|
if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect Bob static key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
// encrypt flags/static key section
|
// encrypt flags/static key section
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
@ -504,7 +516,11 @@ namespace garlic
|
|||||||
MixHash (out + offset, 32); // h = SHA256(h || aepk)
|
MixHash (out + offset, 32); // h = SHA256(h || aepk)
|
||||||
offset += 32;
|
offset += 32;
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk)
|
if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect Bob static key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (0, nonce);
|
CreateNonce (0, nonce);
|
||||||
@ -540,9 +556,17 @@ namespace garlic
|
|||||||
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
|
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
|
||||||
MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk)
|
MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk)
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
m_EphemeralKeys->Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk)
|
if (!m_EphemeralKeys->Agree (m_Aepk, sharedSecret)) // sharedSecret = x25519(besk, aepk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk)
|
if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // sharedSecret = x25519(besk, apk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect Alice static key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (0, nonce);
|
CreateNonce (0, nonce);
|
||||||
@ -624,7 +648,11 @@ namespace garlic
|
|||||||
MixHash (tag, 8); // h = SHA256(h || tag)
|
MixHash (tag, 8); // h = SHA256(h || tag)
|
||||||
MixHash (bepk, 32); // h = SHA256(h || bepk)
|
MixHash (bepk, 32); // h = SHA256(h || bepk)
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk)
|
if (!m_EphemeralKeys->Agree (bepk, sharedSecret)) // sharedSecret = x25519(aesk, bepk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect Bob ephemeral key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk)
|
GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk)
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
@ -788,7 +816,11 @@ namespace garlic
|
|||||||
i2p::crypto::InitNoiseNState (*this, GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk
|
i2p::crypto::InitNoiseNState (*this, GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk
|
||||||
MixHash (buf, 32);
|
MixHash (buf, 32);
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, aepk)
|
if (!GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MixKey (sharedSecret);
|
MixKey (sharedSecret);
|
||||||
buf += 32; len -= 32;
|
buf += 32; len -= 32;
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
|
@ -866,6 +866,7 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
it->second.tagset->DeleteSymmKey (it->second.index);
|
it->second.tagset->DeleteSymmKey (it->second.index);
|
||||||
it = m_ECIESx25519Tags.erase (it);
|
it = m_ECIESx25519Tags.erase (it);
|
||||||
|
numExpiredTags++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
|
@ -729,7 +729,11 @@ namespace i2p
|
|||||||
m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState));
|
m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState));
|
||||||
m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk)
|
m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk)
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
m_Decryptor->Decrypt (encrypted, sharedSecret, ctx, false);
|
if (!m_Decryptor->Decrypt (encrypted, sharedSecret, ctx, false))
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Router: Incorrect ephemeral public key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
m_CurrentNoiseState->MixKey (sharedSecret);
|
m_CurrentNoiseState->MixKey (sharedSecret);
|
||||||
encrypted += 32;
|
encrypted += 32;
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user