mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 13:27:17 +01:00
always use openssl for AES
Some checks are pending
Build Debian packages / ${{ matrix.dist }} (bookworm) (push) Waiting to run
Build Debian packages / ${{ matrix.dist }} (bullseye) (push) Waiting to run
Build Debian packages / ${{ matrix.dist }} (buster) (push) Waiting to run
Build on FreeBSD / with UPnP (push) Waiting to run
Build on OSX / With USE_UPNP=${{ matrix.with_upnp }} (no) (push) Waiting to run
Build on OSX / With USE_UPNP=${{ matrix.with_upnp }} (yes) (push) Waiting to run
Build on Windows / ${{ matrix.arch }} (clang-x86_64, x64-clang, clang, CLANG64) (push) Waiting to run
Build on Windows / ${{ matrix.arch }} (i686, x86, gcc, MINGW32) (push) Waiting to run
Build on Windows / ${{ matrix.arch }} (ucrt-x86_64, x64-ucrt, gcc, UCRT64) (push) Waiting to run
Build on Windows / ${{ matrix.arch }} (x86_64, x64, gcc, MINGW64) (push) Waiting to run
Build on Windows / CMake ${{ matrix.arch }} (clang-x86_64, x64-clang, clang, CLANG64) (push) Waiting to run
Build on Windows / CMake ${{ matrix.arch }} (i686, x86, gcc, MINGW32) (push) Waiting to run
Build on Windows / CMake ${{ matrix.arch }} (ucrt-x86_64, x64-ucrt, gcc, UCRT64) (push) Waiting to run
Build on Windows / CMake ${{ matrix.arch }} (x86_64, x64, gcc, MINGW64) (push) Waiting to run
Build on Windows / XP (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=${{ matrix.with_upnp }} (no) (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=${{ matrix.with_upnp }} (yes) (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=${{ matrix.with_upnp }} (OFF) (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=${{ matrix.with_upnp }} (ON) (push) Waiting to run
Build containers / Building container for ${{ matrix.platform }} (i386, linux/386) (push) Waiting to run
Build containers / Pushing merged manifest (push) Blocked by required conditions
Build containers / Building container for ${{ matrix.platform }} (amd64, linux/amd64) (push) Waiting to run
Build containers / Building container for ${{ matrix.platform }} (arm64, linux/arm64) (push) Waiting to run
Build containers / Building container for ${{ matrix.platform }} (armv7, linux/arm/v7) (push) Waiting to run
Some checks are pending
Build Debian packages / ${{ matrix.dist }} (bookworm) (push) Waiting to run
Build Debian packages / ${{ matrix.dist }} (bullseye) (push) Waiting to run
Build Debian packages / ${{ matrix.dist }} (buster) (push) Waiting to run
Build on FreeBSD / with UPnP (push) Waiting to run
Build on OSX / With USE_UPNP=${{ matrix.with_upnp }} (no) (push) Waiting to run
Build on OSX / With USE_UPNP=${{ matrix.with_upnp }} (yes) (push) Waiting to run
Build on Windows / ${{ matrix.arch }} (clang-x86_64, x64-clang, clang, CLANG64) (push) Waiting to run
Build on Windows / ${{ matrix.arch }} (i686, x86, gcc, MINGW32) (push) Waiting to run
Build on Windows / ${{ matrix.arch }} (ucrt-x86_64, x64-ucrt, gcc, UCRT64) (push) Waiting to run
Build on Windows / ${{ matrix.arch }} (x86_64, x64, gcc, MINGW64) (push) Waiting to run
Build on Windows / CMake ${{ matrix.arch }} (clang-x86_64, x64-clang, clang, CLANG64) (push) Waiting to run
Build on Windows / CMake ${{ matrix.arch }} (i686, x86, gcc, MINGW32) (push) Waiting to run
Build on Windows / CMake ${{ matrix.arch }} (ucrt-x86_64, x64-ucrt, gcc, UCRT64) (push) Waiting to run
Build on Windows / CMake ${{ matrix.arch }} (x86_64, x64, gcc, MINGW64) (push) Waiting to run
Build on Windows / XP (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=${{ matrix.with_upnp }} (no) (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=${{ matrix.with_upnp }} (yes) (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=${{ matrix.with_upnp }} (OFF) (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=${{ matrix.with_upnp }} (ON) (push) Waiting to run
Build containers / Building container for ${{ matrix.platform }} (i386, linux/386) (push) Waiting to run
Build containers / Pushing merged manifest (push) Blocked by required conditions
Build containers / Building container for ${{ matrix.platform }} (amd64, linux/amd64) (push) Waiting to run
Build containers / Building container for ${{ matrix.platform }} (arm64, linux/arm64) (push) Waiting to run
Build containers / Building container for ${{ matrix.platform }} (armv7, linux/arm/v7) (push) Waiting to run
This commit is contained in:
parent
097813a6ca
commit
786da057f2
|
@ -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
|
||||||
|
|
|
@ -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__
|
|
||||||
(
|
void ECBDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
{
|
||||||
"1: \n"
|
EVP_DecryptInit_ex (m_Ctx, EVP_aes_256_ecb(), NULL, m_Key, NULL);
|
||||||
"movups (%[in]), %%xmm0 \n"
|
EVP_CIPHER_CTX_set_padding (m_Ctx, 0);
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
int len;
|
||||||
EncryptAES256(sched)
|
EVP_DecryptUpdate (m_Ctx, out, &len, in, 16);
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
EVP_DecryptFinal_ex (m_Ctx, out + len, &len);
|
||||||
"movups %%xmm0, (%[out]) \n"
|
}
|
||||||
"add $16, %[in] \n"
|
|
||||||
"add $16, %[out] \n"
|
|
||||||
"dec %[num] \n"
|
CBCEncryption::CBCEncryption ()
|
||||||
"jnz 1b \n"
|
{
|
||||||
"movups %%xmm1, (%[iv]) \n"
|
m_Ctx = EVP_CIPHER_CTX_new ();
|
||||||
:
|
//memset ((uint8_t *)m_LastBlock, 0, 16);
|
||||||
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
}
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
|
||||||
: "%xmm0", "%xmm1", "cc", "memory"
|
CBCEncryption::~CBCEncryption ()
|
||||||
);
|
{
|
||||||
}
|
if (m_Ctx)
|
||||||
else
|
EVP_CIPHER_CTX_free (m_Ctx);
|
||||||
#endif
|
|
||||||
{
|
|
||||||
for (int i = 0; i < numBlocks; i++)
|
|
||||||
{
|
|
||||||
*m_LastBlock.GetChipherBlock () ^= in[i];
|
|
||||||
m_ECBEncryption.Encrypt (m_LastBlock.GetChipherBlock (), m_LastBlock.GetChipherBlock ());
|
|
||||||
out[i] = *m_LastBlock.GetChipherBlock ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
m_LayerEncryption.SetIV (out);
|
||||||
{
|
m_LayerEncryption.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
||||||
__asm__
|
m_IVEncryption.Encrypt (out, out); // double iv
|
||||||
(
|
|
||||||
// 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.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
|
||||||
m_IVEncryption.Encrypt ((ChipherBlock *)out, (ChipherBlock *)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)
|
m_LayerDecryption.SetIV (out);
|
||||||
{
|
m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
||||||
__asm__
|
m_IVDecryption.Decrypt (out, out); // double iv
|
||||||
(
|
|
||||||
// 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.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
|
||||||
m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)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);
|
||||||
|
|
129
libi2pd/Crypto.h
129
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
|
||||||
|
|
|
@ -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 ())
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue