Crypto: Add optimized Camellia assembly implementation for x86_64 based on work by Jussi Kivilinna (https://github.com/jkivilin/supercop-blockciphers). This improve speed by a factor of 2.5 when AES-NI supported by CPU and by 30% if AES-NI not supported.

This commit is contained in:
Mounir IDRASSI 2017-06-20 17:43:35 +02:00
parent ee5c1784ea
commit 70097ecfe5
No known key found for this signature in database
GPG Key ID: DD0C382D5FCFB8FC
18 changed files with 2476 additions and 14 deletions

View File

@ -251,6 +251,9 @@ void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
else if (cipher == TWOFISH) {
twofish_encrypt_blocks(ks, data, data, (uint32) blockCount);
}
else if (cipher == CAMELLIA) {
camellia_encrypt_blocks(ks, data, data, (uint32) blockCount);
}
#endif
else if (cipher == GOST89) {
gost_encrypt(data, data, ks, (int)blockCount);
@ -351,6 +354,9 @@ void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
else if (cipher == TWOFISH) {
twofish_decrypt_blocks(ks, data, data, (uint32) blockCount);
}
else if (cipher == CAMELLIA) {
camellia_decrypt_blocks(ks, data, data, (uint32) blockCount);
}
#endif
else if (cipher == GOST89) {
gost_decrypt(data, data, ks, (int)blockCount);
@ -430,6 +436,7 @@ BOOL CipherSupportsIntraDataUnitParallelization (int cipher)
#endif
#if CRYPTOPP_BOOL_X64
|| (cipher == TWOFISH)
|| (cipher == CAMELLIA)
#endif
;
}

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
#define HEADER_Crypto_Camellia
#include "Common/Tcdefs.h"
#include "config.h"
#ifdef __cplusplus
extern "C"
@ -16,6 +17,11 @@ void camellia_set_key(const unsigned __int8 userKey[], unsigned __int8 *ks);
void camellia_encrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock, unsigned __int8 *ks);
void camellia_decrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock, unsigned __int8 *ks);
#if CRYPTOPP_BOOL_X64
void camellia_encrypt_blocks(unsigned __int8 *ks, const byte* in_blk, byte* out_blk, uint32 blockCount);
void camellia_decrypt_blocks(unsigned __int8 *ks, const byte* in_blk, byte* out_blk, uint32 blockCount);
#endif
#ifdef __cplusplus
}
#endif

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
.ifndef WINABI
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
.endif

339
src/Crypto/Camellia_x64.S Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
.ifndef WINABI
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
.endif

View File

@ -264,6 +264,26 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="Camellia_aesni_x64.S">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) &amp; yasm.exe -p gas -D WINABI -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) &amp; yasm.exe -p gas -D WINABI -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command>
</CustomBuild>
<CustomBuild Include="Camellia_x64.S">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) &amp; yasm.exe -p gas -D WINABI -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) &amp; yasm.exe -p gas -D WINABI -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -21,9 +21,6 @@
<ClCompile Include="Aestab.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Camellia.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cpu.c">
<Filter>Source Files</Filter>
</ClCompile>
@ -54,6 +51,9 @@
<ClCompile Include="SerpentFast_simd.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Camellia.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Aes.h">
@ -124,5 +124,11 @@
<CustomBuild Include="Twofish_x64.S">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="Camellia_x64.S">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="Camellia_aesni_x64.S">
<Filter>Source Files</Filter>
</CustomBuild>
</ItemGroup>
</Project>

View File

@ -22,3 +22,10 @@ TC_ASM_ERR_LOG = ..\Driver\build_errors_asm.log
"$(OBJ_PATH)\$(O)\Twofish_$(TC_ARCH).obj": Twofish_$(TC_ARCH).S
yasm.exe $(VC_YASMFLAGS) -o "$@" -l "$(OBJ_PATH)\$(O)\Twofish_$(TC_ARCH).lst" Twofish_$(TC_ARCH).S 2>$(TC_ASM_ERR_LOG)
"$(OBJ_PATH)\$(O)\Camellia_$(TC_ARCH).obj": Camellia_$(TC_ARCH).S
yasm.exe $(VC_YASMFLAGS) -o "$@" -l "$(OBJ_PATH)\$(O)\Camellia_$(TC_ARCH).lst" Camellia_$(TC_ARCH).S 2>$(TC_ASM_ERR_LOG)
"$(OBJ_PATH)\$(O)\Camellia_aesni_$(TC_ARCH).obj": Camellia_aesni_$(TC_ARCH).S
yasm.exe $(VC_YASMFLAGS) -o "$@" -l "$(OBJ_PATH)\$(O)\Camellia_aesni_$(TC_ARCH).lst" Camellia_aesni_$(TC_ARCH).S 2>$(TC_ASM_ERR_LOG)

View File

@ -7,7 +7,9 @@ NTTARGETFILES = \
"$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).obj" \
"$(OBJ_PATH)\$(O)\Aes_hw_cpu.obj" \
"$(OBJ_PATH)\$(O)\gost89_$(TC_ARCH).obj" \
"$(OBJ_PATH)\$(O)\Twofish_$(TC_ARCH).obj"
"$(OBJ_PATH)\$(O)\Twofish_$(TC_ARCH).obj" \
"$(OBJ_PATH)\$(O)\Camellia_$(TC_ARCH).obj" \
"$(OBJ_PATH)\$(O)\Camellia_aesni_$(TC_ARCH).obj"
SOURCES = \
Aes_$(TC_ARCH).asm \
@ -26,4 +28,7 @@ SOURCES = \
Streebog.c \
kuznyechik.c \
Whirlpool.c \
Camellia.c
Camellia.c \
Camellia_$(TC_ARCH).S \
Camellia_aesni_$(TC_ARCH).S

View File

@ -189,7 +189,7 @@ static int TrySSE2()
int g_x86DetectionDone = 0;
int g_hasISSE = 0, g_hasSSE2 = 0, g_hasSSSE3 = 0, g_hasMMX = 0, g_hasAESNI = 0, g_hasCLMUL = 0, g_isP4 = 0;
int g_hasAVX = 0, g_hasAVX2 = 0, g_hasBMI2 = 0, g_hasSSE42 = 0, g_hasSSE41 = 0;
int g_hasAVX = 0, g_hasAVX2 = 0, g_hasBMI2 = 0, g_hasSSE42 = 0, g_hasSSE41 = 0, g_isIntel = 0, g_isAMD = 0;
uint32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
VC_INLINE int IsIntel(const uint32 output[4])
@ -325,11 +325,13 @@ void DetectX86Features()
if (IsIntel(cpuid))
{
g_isIntel = 1;
g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
}
else if (IsAMD(cpuid))
{
g_isAMD = 1;
CpuId(0x80000005, cpuid);
g_cacheLineSize = GETBYTE(cpuid[2], 0);
}

View File

@ -196,6 +196,8 @@ extern int g_hasSSSE3;
extern int g_hasAESNI;
extern int g_hasCLMUL;
extern int g_isP4;
extern int g_isIntel;
extern int g_isAMD;
extern uint32 g_cacheLineSize;
void DetectX86Features(); // must be called at the start of the program/driver
int CpuId(uint32 input, uint32 *output);
@ -225,6 +227,8 @@ extern int g_hasMMX;
#define HasAESNI() g_hasAESNI
#define HasCLMUL() g_hasCLMUL
#define IsP4() g_isP4
#define IsCpuIntel() g_isIntel
#define IsCpuAMD() g_isAMD
#define GetCacheLineSize() g_cacheLineSize
#if defined(__cplusplus)

View File

@ -223,6 +223,9 @@ BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Cry
<None Include="..\Crypto\Aes_hw_cpu.asm" />
<None Include="..\Crypto\Aes_x64.asm" />
<None Include="..\Crypto\Aes_x86.asm" />
<None Include="..\Crypto\Camellia_aesni_x64.S" />
<None Include="..\Crypto\Camellia_x64.S" />
<None Include="..\Crypto\Twofish_x64.S" />
<None Include="BuildDriver.cmd" />
<None Include="Makefile" />
<None Include="Sources" />

View File

@ -143,6 +143,15 @@
<None Include="..\Crypto\Sources">
<Filter>Build Files\Crypto</Filter>
</None>
<None Include="..\Crypto\Camellia_aesni_x64.S">
<Filter>Source Files\Crypto</Filter>
</None>
<None Include="..\Crypto\Camellia_x64.S">
<Filter>Source Files\Crypto</Filter>
</None>
<None Include="..\Crypto\Twofish_x64.S">
<Filter>Source Files\Crypto</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Common\Apidrvr.h">

