Browse Source

Automate AES-NI and AVX detection on runtime, make it default on x86-based systems (#1578)

Rework CPU extensions detection code and build with AES-NI and AVX support by default
pull/1553/merge
R4SAS 4 years ago committed by GitHub
parent
commit
62cd9fffa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      .github/workflows/build-osx.yml
  2. 20
      .github/workflows/build-qt.yml
  3. 18
      .github/workflows/build.yml
  4. 3
      .gitignore
  5. 7
      Makefile
  6. 5
      Makefile.homebrew
  7. 21
      Makefile.linux
  8. 17
      Makefile.mingw
  9. 8
      Makefile.osx
  10. 16
      build/CMakeLists.txt
  11. 29
      build/build_mingw.cmd
  12. 13
      build/win_installer.iss
  13. 9
      contrib/i2pd.conf
  14. 5
      daemon/Daemon.cpp
  15. 2
      debian/compat
  16. 0
      debian/patches/01-fix-1210.patch
  17. 15
      debian/patches/01-tune-build-opts.patch
  18. 3
      debian/patches/series
  19. 31
      libi2pd/CPU.cpp
  20. 2
      libi2pd/CPU.h
  21. 18
      libi2pd/Config.cpp
  22. 15
      libi2pd/Crypto.cpp
  23. 5
      libi2pd/Crypto.h
  24. 2
      libi2pd/Identity.cpp
  25. 5
      libi2pd/api.cpp
  26. 16
      qt/i2pd_qt/i2pd_qt.pro

20
.github/workflows/build-osx.yml

@ -0,0 +1,20 @@
name: Build on OSX
on: [push, pull_request]
jobs:
build:
name: With USE_UPNP=${{ matrix.with_upnp }}
runs-on: macOS-latest
strategy:
fail-fast: true
matrix:
with_upnp: ['yes', 'no']
steps:
- uses: actions/checkout@v2
- name: install packages
run: |
brew update
brew install boost miniupnpc openssl@1.1
- name: build application
run: make HOMEBREW=1 USE_UPNP=${{ matrix.with_upnp }} PREFIX=$GITHUB_WORKSPACE/output -j3

20
.github/workflows/build-qt.yml

@ -1,20 +0,0 @@
name: Build on Ubuntu
on: [push, pull_request]
jobs:
build:
name: With QT GUI
runs-on: ubuntu-16.04
steps:
- uses: actions/checkout@v2
- name: install packages
run: |
sudo add-apt-repository ppa:mhier/libboost-latest
sudo apt-get update
sudo apt-get install build-essential qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
- name: build application
run: |
cd qt/i2pd_qt
qmake
make -j3

18
.github/workflows/build.yml

@ -18,4 +18,20 @@ jobs:
sudo apt-get update sudo apt-get update
sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
- name: build application - name: build application
run: make USE_AVX=no USE_AESNI=no USE_UPNP=${{ matrix.with_upnp }} -j3 run: make USE_UPNP=${{ matrix.with_upnp }} -j3
build_qt:
name: With QT GUI
runs-on: ubuntu-16.04
steps:
- uses: actions/checkout@v2
- name: install packages
run: |
sudo add-apt-repository ppa:mhier/libboost-latest
sudo apt-get update
sudo apt-get install build-essential qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev
- name: build application
run: |
cd qt/i2pd_qt
qmake
make -j3

3
.gitignore vendored

@ -3,11 +3,12 @@
router.info router.info
router.keys router.keys
i2p i2p
libi2pd.so
netDb netDb
/i2pd /i2pd
/libi2pd.a /libi2pd.a
/libi2pdclient.a /libi2pdclient.a
/libi2pd.so
/libi2pdclient.so
*.exe *.exe

7
Makefile

@ -14,7 +14,6 @@ DAEMON_SRC_DIR := daemon
include filelist.mk include filelist.mk
USE_AESNI := yes USE_AESNI := yes
USE_AVX := yes
USE_STATIC := no USE_STATIC := no
USE_MESHNET := no USE_MESHNET := no
USE_UPNP := no USE_UPNP := no
@ -77,7 +76,7 @@ deps: mk_obj_dir
@sed -i -e '/\.o:/ s/^/obj\//' $(DEPS) @sed -i -e '/\.o:/ s/^/obj\//' $(DEPS)
obj/%.o: %.cpp obj/%.o: %.cpp
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(CPU_FLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $<
# '-' is 'ignore if missing' on first run # '-' is 'ignore if missing' on first run
-include $(DEPS) -include $(DEPS)
@ -88,11 +87,11 @@ $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
$(SHLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) $(SHLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
ifneq ($(USE_STATIC),yes) ifneq ($(USE_STATIC),yes)
$(CXX) $(LDFLAGS) $(LDLIBS) -shared -o $@ $^ $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
endif endif
$(SHLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) $(SHLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
$(CXX) $(LDFLAGS) $(LDLIBS) -shared -o $@ $^ $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB)
$(ARLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) $(ARLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
$(AR) -r $@ $^ $(AR) -r $@ $^

5
Makefile.homebrew

@ -35,10 +35,7 @@ endif
# Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2 # Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2
# Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic # Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic
ifeq ($(USE_AESNI),yes) ifeq ($(USE_AESNI),yes)
CXXFLAGS += -maes CXXFLAGS += -D__AES__ -maes
endif
ifeq ($(USE_AVX),1)
CXXFLAGS += -mavx
endif endif
install: all install: all

21
Makefile.linux

@ -1,5 +1,5 @@
# set defaults instead redefine # set defaults instead redefine
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation -Wno-psabi CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi
LDFLAGS ?= ${LD_DEBUG} LDFLAGS ?= ${LD_DEBUG}
## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time ## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time
@ -49,7 +49,7 @@ endif
# UPNP Support (miniupnpc 1.5 and higher) # UPNP Support (miniupnpc 1.5 and higher)
ifeq ($(USE_UPNP),yes) ifeq ($(USE_UPNP),yes)
CXXFLAGS += -DUSE_UPNP NEEDED_CXXFLAGS += -DUSE_UPNP
ifeq ($(USE_STATIC),yes) ifeq ($(USE_STATIC),yes)
LDLIBS += $(LIBDIR)/libminiupnpc.a LDLIBS += $(LIBDIR)/libminiupnpc.a
else else
@ -58,20 +58,7 @@ endif
endif endif
ifeq ($(USE_AESNI),yes) ifeq ($(USE_AESNI),yes)
#check if AES-NI is supported by CPU ifeq (, $(findstring arm, $(SYS))$(findstring aarch64, $(SYS))) # no arm and aarch64 in dumpmachine
ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0) NEEDED_CXXFLAGS += -D__AES__ -maes
machine := $(shell uname -m)
ifeq ($(machine), aarch64)
CXXFLAGS += -DARM64AES
else
CPU_FLAGS += -maes
endif
endif
endif
ifeq ($(USE_AVX),yes)
#check if AVX supported by CPU
ifneq ($(shell $(GREP) -c avx /proc/cpuinfo),0)
CPU_FLAGS += -mavx
endif endif
endif endif

17
Makefile.mingw

@ -1,7 +1,7 @@
USE_WIN32_APP=yes USE_WIN32_APP=yes
CXX = g++ CXX = g++
WINDRES = windres WINDRES = windres
CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN -fPIC -msse
INCFLAGS = -Idaemon -I. INCFLAGS = -Idaemon -I.
LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++ LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++
@ -42,25 +42,18 @@ LDLIBS += \
-lpthread -lpthread
ifeq ($(USE_WIN32_APP), yes) ifeq ($(USE_WIN32_APP), yes)
CXXFLAGS += -DWIN32_APP NEEDED_CXXFLAGS += -DWIN32_APP
LDFLAGS += -mwindows LDFLAGS += -mwindows
DAEMON_RC += Win32/Resource.rc DAEMON_RC += Win32/Resource.rc
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif endif
ifeq ($(USE_WINXP_FLAGS), yes) ifeq ($(USE_WINXP_FLAGS), yes)
CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501
endif endif
# don't change following line to ifeq ($(USE_AESNI),yes) !!! ifeq ($(USE_AESNI),yes)
ifeq ($(USE_AESNI),1) NEEDED_CXXFLAGS += -D__AES__ -maes
CPU_FLAGS += -maes
else
CPU_FLAGS += -msse
endif
ifeq ($(USE_AVX),1)
CPU_FLAGS += -mavx
endif endif
ifeq ($(USE_ASLR),yes) ifeq ($(USE_ASLR),yes)

8
Makefile.osx vendored

@ -22,12 +22,8 @@ ifeq ($(USE_UPNP),yes)
endif endif
endif endif
ifeq ($(USE_AESNI),1) ifeq ($(USE_AESNI),yes)
CXXFLAGS += -maes CXXFLAGS += -D__AES__ -maes
else else
CXXFLAGS += -msse CXXFLAGS += -msse
endif endif
ifeq ($(USE_AVX),1)
CXXFLAGS += -mavx
endif

16
build/CMakeLists.txt

@ -11,9 +11,8 @@ if(WIN32 OR MSVC OR MSYS OR MINGW)
message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.") message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.")
endif() endif()
# configurale options # configurable options
option(WITH_AESNI "Use AES-NI instructions set" OFF) option(WITH_AESNI "Use AES-NI instructions set" ON)
option(WITH_AVX "Use AVX instructions" OFF)
option(WITH_HARDENING "Use hardening compiler flags" OFF) option(WITH_HARDENING "Use hardening compiler flags" OFF)
option(WITH_LIBRARY "Build library" ON) option(WITH_LIBRARY "Build library" ON)
option(WITH_BINARY "Build binary" ON) option(WITH_BINARY "Build binary" ON)
@ -189,13 +188,11 @@ if(UNIX)
endif() endif()
endif() endif()
if(WITH_AESNI) # Note: AES-NI and AVX is available on x86-based CPU's.
# Here also ARM64 implementation, but currently we don't support it.
if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386"))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
add_definitions(-DAESNI) add_definitions(-D__AES__)
endif()
if(WITH_AVX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
endif() endif()
if(WITH_ADDRSANITIZER) if(WITH_ADDRSANITIZER)
@ -309,7 +306,6 @@ message(STATUS "Architecture : ${ARCHITECTURE}")
message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}") message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Options:") message(STATUS "Options:")
message(STATUS " AESNI : ${WITH_AESNI}") message(STATUS " AESNI : ${WITH_AESNI}")
message(STATUS " AVX : ${WITH_AVX}")
message(STATUS " HARDENING : ${WITH_HARDENING}") message(STATUS " HARDENING : ${WITH_HARDENING}")
message(STATUS " LIBRARY : ${WITH_LIBRARY}") message(STATUS " LIBRARY : ${WITH_LIBRARY}")
message(STATUS " BINARY : ${WITH_BINARY}") message(STATUS " BINARY : ${WITH_BINARY}")

29
build/build_mingw.cmd

@ -30,10 +30,10 @@ REM we must work in root of repo
cd .. cd ..
REM deleting old log files REM deleting old log files
del /S build_*.log >> nul del /S build_*.log >> nul 2>&1
echo Receiving latest commit and cleaning up... echo Receiving latest commit and cleaning up...
%xSH% "git pull && make clean" > build/build_git.log 2>&1 %xSH% "git checkout contrib/* && git pull && make clean" > build/build.log 2>&1
echo. echo.
REM set to variable current commit hash REM set to variable current commit hash
@ -43,16 +43,17 @@ FOR /F "usebackq" %%a IN (`%xSH% 'git describe --tags'`) DO (
%xSH% "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul %xSH% "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul
REM converting configuration files to DOS format (usable in default notepad)
%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/*" > build/build.log 2>&1
REM starting building REM starting building
set MSYSTEM=MINGW32 set MSYSTEM=MINGW32
set bitness=32 set bitness=32
call :BUILDING call :BUILDING
echo.
set MSYSTEM=MINGW64 set MSYSTEM=MINGW64
set bitness=64 set bitness=64
call :BUILDING call :BUILDING
echo.
REM building for WinXP REM building for WinXP
set "WD=C:\msys64-xp\usr\bin\" set "WD=C:\msys64-xp\usr\bin\"
@ -62,7 +63,10 @@ set "xSH=%WD%bash -lc"
call :BUILDING_XP call :BUILDING_XP
echo. echo.
del README.txt >> nul REM compile installer
C:\PROGRA~2\INNOSE~1\ISCC.exe build\win_installer.iss
del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul
echo Build complete... echo Build complete...
pause pause
@ -70,20 +74,13 @@ exit /b 0
:BUILDING :BUILDING
%xSH% "make clean" >> nul %xSH% "make clean" >> nul
echo Building i2pd %tag% for win%bitness%: echo Building i2pd %tag% for win%bitness%
echo Build AVX+AESNI... %xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build/build_win%bitness%_%tag%.log 2>&1
%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_aesni_%tag%.log 2>&1
echo Build AVX...
%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_%tag%.log 2>&1
echo Build AESNI...
%xSH% "make DEBUG=no USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_aesni_%tag%.log 2>&1
echo Build without extensions...
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build/build_win%bitness%_%tag%.log 2>&1
goto EOF goto EOF
:BUILDING_XP :BUILDING_XP
%xSH% "make clean" >> nul %xSH% "make clean" >> nul
echo Building i2pd %tag% for winxp... echo Building i2pd %tag% for winxp
%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build/build_winxp_%tag%.log 2>&1 %xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build/build_winxp_%tag%.log 2>&1
:EOF :EOF

13
Win32/installer.iss → build/win_installer.iss

@ -1,6 +1,7 @@
#define I2Pd_AppName "i2pd" #define I2Pd_AppName "i2pd"
#define I2Pd_ver "2.34.0"
#define I2Pd_Publisher "PurpleI2P" #define I2Pd_Publisher "PurpleI2P"
; Get application version from compiled binary
#define I2Pd_ver GetFileVersionString(AddBackslash(SourcePath) + "..\i2pd_x64.exe")
[Setup] [Setup]
AppName={#I2Pd_AppName} AppName={#I2Pd_AppName}
@ -10,9 +11,9 @@ DefaultDirName={pf}\I2Pd
DefaultGroupName=I2Pd DefaultGroupName=I2Pd
UninstallDisplayIcon={app}\I2Pd.exe UninstallDisplayIcon={app}\I2Pd.exe
OutputDir=. OutputDir=.
LicenseFile=../LICENSE LicenseFile=..\LICENSE
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver} OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver}
SetupIconFile=mask.ico SetupIconFile=..\Win32\mask.ico
InternalCompressLevel=ultra64 InternalCompressLevel=ultra64
Compression=lzma/ultra64 Compression=lzma/ultra64
SolidCompression=true SolidCompression=true
@ -23,10 +24,12 @@ AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
AppPublisherURL=http://i2pd.website/ AppPublisherURL=http://i2pd.website/
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases
CloseApplications=yes
[Files] [Files]
Source: ..\i2pd_x86.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64 Source: ..\i2pd_x32.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64; MinVersion: 6.0
Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64 Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64; MinVersion: 6.0
Source: ..\i2pd_xp.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64; OnlyBelowVersion: 6.0
Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist
Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist

9
contrib/i2pd.conf

@ -229,3 +229,12 @@ verify = true
[persist] [persist]
## Save peer profiles on disk (default: true) ## Save peer profiles on disk (default: true)
# profiles = true # profiles = true
[cpuext]
## Use CPU AES-NI instructions set when work with cryptography when available (default: true)
# aesni = true
## Use CPU AVX instructions set when work with cryptography when available (default: true)
# avx = true
## Force usage of CPU instructions set, even if they not found
## DO NOT TOUCH that option if you really don't know what are you doing!
# force = false

5
daemon/Daemon.cpp

@ -128,7 +128,10 @@ namespace i2p
LogPrint(eLogDebug, "FS: data directory: ", datadir); LogPrint(eLogDebug, "FS: data directory: ", datadir);
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
i2p::crypto::InitCrypto (precomputation); bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
bool avx; i2p::config::GetOption("cpuext.avx", avx);
bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
int netID; i2p::config::GetOption("netid", netID); int netID; i2p::config::GetOption("netid", netID);
i2p::context.SetNetID (netID); i2p::context.SetNetID (netID);

2
debian/compat vendored

@ -1 +1 @@
9 10

0
debian/patches/02-fix-1210.patch → debian/patches/01-fix-1210.patch vendored

15
debian/patches/01-tune-build-opts.patch vendored

@ -1,15 +0,0 @@
Index: i2pd/Makefile
===================================================================
--- i2pd.orig/Makefile
+++ i2pd/Makefile
@@ -13,8 +13,8 @@ DAEMON_SRC_DIR := daemon
include filelist.mk
-USE_AESNI := yes
-USE_AVX := yes
+USE_AESNI := no
+USE_AVX := no
USE_STATIC := no
USE_MESHNET := no
USE_UPNP := no

3
debian/patches/series vendored

@ -1,2 +1 @@
01-tune-build-opts.patch 01-fix-1210.patch
02-fix-1210.patch

31
libi2pd/CPU.cpp

@ -27,37 +27,24 @@ namespace cpu
bool aesni = false; bool aesni = false;
bool avx = false; bool avx = false;
void Detect() void Detect(bool AesSwitch, bool AvxSwitch, bool force)
{ {
#if defined(__AES__) || defined(__AVX__)
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
int info[4]; int info[4];
__cpuid(0, info[0], info[1], info[2], info[3]); __cpuid(0, info[0], info[1], info[2], info[3]);
if (info[0] >= 0x00000001) { if (info[0] >= 0x00000001) {
__cpuid(0x00000001, info[0], info[1], info[2], info[3]); __cpuid(0x00000001, info[0], info[1], info[2], info[3]);
#ifdef __AES__ if ((info[2] & bit_AES && AesSwitch) || (AesSwitch && force)) {
aesni = info[2] & bit_AES; // AESNI aesni = true;
#endif // __AES__
#ifdef __AVX__
avx = info[2] & bit_AVX; // AVX
#endif // __AVX__
} }
#endif // defined(__x86_64__) || defined(__i386__) if ((info[2] & bit_AVX && AvxSwitch) || (AvxSwitch && force)) {
avx = true;
#ifdef __AES__
if(aesni)
{
LogPrint(eLogInfo, "AESNI enabled");
} }
#endif // __AES__
#ifdef __AVX__
if(avx)
{
LogPrint(eLogInfo, "AVX enabled");
} }
#endif // __AVX__ #endif // defined(__x86_64__) || defined(__i386__)
#endif // defined(__AES__) || defined(__AVX__)
LogPrint(eLogInfo, "AESNI ", (aesni ? "enabled" : "disabled"));
LogPrint(eLogInfo, "AVX ", (avx ? "enabled" : "disabled"));
} }
} }
} }

2
libi2pd/CPU.h

@ -16,7 +16,7 @@ namespace cpu
extern bool aesni; extern bool aesni;
extern bool avx; extern bool avx;
void Detect(); void Detect(bool AesSwitch, bool AvxSwitch, bool force);
} }
} }

18
libi2pd/Config.cpp

@ -47,11 +47,11 @@ namespace config {
("ifname", value<std::string>()->default_value(""), "Network interface to bind to") ("ifname", value<std::string>()->default_value(""), "Network interface to bind to")
("ifname4", value<std::string>()->default_value(""), "Network interface to bind to for ipv4") ("ifname4", value<std::string>()->default_value(""), "Network interface to bind to for ipv4")
("ifname6", value<std::string>()->default_value(""), "Network interface to bind to for ipv6") ("ifname6", value<std::string>()->default_value(""), "Network interface to bind to for ipv6")
("nat", value<bool>()->default_value(true), "Should we assume we are behind NAT? (default: enabled)") ("nat", bool_switch()->default_value(true), "Should we assume we are behind NAT? (default: enabled)")
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)") ("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
("ipv4", value<bool>()->default_value(true), "Enable communication through ipv4 (default: enabled)") ("ipv4", bool_switch()->default_value(true), "Enable communication through ipv4 (default: enabled)")
("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)") ("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)")
("reservedrange", value<bool>()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)") ("reservedrange", bool_switch()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)")
("netid", value<int>()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2") ("netid", value<int>()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2")
("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)") ("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)")
("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)") ("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)")
@ -59,8 +59,8 @@ namespace config {
("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)") ("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)")
("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)") ("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)")
("share", value<int>()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") ("share", value<int>()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)")
("ntcp", value<bool>()->default_value(false), "Ignored. Always false") ("ntcp", bool_switch()->default_value(false), "Ignored. Always false")
("ssu", value<bool>()->default_value(true), "Enable SSU transport (default: enabled)") ("ssu", bool_switch()->default_value(true), "Enable SSU transport (default: enabled)")
("ntcpproxy", value<std::string>()->default_value(""), "Ignored") ("ntcpproxy", value<std::string>()->default_value(""), "Ignored")
#ifdef _WIN32 #ifdef _WIN32
("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')") ("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
@ -266,6 +266,13 @@ namespace config {
("persist.addressbook", value<bool>()->default_value(true), "Persist full addresses (default: true)") ("persist.addressbook", value<bool>()->default_value(true), "Persist full addresses (default: true)")
; ;
options_description cpuext("CPU encryption extensions options");
cpuext.add_options()
("cpuext.aesni", bool_switch()->default_value(true), "Use auto detection for AESNI CPU extensions. If false, AESNI will be not used")
("cpuext.avx", bool_switch()->default_value(true), "Use auto detection for AVX CPU extensions. If false, AVX will be not used")
("cpuext.force", bool_switch()->default_value(false), "Force usage of CPU extensions. Useful when cpuinfo is not available on virtual machines")
;
m_OptionsDesc m_OptionsDesc
.add(general) .add(general)
.add(limits) .add(limits)
@ -286,6 +293,7 @@ namespace config {
.add(ntcp2) .add(ntcp2)
.add(nettime) .add(nettime)
.add(persist) .add(persist)
.add(cpuext)
; ;
} }

15
libi2pd/Crypto.cpp

@ -522,7 +522,7 @@ namespace crypto
bn2buf (y, encrypted + len, len); bn2buf (y, encrypted + len, len);
RAND_bytes (encrypted + 2*len, 256 - 2*len); RAND_bytes (encrypted + 2*len, 256 - 2*len);
} }
// ecryption key and iv // encryption key and iv
EC_POINT_mul (curve, p, nullptr, key, k, ctx); EC_POINT_mul (curve, p, nullptr, key, k, ctx);
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
uint8_t keyBuf[64], iv[64], shared[32]; uint8_t keyBuf[64], iv[64], shared[32];
@ -638,7 +638,7 @@ namespace crypto
{ {
uint64_t buf[256]; uint64_t buf[256];
uint64_t hash[12]; // 96 bytes uint64_t hash[12]; // 96 bytes
#ifdef __AVX__ #if defined(__x86_64__) || defined(__i386__)
if(i2p::cpu::avx) if(i2p::cpu::avx)
{ {
__asm__ __asm__
@ -696,13 +696,6 @@ namespace crypto
// AES // AES
#ifdef __AES__ #ifdef __AES__
#ifdef ARM64AES
void init_aesenc(void){
// TODO: Implementation
}
#endif
#define KeyExpansion256(round0,round1) \ #define KeyExpansion256(round0,round1) \
"pshufd $0xff, %%xmm2, %%xmm2 \n" \ "pshufd $0xff, %%xmm2, %%xmm2 \n" \
"movaps %%xmm1, %%xmm4 \n" \ "movaps %%xmm1, %%xmm4 \n" \
@ -1352,9 +1345,9 @@ namespace crypto
} }
}*/ }*/
void InitCrypto (bool precomputation) void InitCrypto (bool precomputation, bool aesni, bool avx, bool force)
{ {
i2p::cpu::Detect (); i2p::cpu::Detect (aesni, avx, force);
#if LEGACY_OPENSSL #if LEGACY_OPENSSL
SSL_library_init (); SSL_library_init ();
#endif #endif

5
libi2pd/Crypto.h

@ -169,9 +169,6 @@ namespace crypto
#ifdef __AES__ #ifdef __AES__
#ifdef ARM64AES
void init_aesenc(void) __attribute__((constructor));
#endif
class ECBCryptoAESNI class ECBCryptoAESNI
{ {
public: public:
@ -322,7 +319,7 @@ namespace crypto
}; };
// init and terminate // init and terminate
void InitCrypto (bool precomputation); void InitCrypto (bool precomputation, bool aesni, bool avx, bool force);
void TerminateCrypto (); void TerminateCrypto ();
} }
} }

2
libi2pd/Identity.cpp

@ -828,7 +828,7 @@ namespace data
XORMetric operator^(const IdentHash& key1, const IdentHash& key2) XORMetric operator^(const IdentHash& key1, const IdentHash& key2)
{ {
XORMetric m; XORMetric m;
#ifdef __AVX__ #if defined(__x86_64__) || defined(__i386__)
if(i2p::cpu::avx) if(i2p::cpu::avx)
{ {
__asm__ __asm__

5
libi2pd/api.cpp

@ -37,7 +37,10 @@ namespace api
i2p::fs::Init(); i2p::fs::Init();
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
i2p::crypto::InitCrypto (precomputation); bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
bool avx; i2p::config::GetOption("cpuext.avx", avx);
bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
int netID; i2p::config::GetOption("netid", netID); int netID; i2p::config::GetOption("netid", netID);
i2p::context.SetNetID (netID); i2p::context.SetNetID (netID);

16
qt/i2pd_qt/i2pd_qt.pro

@ -4,14 +4,16 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = i2pd_qt TARGET = i2pd_qt
TEMPLATE = app TEMPLATE = app
QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized -Wno-deprecated-copy
CONFIG += strict_c++ c++11 CONFIG += strict_c++ c++11
CONFIG(debug, debug|release) { CONFIG(debug, debug|release) {
message(Debug build) message(Debug build)
DEFINES += DEBUG_WITH_DEFAULT_LOGGING DEFINES += DEBUG_WITH_DEFAULT_LOGGING
I2PDMAKE += DEBUG=yes
} else { } else {
message(Release build) message(Release build)
I2PDMAKE += DEBUG=no
} }
SOURCES += DaemonQT.cpp mainwindow.cpp \ SOURCES += DaemonQT.cpp mainwindow.cpp \
@ -73,19 +75,19 @@ FORMS += mainwindow.ui \
LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz
libi2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_AVX=no USE_AESNI=no USE_UPNP=yes DEBUG=no api libi2pd.commands = @echo Building i2pd libraries
libi2pd.target = $$PWD/../../libi2pd.a libi2pd.target = $$PWD/../../libi2pd.a
libi2pd.depends = FORCE libi2pd.depends = i2pd FORCE
libi2pdclient.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_AVX=no USE_AESNI=no USE_UPNP=yes DEBUG=no api_client i2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE api_client
libi2pdclient.target = $$PWD/../../libi2pdclient.a i2pd.target += $$PWD/../../libi2pdclient.a
libi2pdclient.depends = FORCE i2pd.depends = FORCE
cleani2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean cleani2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean
cleani2pd.depends = clean cleani2pd.depends = clean
PRE_TARGETDEPS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a PRE_TARGETDEPS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a
QMAKE_EXTRA_TARGETS += cleani2pd libi2pd libi2pdclient QMAKE_EXTRA_TARGETS += cleani2pd i2pd libi2pd
CLEAN_DEPS += cleani2pd CLEAN_DEPS += cleani2pd

Loading…
Cancel
Save