mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-24 01:46:36 +02:00
use AEN-NI for garlic encryption
This commit is contained in:
parent
cc302847a8
commit
3eb4cc9eed
3 changed files with 25 additions and 30 deletions
32
Garlic.cpp
32
Garlic.cpp
|
@ -20,6 +20,7 @@ namespace garlic
|
||||||
{
|
{
|
||||||
// create new session tags and session key
|
// create new session tags and session key
|
||||||
m_Rnd.GenerateBlock (m_SessionKey, 32);
|
m_Rnd.GenerateBlock (m_SessionKey, 32);
|
||||||
|
m_Encryption.SetKey (m_SessionKey);
|
||||||
if (m_NumTags > 0)
|
if (m_NumTags > 0)
|
||||||
{
|
{
|
||||||
m_SessionTags = new uint8_t[m_NumTags*32];
|
m_SessionTags = new uint8_t[m_NumTags*32];
|
||||||
|
@ -77,7 +78,7 @@ namespace garlic
|
||||||
uint8_t iv[32]; // IV is first 16 bytes
|
uint8_t iv[32]; // IV is first 16 bytes
|
||||||
CryptoPP::SHA256().CalculateDigest(iv, elGamal.preIV, 32);
|
CryptoPP::SHA256().CalculateDigest(iv, elGamal.preIV, 32);
|
||||||
m_Destination.GetElGamalEncryption ()->Encrypt ((uint8_t *)&elGamal, sizeof(elGamal), buf, true);
|
m_Destination.GetElGamalEncryption ()->Encrypt ((uint8_t *)&elGamal, sizeof(elGamal), buf, true);
|
||||||
m_Encryption.SetKeyWithIV (m_SessionKey, 32, iv);
|
m_Encryption.SetIV (iv);
|
||||||
buf += 514;
|
buf += 514;
|
||||||
len += 514;
|
len += 514;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +88,7 @@ namespace garlic
|
||||||
memcpy (buf, m_SessionTags + m_NextTag*32, 32);
|
memcpy (buf, m_SessionTags + m_NextTag*32, 32);
|
||||||
uint8_t iv[32]; // IV is first 16 bytes
|
uint8_t iv[32]; // IV is first 16 bytes
|
||||||
CryptoPP::SHA256().CalculateDigest(iv, m_SessionTags + m_NextTag*32, 32);
|
CryptoPP::SHA256().CalculateDigest(iv, m_SessionTags + m_NextTag*32, 32);
|
||||||
m_Encryption.SetKeyWithIV (m_SessionKey, 32, iv);
|
m_Encryption.SetIV (iv);
|
||||||
buf += 32;
|
buf += 32;
|
||||||
len += 32;
|
len += 32;
|
||||||
|
|
||||||
|
@ -132,7 +133,7 @@ namespace garlic
|
||||||
size_t rem = blockSize % 16;
|
size_t rem = blockSize % 16;
|
||||||
if (rem)
|
if (rem)
|
||||||
blockSize += (16-rem); //padding
|
blockSize += (16-rem); //padding
|
||||||
m_Encryption.ProcessData(buf, buf, blockSize);
|
m_Encryption.Encrypt(buf, blockSize, buf);
|
||||||
return blockSize;
|
return blockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,6 +249,9 @@ namespace garlic
|
||||||
for (auto it: m_Sessions)
|
for (auto it: m_Sessions)
|
||||||
delete it.second;
|
delete it.second;
|
||||||
m_Sessions.clear ();
|
m_Sessions.clear ();
|
||||||
|
for (auto it: m_SessionDecryptions)
|
||||||
|
delete it;
|
||||||
|
m_SessionDecryptions.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
I2NPMessage * GarlicRouting::WrapSingleMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg)
|
I2NPMessage * GarlicRouting::WrapSingleMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg)
|
||||||
|
@ -298,13 +302,12 @@ namespace garlic
|
||||||
if (it != m_SessionTags.end ())
|
if (it != m_SessionTags.end ())
|
||||||
{
|
{
|
||||||
// existing session
|
// existing session
|
||||||
std::string sessionKey (it->second);
|
|
||||||
m_SessionTags.erase (it); // tag might be used only once
|
|
||||||
uint8_t iv[32]; // IV is first 16 bytes
|
uint8_t iv[32]; // IV is first 16 bytes
|
||||||
CryptoPP::SHA256().CalculateDigest(iv, buf, 32);
|
CryptoPP::SHA256().CalculateDigest(iv, buf, 32);
|
||||||
m_Decryption.SetKeyWithIV ((uint8_t *)sessionKey.c_str (), 32, iv); // tag is mapped to 32 bytes key
|
it->second->SetIV (iv);
|
||||||
m_Decryption.ProcessData(buf + 32, buf + 32, length - 32);
|
it->second->Decrypt (buf + 32, length - 32, buf + 32);
|
||||||
HandleAESBlock (buf + 32, length - 32, (uint8_t *)sessionKey.c_str ());
|
HandleAESBlock (buf + 32, length - 32, it->second);
|
||||||
|
m_SessionTags.erase (it); // tag might be used only once
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -317,11 +320,14 @@ namespace garlic
|
||||||
pool ? pool->GetEncryptionPrivateKey () : i2p::context.GetPrivateKey (),
|
pool ? pool->GetEncryptionPrivateKey () : i2p::context.GetPrivateKey (),
|
||||||
buf, (uint8_t *)&elGamal, true))
|
buf, (uint8_t *)&elGamal, true))
|
||||||
{
|
{
|
||||||
|
i2p::crypto::CBCDecryption * decryption = new i2p::crypto::CBCDecryption;
|
||||||
|
m_SessionDecryptions.push_back (decryption);
|
||||||
|
decryption->SetKey (elGamal.sessionKey);
|
||||||
uint8_t iv[32]; // IV is first 16 bytes
|
uint8_t iv[32]; // IV is first 16 bytes
|
||||||
CryptoPP::SHA256().CalculateDigest(iv, elGamal.preIV, 32);
|
CryptoPP::SHA256().CalculateDigest(iv, elGamal.preIV, 32);
|
||||||
m_Decryption.SetKeyWithIV (elGamal.sessionKey, 32, iv);
|
decryption->SetIV (iv);
|
||||||
m_Decryption.ProcessData(buf + 514, buf + 514, length - 514);
|
decryption->Decrypt(buf + 514, length - 514, buf + 514);
|
||||||
HandleAESBlock (buf + 514, length - 514, elGamal.sessionKey);
|
HandleAESBlock (buf + 514, length - 514, decryption);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint ("Failed to decrypt garlic");
|
LogPrint ("Failed to decrypt garlic");
|
||||||
|
@ -329,12 +335,12 @@ namespace garlic
|
||||||
DeleteI2NPMessage (msg);
|
DeleteI2NPMessage (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicRouting::HandleAESBlock (uint8_t * buf, size_t len, uint8_t * sessionKey)
|
void GarlicRouting::HandleAESBlock (uint8_t * buf, size_t len, i2p::crypto::CBCDecryption * decryption)
|
||||||
{
|
{
|
||||||
uint16_t tagCount = be16toh (*(uint16_t *)buf);
|
uint16_t tagCount = be16toh (*(uint16_t *)buf);
|
||||||
buf += 2;
|
buf += 2;
|
||||||
for (int i = 0; i < tagCount; i++)
|
for (int i = 0; i < tagCount; i++)
|
||||||
m_SessionTags[std::string ((const char *)(buf + i*32), 32)] = std::string ((const char *)sessionKey, 32);
|
m_SessionTags[std::string ((const char *)(buf + i*32), 32)] = decryption;
|
||||||
buf += tagCount*32;
|
buf += tagCount*32;
|
||||||
uint32_t payloadSize = be32toh (*(uint32_t *)buf);
|
uint32_t payloadSize = be32toh (*(uint32_t *)buf);
|
||||||
if (payloadSize > len)
|
if (payloadSize > len)
|
||||||
|
|
12
Garlic.h
12
Garlic.h
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <cryptopp/modes.h>
|
|
||||||
#include <cryptopp/aes.h>
|
|
||||||
#include <cryptopp/osrng.h>
|
#include <cryptopp/osrng.h>
|
||||||
|
#include "aes.h"
|
||||||
#include "I2NPProtocol.h"
|
#include "I2NPProtocol.h"
|
||||||
#include "LeaseSet.h"
|
#include "LeaseSet.h"
|
||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
|
@ -68,7 +68,7 @@ namespace garlic
|
||||||
uint8_t * m_SessionTags; // m_NumTags*32 bytes
|
uint8_t * m_SessionTags; // m_NumTags*32 bytes
|
||||||
uint32_t m_TagsCreationTime; // seconds since epoch
|
uint32_t m_TagsCreationTime; // seconds since epoch
|
||||||
|
|
||||||
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption m_Encryption;
|
i2p::crypto::CBCEncryption m_Encryption;
|
||||||
CryptoPP::AutoSeededRandomPool m_Rnd;
|
CryptoPP::AutoSeededRandomPool m_Rnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ namespace garlic
|
||||||
|
|
||||||
void Run ();
|
void Run ();
|
||||||
void ProcessGarlicMessage (I2NPMessage * msg);
|
void ProcessGarlicMessage (I2NPMessage * msg);
|
||||||
void HandleAESBlock (uint8_t * buf, size_t len, uint8_t * sessionKey);
|
void HandleAESBlock (uint8_t * buf, size_t len, i2p::crypto::CBCDecryption * decryption);
|
||||||
void HandleGarlicPayload (uint8_t * buf, size_t len);
|
void HandleGarlicPayload (uint8_t * buf, size_t len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -105,8 +105,8 @@ namespace garlic
|
||||||
std::map<i2p::data::IdentHash, GarlicRoutingSession *> m_Sessions;
|
std::map<i2p::data::IdentHash, GarlicRoutingSession *> m_Sessions;
|
||||||
std::map<uint32_t, GarlicRoutingSession *> m_CreatedSessions; // msgID -> session
|
std::map<uint32_t, GarlicRoutingSession *> m_CreatedSessions; // msgID -> session
|
||||||
// incoming session
|
// incoming session
|
||||||
std::map<std::string, std::string> m_SessionTags; // tag -> key
|
std::list<i2p::crypto::CBCDecryption *> m_SessionDecryptions; // multiple tags refer to one decyption
|
||||||
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption m_Decryption;
|
std::map<std::string, i2p::crypto::CBCDecryption *> m_SessionTags; // tag -> decryption
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GarlicRouting routing;
|
extern GarlicRouting routing;
|
||||||
|
|
11
aes.h
11
aes.h
|
@ -16,19 +16,8 @@ namespace crypto
|
||||||
|
|
||||||
void operator^=(const ChipherBlock& other) // XOR
|
void operator^=(const ChipherBlock& other) // XOR
|
||||||
{
|
{
|
||||||
#ifdef __x86_64__
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
"movups (%[b1]), %%xmm0 \n"
|
|
||||||
"movups (%[b2]), %%xmm1 \n" // b2 might not be 16-bytes aligned
|
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
|
||||||
"movups %%xmm0, (%[b1]) \n"
|
|
||||||
: : [b1]"r"(buf), [b2]"r"(other.buf): "memory", "%xmm0"
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
ll[0] ^= other.ll[0];
|
ll[0] ^= other.ll[0];
|
||||||
ll[1] ^= other.ll[1];
|
ll[1] ^= other.ll[1];
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue