Browse Source

common MixHash and MixKey

pull/1575/head
orignal 4 years ago
parent
commit
9f2a2e44a3
  1. 16
      libi2pd/Crypto.cpp
  2. 10
      libi2pd/Crypto.h
  3. 15
      libi2pd/NTCP2.cpp
  4. 6
      libi2pd/NTCP2.h
  5. 2
      libi2pd/Tunnel.cpp
  6. 22
      libi2pd/TunnelConfig.cpp
  7. 5
      libi2pd/TunnelConfig.h

16
libi2pd/Crypto.cpp

@ -1323,6 +1323,21 @@ namespace crypto
#endif #endif
} }
void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len)
{
SHA256_CTX ctx;
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, buf, len);
SHA256_Final (m_H, &ctx);
}
void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
{
HKDF (m_CK, sharedSecret, 32, "", m_CK);
// new ck is m_CK[0:31], key is m_CK[32:63]
}
// init and terminate // init and terminate
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes; /* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
@ -1337,7 +1352,6 @@ namespace crypto
} }
}*/ }*/
void InitCrypto (bool precomputation) void InitCrypto (bool precomputation)
{ {
i2p::cpu::Detect (); i2p::cpu::Detect ();

10
libi2pd/Crypto.h

@ -311,6 +311,16 @@ namespace crypto
void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32 void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32
// Noise
struct NoiseSymmetricState
{
uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/;
void MixHash (const uint8_t * buf, size_t len);
void MixKey (const uint8_t * sharedSecret);
};
// init and terminate // init and terminate
void InitCrypto (bool precomputation); void InitCrypto (bool precomputation);
void TerminateCrypto (); void TerminateCrypto ();

15
libi2pd/NTCP2.cpp

@ -39,21 +39,6 @@ namespace transport
delete[] m_SessionConfirmedBuffer; delete[] m_SessionConfirmedBuffer;
} }
void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial)
{
i2p::crypto::HKDF (m_CK, inputKeyMaterial, 32, "", m_CK);
// ck is m_CK[0:31], k is m_CK[32:63]
}
void NTCP2Establisher::MixHash (const uint8_t * buf, size_t len)
{
SHA256_CTX ctx;
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, buf, len);
SHA256_Final (m_H, &ctx);
}
void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& 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[] =

6
libi2pd/NTCP2.h

