mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-04-26 00:02:24 +00:00
max padding size is double message size for post-quantum crypto
This commit is contained in:
@@ -168,7 +168,9 @@ namespace transport
|
||||
offset += 32;
|
||||
// encryption key for next block
|
||||
if (!KDF1Alice ()) return false;
|
||||
size_t maxMsgLength = m_IsLongPadding ? NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE : NTCP2_SESSION_HANDSHAKE_MAX_SIZE;
|
||||
size_t maxPaddingLength = m_IsLongPadding ? NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE : NTCP2_SESSION_HANDSHAKE_MAX_SIZE;
|
||||
maxPaddingLength -= 64;
|
||||
size_t maxMsgSize = m_MaxMsgSize;
|
||||
#if OPENSSL_PQ
|
||||
if (m_PQKeys)
|
||||
{
|
||||
@@ -184,11 +186,15 @@ namespace transport
|
||||
}
|
||||
MixHash (m_Buffer + offset, keyLen + 16); // h = SHA256(h || ciphertext)
|
||||
offset += keyLen + 16;
|
||||
maxMsgLength += keyLen + 16;
|
||||
maxPaddingLength = offset + 32; // 32 bytes following options block size
|
||||
// adjust max msg size because we might send smaller message that we can receive
|
||||
maxMsgSize = NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE + i2p::crypto::MLKEM1024_KEY_LENGTH + 16;
|
||||
if (maxMsgSize > m_MaxMsgSize) maxMsgSize = m_MaxMsgSize;
|
||||
}
|
||||
#endif
|
||||
// calculate padding length
|
||||
auto paddingLength = (offset + 32 < maxMsgLength) ? (rng () % (maxMsgLength - offset - 32)) : 0; // 32 bytes following options block size
|
||||
if (offset + 32 + maxPaddingLength > maxMsgSize) maxPaddingLength = maxMsgSize - offset - 32;
|
||||
auto paddingLength = maxPaddingLength ? rng () % maxPaddingLength : 0;
|
||||
// fill options
|
||||
uint8_t options[32]; // actual options size is 16 bytes
|
||||
memset (options, 0, 16);
|
||||
@@ -239,7 +245,9 @@ namespace transport
|
||||
offset += 32;
|
||||
// encryption key for next block (m_K)
|
||||
if (!KDF2Bob ()) return false;
|
||||
size_t maxMsgLength = m_IsLongPadding ? NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE : NTCP2_SESSION_HANDSHAKE_MAX_SIZE;
|
||||
size_t maxPaddingLength = m_IsLongPadding ? NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE : NTCP2_SESSION_HANDSHAKE_MAX_SIZE;
|
||||
maxPaddingLength -= 64;
|
||||
size_t maxMsgSize = m_MaxMsgSize;
|
||||
#if OPENSSL_PQ
|
||||
if (m_PQKeys)
|
||||
{
|
||||
@@ -255,13 +263,18 @@ namespace transport
|
||||
MixHash (m_Buffer + offset, cipherTextLen + 16); // encrypt ML-KEM frame
|
||||
MixKey (sharedSecret);
|
||||
offset += cipherTextLen + 16;
|
||||
maxPaddingLength= offset + 32; // 32 bytes following options block size
|
||||
// adjust max msg size because we might send smaller message that we can receive
|
||||
maxMsgSize = NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE + i2p::crypto::MLKEM1024_KEY_LENGTH + 16;
|
||||
if (maxMsgSize > m_MaxMsgSize) maxMsgSize = m_MaxMsgSize;
|
||||
}
|
||||
#endif
|
||||
// calculate padding length
|
||||
auto paddingLen = (offset + 32 < maxMsgLength) ? (rng () % (maxMsgLength - offset - 32)) : 0; // 32 bytes following options block size
|
||||
// calculate padding length
|
||||
if (offset + 32 + maxPaddingLength > maxMsgSize) maxPaddingLength = maxMsgSize - offset - 32;
|
||||
auto paddingLength = maxPaddingLength ? rng () % maxPaddingLength : 0;
|
||||
uint8_t options[16];
|
||||
memset (options, 0, 16);
|
||||
htobe16buf (options + 2, paddingLen); // padLen
|
||||
htobe16buf (options + 2, paddingLength); // padLen
|
||||
htobe32buf (options + 8, (i2p::util::GetMillisecondsSinceEpoch () + 500)/1000); // tsB, rounded to seconds
|
||||
// encrypt options
|
||||
if (!Encrypt (options, m_Buffer + offset, 16))
|
||||
@@ -272,12 +285,12 @@ namespace transport
|
||||
MixHash (m_Buffer + offset, 32); // encrypted options
|
||||
offset += 32;
|
||||
// padding
|
||||
if (paddingLen)
|
||||
if (paddingLength)
|
||||
{
|
||||
RAND_bytes (m_Buffer + offset, paddingLen);
|
||||
MixHash (m_Buffer + offset, paddingLen);
|
||||
RAND_bytes (m_Buffer + offset, paddingLength);
|
||||
MixHash (m_Buffer + offset, paddingLength);
|
||||
}
|
||||
m_BufferLen = offset + paddingLen;
|
||||
m_BufferLen = offset + paddingLength;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -530,7 +543,7 @@ namespace transport
|
||||
if (m_Server.GetVersion () > 2) // we support post quantum in config
|
||||
m_Establisher->SetVersion (addr->v);
|
||||
#endif
|
||||
if (addr->v > 2) m_Establisher->m_IsLongPadding = true;
|
||||
//if (addr->v > 2) m_Establisher->m_IsLongPadding = true; // TODO: check router version
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "NTCP2: Missing NTCP2 address");
|
||||
@@ -727,11 +740,7 @@ namespace transport
|
||||
#endif
|
||||
else if (paddingLen > 0)
|
||||
{
|
||||
#if OPENSSL_PQ
|
||||
if (len + paddingLen <= NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE + i2p::crypto::MLKEM1024_KEY_LENGTH + 16)
|
||||
#else
|
||||
if (len + paddingLen <= NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE)
|
||||
#endif
|
||||
if (len + paddingLen <= m_Establisher->m_MaxMsgSize)
|
||||
{
|
||||
boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_Buffer + len, paddingLen), boost::asio::transfer_all (),
|
||||
std::bind(&NTCP2Session::HandleSessionRequestPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
||||
@@ -828,9 +837,9 @@ namespace transport
|
||||
if (paddingLen > 0)
|
||||
{
|
||||
#if OPENSSL_PQ
|
||||
if (paddingLen <= NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE + i2p::crypto::MLKEM1024_KEY_LENGTH - 48)
|
||||
if (paddingLen <= m_Establisher->m_MaxMsgSize - 80)
|
||||
#else
|
||||
if (paddingLen <= NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE - 64)
|
||||
if (paddingLen <= m_Establisher->m_MaxMsgSize - 64)
|
||||
#endif
|
||||
{
|
||||
boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_Buffer + m_Establisher->m_BufferLen, paddingLen), boost::asio::transfer_all (),
|
||||
|
||||
@@ -29,10 +29,10 @@ namespace i2p
|
||||
namespace transport
|
||||
{
|
||||
|
||||
const size_t NTCP2_UNENCRYPTED_FRAME_MAX_SIZE = 65519;
|
||||
const size_t NTCP2_SEND_AFTER_FRAME_SIZE = 16386; // send frame when exceeds this size
|
||||
const size_t NTCP2_SESSION_HANDSHAKE_MAX_SIZE = 287; // SessionRequest/SesionCreated without ML-KEM frame
|
||||
const size_t NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE = 1248; // 1248 = 1184(MLKEM768 key len) + 64
|
||||
constexpr size_t NTCP2_UNENCRYPTED_FRAME_MAX_SIZE = 65519;
|
||||
constexpr size_t NTCP2_SEND_AFTER_FRAME_SIZE = 16386; // send frame when exceeds this size
|
||||
constexpr size_t NTCP2_SESSION_HANDSHAKE_MAX_SIZE = 287; // SessionRequest/SesionCreated without ML-KEM frame
|
||||
constexpr size_t NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE = 1248; // for non-PQ, 1248 = 1184(MLKEM768 key len) + 64
|
||||
const int NTCP2_MAX_PADDING_RATIO = 6; // in %
|
||||
|
||||
const int NTCP2_CONNECT_TIMEOUT = 5; // 5 seconds
|
||||
@@ -128,10 +128,11 @@ namespace transport
|
||||
|
||||
#if OPENSSL_PQ
|
||||
std::unique_ptr<i2p::crypto::MLKEMKeys> m_PQKeys;
|
||||
uint8_t m_Buffer[NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE + i2p::crypto::MLKEM1024_KEY_LENGTH + 16],
|
||||
static constexpr size_t m_MaxMsgSize = 2*i2p::crypto::MLKEM1024_KEY_LENGTH + 160;
|
||||
#else
|
||||
uint8_t m_Buffer[NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE], // for SessionRequest and SessionCreated
|
||||
static constexpr size_t m_MaxMsgSize = NTCP2_SESSION_HANDSHAKE_LONG_MAX_SIZE;
|
||||
#endif
|
||||
uint8_t m_Buffer[m_MaxMsgSize], // for SessionRequest and SessionCreated
|
||||
* m_SessionConfirmedBuffer;
|
||||
size_t m_BufferLen;
|
||||
bool m_IsLongPadding;
|
||||
|
||||
Reference in New Issue
Block a user