View File

@ -24,6 +24,23 @@
#endif
#include "Crypto/cpu.h"
extern "C" int IsAesHwCpuSupported ()
{
#ifdef TC_AES_HW_CPU
static bool state = false;
static bool stateValid = false;
if (!stateValid)
{
state = g_hasAESNI ? true : false;
stateValid = true;
}
return state && Cipher::IsHwSupportEnabled();
#else
return false;
#endif
}
namespace VeraCrypt
{
Cipher::Cipher () : Initialized (false)
@ -349,6 +366,39 @@ namespace VeraCrypt
{
camellia_set_key (key, ScheduledKey.Ptr());
}
void CipherCamellia::EncryptBlocks (byte *data, size_t blockCount) const
{
if (!Initialized)
throw NotInitialized (SRC_POS);
#if CRYPTOPP_BOOL_X64
camellia_encrypt_blocks ( ScheduledKey.Ptr(), data, data, blockCount);
#else
Cipher::EncryptBlocks (data, blockCount);
#endif
}
void CipherCamellia::DecryptBlocks (byte *data, size_t blockCount) const
{
if (!Initialized)
throw NotInitialized (SRC_POS);
#if CRYPTOPP_BOOL_X64
camellia_decrypt_blocks ( ScheduledKey.Ptr(), data, data, blockCount);
#else
Cipher::DecryptBlocks (data, blockCount);
#endif
}
bool CipherCamellia::IsHwSupportAvailable () const
{
#if CRYPTOPP_BOOL_X64
return true;
#else
return false;
#endif
}
// GOST89
void CipherGost89::Decrypt (byte *data) const

View File

@ -103,11 +103,11 @@ namespace VeraCrypt
TC_CIPHER (AES, 16, 32);
TC_CIPHER (Serpent, 16, 32);
TC_CIPHER (Twofish, 16, 32);
TC_CIPHER (Camellia, 16, 32);
#undef TC_CIPHER_ADD_METHODS
#define TC_CIPHER_ADD_METHODS
TC_CIPHER (Camellia, 16, 32);
TC_CIPHER (Gost89, 16, 32);
TC_CIPHER (Gost89StaticSBOX, 16, 32);
TC_CIPHER (Kuznyechik, 16, 32);

View File

@ -34,6 +34,8 @@ ifeq "$(PLATFORM)" "MacOSX"
OBJS += ../Crypto/Aes_hw_cpu.o
OBJS += ../Crypto/Aescrypt.o
OBJSEX += ../Crypto/Twofish_asm.oo
OBJSEX += ../Crypto/Camellia_asm.oo
OBJSEX += ../Crypto/Camellia_aesni_asm.oo
else ifeq "$(CPU_ARCH)" "x86"
OBJS += ../Crypto/Aes_x86.o
OBJS += ../Crypto/Aes_hw_cpu.o
@ -41,6 +43,8 @@ else ifeq "$(CPU_ARCH)" "x64"
OBJS += ../Crypto/Aes_x64.o
OBJS += ../Crypto/Aes_hw_cpu.o
OBJS += ../Crypto/Twofish_x64.o
OBJS += ../Crypto/Camellia_x64.o
OBJS += ../Crypto/Camellia_aesni_x64.o
else
OBJS += ../Crypto/Aescrypt.o
endif
@ -77,6 +81,12 @@ ifeq "$(PLATFORM)" "MacOSX"
../Crypto/Twofish_asm.oo: ../Crypto/Twofish_x64.S
@echo Assembling $(<F)
$(YASM) -p gas -f macho64 -o ../Crypto/Twofish_asm.oo ../Crypto/Twofish_x64.S
../Crypto/Camellia_asm.oo: ../Crypto/Camellia_x64.S
@echo Assembling $(<F)
$(YASM) -p gas -f macho64 -o ../Crypto/Camellia_asm.oo ../Crypto/Camellia_x64.S
../Crypto/Camellia_aesni_asm.oo: ../Crypto/Camellia_aesni_x64.S
@echo Assembling $(<F)
$(YASM) -p gas -f macho64 -o ../Crypto/Camellia_aesni_asm.oo ../Crypto/Camellia_aesni_x64.S
endif
include $(BUILD_INC)/Makefile.inc