Use noise state Encrypt/Decrypt operations
Some checks failed
Build Debian packages / bookworm (push) Has been cancelled
Build Debian packages / bullseye (push) Has been cancelled
Build Debian packages / buster (push) Has been cancelled
Build on FreeBSD / with UPnP (push) Has been cancelled
Build on OSX / With USE_UPNP=no (push) Has been cancelled
Build on OSX / With USE_UPNP=yes (push) Has been cancelled
Build on Windows / clang-x86_64 (push) Has been cancelled
Build on Windows / i686 (push) Has been cancelled
Build on Windows / ucrt-x86_64 (push) Has been cancelled
Build on Windows / x86_64 (push) Has been cancelled
Build on Windows / CMake clang-x86_64 (push) Has been cancelled
Build on Windows / CMake i686 (push) Has been cancelled
Build on Windows / CMake ucrt-x86_64 (push) Has been cancelled
Build on Windows / CMake x86_64 (push) Has been cancelled
Build on Windows / XP (push) Has been cancelled
Build on Ubuntu / Make with USE_UPNP=no (push) Has been cancelled
Build on Ubuntu / Make with USE_UPNP=yes (push) Has been cancelled
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Has been cancelled
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Has been cancelled
Build containers / Building container for linux/amd64 (push) Has been cancelled
Build containers / Building container for linux/arm64 (push) Has been cancelled
Build containers / Building container for linux/arm/v7 (push) Has been cancelled
Build containers / Building container for linux/386 (push) Has been cancelled
Build containers / Pushing merged manifest (push) Has been cancelled

This commit is contained in:
orignal 2025-04-08 14:39:46 -04:00
parent 711f5bcc62
commit f6abbe5908
2 changed files with 49 additions and 41 deletions

View file

