Browse Source

check if x25519 key is valid

pull/1622/head
orignal 4 years ago
parent
commit
726bd0d63b
  1. 5
      libi2pd/Crypto.cpp
  2. 2
      libi2pd/Crypto.h
  3. 3
      libi2pd/CryptoKey.cpp
  4. 48
      libi2pd/ECIESX25519AEADRatchetSession.cpp
  5. 1
      libi2pd/Garlic.cpp
  6. 6
      libi2pd/RouterContext.cpp

5
libi2pd/Crypto.cpp

@ -351,11 +351,13 @@ namespace crypto @@ -351,11 +351,13 @@ namespace crypto
#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
EVP_PKEY_derive_init (m_Ctx);
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);
size_t len = 32;
EVP_PKEY_derive (m_Ctx, shared, &len);
@ -363,6 +365,7 @@ namespace crypto @@ -363,6 +365,7 @@ namespace crypto
#else
GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx);
#endif
return true;
}
void X25519Keys::GetPrivateKey (uint8_t * priv) const

2
libi2pd/Crypto.h

@ -89,7 +89,7 @@ namespace crypto @@ -89,7 +89,7 @@ namespace crypto
const uint8_t * GetPublicKey () const { return m_PublicKey; };
void GetPrivateKey (uint8_t * priv) const;
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; }
void SetElligatorIneligible () { m_IsElligatorIneligible = true; }

3
libi2pd/CryptoKey.cpp

@ -173,8 +173,7 @@ namespace crypto @@ -173,8 +173,7 @@ namespace crypto
bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding)
{
m_StaticKeys.Agree (epub, sharedSecret);
return true;
return m_StaticKeys.Agree (epub, sharedSecret);
}
void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub)

48
libi2pd/ECIESX25519AEADRatchetSession.cpp

@ -231,7 +231,11 @@ namespace garlic @@ -231,7 +231,11 @@ namespace garlic
MixHash (m_Aepk, 32); // h = SHA256(h || aepk)
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);
// decrypt flags/static
@ -251,7 +255,11 @@ namespace garlic @@ -251,7 +255,11 @@ namespace garlic
{
// static key, fs is apk
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);
}
else // all zeros flags
@ -448,7 +456,11 @@ namespace garlic @@ -448,7 +456,11 @@ namespace garlic
i2p::crypto::InitNoiseIKState (*this, m_RemoteStaticKey); // bpk
MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk)
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);
// encrypt flags/static key section
uint8_t nonce[12];
@ -504,7 +516,11 @@ namespace garlic @@ -504,7 +516,11 @@ namespace garlic
MixHash (out + offset, 32); // h = SHA256(h || aepk)
offset += 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);
uint8_t nonce[12];
CreateNonce (0, nonce);
@ -540,9 +556,17 @@ namespace garlic @@ -540,9 +556,17 @@ namespace garlic
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk)
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);
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);
uint8_t nonce[12];
CreateNonce (0, nonce);
@ -624,7 +648,11 @@ namespace garlic @@ -624,7 +648,11 @@ namespace garlic
MixHash (tag, 8); // h = SHA256(h || tag)
MixHash (bepk, 32); // h = SHA256(h || bepk)
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);
GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk)
MixKey (sharedSecret);
@ -788,7 +816,11 @@ namespace garlic @@ -788,7 +816,11 @@ namespace garlic
i2p::crypto::InitNoiseNState (*this, GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk
MixHash (buf, 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);
buf += 32; len -= 32;
uint8_t nonce[12];

1
libi2pd/Garlic.cpp

@ -866,6 +866,7 @@ namespace garlic @@ -866,6 +866,7 @@ namespace garlic
{
it->second.tagset->DeleteSymmKey (it->second.index);
it = m_ECIESx25519Tags.erase (it);
numExpiredTags++;
}
else
++it;

6
libi2pd/RouterContext.cpp

@ -729,7 +729,11 @@ namespace i2p @@ -729,7 +729,11 @@ namespace i2p
m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState));
m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk)
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);
encrypted += 32;
uint8_t nonce[12];

Loading…
Cancel
Save