mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
3 Commits
master
...
786da057f2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
786da057f2 | ||
|
|
097813a6ca | ||
|
|
226257aa71 |
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2023, The PurpleI2P Project
|
|
||||||
*
|
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
|
||||||
*
|
|
||||||
* See full license text in LICENSE file at top of project tree
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "CPU.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#ifndef bit_AES
|
|
||||||
#define bit_AES (1 << 25)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ < 6 && IS_X86
|
|
||||||
#include <cpuid.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <intrin.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace cpu
|
|
||||||
{
|
|
||||||
bool aesni = false;
|
|
||||||
|
|
||||||
inline bool cpu_support_aes()
|
|
||||||
{
|
|
||||||
#if IS_X86
|
|
||||||
#if defined(__clang__)
|
|
||||||
# if (__clang_major__ >= 6)
|
|
||||||
__builtin_cpu_init();
|
|
||||||
# endif
|
|
||||||
return __builtin_cpu_supports("aes");
|
|
||||||
#elif (defined(__GNUC__) && __GNUC__ >= 6)
|
|
||||||
__builtin_cpu_init();
|
|
||||||
return __builtin_cpu_supports("aes");
|
|
||||||
#elif (defined(__GNUC__) && __GNUC__ < 6)
|
|
||||||
int cpu_info[4];
|
|
||||||
bool flag = false;
|
|
||||||
__cpuid(0, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]);
|
|
||||||
if (cpu_info[0] >= 0x00000001) {
|
|
||||||
__cpuid(0x00000001, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]);
|
|
||||||
flag = ((cpu_info[2] & bit_AES) != 0);
|
|
||||||
}
|
|
||||||
return flag;
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
int cpu_info[4];
|
|
||||||
__cpuid(cpu_info, 1);
|
|
||||||
return ((cpu_info[2] & bit_AES) != 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Detect(bool AesSwitch, bool force)
|
|
||||||
{
|
|
||||||
if ((cpu_support_aes() && AesSwitch) || (AesSwitch && force)) {
|
|
||||||
aesni = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogPrint(eLogInfo, "AESNI ", (aesni ? "enabled" : "disabled"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2023, The PurpleI2P Project
|
* Copyright (c) 2013-2024, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -21,20 +21,4 @@
|
|||||||
# define IS_X86_64 0
|
# define IS_X86_64 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__AES__) && !defined(_MSC_VER) && IS_X86
|
|
||||||
# define SUPPORTS_AES 1
|
|
||||||
#else
|
|
||||||
# define SUPPORTS_AES 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace cpu
|
|
||||||
{
|
|
||||||
extern bool aesni;
|
|
||||||
|
|
||||||
void Detect(bool AesSwitch, bool force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ namespace config {
|
|||||||
("httpproxy.latency.max", value<std::string>()->default_value("0"), "HTTP proxy max latency for tunnels")
|
("httpproxy.latency.max", value<std::string>()->default_value("0"), "HTTP proxy max latency for tunnels")
|
||||||
("httpproxy.outproxy", value<std::string>()->default_value(""), "HTTP proxy upstream out proxy url")
|
("httpproxy.outproxy", value<std::string>()->default_value(""), "HTTP proxy upstream out proxy url")
|
||||||
("httpproxy.addresshelper", value<bool>()->default_value(true), "Enable or disable addresshelper")
|
("httpproxy.addresshelper", value<bool>()->default_value(true), "Enable or disable addresshelper")
|
||||||
("httpproxy.senduseragent", value<bool>()->default_value(false), "Pass through user's User-Agent if enabled. Disabled by deafult")
|
("httpproxy.senduseragent", value<bool>()->default_value(false), "Pass through user's User-Agent if enabled. Disabled by default")
|
||||||
("httpproxy.i2cp.leaseSetType", value<std::string>()->default_value("3"), "Local destination's LeaseSet type")
|
("httpproxy.i2cp.leaseSetType", value<std::string>()->default_value("3"), "Local destination's LeaseSet type")
|
||||||
("httpproxy.i2cp.leaseSetEncType", value<std::string>()->default_value("0,4"), "Local destination's LeaseSet encryption type")
|
("httpproxy.i2cp.leaseSetEncType", value<std::string>()->default_value("0,4"), "Local destination's LeaseSet encryption type")
|
||||||
("httpproxy.i2cp.leaseSetPrivKey", value<std::string>()->default_value(""), "LeaseSet private key")
|
("httpproxy.i2cp.leaseSetPrivKey", value<std::string>()->default_value(""), "LeaseSet private key")
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#if OPENSSL_HKDF
|
#if OPENSSL_HKDF
|
||||||
#include <openssl/kdf.h>
|
#include <openssl/kdf.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "CPU.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "Ed25519.h"
|
#include "Ed25519.h"
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
@@ -515,429 +516,105 @@ namespace crypto
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AES
|
// AES
|
||||||
#if SUPPORTS_AES
|
ECBEncryption::ECBEncryption ()
|
||||||
#define KeyExpansion256(round0,round1) \
|
|
||||||
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
|
||||||
"movaps %%xmm1, %%xmm4 \n" \
|
|
||||||
"pslldq $4, %%xmm4 \n" \
|
|
||||||
"pxor %%xmm4, %%xmm1 \n" \
|
|
||||||
"pslldq $4, %%xmm4 \n" \
|
|
||||||
"pxor %%xmm4, %%xmm1 \n" \
|
|
||||||
"pslldq $4, %%xmm4 \n" \
|
|
||||||
"pxor %%xmm4, %%xmm1 \n" \
|
|
||||||
"pxor %%xmm2, %%xmm1 \n" \
|
|
||||||
"movaps %%xmm1, "#round0"(%[sched]) \n" \
|
|
||||||
"aeskeygenassist $0, %%xmm1, %%xmm4 \n" \
|
|
||||||
"pshufd $0xaa, %%xmm4, %%xmm2 \n" \
|
|
||||||
"movaps %%xmm3, %%xmm4 \n" \
|
|
||||||
"pslldq $4, %%xmm4 \n" \
|
|
||||||
"pxor %%xmm4, %%xmm3 \n" \
|
|
||||||
"pslldq $4, %%xmm4 \n" \
|
|
||||||
"pxor %%xmm4, %%xmm3 \n" \
|
|
||||||
"pslldq $4, %%xmm4 \n" \
|
|
||||||
"pxor %%xmm4, %%xmm3 \n" \
|
|
||||||
"pxor %%xmm2, %%xmm3 \n" \
|
|
||||||
"movaps %%xmm3, "#round1"(%[sched]) \n"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SUPPORTS_AES
|
|
||||||
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
|
|
||||||
{
|
{
|
||||||
__asm__
|
m_Ctx = EVP_CIPHER_CTX_new ();
|
||||||
(
|
|
||||||
"movups (%[key]), %%xmm1 \n"
|
|
||||||
"movups 16(%[key]), %%xmm3 \n"
|
|
||||||
"movaps %%xmm1, (%[sched]) \n"
|
|
||||||
"movaps %%xmm3, 16(%[sched]) \n"
|
|
||||||
"aeskeygenassist $1, %%xmm3, %%xmm2 \n"
|
|
||||||
KeyExpansion256(32,48)
|
|
||||||
"aeskeygenassist $2, %%xmm3, %%xmm2 \n"
|
|
||||||
KeyExpansion256(64,80)
|
|
||||||
"aeskeygenassist $4, %%xmm3, %%xmm2 \n"
|
|
||||||
KeyExpansion256(96,112)
|
|
||||||
"aeskeygenassist $8, %%xmm3, %%xmm2 \n"
|
|
||||||
KeyExpansion256(128,144)
|
|
||||||
"aeskeygenassist $16, %%xmm3, %%xmm2 \n"
|
|
||||||
KeyExpansion256(160,176)
|
|
||||||
"aeskeygenassist $32, %%xmm3, %%xmm2 \n"
|
|
||||||
KeyExpansion256(192,208)
|
|
||||||
"aeskeygenassist $64, %%xmm3, %%xmm2 \n"
|
|
||||||
// key expansion final
|
|
||||||
"pshufd $0xff, %%xmm2, %%xmm2 \n"
|
|
||||||
"movaps %%xmm1, %%xmm4 \n"
|
|
||||||
"pslldq $4, %%xmm4 \n"
|
|
||||||
"pxor %%xmm4, %%xmm1 \n"
|
|
||||||
"pslldq $4, %%xmm4 \n"
|
|
||||||
"pxor %%xmm4, %%xmm1 \n"
|
|
||||||
"pslldq $4, %%xmm4 \n"
|
|
||||||
"pxor %%xmm4, %%xmm1 \n"
|
|
||||||
"pxor %%xmm2, %%xmm1 \n"
|
|
||||||
"movups %%xmm1, 224(%[sched]) \n"
|
|
||||||
: // output
|
|
||||||
: [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input
|
|
||||||
: "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory" // clogged
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if SUPPORTS_AES
|
|
||||||
#define EncryptAES256(sched) \
|
|
||||||
"pxor (%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 16(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 32(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 48(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 64(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 80(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 96(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 112(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 128(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 144(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 160(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 176(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 192(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenc 208(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesenclast 224(%["#sched"]), %%xmm0 \n"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out)
|
|
||||||
{
|
|
||||||
#if SUPPORTS_AES
|
|
||||||
if(i2p::cpu::aesni)
|
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
EncryptAES256(sched)
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
:
|
|
||||||
: [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out)
|
|
||||||
: "%xmm0", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
AES_encrypt (in->buf, out->buf, &m_Key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SUPPORTS_AES
|
ECBEncryption::~ECBEncryption ()
|
||||||
#define DecryptAES256(sched) \
|
|
||||||
"pxor 224(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 208(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 192(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 176(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 160(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 144(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 128(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 112(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 96(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 80(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 64(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 48(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 32(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdec 16(%["#sched"]), %%xmm0 \n" \
|
|
||||||
"aesdeclast (%["#sched"]), %%xmm0 \n"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out)
|
|
||||||
{
|
{
|
||||||
#if SUPPORTS_AES
|
if (m_Ctx)
|
||||||
if(i2p::cpu::aesni)
|
EVP_CIPHER_CTX_free (m_Ctx);
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
DecryptAES256(sched)
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
:
|
|
||||||
: [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out)
|
|
||||||
: "%xmm0", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
AES_decrypt (in->buf, out->buf, &m_Key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SUPPORTS_AES
|
void ECBEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
||||||
#define CallAESIMC(offset) \
|
|
||||||
"movaps "#offset"(%[shed]), %%xmm0 \n" \
|
|
||||||
"aesimc %%xmm0, %%xmm0 \n" \
|
|
||||||
"movaps %%xmm0, "#offset"(%[shed]) \n"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ECBEncryption::SetKey (const AESKey& key)
|
|
||||||
{
|
{
|
||||||
#if SUPPORTS_AES
|
EVP_EncryptInit_ex (m_Ctx, EVP_aes_256_ecb(), NULL, m_Key, NULL);
|
||||||
if(i2p::cpu::aesni)
|
EVP_CIPHER_CTX_set_padding (m_Ctx, 0);
|
||||||
{
|
int len;
|
||||||
ExpandKey (key);
|
EVP_EncryptUpdate (m_Ctx, out, &len, in, 16);
|
||||||
}
|
EVP_EncryptFinal_ex (m_Ctx, out + len, &len);
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
AES_set_encrypt_key (key, 256, &m_Key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECBDecryption::SetKey (const AESKey& key)
|
ECBDecryption::ECBDecryption ()
|
||||||
{
|
{
|
||||||
#if SUPPORTS_AES
|
m_Ctx = EVP_CIPHER_CTX_new ();
|
||||||
if(i2p::cpu::aesni)
|
|
||||||
{
|
|
||||||
ExpandKey (key); // expand encryption key first
|
|
||||||
// then invert it using aesimc
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
CallAESIMC(16)
|
|
||||||
CallAESIMC(32)
|
|
||||||
CallAESIMC(48)
|
|
||||||
CallAESIMC(64)
|
|
||||||
CallAESIMC(80)
|
|
||||||
CallAESIMC(96)
|
|
||||||
CallAESIMC(112)
|
|
||||||
CallAESIMC(128)
|
|
||||||
CallAESIMC(144)
|
|
||||||
CallAESIMC(160)
|
|
||||||
CallAESIMC(176)
|
|
||||||
CallAESIMC(192)
|
|
||||||
CallAESIMC(208)
|
|
||||||
:
|
|
||||||
: [shed]"r"(GetKeySchedule ())
|
|
||||||
: "%xmm0", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
AES_set_decrypt_key (key, 256, &m_Key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
ECBDecryption::~ECBDecryption ()
|
||||||
{
|
{
|
||||||
#if SUPPORTS_AES
|
if (m_Ctx)
|
||||||
if(i2p::cpu::aesni)
|
EVP_CIPHER_CTX_free (m_Ctx);
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
|
||||||
"1: \n"
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
|
||||||
EncryptAES256(sched)
|
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
"add $16, %[in] \n"
|
|
||||||
"add $16, %[out] \n"
|
|
||||||
"dec %[num] \n"
|
|
||||||
"jnz 1b \n"
|
|
||||||
"movups %%xmm1, (%[iv]) \n"
|
|
||||||
:
|
|
||||||
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
|
||||||
: "%xmm0", "%xmm1", "cc", "memory"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
void ECBDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numBlocks; i++)
|
EVP_DecryptInit_ex (m_Ctx, EVP_aes_256_ecb(), NULL, m_Key, NULL);
|
||||||
|
EVP_CIPHER_CTX_set_padding (m_Ctx, 0);
|
||||||
|
int len;
|
||||||
|
EVP_DecryptUpdate (m_Ctx, out, &len, in, 16);
|
||||||
|
EVP_DecryptFinal_ex (m_Ctx, out + len, &len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CBCEncryption::CBCEncryption ()
|
||||||
{
|
{
|
||||||
*m_LastBlock.GetChipherBlock () ^= in[i];
|
m_Ctx = EVP_CIPHER_CTX_new ();
|
||||||
m_ECBEncryption.Encrypt (m_LastBlock.GetChipherBlock (), m_LastBlock.GetChipherBlock ());
|
//memset ((uint8_t *)m_LastBlock, 0, 16);
|
||||||
out[i] = *m_LastBlock.GetChipherBlock ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CBCEncryption::~CBCEncryption ()
|
||||||
|
{
|
||||||
|
if (m_Ctx)
|
||||||
|
EVP_CIPHER_CTX_free (m_Ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCEncryption::Encrypt (const uint8_t * in, std::size_t len, uint8_t * out)
|
void CBCEncryption::Encrypt (const uint8_t * in, std::size_t len, uint8_t * out)
|
||||||
{
|
{
|
||||||
// len/16
|
// len/16
|
||||||
int numBlocks = len >> 4;
|
EVP_EncryptInit_ex (m_Ctx, EVP_aes_256_cbc(), NULL, m_Key, m_IV);
|
||||||
if (numBlocks > 0)
|
EVP_CIPHER_CTX_set_padding (m_Ctx, 0);
|
||||||
Encrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out);
|
int l;
|
||||||
|
EVP_EncryptUpdate (m_Ctx, out, &l, in, len);
|
||||||
|
EVP_EncryptFinal_ex (m_Ctx, out + l, &l);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
CBCDecryption::CBCDecryption ()
|
||||||
{
|
{
|
||||||
#if SUPPORTS_AES
|
m_Ctx = EVP_CIPHER_CTX_new ();
|
||||||
if(i2p::cpu::aesni)
|
//memset ((uint8_t *)m_IV, 0, 16);
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
|
||||||
EncryptAES256(sched)
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
"movups %%xmm0, (%[iv]) \n"
|
|
||||||
:
|
|
||||||
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
|
||||||
[in]"r"(in), [out]"r"(out)
|
|
||||||
: "%xmm0", "%xmm1", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
Encrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
CBCDecryption::~CBCDecryption ()
|
||||||
{
|
{
|
||||||
#if SUPPORTS_AES
|
if (m_Ctx)
|
||||||
if(i2p::cpu::aesni)
|
EVP_CIPHER_CTX_free (m_Ctx);
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
|
||||||
"1: \n"
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
"movaps %%xmm0, %%xmm2 \n"
|
|
||||||
DecryptAES256(sched)
|
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
"movaps %%xmm2, %%xmm1 \n"
|
|
||||||
"add $16, %[in] \n"
|
|
||||||
"add $16, %[out] \n"
|
|
||||||
"dec %[num] \n"
|
|
||||||
"jnz 1b \n"
|
|
||||||
"movups %%xmm1, (%[iv]) \n"
|
|
||||||
:
|
|
||||||
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
|
||||||
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
for (int i = 0; i < numBlocks; i++)
|
|
||||||
{
|
|
||||||
ChipherBlock tmp = in[i];
|
|
||||||
m_ECBDecryption.Decrypt (in + i, out + i);
|
|
||||||
out[i] ^= *m_IV.GetChipherBlock ();
|
|
||||||
*m_IV.GetChipherBlock () = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCDecryption::Decrypt (const uint8_t * in, std::size_t len, uint8_t * out)
|
void CBCDecryption::Decrypt (const uint8_t * in, std::size_t len, uint8_t * out)
|
||||||
{
|
{
|
||||||
int numBlocks = len >> 4;
|
// len/16
|
||||||
if (numBlocks > 0)
|
EVP_DecryptInit_ex (m_Ctx, EVP_aes_256_cbc(), NULL, m_Key, m_IV);
|
||||||
Decrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out);
|
EVP_CIPHER_CTX_set_padding (m_Ctx, 0);
|
||||||
}
|
int l;
|
||||||
|
EVP_DecryptUpdate (m_Ctx, out, &l, in, len);
|
||||||
void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
EVP_DecryptFinal_ex (m_Ctx, out + l, &l);
|
||||||
{
|
|
||||||
#if SUPPORTS_AES
|
|
||||||
if(i2p::cpu::aesni)
|
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
"movups %%xmm0, (%[iv]) \n"
|
|
||||||
DecryptAES256(sched)
|
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
:
|
|
||||||
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
|
||||||
[in]"r"(in), [out]"r"(out)
|
|
||||||
: "%xmm0", "%xmm1", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
Decrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
||||||
{
|
{
|
||||||
#if SUPPORTS_AES
|
m_IVEncryption.Encrypt (in, out); // iv
|
||||||
if(i2p::cpu::aesni)
|
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
// encrypt IV
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
EncryptAES256(sched_iv)
|
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
|
||||||
// double IV encryption
|
|
||||||
EncryptAES256(sched_iv)
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
// encrypt data, IV is xmm1
|
|
||||||
"1: \n"
|
|
||||||
"add $16, %[in] \n"
|
|
||||||
"add $16, %[out] \n"
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
|
||||||
EncryptAES256(sched_l)
|
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
"dec %[num] \n"
|
|
||||||
"jnz 1b \n"
|
|
||||||
:
|
|
||||||
: [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.ECB().GetKeySchedule ()),
|
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
|
||||||
: "%xmm0", "%xmm1", "cc", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
m_IVEncryption.Encrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
|
||||||
m_LayerEncryption.SetIV (out);
|
m_LayerEncryption.SetIV (out);
|
||||||
m_LayerEncryption.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
m_LayerEncryption.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
||||||
m_IVEncryption.Encrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
|
m_IVEncryption.Encrypt (out, out); // double iv
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
||||||
{
|
{
|
||||||
#if SUPPORTS_AES
|
m_IVDecryption.Decrypt (in, out); // iv
|
||||||
if(i2p::cpu::aesni)
|
|
||||||
{
|
|
||||||
__asm__
|
|
||||||
(
|
|
||||||
// decrypt IV
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
DecryptAES256(sched_iv)
|
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
|
||||||
// double IV encryption
|
|
||||||
DecryptAES256(sched_iv)
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
// decrypt data, IV is xmm1
|
|
||||||
"1: \n"
|
|
||||||
"add $16, %[in] \n"
|
|
||||||
"add $16, %[out] \n"
|
|
||||||
"movups (%[in]), %%xmm0 \n"
|
|
||||||
"movaps %%xmm0, %%xmm2 \n"
|
|
||||||
DecryptAES256(sched_l)
|
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
|
||||||
"movups %%xmm0, (%[out]) \n"
|
|
||||||
"movaps %%xmm2, %%xmm1 \n"
|
|
||||||
"dec %[num] \n"
|
|
||||||
"jnz 1b \n"
|
|
||||||
:
|
|
||||||
: [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.ECB().GetKeySchedule ()),
|
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
|
||||||
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
m_IVDecryption.Decrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
|
||||||
m_LayerDecryption.SetIV (out);
|
m_LayerDecryption.SetIV (out);
|
||||||
m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
||||||
m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
|
m_IVDecryption.Decrypt (out, out); // double iv
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AEAD/ChaCha20/Poly1305
|
// AEAD/ChaCha20/Poly1305
|
||||||
@@ -1159,7 +836,6 @@ namespace crypto
|
|||||||
|
|
||||||
void InitCrypto (bool precomputation, bool aesni, bool force)
|
void InitCrypto (bool precomputation, bool aesni, bool force)
|
||||||
{
|
{
|
||||||
i2p::cpu::Detect (aesni, force);
|
|
||||||
/* auto numLocks = CRYPTO_num_locks();
|
/* auto numLocks = CRYPTO_num_locks();
|
||||||
for (int i = 0; i < numLocks; i++)
|
for (int i = 0; i < numLocks; i++)
|
||||||
m_OpenSSLMutexes.emplace_back (new std::mutex);
|
m_OpenSSLMutexes.emplace_back (new std::mutex);
|
||||||
|
|||||||
127
libi2pd/Crypto.h
127
libi2pd/Crypto.h
@@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Tag.h"
|
#include "Tag.h"
|
||||||
#include "CPU.h"
|
|
||||||
|
|
||||||
// recognize openssl version and features
|
// recognize openssl version and features
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
#if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
||||||
@@ -85,142 +84,76 @@ namespace crypto
|
|||||||
void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub);
|
void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub);
|
||||||
|
|
||||||
// AES
|
// AES
|
||||||
struct ChipherBlock
|
|
||||||
{
|
|
||||||
uint8_t buf[16];
|
|
||||||
|
|
||||||
void operator^=(const ChipherBlock& other) // XOR
|
|
||||||
{
|
|
||||||
if (!(((size_t)buf | (size_t)other.buf) & 0x03)) // multiple of 4 ?
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
reinterpret_cast<uint32_t *>(buf)[i] ^= reinterpret_cast<const uint32_t *>(other.buf)[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
buf[i] ^= other.buf[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef i2p::data::Tag<32> AESKey;
|
typedef i2p::data::Tag<32> AESKey;
|
||||||
|
|
||||||
template<size_t sz>
|
|
||||||
class AESAlignedBuffer // 16 bytes alignment
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
AESAlignedBuffer ()
|
|
||||||
{
|
|
||||||
m_Buf = m_UnalignedBuffer;
|
|
||||||
uint8_t rem = ((size_t)m_Buf) & 0x0f;
|
|
||||||
if (rem)
|
|
||||||
m_Buf += (16 - rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator uint8_t * () { return m_Buf; };
|
|
||||||
operator const uint8_t * () const { return m_Buf; };
|
|
||||||
ChipherBlock * GetChipherBlock () { return (ChipherBlock *)m_Buf; };
|
|
||||||
const ChipherBlock * GetChipherBlock () const { return (const ChipherBlock *)m_Buf; };
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
uint8_t m_UnalignedBuffer[sz + 15]; // up to 15 bytes alignment
|
|
||||||
uint8_t * m_Buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if SUPPORTS_AES
|
|
||||||
class ECBCryptoAESNI
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
uint8_t * GetKeySchedule () { return m_KeySchedule; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void ExpandKey (const AESKey& key);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
AESAlignedBuffer<240> m_KeySchedule; // 14 rounds for AES-256, 240 bytes
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SUPPORTS_AES
|
|
||||||
class ECBEncryption: public ECBCryptoAESNI
|
|
||||||
#else
|
|
||||||
class ECBEncryption
|
class ECBEncryption
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void SetKey (const AESKey& key);
|
ECBEncryption ();
|
||||||
|
~ECBEncryption ();
|
||||||
|
|
||||||
void Encrypt(const ChipherBlock * in, ChipherBlock * out);
|
void SetKey (const AESKey& key) { m_Key = key; };
|
||||||
|
void Encrypt(const uint8_t * in, uint8_t * out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AES_KEY m_Key;
|
|
||||||
|
AESKey m_Key;
|
||||||
|
EVP_CIPHER_CTX * m_Ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if SUPPORTS_AES
|
|
||||||
class ECBDecryption: public ECBCryptoAESNI
|
|
||||||
#else
|
|
||||||
class ECBDecryption
|
class ECBDecryption
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void SetKey (const AESKey& key);
|
ECBDecryption ();
|
||||||
void Decrypt (const ChipherBlock * in, ChipherBlock * out);
|
~ECBDecryption ();
|
||||||
|
|
||||||
|
void SetKey (const AESKey& key) { m_Key = key; };
|
||||||
|
void Decrypt (const uint8_t * in, uint8_t * out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AES_KEY m_Key;
|
|
||||||
|
AESKey m_Key;
|
||||||
|
EVP_CIPHER_CTX * m_Ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBCEncryption
|
class CBCEncryption
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CBCEncryption () { memset ((uint8_t *)m_LastBlock, 0, 16); };
|
CBCEncryption ();
|
||||||
|
~CBCEncryption ();
|
||||||
|
|
||||||
void SetKey (const AESKey& key) { m_ECBEncryption.SetKey (key); }; // 32 bytes
|
void SetKey (const AESKey& key) { m_Key = key; }; // 32 bytes
|
||||||
void SetIV (const uint8_t * iv) { memcpy ((uint8_t *)m_LastBlock, iv, 16); }; // 16 bytes
|
void SetIV (const uint8_t * iv) { m_IV = iv; }; // 16 bytes
|
||||||
void GetIV (uint8_t * iv) const { memcpy (iv, (const uint8_t *)m_LastBlock, 16); };
|
|
||||||
|
|
||||||
void Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out);
|
|
||||||
void Encrypt (const uint8_t * in, std::size_t len, uint8_t * out);
|
void Encrypt (const uint8_t * in, std::size_t len, uint8_t * out);
|
||||||
void Encrypt (const uint8_t * in, uint8_t * out); // one block
|
|
||||||
|
|
||||||
ECBEncryption & ECB() { return m_ECBEncryption; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AESAlignedBuffer<16> m_LastBlock;
|
AESKey m_Key;
|
||||||
|
i2p::data::Tag<16> m_IV;
|
||||||
ECBEncryption m_ECBEncryption;
|
EVP_CIPHER_CTX * m_Ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBCDecryption
|
class CBCDecryption
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CBCDecryption () { memset ((uint8_t *)m_IV, 0, 16); };
|
CBCDecryption ();
|
||||||
|
~CBCDecryption ();
|
||||||
|
|
||||||
void SetKey (const AESKey& key) { m_ECBDecryption.SetKey (key); }; // 32 bytes
|
void SetKey (const AESKey& key) { m_Key = key; }; // 32 bytes
|
||||||
void SetIV (const uint8_t * iv) { memcpy ((uint8_t *)m_IV, iv, 16); }; // 16 bytes
|
void SetIV (const uint8_t * iv) { m_IV = iv; }; // 16 bytes
|
||||||
void GetIV (uint8_t * iv) const { memcpy (iv, (const uint8_t *)m_IV, 16); };
|
|
||||||
|
|
||||||
void Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out);
|
|
||||||
void Decrypt (const uint8_t * in, std::size_t len, uint8_t * out);
|
void Decrypt (const uint8_t * in, std::size_t len, uint8_t * out);
|
||||||
void Decrypt (const uint8_t * in, uint8_t * out); // one block
|
|
||||||
|
|
||||||
ECBDecryption & ECB() { return m_ECBDecryption; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AESAlignedBuffer<16> m_IV;
|
AESKey m_Key;
|
||||||
ECBDecryption m_ECBDecryption;
|
i2p::data::Tag<16> m_IV;
|
||||||
|
EVP_CIPHER_CTX * m_Ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TunnelEncryption // with double IV encryption
|
class TunnelEncryption // with double IV encryption
|
||||||
|
|||||||
@@ -550,7 +550,7 @@ namespace garlic
|
|||||||
LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message");
|
LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Garlic: Incoming sessions come too ofter");
|
LogPrint (eLogWarning, "Garlic: Incoming sessions come too often");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ namespace garlic
|
|||||||
std::unordered_map<i2p::data::IdentHash, ElGamalAESSessionPtr> m_Sessions;
|
std::unordered_map<i2p::data::IdentHash, ElGamalAESSessionPtr> m_Sessions;
|
||||||
std::unordered_map<i2p::data::Tag<32>, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session
|
std::unordered_map<i2p::data::Tag<32>, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session
|
||||||
uint8_t * m_PayloadBuffer; // for ECIESX25519AEADRatchet
|
uint8_t * m_PayloadBuffer; // for ECIESX25519AEADRatchet
|
||||||
uint64_t m_LastIncomingSessionTimestamp; // in millseconds
|
uint64_t m_LastIncomingSessionTimestamp; // in milliseconds
|
||||||
// incoming
|
// incoming
|
||||||
int m_NumRatchetInboundTags;
|
int m_NumRatchetInboundTags;
|
||||||
std::unordered_map<SessionTag, std::shared_ptr<AESDecryption>, std::hash<i2p::data::Tag<32> > > m_Tags;
|
std::unordered_map<SessionTag, std::shared_ptr<AESDecryption>, std::hash<i2p::data::Tag<32> > > m_Tags;
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ namespace transport
|
|||||||
encryption.SetKey (m_RemoteIdentHash);
|
encryption.SetKey (m_RemoteIdentHash);
|
||||||
encryption.SetIV (m_IV);
|
encryption.SetIV (m_IV);
|
||||||
encryption.Encrypt (GetPub (), 32, m_SessionRequestBuffer); // X
|
encryption.Encrypt (GetPub (), 32, m_SessionRequestBuffer); // X
|
||||||
encryption.GetIV (m_IV); // save IV for SessionCreated
|
memcpy (m_IV, m_SessionRequestBuffer + 16, 16); // save last block as IV for SessionCreated
|
||||||
// encryption key for next block
|
// encryption key for next block
|
||||||
if (!KDF1Alice ()) return false;
|
if (!KDF1Alice ()) return false;
|
||||||
// fill options
|
// fill options
|
||||||
@@ -210,7 +210,7 @@ namespace transport
|
|||||||
decryption.SetKey (i2p::context.GetIdentHash ());
|
decryption.SetKey (i2p::context.GetIdentHash ());
|
||||||
decryption.SetIV (i2p::context.GetNTCP2IV ());
|
decryption.SetIV (i2p::context.GetNTCP2IV ());
|
||||||
decryption.Decrypt (m_SessionRequestBuffer, 32, GetRemotePub ());
|
decryption.Decrypt (m_SessionRequestBuffer, 32, GetRemotePub ());
|
||||||
decryption.GetIV (m_IV); // save IV for SessionCreated
|
memcpy (m_IV, m_SessionRequestBuffer + 16, 16); // save last block as IV for SessionCreated
|
||||||
// decryption key for next block
|
// decryption key for next block
|
||||||
if (!KDF1Bob ())
|
if (!KDF1Bob ())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -637,7 +637,7 @@ namespace data
|
|||||||
if (checkForExpiration && uptime > i2p::transport::SSU2_TO_INTRODUCER_SESSION_DURATION) // 1 hour
|
if (checkForExpiration && uptime > i2p::transport::SSU2_TO_INTRODUCER_SESSION_DURATION) // 1 hour
|
||||||
expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL :
|
expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL :
|
||||||
NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total;
|
NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total;
|
||||||
bool isOffline = checkForExpiration && i2p::transport::transports.GetNumPeers () < NETDB_MIN_TRANSPORTS; // enough routers and uptime, but no tranports
|
bool isOffline = checkForExpiration && i2p::transport::transports.GetNumPeers () < NETDB_MIN_TRANSPORTS; // enough routers and uptime, but no transports
|
||||||
|
|
||||||
std::list<std::pair<std::string, std::shared_ptr<RouterInfo::Buffer> > > saveToDisk;
|
std::list<std::pair<std::string, std::shared_ptr<RouterInfo::Buffer> > > saveToDisk;
|
||||||
std::list<std::string> removeFromDisk;
|
std::list<std::string> removeFromDisk;
|
||||||
|
|||||||
@@ -1389,7 +1389,7 @@ namespace transport
|
|||||||
excluded.insert (ident);
|
excluded.insert (ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sesssion about to expire are not counted
|
// session about to expire are not counted
|
||||||
for (auto i = introducers.size (); i < SSU2_MAX_NUM_INTRODUCERS + numOldSessions; i++)
|
for (auto i = introducers.size (); i < SSU2_MAX_NUM_INTRODUCERS + numOldSessions; i++)
|
||||||
{
|
{
|
||||||
auto introducer = i2p::data::netdb.GetRandomSSU2Introducer (v4, excluded);
|
auto introducer = i2p::data::netdb.GetRandomSSU2Introducer (v4, excluded);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace transport
|
|||||||
void SSU2PeerTestSession::HandleAddress (const uint8_t * buf, size_t len)
|
void SSU2PeerTestSession::HandleAddress (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
if (!ExtractEndpoint (buf, len, m_OurEndpoint))
|
if (!ExtractEndpoint (buf, len, m_OurEndpoint))
|
||||||
LogPrint (eLogWarning, "SSU2: Can't hanlde address block from peer test message");
|
LogPrint (eLogWarning, "SSU2: Can't handle address block from peer test message");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSU2PeerTestSession::HandlePeerTest (const uint8_t * buf, size_t len)
|
void SSU2PeerTestSession::HandlePeerTest (const uint8_t * buf, size_t len)
|
||||||
@@ -89,7 +89,7 @@ namespace transport
|
|||||||
{
|
{
|
||||||
if (htobe64 (((uint64_t)nonce << 32) | nonce) == GetSourceConnID ())
|
if (htobe64 (((uint64_t)nonce << 32) | nonce) == GetSourceConnID ())
|
||||||
{
|
{
|
||||||
m_PeerTestResendTimer.cancel (); // calcel delayed msg 6 if any
|
m_PeerTestResendTimer.cancel (); // cancel delayed msg 6 if any
|
||||||
m_IsConnectedRecently = GetServer ().IsConnectedRecently (GetRemoteEndpoint ());
|
m_IsConnectedRecently = GetServer ().IsConnectedRecently (GetRemoteEndpoint ());
|
||||||
if (GetAddress ())
|
if (GetAddress ())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -958,7 +958,7 @@ namespace stream
|
|||||||
if (choking || requestImmediateAck)
|
if (choking || requestImmediateAck)
|
||||||
{
|
{
|
||||||
htobe16buf (packet + size, 2); // 2 bytes delay interval
|
htobe16buf (packet + size, 2); // 2 bytes delay interval
|
||||||
htobe16buf (packet + size + 2, choking ? DELAY_CHOKING : 0); // set choking or immediated ack interval
|
htobe16buf (packet + size + 2, choking ? DELAY_CHOKING : 0); // set choking or immediate ack interval
|
||||||
size += 2;
|
size += 2;
|
||||||
if (requestImmediateAck) // ack request sent
|
if (requestImmediateAck) // ack request sent
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ namespace stream
|
|||||||
int m_WindowIncCounter, m_RTO, m_AckDelay, m_PrevRTTSample;
|
int m_WindowIncCounter, m_RTO, m_AckDelay, m_PrevRTTSample;
|
||||||
double m_Jitter;
|
double m_Jitter;
|
||||||
uint64_t m_MinPacingTime, m_PacingTime, m_PacingTimeRem, // microseconds
|
uint64_t m_MinPacingTime, m_PacingTime, m_PacingTimeRem, // microseconds
|
||||||
m_LastSendTime, m_RemoteLeaseChangeTime; // miliseconds
|
m_LastSendTime, m_RemoteLeaseChangeTime; // milliseconds
|
||||||
uint64_t m_LastACKSendTime, m_PacketACKInterval, m_PacketACKIntervalRem; // for limit inbound speed
|
uint64_t m_LastACKSendTime, m_PacketACKInterval, m_PacketACKIntervalRem; // for limit inbound speed
|
||||||
int m_NumResendAttempts, m_NumPacketsToSend;
|
int m_NumResendAttempts, m_NumPacketsToSend;
|
||||||
size_t m_MTU;
|
size_t m_MTU;
|
||||||
|
|||||||
@@ -240,13 +240,13 @@ namespace tunnel
|
|||||||
auto currentTransport = m_CurrentTransport.lock ();
|
auto currentTransport = m_CurrentTransport.lock ();
|
||||||
if (!currentTransport)
|
if (!currentTransport)
|
||||||
{
|
{
|
||||||
// try to obtain transport from peding reequest or send thought transport is not complete
|
// try to obtain transport from pending request or send thought transport is not complete
|
||||||
if (m_PendingTransport.valid ()) // pending request?
|
if (m_PendingTransport.valid ()) // pending request?
|
||||||
{
|
{
|
||||||
if (m_PendingTransport.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
if (m_PendingTransport.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||||
{
|
{
|
||||||
// pending request complete
|
// pending request complete
|
||||||
currentTransport = m_PendingTransport.get (); // take tarnsports used in pending request
|
currentTransport = m_PendingTransport.get (); // take transports used in pending request
|
||||||
if (currentTransport)
|
if (currentTransport)
|
||||||
{
|
{
|
||||||
if (currentTransport->IsEstablished ())
|
if (currentTransport->IsEstablished ())
|
||||||
@@ -257,7 +257,7 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
else // still pending
|
else // still pending
|
||||||
{
|
{
|
||||||
// send through transports, but don't update pedning transport
|
// send through transports, but don't update pending transport
|
||||||
i2p::transport::transports.SendMessages (m_Tunnel.GetNextIdentHash (), std::move (newTunnelMsgs));
|
i2p::transport::transports.SendMessages (m_Tunnel.GetNextIdentHash (), std::move (newTunnelMsgs));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -879,7 +879,7 @@ namespace client
|
|||||||
if (!remoteSession || !m_Destination->SendMsg (buf + offset, payloadLen, remoteSession, nonce))
|
if (!remoteSession || !m_Destination->SendMsg (buf + offset, payloadLen, remoteSession, nonce))
|
||||||
{
|
{
|
||||||
i2p::data::IdentHash identHash;
|
i2p::data::IdentHash identHash;
|
||||||
SHA256(ident, identSize, identHash); // caclulate ident hash, because we don't need full identity
|
SHA256(ident, identSize, identHash); // calculate ident hash, because we don't need full identity
|
||||||
m_Destination->SendMsgTo (buf + offset, payloadLen, identHash, nonce);
|
m_Destination->SendMsgTo (buf + offset, payloadLen, identHash, nonce);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint(eLogWarning, "UDPServer: Session with from ", remotePort, " and to ", localPort, " ports already exists. But from differend address. Removed");
|
LogPrint(eLogWarning, "UDPServer: Session with from ", remotePort, " and to ", localPort, " ports already exists. But from different address. Removed");
|
||||||
m_Sessions.erase (it);
|
m_Sessions.erase (it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user