@ -145,10 +145,12 @@ namespace transport
// 2 bytes reserved // 2 bytes reserved
htobe32buf (options + 8, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); // tsA, rounded to seconds htobe32buf (options + 8, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); // tsA, rounded to seconds
// 4 bytes reserved // 4 bytes reserved
// sign and encrypt options, use m_H as AD // encrypt options
uint8_t nonce[12]; if (!Encrypt (options, m_SessionRequestBuffer + 32, 16))
memset (nonce, 0, 12); // set nonce to zero {
i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionRequestBuffer + 32, 32, true); // encrypt LogPrint (eLogWarning, "NTCP2: SessionRequest failed to encrypt options");
return false;
}
return true; return true;
} }
@ -167,14 +169,16 @@ namespace transport
memset (options, 0, 16); memset (options, 0, 16);
htobe16buf (options + 2, paddingLen); // padLen htobe16buf (options + 2, paddingLen); // padLen
htobe32buf (options + 8, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); // tsB, rounded to seconds htobe32buf (options + 8, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); // tsB, rounded to seconds
// sign and encrypt options, use m_H as AD // encrypt options
uint8_t nonce[12]; if (!Encrypt (options, m_SessionCreatedBuffer + 32, 16))
memset (nonce, 0, 12); // set nonce to zero {
i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionCreatedBuffer + 32, 32, true); // encrypt LogPrint (eLogWarning, "NTCP2: SessionCreated failed to encrypt options");
return false;
}
return true; return true;
} }
void NTCP2Establisher::CreateSessionConfirmedMessagePart1 (const uint8_t * nonce) bool NTCP2Establisher::CreateSessionConfirmedMessagePart1 ()
{ {
// update AD // update AD
MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload
@ -182,19 +186,28 @@ namespace transport
if (paddingLength > 0) if (paddingLength > 0)
MixHash (m_SessionCreatedBuffer + 64, paddingLength); MixHash (m_SessionCreatedBuffer + 64, paddingLength);
// part1 48 bytes // part1 48 bytes, n = 1
i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, GetH (), 32, GetK (), nonce, m_SessionConfirmedBuffer, 48, true); // encrypt if (!Encrypt (i2p::context.GetNTCP2StaticPublicKey (), m_SessionConfirmedBuffer, 32))
{
LogPrint (eLogWarning, "NTCP2: SessionConfirmed failed to encrypt part1");
return false;
}
return true;
} }
bool NTCP2Establisher::CreateSessionConfirmedMessagePart2 (const uint8_t * nonce) bool NTCP2Establisher::CreateSessionConfirmedMessagePart2 ()
{ {
// part 2 // part 2
// update AD again // update AD again
MixHash (m_SessionConfirmedBuffer, 48); MixHash (m_SessionConfirmedBuffer, 48);
// encrypt m3p2, it must be filled in SessionRequest // encrypt m3p2, it must be filled in SessionRequest
if (!KDF3Alice ()) return false; if (!KDF3Alice ()) return false; // MixKey, n = 0
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2, m3p2Len, true); // encrypt if (!Encrypt (m3p2, m3p2, m3p2Len - 16))
{
LogPrint (eLogWarning, "NTCP2: SessionConfirmed failed to encrypt part2");
return false;
}
// update h again // update h again
MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext) MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext)
return true; return true;
@ -214,10 +227,9 @@ namespace transport
LogPrint (eLogWarning, "NTCP2: SessionRequest KDF failed"); LogPrint (eLogWarning, "NTCP2: SessionRequest KDF failed");
return false; return false;
} }
// verify MAC and decrypt options block (32 bytes), use m_H as AD // verify MAC and decrypt options block (32 bytes)
uint8_t nonce[12], options[16]; uint8_t options[16];
memset (nonce, 0, 12); // set nonce to zero if (Decrypt (m_SessionRequestBuffer + 32, options, 16))
if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionRequestBuffer + 32, 16, GetH (), 32, GetK (), nonce, options, 16, false)) // decrypt
{ {
// options // options
if (options[0] && options[0] != i2p::context.GetNetID ()) if (options[0] && options[0] != i2p::context.GetNetID ())
@ -274,9 +286,7 @@ namespace transport
} }
// decrypt and verify MAC // decrypt and verify MAC
uint8_t payload[16]; uint8_t payload[16];
uint8_t nonce[12]; if (Decrypt (m_SessionCreatedBuffer + 32, payload, 16))
memset (nonce, 0, 12); // set nonce to zero
if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionCreatedBuffer + 32, 16, GetH (), 32, GetK (), nonce, payload, 16, false)) // decrypt
{ {
// options // options
paddingLen = bufbe16toh(payload + 2); paddingLen = bufbe16toh(payload + 2);
@ -297,7 +307,7 @@ namespace transport
return true; return true;
} }
bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce) bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 ()
{ {
// update AD // update AD
MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload
@ -305,7 +315,8 @@ namespace transport
if (paddingLength > 0) if (paddingLength > 0)
MixHash (m_SessionCreatedBuffer + 64, paddingLength); MixHash (m_SessionCreatedBuffer + 64, paddingLength);
if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, GetH (), 32, GetK (), nonce, m_RemoteStaticKey, 32, false)) // decrypt S // decrypt S, n = 1
if (!Decrypt (m_SessionConfirmedBuffer, m_RemoteStaticKey, 32))
{ {
LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed "); LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed ");
return false; return false;
@ -313,17 +324,17 @@ namespace transport
return true; return true;
} }
bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf) bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (uint8_t * m3p2Buf)
{ {
// update AD again // update AD again
MixHash (m_SessionConfirmedBuffer, 48); MixHash (m_SessionConfirmedBuffer, 48);
if (!KDF3Bob ()) if (!KDF3Bob ()) // MixKey, n = 0
{ {
LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part2 KDF failed"); LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part2 KDF failed");
return false; return false;
} }
if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt if (Decrypt (m_SessionConfirmedBuffer + 48, m3p2Buf, m3p2Len - 16))
// calculate new h again for KDF data // calculate new h again for KDF data
MixHash (m_SessionConfirmedBuffer + 48, m3p2Len); // h = SHA256(h || ciphertext) MixHash (m_SessionConfirmedBuffer + 48, m3p2Len); // h = SHA256(h || ciphertext)
else else
@ -657,11 +668,12 @@ namespace transport
void NTCP2Session::SendSessionConfirmed () void NTCP2Session::SendSessionConfirmed ()
{ {
uint8_t nonce[12]; if (!m_Establisher->CreateSessionConfirmedMessagePart1 ())
CreateNonce (1, nonce); // set nonce to 1 {
m_Establisher->CreateSessionConfirmedMessagePart1 (nonce); boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ()));
memset (nonce, 0, 12); // set nonce back to 0 return;
if (!m_Establisher->CreateSessionConfirmedMessagePart2 (nonce)) }
if (!m_Establisher->CreateSessionConfirmedMessagePart2 ())
{ {
LogPrint (eLogWarning, "NTCP2: Send SessionConfirmed Part2 KDF failed"); LogPrint (eLogWarning, "NTCP2: Send SessionConfirmed Part2 KDF failed");
boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ()));
@ -740,14 +752,11 @@ namespace transport
// run on establisher thread // run on establisher thread
LogPrint (eLogDebug, "NTCP2: SessionConfirmed received"); LogPrint (eLogDebug, "NTCP2: SessionConfirmed received");
// part 1 // part 1
uint8_t nonce[12]; if (m_Establisher->ProcessSessionConfirmedMessagePart1 ())
CreateNonce (1, nonce);
if (m_Establisher->ProcessSessionConfirmedMessagePart1 (nonce))
{ {
// part 2 // part 2
auto buf = std::make_shared<std::vector<uint8_t> > (m_Establisher->m3p2Len - 16); // -MAC auto buf = std::make_shared<std::vector<uint8_t> > (m_Establisher->m3p2Len - 16); // -MAC
memset (nonce, 0, 12); // set nonce to 0 again if (m_Establisher->ProcessSessionConfirmedMessagePart2 (buf->data ())) // TODO:handle in establisher thread
if (m_Establisher->ProcessSessionConfirmedMessagePart2 (nonce, buf->data ())) // TODO:handle in establisher thread
{ {
// payload // payload
// RI block must be first // RI block must be first

View file

@ -91,7 +91,6 @@ namespace transport
const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob
uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set
const uint8_t * GetK () const { return m_CK + 32; };
const uint8_t * GetCK () const { return m_CK; }; const uint8_t * GetCK () const { return m_CK; };
const uint8_t * GetH () const { return m_H; }; const uint8_t * GetH () const { return m_H; };
@ -108,13 +107,13 @@ namespace transport
bool CreateSessionRequestMessage (std::mt19937& rng); bool CreateSessionRequestMessage (std::mt19937& rng);
bool CreateSessionCreatedMessage (std::mt19937& rng); bool CreateSessionCreatedMessage (std::mt19937& rng);
void CreateSessionConfirmedMessagePart1 (const uint8_t * nonce); bool CreateSessionConfirmedMessagePart1 ();
bool CreateSessionConfirmedMessagePart2 (const uint8_t * nonce); bool CreateSessionConfirmedMessagePart2 ();
bool ProcessSessionRequestMessage (uint16_t& paddingLen, bool& clockSkew); bool ProcessSessionRequestMessage (uint16_t& paddingLen, bool& clockSkew);
bool ProcessSessionCreatedMessage (uint16_t& paddingLen); bool ProcessSessionCreatedMessage (uint16_t& paddingLen);
bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce); bool ProcessSessionConfirmedMessagePart1 ();
bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf); bool ProcessSessionConfirmedMessagePart2 (uint8_t * m3p2Buf);
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