mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
AEAD/Chacha20/Poly1305 encryption
This commit is contained in:
parent
bf1e1ad457
commit
df60e78766
|
@ -8,6 +8,9 @@
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include "TunnelBase.h"
|
#include "TunnelBase.h"
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
#include "I2PEndian.h"
|
||||||
|
#include "ChaCha20.h"
|
||||||
|
#include "Poly1305.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
|
|
||||||
|
@ -1057,6 +1060,32 @@ namespace crypto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AEAD/ChaCha20/Poly1305
|
||||||
|
|
||||||
|
size_t AEADChaCha20Poly1305Encrypt (const uint8_t * msg, size_t msgLen, const uint8_t * ad, size_t adLen, const uint8_t * key, const uint8_t * nonce, uint8_t * buf, size_t len)
|
||||||
|
{
|
||||||
|
if (msgLen + 16 < len) return 0;
|
||||||
|
// generate one time poly key
|
||||||
|
uint8_t polyKey[64];
|
||||||
|
memset(polyKey, 0, sizeof(polyKey));
|
||||||
|
chacha20 (polyKey, 64, nonce, key, 0);
|
||||||
|
// encrypt data
|
||||||
|
memcpy (buf, msg, msgLen);
|
||||||
|
chacha20 (buf, msgLen, nonce, key, 1);
|
||||||
|
// create Poly1305 message
|
||||||
|
std::vector<uint8_t> polyMsg(adLen + msgLen + 16);
|
||||||
|
size_t offset = 0;
|
||||||
|
memcpy (polyMsg.data (), ad, adLen); offset += adLen;
|
||||||
|
memcpy (polyMsg.data () + offset, buf, msgLen); offset += msgLen; // encrypted data
|
||||||
|
htole64buf (polyMsg.data () + offset, adLen); offset += 8;
|
||||||
|
htole64buf (polyMsg.data () + offset, msgLen); offset += 8;
|
||||||
|
// calculate Poly1305 tag and write in after encrypted data
|
||||||
|
Poly1305HMAC ((uint32_t *)(buf + msgLen), (uint32_t *)key, polyMsg.data (), offset);
|
||||||
|
return msgLen + 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init and terminate
|
||||||
|
|
||||||
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
|
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
|
||||||
static void OpensslLockingCallback(int mode, int type, const char * file, int line)
|
static void OpensslLockingCallback(int mode, int type, const char * file, int line)
|
||||||
{
|
{
|
||||||
|
|
|
@ -252,6 +252,10 @@ namespace crypto
|
||||||
CBCDecryption m_LayerDecryption;
|
CBCDecryption m_LayerDecryption;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// AEAD/ChaCha20/Poly1305
|
||||||
|
size_t AEADChaCha20Poly1305Encrypt (const uint8_t * msg, size_t msgLen, const uint8_t * ad, size_t adLen, const uint8_t * key, const uint8_t * nonce, uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
// init and terminate
|
||||||
void InitCrypto (bool precomputation);
|
void InitCrypto (bool precomputation);
|
||||||
void TerminateCrypto ();
|
void TerminateCrypto ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,20 @@ inline void htobe64buf(void *buf, uint64_t big64)
|
||||||
htobuf64(buf, htobe64(big64));
|
htobuf64(buf, htobe64(big64));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void htole16buf(void *buf, uint16_t big16)
|
||||||
|
{
|
||||||
|
htobuf16(buf, htole16(big16));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void htole32buf(void *buf, uint32_t big32)
|
||||||
|
{
|
||||||
|
htobuf32(buf, htole32(big32));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void htole64buf(void *buf, uint64_t big64)
|
||||||
|
{
|
||||||
|
htobuf64(buf, htole64(big64));
|
||||||
|
}
|
||||||
|
|
||||||
#endif // I2PENDIAN_H__
|
#endif // I2PENDIAN_H__
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "Ed25519.h"
|
#include "Ed25519.h"
|
||||||
#include "ChaCha20.h"
|
|
||||||
#include "Poly1305.h"
|
|
||||||
#include "NTCP2.h"
|
#include "NTCP2.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
|
@ -52,7 +50,7 @@ namespace transport
|
||||||
m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ()));
|
m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NTCP2Session::KeyDerivationFunction1 (const uint8_t * rs, const uint8_t * pub, uint8_t * derived)
|
bool NTCP2Session::KeyDerivationFunction1 (const uint8_t * rs, const uint8_t * pub, uint8_t * derived, uint8_t * ad)
|
||||||
{
|
{
|
||||||
static const char protocolName[] = "Noise_XK_25519_ChaChaPoly_SHA256"; // 32 bytes
|
static const char protocolName[] = "Noise_XK_25519_ChaChaPoly_SHA256"; // 32 bytes
|
||||||
uint8_t h[64], ck[33];
|
uint8_t h[64], ck[33];
|
||||||
|
@ -63,7 +61,7 @@ namespace transport
|
||||||
SHA256 (h, 64, h);
|
SHA256 (h, 64, h);
|
||||||
// h = SHA256(h || pub)
|
// h = SHA256(h || pub)
|
||||||
memcpy (h + 32, pub, 32);
|
memcpy (h + 32, pub, 32);
|
||||||
SHA256 (h, 64, h);
|
SHA256 (h, 64, ad);
|
||||||
// x25519 between rs and priv
|
// x25519 between rs and priv
|
||||||
uint8_t inputKeyMaterial[32];
|
uint8_t inputKeyMaterial[32];
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
|
@ -106,8 +104,8 @@ namespace transport
|
||||||
encryption.SetIV (m_RemoteIV);
|
encryption.SetIV (m_RemoteIV);
|
||||||
encryption.Encrypt (x, 32, m_SessionRequestBuffer);
|
encryption.Encrypt (x, 32, m_SessionRequestBuffer);
|
||||||
// encryption key for next block
|
// encryption key for next block
|
||||||
uint8_t key[32];
|
uint8_t key[32], ad[32];
|
||||||
KeyDerivationFunction1 (m_RemoteStaticKey, x, key);
|
KeyDerivationFunction1 (m_RemoteStaticKey, x, key, ad);
|
||||||
// fill options
|
// fill options
|
||||||
uint8_t options[32]; // actual options size is 16 bytes
|
uint8_t options[32]; // actual options size is 16 bytes
|
||||||
memset (options, 0, 16);
|
memset (options, 0, 16);
|
||||||
|
@ -118,11 +116,9 @@ namespace transport
|
||||||
htobe32buf (options + 8, i2p::util::GetSecondsSinceEpoch ()); // tsA
|
htobe32buf (options + 8, i2p::util::GetSecondsSinceEpoch ()); // tsA
|
||||||
// 4 bytes reserved
|
// 4 bytes reserved
|
||||||
// sign and encrypt options
|
// sign and encrypt options
|
||||||
i2p::crypto::Poly1305HMAC (((uint32_t *)options) + 4, (uint32_t *)key, options, 16); // calculate MAC first
|
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
memset (nonce, 0, 12); // set nonce to zero
|
memset (nonce, 0, 12); // set nonce to zero
|
||||||
i2p::crypto::chacha20 (options, 16, nonce, key); // then encrypt
|
i2p::crypto::AEADChaCha20Poly1305Encrypt (options, 16, ad, 32, key, nonce, m_SessionRequestBuffer + 32, 32);
|
||||||
memcpy (m_SessionRequestBuffer + 32, options, 32);
|
|
||||||
// send message
|
// send message
|
||||||
boost::asio::async_write (m_Socket, boost::asio::buffer (m_SessionRequestBuffer, paddingLength + 64), boost::asio::transfer_all (),
|
boost::asio::async_write (m_Socket, boost::asio::buffer (m_SessionRequestBuffer, paddingLength + 64), boost::asio::transfer_all (),
|
||||||
std::bind(&NTCP2Session::HandleSessionRequestSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
std::bind(&NTCP2Session::HandleSessionRequestSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace transport
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool KeyDerivationFunction1 (const uint8_t * rs, const uint8_t * pub, uint8_t * derived); // for SessionRequest
|
bool KeyDerivationFunction1 (const uint8_t * rs, const uint8_t * pub, uint8_t * derived, uint8_t * ad); // for SessionRequest
|
||||||
void CreateEphemeralKey (uint8_t * pub);
|
void CreateEphemeralKey (uint8_t * pub);
|
||||||
void SendSessionRequest ();
|
void SendSessionRequest ();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue