Browse Source

use AEN-NI for garlic encryption

pull/72/head
orignal 11 years ago
parent
commit
3eb4cc9eed
  1. 32
      Garlic.cpp
  2. 12
      Garlic.h
  3. 11
      aes.h

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

@ -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

@ -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…
Cancel
Save