Browse Source

common MixHash

pull/1269/head
orignal 6 years ago
parent
commit
23e3602ea1
  1. 93
      libi2pd/NTCP2.cpp
  2. 3
      libi2pd/NTCP2.h

93
libi2pd/NTCP2.cpp

@ -40,7 +40,7 @@ namespace transport
delete[] m_SessionConfirmedBuffer; delete[] m_SessionConfirmedBuffer;
} }
void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived) void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial)
{ {
// temp_key = HMAC-SHA256(ck, input_key_material) // temp_key = HMAC-SHA256(ck, input_key_material)
uint8_t tempKey[32]; unsigned int len; uint8_t tempKey[32]; unsigned int len;
@ -50,7 +50,16 @@ namespace transport
HMAC(EVP_sha256(), tempKey, 32, one, 1, m_CK, &len); HMAC(EVP_sha256(), tempKey, 32, one, 1, m_CK, &len);
// derived = HMAC-SHA256(temp_key, ck || byte(0x02)) // derived = HMAC-SHA256(temp_key, ck || byte(0x02))
m_CK[32] = 2; m_CK[32] = 2;
HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, derived, &len); HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, m_K, &len);
}
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)
@ -73,14 +82,11 @@ namespace transport
SHA256_Update (&ctx, rs, 32); SHA256_Update (&ctx, rs, 32);
SHA256_Final (m_H, &ctx); SHA256_Final (m_H, &ctx);
// h = SHA256(h || epub) // h = SHA256(h || epub)
SHA256_Init (&ctx); MixHash (epub, 32);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, epub, 32);
SHA256_Final (m_H, &ctx);
// x25519 between pub and priv // x25519 between pub and priv
uint8_t inputKeyMaterial[32]; uint8_t inputKeyMaterial[32];
priv.Agree (pub, inputKeyMaterial); priv.Agree (pub, inputKeyMaterial);
MixKey (inputKeyMaterial, m_K); MixKey (inputKeyMaterial);
} }
void NTCP2Establisher::KDF1Alice () void NTCP2Establisher::KDF1Alice ()
@ -95,30 +101,18 @@ namespace transport
void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub)
{ {
SHA256_CTX ctx; MixHash (sessionRequest + 32, 32); // encrypted payload
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, sessionRequest + 32, 32); // encrypted payload
SHA256_Final (m_H, &ctx);
int paddingLength = sessionRequestLen - 64; int paddingLength = sessionRequestLen - 64;
if (paddingLength > 0) if (paddingLength > 0)
{ MixHash (sessionRequest + 64, paddingLength);
SHA256_Init (&ctx); MixHash (epub, 32);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, sessionRequest + 64, paddingLength);
SHA256_Final (m_H, &ctx);
}
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, epub, 32);
SHA256_Final (m_H, &ctx);
// x25519 between remote pub and ephemaral priv // x25519 between remote pub and ephemaral priv
uint8_t inputKeyMaterial[32]; uint8_t inputKeyMaterial[32];
m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial); m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial);
MixKey (inputKeyMaterial, m_K); MixKey (inputKeyMaterial);
} }
void NTCP2Establisher::KDF2Alice () void NTCP2Establisher::KDF2Alice ()
@ -135,14 +129,14 @@ namespace transport
{ {
uint8_t inputKeyMaterial[32]; uint8_t inputKeyMaterial[32];
i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial);
MixKey (inputKeyMaterial, m_K); MixKey (inputKeyMaterial);
} }
void NTCP2Establisher::KDF3Bob () void NTCP2Establisher::KDF3Bob ()
{ {
uint8_t inputKeyMaterial[32]; uint8_t inputKeyMaterial[32];
m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial); m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial);
MixKey (inputKeyMaterial, m_K); MixKey (inputKeyMaterial);
} }
void NTCP2Establisher::CreateEphemeralKey () void NTCP2Establisher::CreateEphemeralKey ()
@ -217,21 +211,11 @@ namespace transport
void NTCP2Establisher::CreateSessionConfirmedMessagePart1 (const uint8_t * nonce) void NTCP2Establisher::CreateSessionConfirmedMessagePart1 (const uint8_t * nonce)
{ {
// update AD // update AD
SHA256_CTX ctx; MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, m_SessionCreatedBuffer + 32, 32); // encrypted payload
SHA256_Final (m_H, &ctx);
int paddingLength = m_SessionCreatedBufferLen - 64; int paddingLength = m_SessionCreatedBufferLen - 64;
if (paddingLength > 0) if (paddingLength > 0)
{ MixHash (m_SessionCreatedBuffer + 64, paddingLength);
SHA256_CTX ctx1;
SHA256_Init (&ctx1);
SHA256_Update (&ctx1, m_H, 32);
SHA256_Update (&ctx1, m_SessionCreatedBuffer + 64, paddingLength);
SHA256_Final (m_H, &ctx1);
}
// part1 48 bytes // part1 48 bytes
i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, m_H, 32, m_K, nonce, m_SessionConfirmedBuffer, 48, true); // encrypt i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, m_H, 32, m_K, nonce, m_SessionConfirmedBuffer, 48, true); // encrypt
} }
@ -240,20 +224,13 @@ namespace transport
{ {
// part 2 // part 2
// update AD again // update AD again
SHA256_CTX ctx; MixHash (m_SessionConfirmedBuffer, 48);
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, m_SessionConfirmedBuffer, 48);
SHA256_Final (m_H, &ctx);
// encrypt m3p2, it must be filled in SessionRequest // encrypt m3p2, it must be filled in SessionRequest
KDF3Alice (); KDF3Alice ();
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2, m3p2Len, true); // encrypt i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2, m3p2Len, true); // encrypt
// update h again // update h again
SHA256_Init (&ctx); MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext)
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, m3p2, m3p2Len);
SHA256_Final (m_H, &ctx); //h = SHA256(h || ciphertext)
} }
bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen) bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen)
@ -343,21 +320,11 @@ namespace transport
bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce) bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce)
{ {
// update AD // update AD
SHA256_CTX ctx; MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, m_SessionCreatedBuffer + 32, 32); // encrypted payload
SHA256_Final (m_H, &ctx);
int paddingLength = m_SessionCreatedBufferLen - 64; int paddingLength = m_SessionCreatedBufferLen - 64;
if (paddingLength > 0) if (paddingLength > 0)
{ MixHash (m_SessionCreatedBuffer + 64, paddingLength);
SHA256_CTX ctx1;
SHA256_Init (&ctx1);
SHA256_Update (&ctx1, m_H, 32);
SHA256_Update (&ctx1, m_SessionCreatedBuffer + 64, paddingLength);
SHA256_Final (m_H, &ctx1);
}
if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, m_H, 32, m_K, nonce, m_RemoteStaticKey, 32, false)) // decrypt S if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, m_H, 32, m_K, nonce, m_RemoteStaticKey, 32, false)) // decrypt S
{ {
LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed "); LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed ");
@ -369,11 +336,7 @@ namespace transport
bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf) bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf)
{ {
// update AD again // update AD again
SHA256_CTX ctx; MixHash (m_SessionConfirmedBuffer, 48);
SHA256_Init (&ctx);
SHA256_Update (&ctx, m_H, 32);
SHA256_Update (&ctx, m_SessionConfirmedBuffer, 48);
SHA256_Final (m_H, &ctx);
KDF3Bob (); KDF3Bob ();
if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt

3
libi2pd/NTCP2.h

@ -95,7 +95,8 @@ namespace transport
void KDF3Alice (); // for SessionConfirmed part 2 void KDF3Alice (); // for SessionConfirmed part 2
void KDF3Bob (); void KDF3Bob ();
void MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived); 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 ();

Loading…
Cancel
Save