@ -74,7 +74,7 @@ namespace transport
// RouterInfo flags // RouterInfo flags
const uint8_t NTCP2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01; const uint8_t NTCP2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01;
struct NTCP2Establisher struct NTCP2Establisher: private i2p::crypto::NoiseSymmetricState
{ {
NTCP2Establisher (); NTCP2Establisher ();
~NTCP2Establisher (); ~NTCP2Establisher ();
@ -94,8 +94,6 @@ namespace transport
void KDF3Alice (); // for SessionConfirmed part 2 void KDF3Alice (); // for SessionConfirmed part 2
void KDF3Bob (); void KDF3Bob ();
void MixKey (const uint8_t * inputKeyMaterial);
void MixHash (const uint8_t * buf, size_t len);
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 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 ();
@ -112,7 +110,7 @@ namespace transport
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys; std::shared_ptr<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[64] /* [ck, k]*/; uint8_t m_RemoteStaticKey[32], m_IV[16];
i2p::data::IdentHash m_RemoteIdentHash; i2p::data::IdentHash m_RemoteIdentHash;
uint16_t m3p2Len; uint16_t m3p2Len;

2
libi2pd/Tunnel.cpp

@ -124,7 +124,7 @@ namespace tunnel
uint8_t nonce[12]; uint8_t nonce[12];
memset (nonce, 0, 12); memset (nonce, 0, 12);
if (!i2p::crypto::AEADChaCha20Poly1305 (record, TUNNEL_BUILD_RECORD_SIZE - 16, if (!i2p::crypto::AEADChaCha20Poly1305 (record, TUNNEL_BUILD_RECORD_SIZE - 16,
hop->h, 32, hop->ck, nonce, record, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt hop->m_H, 32, hop->m_CK, nonce, record, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt
{ {
LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed");
return false; return false;

22
libi2pd/TunnelConfig.cpp

@ -10,7 +10,6 @@
#include <memory> #include <memory>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include "Crypto.h"
#include "Log.h" #include "Log.h"
#include "Transports.h" #include "Transports.h"
#include "Timestamp.h" #include "Timestamp.h"
@ -129,8 +128,8 @@ namespace tunnel
const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx)
{ {
static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars
memcpy (ck, protocolName, 32); // ck = h = protocol_name || 0 memcpy (m_CK, protocolName, 32); // ck = h = protocol_name || 0
SHA256 (ck, 32, h); // h = SHA256(h); SHA256 (m_CK, 32, m_H); // h = SHA256(h);
uint8_t hepk[32]; uint8_t hepk[32];
encryptor->Encrypt (nullptr, hepk, nullptr, false); encryptor->Encrypt (nullptr, hepk, nullptr, false);
MixHash (hepk, 32); // h = SHA256(h || hepk) MixHash (hepk, 32); // h = SHA256(h || hepk)
@ -140,27 +139,16 @@ namespace tunnel
encrypted += 32; encrypted += 32;
uint8_t sharedSecret[32]; uint8_t sharedSecret[32];
ephemeralKeys->Agree (hepk, sharedSecret); // x25519(sesk, hepk) ephemeralKeys->Agree (hepk, sharedSecret); // x25519(sesk, hepk)
uint8_t keydata[64]; MixKey (sharedSecret);
i2p::crypto::HKDF (ck, sharedSecret, 32, "", keydata);
memcpy (ck, keydata, 32);
uint8_t nonce[12]; uint8_t nonce[12];
memset (nonce, 0, 12); memset (nonce, 0, 12);
if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, h, 32, if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, m_H, 32,
keydata + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16, true)) // encrypt m_CK + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16, true)) // encrypt
{ {
LogPrint (eLogWarning, "Tunnel: Plaintext AEAD encryption failed"); LogPrint (eLogWarning, "Tunnel: Plaintext AEAD encryption failed");
return; return;
} }
MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext)
} }
void TunnelHopConfig::MixHash (const uint8_t * buf, size_t len)
{
SHA256_CTX ctx;
SHA256_Init (&ctx);
SHA256_Update (&ctx, h, 32);
SHA256_Update (&ctx, buf, len);
SHA256_Final (h, &ctx);
}
} }
} }

5
libi2pd/TunnelConfig.h

@ -12,12 +12,13 @@
#include <vector> #include <vector>
#include "Identity.h" #include "Identity.h"
#include "RouterContext.h" #include "RouterContext.h"
#include "Crypto.h"
namespace i2p namespace i2p
{ {
namespace tunnel namespace tunnel
{ {
struct TunnelHopConfig struct TunnelHopConfig: public i2p::crypto::NoiseSymmetricState
{ {
std::shared_ptr<const i2p::data::IdentityEx> ident; std::shared_ptr<const i2p::data::IdentityEx> ident;
i2p::data::IdentHash nextIdent; i2p::data::IdentHash nextIdent;
@ -30,7 +31,6 @@ namespace tunnel
TunnelHopConfig * next, * prev; TunnelHopConfig * next, * prev;
int recordIndex; // record # in tunnel build message int recordIndex; // record # in tunnel build message
uint8_t ck[32], h[32]; // for ECIES
TunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r); TunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r);
@ -43,7 +43,6 @@ namespace tunnel
void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx);
void EncryptECIES (std::shared_ptr<i2p::crypto::CryptoKeyEncryptor>& encryptor, void EncryptECIES (std::shared_ptr<i2p::crypto::CryptoKeyEncryptor>& encryptor,
const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx);
void MixHash (const uint8_t * buf, size_t len);
}; };
class TunnelConfig class TunnelConfig

Loading…
Cancel
Save