mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
WrapECIESX25519MessageForRouter wihout session
This commit is contained in:
parent
1e9eb30aa3
commit
ba1b8c7c2b
|
@ -519,35 +519,6 @@ namespace garlic
|
||||||
return true;
|
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 (GetNoiseState (), 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];
|
|
||||||
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);
|
|
||||||
// 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)
|
bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||||
{
|
{
|
||||||
// we are Bob
|
// we are Bob
|
||||||
|
@ -858,11 +829,6 @@ namespace garlic
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 96;
|
len += 96;
|
||||||
break;
|
break;
|
||||||
case eSessionStateForRouter:
|
|
||||||
if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen))
|
|
||||||
return nullptr;
|
|
||||||
len += 48;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -873,9 +839,9 @@ namespace garlic
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg, bool isForRouter)
|
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime;
|
m_State = eSessionStateOneTime;
|
||||||
return WrapSingleMessage (msg);
|
return WrapSingleMessage (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1133,18 +1099,9 @@ namespace garlic
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
|
static size_t CreateGarlicCloveBlock (std::shared_ptr<const I2NPMessage> msg, uint8_t * payload)
|
||||||
{
|
{
|
||||||
auto m = NewI2NPMessage ();
|
|
||||||
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
|
||||||
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
|
||||||
uint8_t nonce[12];
|
|
||||||
memset (nonce, 0, 12); // n = 0
|
|
||||||
size_t offset = 0;
|
|
||||||
memcpy (buf + offset, &tag, 8); offset += 8;
|
|
||||||
auto payload = buf + offset;
|
|
||||||
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
||||||
size_t len = cloveSize + 3;
|
|
||||||
payload[0] = eECIESx25519BlkGalicClove; // clove type
|
payload[0] = eECIESx25519BlkGalicClove; // clove type
|
||||||
htobe16buf (payload + 1, cloveSize); // size
|
htobe16buf (payload + 1, cloveSize); // size
|
||||||
payload += 3;
|
payload += 3;
|
||||||
|
@ -1153,14 +1110,26 @@ namespace garlic
|
||||||
htobe32buf (payload + 1, msg->GetMsgID ()); // msgID
|
htobe32buf (payload + 1, msg->GetMsgID ()); // msgID
|
||||||
htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds
|
htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds
|
||||||
memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
||||||
|
return cloveSize + 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt
|
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
|
||||||
|
{
|
||||||
|
auto m = NewI2NPMessage ();
|
||||||
|
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||||
|
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
||||||
|
size_t offset = 0;
|
||||||
|
memcpy (buf + offset, &tag, 8); offset += 8;
|
||||||
|
auto payload = buf + offset;
|
||||||
|
size_t len = CreateGarlicCloveBlock (msg, payload);
|
||||||
|
uint8_t nonce[12];
|
||||||
|
memset (nonce, 0, 12); // n = 0
|
||||||
|
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
|
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
offset += len + 16;
|
offset += len + 16;
|
||||||
|
|
||||||
htobe32buf (m->GetPayload (), offset);
|
htobe32buf (m->GetPayload (), offset);
|
||||||
m->len += offset + 4;
|
m->len += offset + 4;
|
||||||
m->FillI2NPMessageHeader (eI2NPGarlic);
|
m->FillI2NPMessageHeader (eI2NPGarlic);
|
||||||
|
@ -1169,10 +1138,39 @@ namespace garlic
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> WrapECIESX25519MessageForRouter (std::shared_ptr<const I2NPMessage> msg, const uint8_t * routerPublicKey)
|
std::shared_ptr<I2NPMessage> WrapECIESX25519MessageForRouter (std::shared_ptr<const I2NPMessage> msg, const uint8_t * routerPublicKey)
|
||||||
{
|
{
|
||||||
// TODO: implement without session
|
// Noise_N, we are Alice, routerPublicKey is Bob's
|
||||||
auto session = std::make_shared<ECIESX25519AEADRatchetSession>(nullptr, false);
|
i2p::crypto::NoiseSymmetricState noiseState;
|
||||||
session->SetRemoteStaticKey (routerPublicKey);
|
i2p::crypto::InitNoiseNState (noiseState, routerPublicKey);
|
||||||
return session->WrapOneTimeMessage (msg, true);
|
auto m = NewI2NPMessage ();
|
||||||
|
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||||
|
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
||||||
|
size_t offset = 0;
|
||||||
|
auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
|
||||||
|
memcpy (buf + offset, ephemeralKeys->GetPublicKey (), 32);
|
||||||
|
noiseState.MixHash (buf + offset, 32); // h = SHA256(h || aepk)
|
||||||
|
offset += 32;
|
||||||
|
uint8_t sharedSecret[32];
|
||||||
|
if (!ephemeralKeys->Agree (routerPublicKey, sharedSecret)) // x25519(aesk, bpk)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Incorrect Bob static key");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
noiseState.MixKey (sharedSecret);
|
||||||
|
auto payload = buf + offset;
|
||||||
|
size_t len = CreateGarlicCloveBlock (msg, payload);
|
||||||
|
uint8_t nonce[12];
|
||||||
|
memset (nonce, 0, 12);
|
||||||
|
// encrypt payload
|
||||||
|
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, noiseState.m_H, 32, noiseState.m_CK + 32, nonce, payload, len + 16, true)) // encrypt
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
offset += len + 16;
|
||||||
|
htobe32buf (m->GetPayload (), offset);
|
||||||
|
m->len += offset + 4;
|
||||||
|
m->FillI2NPMessageHeader (eI2NPGarlic);
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,8 +147,7 @@ namespace garlic
|
||||||
eSessionStateNewSessionSent,
|
eSessionStateNewSessionSent,
|
||||||
eSessionStateNewSessionReplySent,
|
eSessionStateNewSessionReplySent,
|
||||||
eSessionStateEstablished,
|
eSessionStateEstablished,
|
||||||
eSessionStateOneTime,
|
eSessionStateOneTime
|
||||||
eSessionStateForRouter
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DHRatchet
|
struct DHRatchet
|
||||||
|
@ -166,7 +165,7 @@ namespace garlic
|
||||||
|
|
||||||
bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr<ReceiveRatchetTagSet> receiveTagset, int index = 0);
|
bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr<ReceiveRatchetTagSet> receiveTagset, int index = 0);
|
||||||
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
||||||
std::shared_ptr<I2NPMessage> WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg, bool isForRouter = false);
|
std::shared_ptr<I2NPMessage> WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; }
|
const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; }
|
||||||
void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); }
|
void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); }
|
||||||
|
@ -207,7 +206,6 @@ namespace garlic
|
||||||
bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
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 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 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);
|
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 CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len);
|
||||||
|
|
Loading…
Reference in a new issue