mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 13:27:17 +01:00
encrypt message for ECIES router
This commit is contained in:
parent
32fc6482cc
commit
abdf92c084
|
@ -1333,26 +1333,31 @@ namespace crypto
|
|||
// new ck is m_CK[0:31], key is m_CK[32:63]
|
||||
}
|
||||
|
||||
static void InitNoiseState (NoiseSymmetricState& state, const uint8_t * ck,
|
||||
const uint8_t * hh, const uint8_t * pub)
|
||||
{
|
||||
// pub is Bob's public static key, hh = SHA256(h)
|
||||
memcpy (state.m_CK, ck, 32);
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, hh, 32);
|
||||
SHA256_Update (&ctx, pub, 32);
|
||||
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
||||
}
|
||||
|
||||
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||
{
|
||||
// pub is Bob's public static key
|
||||
static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars
|
||||
static const uint8_t hh[32] =
|
||||
{
|
||||
0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1,
|
||||
0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54
|
||||
}; // hh = SHA256(protocol_name || 0)
|
||||
memcpy (state.m_CK, protocolName, 32); // ck = protocol_name || 0
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, hh, 32);
|
||||
SHA256_Update (&ctx, pub, 32);
|
||||
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
||||
InitNoiseState (state, (const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0
|
||||
}
|
||||
|
||||
|
||||
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||
{
|
||||
// pub is Bob's public static key
|
||||
static const uint8_t protocolNameHash[] =
|
||||
{
|
||||
0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed,
|
||||
|
@ -1363,17 +1368,11 @@ namespace crypto
|
|||
0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5,
|
||||
0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e
|
||||
}; // SHA256 (protocolNameHash)
|
||||
memcpy (state.m_CK, protocolNameHash, 32);
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, hh, 32);
|
||||
SHA256_Update (&ctx, pub, 32);
|
||||
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
||||
InitNoiseState (state, protocolNameHash, hh, pub);
|
||||
}
|
||||
|
||||
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
|
||||
{
|
||||
// pub is Bob's public static key
|
||||
static const uint8_t protocolNameHash[32] =
|
||||
{
|
||||
0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba,
|
||||
|
@ -1384,12 +1383,7 @@ namespace crypto
|
|||
0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32,
|
||||
0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c
|
||||
}; // SHA256 (protocolNameHash)
|
||||
memcpy (state.m_CK, protocolNameHash, 32);
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, hh, 32);
|
||||
SHA256_Update (&ctx, pub, 32);
|
||||
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
|
||||
InitNoiseState (state, protocolNameHash, hh, pub);
|
||||
}
|
||||
|
||||
// init and terminate
|
||||
|
|
|
@ -490,6 +490,31 @@ namespace garlic
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||
{
|
||||
// we are Alice, router's bpk is m_RemoteStaticKey
|
||||
i2p::crypto::InitNoiseNState (*this, m_RemoteStaticKey);
|
||||
size_t offset = 0;
|
||||
m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
|
||||
memcpy (out + offset, m_EphemeralKeys->GetPublicKey (), 32);
|
||||
MixHash (out + offset, 32); // h = SHA256(h || aepk)
|
||||
offset += 32;
|
||||
uint8_t sharedSecret[32];
|
||||
m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk)
|
||||
MixKey (sharedSecret);
|
||||
uint8_t nonce[12];
|
||||
memset (nonce, 0, 12);
|
||||
// encrypt payload
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_State = eSessionStateNewSessionSent;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||
{
|
||||
// we are Bob
|
||||
|
@ -549,7 +574,7 @@ namespace garlic
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||
{
|
||||
// we are Bob and sent NSR already
|
||||
|
@ -781,6 +806,11 @@ namespace garlic
|
|||
return nullptr;
|
||||
len += 96;
|
||||
break;
|
||||
case eSessionStateForRouter:
|
||||
if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen))
|
||||
return nullptr;
|
||||
len += 48;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -791,9 +821,9 @@ namespace garlic
|
|||
return m;
|
||||
}
|
||||
|
||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg, bool isForRouter)
|
||||
{
|
||||
m_State = eSessionStateOneTime;
|
||||
m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime;
|
||||
return WrapSingleMessage (msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -140,7 +140,8 @@ namespace garlic
|
|||
eSessionStateNewSessionSent,
|
||||
eSessionStateNewSessionReplySent,
|
||||
eSessionStateEstablished,
|
||||
eSessionStateOneTime
|
||||
eSessionStateOneTime,
|
||||
eSessionStateForRouter
|
||||
};
|
||||
|
||||
struct DHRatchet
|
||||
|
@ -158,7 +159,7 @@ namespace garlic
|
|||
|
||||
bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr<RatchetTagSet> receiveTagset, int index = 0);
|
||||
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
||||
std::shared_ptr<I2NPMessage> WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg);
|
||||
std::shared_ptr<I2NPMessage> WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg, bool isForRouter = false);
|
||||
|
||||
const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; }
|
||||
void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); }
|
||||
|
@ -192,7 +193,8 @@ namespace garlic
|
|||
bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||
bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||
bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||
|
||||
bool NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||
|
||||
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first);
|
||||
size_t CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len);
|
||||
size_t CreateLeaseSetClove (std::shared_ptr<const i2p::data::LocalLeaseSet> ls, uint64_t ts, uint8_t * buf, size_t len);
|
||||
|
|
|
@ -716,7 +716,7 @@ namespace garlic
|
|||
{
|
||||
auto session = std::make_shared<ECIESX25519AEADRatchetSession>(this, false);
|
||||
session->SetRemoteStaticKey (router->GetIdentity ()->GetEncryptionPublicKey ());
|
||||
return session->WrapOneTimeMessage (msg);
|
||||
return session->WrapOneTimeMessage (msg, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue