diff options
Diffstat (limited to 'src/Crypto')
45 files changed, 3262 insertions, 2018 deletions
diff --git a/src/Crypto/Aes.h b/src/Crypto/Aes.h index e12c6fc8..db1bed27 100644 --- a/src/Crypto/Aes.h +++ b/src/Crypto/Aes.h @@ -35,6 +35,11 @@ #include "Common/Tcdefs.h" +#ifdef WOLFCRYPT_BACKEND + #include <wolfssl/options.h> + #include <wolfssl/wolfcrypt/aes.h> +#endif + #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 @@ -93,11 +98,19 @@ typedef union typedef struct { uint_32t ks[KS_LENGTH]; aes_inf inf; +#ifdef WOLFCRYPT_BACKEND + XtsAes wc_enc_xts; + Aes wc_enc_aes; +#endif } aes_encrypt_ctx; typedef struct { uint_32t ks[KS_LENGTH]; aes_inf inf; +#ifdef WOLFCRYPT_BACKEND + XtsAes wc_dec_xts; + Aes wc_dec_aes; +#endif } aes_decrypt_ctx; /* This routine must be called before first use if non-static */ @@ -152,6 +165,13 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de #endif +#ifdef WOLFCRYPT_BACKEND +AES_RETURN xts_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); +AES_RETURN xts_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); +AES_RETURN xts_encrypt(const unsigned char *in, unsigned char *out, word64 length, word64 sector, const aes_encrypt_ctx cx[1]); +AES_RETURN xts_decrypt(const unsigned char *in, unsigned char *out, word64 length, word64 sector, const aes_decrypt_ctx cx[1]); +#endif + #if defined(AES_MODES) /* Multiple calls to the following subroutines for multiple block */ diff --git a/src/Crypto/Aes_hw_cpu.h b/src/Crypto/Aes_hw_cpu.h index 8977cbc0..b294e2ee 100644 --- a/src/Crypto/Aes_hw_cpu.h +++ b/src/Crypto/Aes_hw_cpu.h @@ -20,7 +20,9 @@ extern "C" { #endif +#if defined (TC_WINDOWS_BOOT) byte is_aes_hw_cpu_supported (); +#endif void aes_hw_cpu_enable_sse (); void aes_hw_cpu_decrypt (const byte *ks, byte *data); void aes_hw_cpu_decrypt_32_blocks (const byte *ks, byte *data); diff --git a/src/Crypto/Aeskey.c b/src/Crypto/Aeskey.c index c9ab0269..9b7bfd18 100644 --- a/src/Crypto/Aeskey.c +++ b/src/Crypto/Aeskey.c @@ -27,6 +27,7 @@ #include "Aesopt.h" #include "Aestab.h" +#include "Common/Tcdefs.h" #ifdef USE_VIA_ACE_IF_PRESENT # include "aes_via_ace.h" @@ -95,6 +96,8 @@ AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]) cx->inf.b[1] = 0xff; #endif + burn(ss, sizeof(ss)); + #if defined( AES_ERR_CHK ) return EXIT_SUCCESS; #endif @@ -147,6 +150,8 @@ AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) cx->inf.b[1] = 0xff; #endif + burn(ss, sizeof(ss)); + #if defined( AES_ERR_CHK ) return EXIT_SUCCESS; #endif @@ -202,6 +207,8 @@ AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) cx->inf.b[1] = 0xff; #endif + burn(ss, sizeof(ss)); + #if defined( AES_ERR_CHK ) return EXIT_SUCCESS; #endif @@ -352,6 +359,8 @@ AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) cx->inf.b[1] = 0xff; #endif + burn(ss, sizeof(ss)); + #if defined( AES_ERR_CHK ) return EXIT_SUCCESS; #endif @@ -439,6 +448,8 @@ AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) cx->inf.b[1] = 0xff; #endif + burn(ss, sizeof(ss)); + #if defined( AES_ERR_CHK ) return EXIT_SUCCESS; #endif @@ -538,6 +549,8 @@ AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) cx->inf.b[1] = 0xff; #endif + burn(ss, sizeof(ss)); + #if defined( AES_ERR_CHK ) return EXIT_SUCCESS; #endif diff --git a/src/Crypto/Camellia.c b/src/Crypto/Camellia.c index 49bc7670..f4fde8aa 100644 --- a/src/Crypto/Camellia.c +++ b/src/Crypto/Camellia.c @@ -3,7 +3,7 @@ #include "Crypto/cpu.h" #include "Crypto/misc.h" -#if CRYPTOPP_BOOL_X64 +#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) /* camellia.c ver 1.2.0-x86_64_asm1.1 * @@ -1100,7 +1100,7 @@ void camellia_encrypt_blocks(unsigned __int8 *instance, const byte* in_blk, byte { #if defined (TC_WINDOWS_DRIVER) XSTATE_SAVE SaveState; - if (NT_SUCCESS (KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState))) + if (NT_SUCCESS (KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState))) { #endif while (blockCount >= 16) @@ -1111,7 +1111,7 @@ void camellia_encrypt_blocks(unsigned __int8 *instance, const byte* in_blk, byte blockCount -= 16; } #if defined (TC_WINDOWS_DRIVER) - KeRestoreExtendedProcessorState(&SaveState); + KeRestoreExtendedProcessorStateVC(&SaveState); } #endif } @@ -1136,7 +1136,7 @@ void camellia_decrypt_blocks(unsigned __int8 *instance, const byte* in_blk, byte { #if defined (TC_WINDOWS_DRIVER) XSTATE_SAVE SaveState; - if (NT_SUCCESS (KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState))) + if (NT_SUCCESS (KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState))) { #endif while (blockCount >= 16) @@ -1147,7 +1147,7 @@ void camellia_decrypt_blocks(unsigned __int8 *instance, const byte* in_blk, byte blockCount -= 16; } #if defined (TC_WINDOWS_DRIVER) - KeRestoreExtendedProcessorState(&SaveState); + KeRestoreExtendedProcessorStateVC(&SaveState); } #endif } diff --git a/src/Crypto/Camellia.h b/src/Crypto/Camellia.h index 988203d0..a1cb832e 100644 --- a/src/Crypto/Camellia.h +++ b/src/Crypto/Camellia.h @@ -17,7 +17,7 @@ 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 +#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) 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 diff --git a/src/Crypto/Crypto.vcxproj b/src/Crypto/Crypto.vcxproj index 027a87e0..97a472f7 100644 --- a/src/Crypto/Crypto.vcxproj +++ b/src/Crypto/Crypto.vcxproj @@ -200,26 +200,19 @@ </Command> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> </CustomBuild> - <CustomBuild Include="Gost89_x64.asm"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" -</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" -</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> - </CustomBuild> </ItemGroup> <ItemGroup> <ClCompile Include="Aeskey.c" /> <ClCompile Include="Aestab.c" /> + <ClCompile Include="blake2s.c" /> + <ClCompile Include="blake2s_SSE2.c" /> + <ClCompile Include="blake2s_SSE41.c" /> + <ClCompile Include="blake2s_SSSE3.c" /> <ClCompile Include="Camellia.c" /> <ClCompile Include="chacha-xmm.c" /> <ClCompile Include="chacha256.c" /> <ClCompile Include="chachaRng.c" /> <ClCompile Include="cpu.c" /> - <ClCompile Include="GostCipher.c" /> <ClCompile Include="jitterentropy-base.c"> <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Disabled</Optimization> <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Disabled</Optimization> @@ -227,7 +220,6 @@ <ClCompile Include="kuznyechik.c" /> <ClCompile Include="kuznyechik_simd.c" /> <ClCompile Include="rdrand.c" /> - <ClCompile Include="Rmd160.c" /> <ClCompile Include="SerpentFast.c" /> <ClCompile Include="SerpentFast_simd.cpp" /> <ClCompile Include="Sha2.c" /> @@ -243,6 +235,9 @@ <ClInclude Include="Aes_hw_cpu.h" /> <ClInclude Include="Aesopt.h" /> <ClInclude Include="Aestab.h" /> + <ClInclude Include="blake2s-load-sse2.h" /> + <ClInclude Include="blake2s-load-sse41.h" /> + <ClInclude Include="blake2s-round.h" /> <ClInclude Include="Camellia.h" /> <ClInclude Include="chacha256.h" /> <ClInclude Include="chachaRng.h" /> @@ -250,13 +245,11 @@ <ClInclude Include="chacha_u4.h" /> <ClInclude Include="config.h" /> <ClInclude Include="cpu.h" /> - <ClInclude Include="GostCipher.h" /> <ClInclude Include="jitterentropy-base-user.h" /> <ClInclude Include="jitterentropy.h" /> <ClInclude Include="kuznyechik.h" /> <ClInclude Include="misc.h" /> <ClInclude Include="rdrand.h" /> - <ClInclude Include="Rmd160.h" /> <ClInclude Include="SerpentFast.h" /> <ClInclude Include="SerpentFast_sbox.h" /> <ClInclude Include="Sha2.h" /> @@ -403,6 +396,21 @@ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> </CustomBuild> + <CustomBuild Include="rdseed_ml.asm"> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & ml.exe /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & ml.exe /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/src/Crypto/Crypto.vcxproj.filters b/src/Crypto/Crypto.vcxproj.filters index e7b3c3a5..5d149bdd 100644 --- a/src/Crypto/Crypto.vcxproj.filters +++ b/src/Crypto/Crypto.vcxproj.filters @@ -24,9 +24,6 @@ <ClCompile Include="cpu.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="Rmd160.c"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="Sha2.c"> <Filter>Source Files</Filter> </ClCompile> @@ -36,9 +33,6 @@ <ClCompile Include="Whirlpool.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="GostCipher.c"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="kuznyechik.c"> <Filter>Source Files</Filter> </ClCompile> @@ -81,6 +75,18 @@ <ClCompile Include="t1ha2_selfcheck.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="blake2s.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="blake2s_SSE2.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="blake2s_SSE41.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="blake2s_SSSE3.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="Aes.h"> @@ -107,9 +113,6 @@ <ClInclude Include="misc.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="Rmd160.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="Sha2.h"> <Filter>Header Files</Filter> </ClInclude> @@ -119,9 +122,6 @@ <ClInclude Include="Whirlpool.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="GostCipher.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="kuznyechik.h"> <Filter>Header Files</Filter> </ClInclude> @@ -164,6 +164,15 @@ <ClInclude Include="t1ha_selfcheck.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="blake2s-load-sse2.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="blake2s-load-sse41.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="blake2s-round.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <CustomBuild Include="Aes_hw_cpu.asm"> @@ -175,9 +184,6 @@ <CustomBuild Include="Aes_x86.asm"> <Filter>Source Files</Filter> </CustomBuild> - <CustomBuild Include="Gost89_x64.asm"> - <Filter>Source Files</Filter> - </CustomBuild> <CustomBuild Include="Twofish_x64.S"> <Filter>Source Files</Filter> </CustomBuild> @@ -217,5 +223,8 @@ <CustomBuild Include="rdrand_ml.asm"> <Filter>Source Files</Filter> </CustomBuild> + <CustomBuild Include="rdseed_ml.asm"> + <Filter>Source Files</Filter> + </CustomBuild> </ItemGroup> </Project>
\ No newline at end of file diff --git a/src/Crypto/Crypto_vs2019.vcxproj b/src/Crypto/Crypto_vs2019.vcxproj new file mode 100644 index 00000000..ccd512b9 --- /dev/null +++ b/src/Crypto/Crypto_vs2019.vcxproj @@ -0,0 +1,599 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{993245CF-6B70-47EE-91BB-39F8FC6DC0E7}</ProjectGuid> + <RootNamespace>Crypto</RootNamespace> + <Keyword>Win32Proj</Keyword> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>Crypto</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Platform)\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Platform)\$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Platform)\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)\..;$(ProjectDir)\..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;DEBUG;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4100;4127;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)Crypto.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Midl> + <TargetEnvironment>X64</TargetEnvironment> + </Midl> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)\..;$(ProjectDir)\..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;DEBUG;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4100;4127;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)Crypto.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <Midl /> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)\..;$(ProjectDir)\..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;DEBUG;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4100;4127;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)Crypto.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)\..;$(ProjectDir)\..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <PrecompiledHeader> + </PrecompiledHeader> + <AssemblerOutput>All</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WarningLevel>Level4</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4100;4127;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)Crypto.lib</OutputFile> + <AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Midl> + <TargetEnvironment>X64</TargetEnvironment> + </Midl> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)\..;$(ProjectDir)\..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <PrecompiledHeader> + </PrecompiledHeader> + <AssemblerOutput>All</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WarningLevel>Level4</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4100;4127;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)Crypto.lib</OutputFile> + <AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <Midl /> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)\..;$(ProjectDir)\..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <PrecompiledHeader> + </PrecompiledHeader> + <AssemblerOutput>All</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WarningLevel>Level4</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4100;4127;4201;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)Crypto.lib</OutputFile> + <AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <CustomBuild Include="Aes_hw_cpu.asm"> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -g -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -g -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox --prefix _ -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="Aes_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="Aes_x86.asm"> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox --prefix _ -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox --prefix _ -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox --prefix _ -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Aescrypt.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="Aeskey.c" /> + <ClCompile Include="Aestab.c" /> + <ClCompile Include="blake2s.c" /> + <ClCompile Include="blake2s_SSE2.c" /> + <ClCompile Include="blake2s_SSE41.c" /> + <ClCompile Include="blake2s_SSSE3.c" /> + <ClCompile Include="Camellia.c" /> + <ClCompile Include="chacha-xmm.c" /> + <ClCompile Include="chacha256.c" /> + <ClCompile Include="chachaRng.c" /> + <ClCompile Include="cpu.c" /> + <ClCompile Include="jitterentropy-base.c"> + <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Disabled</Optimization> + <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Disabled</Optimization> + <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Disabled</Optimization> + </ClCompile> + <ClCompile Include="kuznyechik.c" /> + <ClCompile Include="kuznyechik_simd.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="rdrand.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="SerpentFast.c" /> + <ClCompile Include="SerpentFast_simd.cpp" /> + <ClCompile Include="Sha2.c" /> + <ClCompile Include="Streebog.c" /> + <ClCompile Include="t1ha2.c" /> + <ClCompile Include="t1ha2_selfcheck.c" /> + <ClCompile Include="t1ha_selfcheck.c" /> + <ClCompile Include="Twofish.c" /> + <ClCompile Include="Whirlpool.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Aes.h" /> + <ClInclude Include="Aes_hw_cpu.h" /> + <ClInclude Include="Aesopt.h" /> + <ClInclude Include="Aestab.h" /> + <ClInclude Include="Camellia.h" /> + <ClInclude Include="chacha256.h" /> + <ClInclude Include="chachaRng.h" /> + <ClInclude Include="chacha_u1.h" /> + <ClInclude Include="chacha_u4.h" /> + <ClInclude Include="config.h" /> + <ClInclude Include="cpu.h" /> + <ClInclude Include="jitterentropy-base-user.h" /> + <ClInclude Include="jitterentropy.h" /> + <ClInclude Include="kuznyechik.h" /> + <ClInclude Include="misc.h" /> + <ClInclude Include="rdrand.h" /> + <ClInclude Include="SerpentFast.h" /> + <ClInclude Include="SerpentFast_sbox.h" /> + <ClInclude Include="Sha2.h" /> + <ClInclude Include="Streebog.h" /> + <ClInclude Include="t1ha.h" /> + <ClInclude Include="t1ha_bits.h" /> + <ClInclude Include="t1ha_selfcheck.h" /> + <ClInclude Include="Twofish.h" /> + <ClInclude Include="Whirlpool.h" /> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="Twofish_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)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </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) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </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) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -p gas -D WINABI -D __YASM__ -f win64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="sha256-x86-nayuki.S"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & vsyasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f win32 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & vsyasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f win32 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + <CustomBuild Include="sha256_avx1_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="sha256_avx2_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="sha256_sse4_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="sha512-x86-nayuki.S"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & vsyasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f win32 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & vsyasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f win32 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + </CustomBuild> + <CustomBuild Include="sha512-x64-nayuki.S"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -Xvc -p gas -D WINABI -D __YASM__ -f x64 -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="sha512_avx1_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="sha512_avx2_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="sha512_sse4_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -o "$(TargetDir)\%(Filename).obj" -l "$(TargetDir)\%(Filename).lst" "%(FullPath)"</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & yasm.exe -D WINABI -D __YASM__ -f x64 -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)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="rdrand_ml.asm"> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & ml.exe /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & ml.exe /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + <CustomBuild Include="rdseed_ml.asm"> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & ml.exe /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & ml.exe /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/src/Crypto/Crypto_vs2019.vcxproj.user b/src/Crypto/Crypto_vs2019.vcxproj.user new file mode 100644 index 00000000..88a55094 --- /dev/null +++ b/src/Crypto/Crypto_vs2019.vcxproj.user @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup /> +</Project>
\ No newline at end of file diff --git a/src/Crypto/GostCipher.c b/src/Crypto/GostCipher.c deleted file mode 100644 index ddd649cd..00000000 --- a/src/Crypto/GostCipher.c +++ /dev/null @@ -1,265 +0,0 @@ -/** @file -GOST89 implementation - -Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov - -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the Apache License, Version 2.0. -The full text of the license may be found at -https://opensource.org/licenses/Apache-2.0 - -Dynamic SBOX idea is from GostCrypt project. Copyright (c) 2008-2011 TrueCrypt Developers Association -**/ - - - -#include "GostCipher.h" -#include "Streebog.h" -#include "cpu.h" - -#if defined(CIPHER_GOST89) - -// Crypto Pro -byte S_CryptoPro[8][16] = { - {0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC}, - {0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB}, - {0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3}, - {0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5}, - {0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3}, - {0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD}, - {0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8}, - {0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF} - }; - -// TC26 -byte S_TC26[8][16] = -{ - { 0xc, 0x4, 0x6, 0x2, 0xa, 0x5, 0xb, 0x9, 0xe, 0x8, 0xd, 0x7, 0x0, 0x3, 0xf, 0x1 }, - { 0x6, 0x8, 0x2, 0x3, 0x9, 0xa, 0x5, 0xc, 0x1, 0xe, 0x4, 0x7, 0xb, 0xd, 0x0, 0xf }, - { 0xb, 0x3, 0x5, 0x8, 0x2, 0xf, 0xa, 0xd, 0xe, 0x1, 0x7, 0x4, 0xc, 0x9, 0x6, 0x0 }, - { 0xc, 0x8, 0x2, 0x1, 0xd, 0x4, 0xf, 0x6, 0x7, 0x0, 0xa, 0x5, 0x3, 0xe, 0x9, 0xb }, - { 0x7, 0xf, 0x5, 0xa, 0x8, 0x1, 0x6, 0xd, 0x0, 0x9, 0x3, 0xe, 0xb, 0x4, 0x2, 0xc }, - { 0x5, 0xd, 0xf, 0x6, 0x9, 0x2, 0xc, 0xa, 0xb, 0x7, 0x8, 0x1, 0x4, 0x3, 0xe, 0x0 }, - { 0x8, 0xe, 0x2, 0x5, 0x6, 0x9, 0x1, 0xc, 0xf, 0x4, 0xb, 0x0, 0xd, 0xa, 0x3, 0x7 }, - { 0x1, 0x7, 0xe, 0xd, 0x0, 0x5, 0x8, 0x3, 0x4, 0xf, 0xa, 0x6, 0x9, 0xc, 0xb, 0x2 }, -}; - -void gost_prepare_kds(gost_kds* kds) { - uint32 i; - // Build substitution tables. - for (i = 0; i < 256; ++i) { - uint32 p; - p = kds->sbox[7][i >> 4] << 4 | kds->sbox[6][i & 15]; - p = p << 24; p = p << 11 | p >> 21; - kds->sbox_cvt[i] = p; // S87 - - p = kds->sbox[5][i >> 4] << 4 | kds->sbox[4][i & 15]; - p = p << 16; p = p << 11 | p >> 21; - kds->sbox_cvt[256 + i] = p; // S65 - - p = kds->sbox[3][i >> 4] << 4 | kds->sbox[2][i & 15]; - p = p << 8; p = p << 11 | p >> 21; - kds->sbox_cvt[256 * 2 + i] = p; // S43 - - p = kds->sbox[1][i >> 4] << 4 | kds->sbox[0][i & 15]; - p = p << 11 | p >> 21; - kds->sbox_cvt[256 * 3 + i] = p; // S21 - } -} - - -static void xor_s_box(byte s_box[8][16], byte *seed) -{ - int i; - for (i = 0; i < 16; i++) - { - s_box[0][i] ^= (seed[ (i * 4) + 0 ] ) & 0xF; - s_box[1][i] ^= (seed[ (i * 4) + 0 ]>>4) & 0xF; - s_box[2][i] ^= (seed[ (i * 4) + 1 ] ) & 0xF; - s_box[3][i] ^= (seed[ (i * 4) + 1 ]>>4) & 0xF; - s_box[4][i] ^= (seed[ (i * 4) + 2 ] ) & 0xF; - s_box[5][i] ^= (seed[ (i * 4) + 2 ]>>4) & 0xF; - s_box[6][i] ^= (seed[ (i * 4) + 3 ] ) & 0xF; - s_box[7][i] ^= (seed[ (i * 4) + 3 ]>>4) & 0xF; - } -} - -void gost_set_key(const byte *key, gost_kds *ks, int useDynamicSbox) -{ - memcpy(ks->key, key, GOST_KEYSIZE); - memcpy(ks->sbox, S_TC26, sizeof(ks->sbox)); - - if (useDynamicSbox) - { - STREEBOG_CTX sctx; - byte sbox_seed[64]; -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; - if (HasSSE2() || HasSSE41()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif - //Generate pseudorandom data based on the key - STREEBOG_init(&sctx); - STREEBOG_add(&sctx, ks->key, 32); - STREEBOG_finalize(&sctx, sbox_seed); - -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - if (NT_SUCCESS (saveStatus)) - KeRestoreFloatingPointState (&floatingPointState); -#endif - - xor_s_box(ks->sbox, sbox_seed); - } - - gost_prepare_kds(ks); -} - -static uint32 f(uint32 v, uint32* sbox){ - byte* x =(byte*) &v; - /* Do substitutions */ - return sbox[x[3]] | sbox[256 + x[2]] | sbox[256*2 + x[1]] | sbox[256*3 + x[0]]; -} - -void gost_encrypt_block(uint64 in_, uint64* out_, gost_kds* kds) { - uint32* in = (uint32*)&in_; - uint32* out = (uint32*)out_; - uint32* key = (uint32*)kds->key; - uint32* sbox = kds->sbox_cvt; - - // As named in the GOST - uint32 n1 = in[0]; - uint32 n2 = in[1]; - - n2 ^= f(n1+key[0], sbox); - n1 ^= f(n2+key[1], sbox); - n2 ^= f(n1+key[2], sbox); - n1 ^= f(n2+key[3], sbox); - n2 ^= f(n1+key[4], sbox); - n1 ^= f(n2+key[5], sbox); - n2 ^= f(n1+key[6], sbox); - n1 ^= f(n2+key[7], sbox); - - n2 ^= f(n1+key[0], sbox); - n1 ^= f(n2+key[1], sbox); - n2 ^= f(n1+key[2], sbox); - n1 ^= f(n2+key[3], sbox); - n2 ^= f(n1+key[4], sbox); - n1 ^= f(n2+key[5], sbox); - n2 ^= f(n1+key[6], sbox); - n1 ^= f(n2+key[7], sbox); - - n2 ^= f(n1+key[0], sbox); - n1 ^= f(n2+key[1], sbox); - n2 ^= f(n1+key[2], sbox); - n1 ^= f(n2+key[3], sbox); - n2 ^= f(n1+key[4], sbox); - n1 ^= f(n2+key[5], sbox); - n2 ^= f(n1+key[6], sbox); - n1 ^= f(n2+key[7], sbox); - - n2 ^= f(n1+key[7], sbox); - n1 ^= f(n2+key[6], sbox); - n2 ^= f(n1+key[5], sbox); - n1 ^= f(n2+key[4], sbox); - n2 ^= f(n1+key[3], sbox); - n1 ^= f(n2+key[2], sbox); - n2 ^= f(n1+key[1], sbox); - n1 ^= f(n2+key[0], sbox); - - // There is no swap after the last round - out[0] = n2; - out[1] = n1; -} - -void gost_decrypt_block(uint64 in_, uint64* out_, gost_kds* kds) { - uint32* in = (uint32*)&in_; - uint32* out = (uint32*)out_; - uint32* key = (uint32*)kds->key; - uint32* sbox = kds->sbox_cvt; - - // As named in the GOST - uint32 n1 = in[0]; - uint32 n2 = in[1]; - - n2 ^= f(n1+key[0], sbox); - n1 ^= f(n2+key[1], sbox); - n2 ^= f(n1+key[2], sbox); - n1 ^= f(n2+key[3], sbox); - n2 ^= f(n1+key[4], sbox); - n1 ^= f(n2+key[5], sbox); - n2 ^= f(n1+key[6], sbox); - n1 ^= f(n2+key[7], sbox); - - n2 ^= f(n1+key[7], sbox); - n1 ^= f(n2+key[6], sbox); - n2 ^= f(n1+key[5], sbox); - n1 ^= f(n2+key[4], sbox); - n2 ^= f(n1+key[3], sbox); - n1 ^= f(n2+key[2], sbox); - n2 ^= f(n1+key[1], sbox); - n1 ^= f(n2+key[0], sbox); - - n2 ^= f(n1+key[7], sbox); - n1 ^= f(n2+key[6], sbox); - n2 ^= f(n1+key[5], sbox); - n1 ^= f(n2+key[4], sbox); - n2 ^= f(n1+key[3], sbox); - n1 ^= f(n2+key[2], sbox); - n2 ^= f(n1+key[1], sbox); - n1 ^= f(n2+key[0], sbox); - - n2 ^= f(n1+key[7], sbox); - n1 ^= f(n2+key[6], sbox); - n2 ^= f(n1+key[5], sbox); - n1 ^= f(n2+key[4], sbox); - n2 ^= f(n1+key[3], sbox); - n1 ^= f(n2+key[2], sbox); - n2 ^= f(n1+key[1], sbox); - n1 ^= f(n2+key[0], sbox); - - out[0] = n2; - out[1] = n1; -} - -#if defined(_M_AMD64) -void gost_encrypt_128_CBC_asm(const byte *in, byte *out, gost_kds *ks, uint64 count); -void gost_decrypt_128_CBC_asm(const byte *in, byte *out, gost_kds *ks, uint64 count); -#endif - -void gost_encrypt(const byte *in, byte *out, gost_kds *ks, int count) { -#if defined(_M_AMD64) - gost_encrypt_128_CBC_asm(in, out, ks, (uint64)count); -#else - while (count > 0) { - // encrypt two blocks in CBC mode - gost_encrypt_block(*((uint64*)in), (uint64*)out, ks); - *((gst_udword*)(out + 8)) = *((gst_udword*)(in + 8)) ^ *((gst_udword*)(out)); - *((gst_udword*)(out + 12)) = *((gst_udword*)(in + 12)) ^ *((gst_udword*)(out + 4)); - gost_encrypt_block(*((uint64*)(out + 8)), (uint64*)(out + 8), ks); - count--; - in += 16; - out += 16; - } -#endif -} - -void gost_decrypt(const byte *in, byte *out, gost_kds *ks, int count) { -#if defined(_M_AMD64) - gost_decrypt_128_CBC_asm(in, out, ks, (uint64)count); -#else - while (count > 0) { - // decrypt two blocks in CBC mode - gost_decrypt_block(*((uint64*)(in + 8)), (uint64*)(out + 8), ks); - *((gst_udword*)(out + 8)) ^= *((gst_udword*)(in));; - *((gst_udword*)(out + 12)) ^= *((gst_udword*)(in + 4));; - gost_decrypt_block(*((uint64*)(in)), (uint64*)(out), ks); - count--; - in += 16; - out += 16; - } -#endif -} - -#endif diff --git a/src/Crypto/GostCipher.h b/src/Crypto/GostCipher.h deleted file mode 100644 index bcb77207..00000000 --- a/src/Crypto/GostCipher.h +++ /dev/null @@ -1,68 +0,0 @@ - -/* - Copyright (c) 2008-2011 TrueCrypt Developers Association. All rights reserved. - - Governed by the TrueCrypt License 3.0 the full text of which is contained in - the file License.txt included in TrueCrypt binary and source code distribution - packages. -*/ - - - -#ifndef GOST_CIPHER_H -#define GOST_CIPHER_H - -#include "Common/Tcdefs.h" -#include "config.h" -#include "misc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -//In unsigned chars -#define GOST_KEYSIZE 32 -#define GOST_BLOCKSIZE 8 -#define GOST_SBOX_SIZE 16 - -//Production setting, but can be turned off to compare the algorithm with other implementations -#define CIPHER_GOST89 -#define GOST_DYNAMIC_SBOXES - -#if defined(CIPHER_GOST89) - -#ifdef GST_WINDOWS_BOOT -typedef int gst_word; -typedef long gst_dword; -typedef unsigned int gst_uword; -typedef unsigned long gst_udword; -#else -typedef short gst_word; -typedef int gst_dword; -typedef unsigned short gst_uword; -typedef unsigned int gst_udword; -#endif - -typedef struct gost_kds -{ - CRYPTOPP_ALIGN_DATA(16) byte key[32]; - gst_udword sbox_cvt[256 * 4]; - byte sbox[8][16]; -} gost_kds; - -#define GOST_KS (sizeof(gost_kds)) - -void gost_encrypt(const byte *in, byte *out, gost_kds *ks, int count); -void gost_decrypt(const byte *in, byte *out, gost_kds *ks, int count); -void gost_set_key(const byte *key, gost_kds *ks, int useDynamicSbox); - -#else -#define GOST_KS (0) -#endif - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/src/Crypto/Makefile.inc b/src/Crypto/Makefile.inc index 86b7a6fa..e05d02ca 100644 --- a/src/Crypto/Makefile.inc +++ b/src/Crypto/Makefile.inc @@ -16,9 +16,6 @@ VC_MLEXE = ml64.exe TC_ASM_ERR_LOG = ..\Driver\build_errors_asm.log -"$(OBJ_PATH)\$(O)\gost89_$(TC_ARCH).obj": gost89_$(TC_ARCH).asm - nasm.exe $(TC_ASFLAGS) -o "$@" -l "$(OBJ_PATH)\$(O)\gost89_$(TC_ARCH).lst" gost89_$(TC_ARCH).asm 2>$(TC_ASM_ERR_LOG) - "$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).obj": Aes_$(TC_ARCH).asm nasm.exe $(TC_ASFLAGS) -o "$@" -l "$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).lst" Aes_$(TC_ARCH).asm 2>$(TC_ASM_ERR_LOG) @@ -60,4 +57,8 @@ TC_ASM_ERR_LOG = ..\Driver\build_errors_asm.log "$(OBJ_PATH)\$(O)\rdrand_ml.obj": rdrand_ml.asm $(VC_MLEXE) $(VC_MLFLAGS) /Fo "$@" /c rdrand_ml.asm 2>$(TC_ASM_ERR_LOG) + +"$(OBJ_PATH)\$(O)\rdseed_ml.obj": rdseed_ml.asm + $(VC_MLEXE) $(VC_MLFLAGS) /Fo "$@" /c rdseed_ml.asm 2>$(TC_ASM_ERR_LOG) + diff --git a/src/Crypto/Rmd160.c b/src/Crypto/Rmd160.c deleted file mode 100644 index 0c6ec839..00000000 --- a/src/Crypto/Rmd160.c +++ /dev/null @@ -1,500 +0,0 @@ -// RIPEMD-160 written and placed in the public domain by Wei Dai - -/* - * This code implements the MD4 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - */ - -/* Adapted for TrueCrypt */ -/* Adapted for VeraCrypt */ -#if !defined(_UEFI) -#include <memory.h> -#endif // !defined(_UEFI) - -#include "Common/Tcdefs.h" -#include "Common/Endian.h" -#include "Rmd160.h" - -#define F(x, y, z) (x ^ y ^ z) -#define G(x, y, z) (z ^ (x & (y^z))) -#define H(x, y, z) (z ^ (x | ~y)) -#define I(x, y, z) (y ^ (z & (x^y))) -#define J(x, y, z) (x ^ (y | ~z)) - -#define PUT_64BIT_LE(cp, value) do { \ - (cp)[7] = (byte) ((value) >> 56); \ - (cp)[6] = (byte) ((value) >> 48); \ - (cp)[5] = (byte) ((value) >> 40); \ - (cp)[4] = (byte) ((value) >> 32); \ - (cp)[3] = (byte) ((value) >> 24); \ - (cp)[2] = (byte) ((value) >> 16); \ - (cp)[1] = (byte) ((value) >> 8); \ - (cp)[0] = (byte) (value); } while (0) - -#define PUT_32BIT_LE(cp, value) do { \ - (cp)[3] = (byte) ((value) >> 24); \ - (cp)[2] = (byte) ((value) >> 16); \ - (cp)[1] = (byte) ((value) >> 8); \ - (cp)[0] = (byte) (value); } while (0) - -#ifndef TC_MINIMIZE_CODE_SIZE - -static byte PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -#else - -static byte PADDING[64]; - -#endif - -void RMD160Init (RMD160_CTX *ctx) -{ - ctx->count = 0; - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xefcdab89; - ctx->state[2] = 0x98badcfe; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xc3d2e1f0; - PADDING[0] = 0x80; -} - -/* -* Update context to reflect the concatenation of another buffer full -* of bytes. -*/ -void RMD160Update (RMD160_CTX *ctx, const unsigned char *input, unsigned __int32 lenArg) -{ -#ifndef TC_WINDOWS_BOOT - uint64 len = lenArg; -#else - uint32 len = lenArg; -#endif - unsigned int have, need; - - /* Check how many bytes we already have and how many more we need. */ - have = (unsigned int) ((ctx->count) & (RIPEMD160_BLOCK_LENGTH - 1)); - need = RIPEMD160_BLOCK_LENGTH - have; - - /* Update bitcount */ - ctx->count += len; - - if (len >= need) { - if (have != 0) { - memcpy (ctx->buffer + have, input, (size_t) need); - RMD160Transform ((uint32 *) ctx->state, (const uint32 *) ctx->buffer); - input += need; - len -= need; - have = 0; - } - - /* Process data in RIPEMD160_BLOCK_LENGTH-byte chunks. */ - while (len >= RIPEMD160_BLOCK_LENGTH) { - RMD160Transform ((uint32 *) ctx->state, (const uint32 *) input); - input += RIPEMD160_BLOCK_LENGTH; - len -= RIPEMD160_BLOCK_LENGTH; - } - } - - /* Handle any remaining bytes of data. */ - if (len != 0) - memcpy (ctx->buffer + have, input, (size_t) len); -} - -/* -* Pad pad to 64-byte boundary with the bit pattern -* 1 0* (64-bit count of bits processed, MSB-first) -*/ -static void RMD160Pad(RMD160_CTX *ctx) -{ - byte count[8]; - uint32 padlen; - - /* Convert count to 8 bytes in little endian order. */ - -#ifndef TC_WINDOWS_BOOT - uint64 bitcount = ctx->count << 3; - PUT_64BIT_LE(count, bitcount); -#else - *(uint32 *) (count + 4) = 0; - *(uint32 *) (count + 0) = ctx->count << 3; -#endif - - /* Pad out to 56 mod 64. */ - padlen = RIPEMD160_BLOCK_LENGTH - - (uint32)((ctx->count) & (RIPEMD160_BLOCK_LENGTH - 1)); - if (padlen < 1 + 8) - padlen += RIPEMD160_BLOCK_LENGTH; - RMD160Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ - RMD160Update(ctx, count, 8); -} - -/* -* Final wrapup--call RMD160Pad, fill in digest and zero out ctx. -*/ -void RMD160Final(unsigned char *digest, RMD160_CTX *ctx) -{ - int i; - - RMD160Pad(ctx); - if (digest) { - for (i = 0; i < 5; i++) - PUT_32BIT_LE(digest + i * 4, ctx->state[i]); -#ifndef TC_WINDOWS_BOOT - burn (ctx, sizeof(*ctx)); -#endif - } -} - - -#ifndef TC_MINIMIZE_CODE_SIZE - -#define word32 unsigned __int32 - -#define k0 0 -#define k1 0x5a827999UL -#define k2 0x6ed9eba1UL -#define k3 0x8f1bbcdcUL -#define k4 0xa953fd4eUL -#define k5 0x50a28be6UL -#define k6 0x5c4dd124UL -#define k7 0x6d703ef3UL -#define k8 0x7a6d76e9UL -#define k9 0 - -static word32 rotlFixed (word32 x, unsigned int y) -{ - return (word32)((x<<y) | (x>>(sizeof(word32)*8-y))); -} - -#define Subround(f, a, b, c, d, e, x, s, k) \ - a += f(b, c, d) + x + k;\ - a = rotlFixed((word32)a, s) + e;\ - c = rotlFixed((word32)c, 10U) - -void RMD160Transform (unsigned __int32 *digest, const unsigned __int32 *data) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - const word32 *X = data; -#else - word32 X[16]; - int i; -#endif - - word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; - a1 = a2 = digest[0]; - b1 = b2 = digest[1]; - c1 = c2 = digest[2]; - d1 = d2 = digest[3]; - e1 = e2 = digest[4]; - -#if BYTE_ORDER == BIG_ENDIAN - for (i = 0; i < 16; i++) - { - X[i] = LE32 (data[i]); - } -#endif - - Subround(F, a1, b1, c1, d1, e1, X[ 0], 11, k0); - Subround(F, e1, a1, b1, c1, d1, X[ 1], 14, k0); - Subround(F, d1, e1, a1, b1, c1, X[ 2], 15, k0); - Subround(F, c1, d1, e1, a1, b1, X[ 3], 12, k0); - Subround(F, b1, c1, d1, e1, a1, X[ 4], 5, k0); - Subround(F, a1, b1, c1, d1, e1, X[ 5], 8, k0); - Subround(F, e1, a1, b1, c1, d1, X[ 6], 7, k0); - Subround(F, d1, e1, a1, b1, c1, X[ 7], 9, k0); - Subround(F, c1, d1, e1, a1, b1, X[ 8], 11, k0); - Subround(F, b1, c1, d1, e1, a1, X[ 9], 13, k0); - Subround(F, a1, b1, c1, d1, e1, X[10], 14, k0); - Subround(F, e1, a1, b1, c1, d1, X[11], 15, k0); - Subround(F, d1, e1, a1, b1, c1, X[12], 6, k0); - Subround(F, c1, d1, e1, a1, b1, X[13], 7, k0); - Subround(F, b1, c1, d1, e1, a1, X[14], 9, k0); - Subround(F, a1, b1, c1, d1, e1, X[15], 8, k0); - - Subround(G, e1, a1, b1, c1, d1, X[ 7], 7, k1); - Subround(G, d1, e1, a1, b1, c1, X[ 4], 6, k1); - Subround(G, c1, d1, e1, a1, b1, X[13], 8, k1); - Subround(G, b1, c1, d1, e1, a1, X[ 1], 13, k1); - Subround(G, a1, b1, c1, d1, e1, X[10], 11, k1); - Subround(G, e1, a1, b1, c1, d1, X[ 6], 9, k1); - Subround(G, d1, e1, a1, b1, c1, X[15], 7, k1); - Subround(G, c1, d1, e1, a1, b1, X[ 3], 15, k1); - Subround(G, b1, c1, d1, e1, a1, X[12], 7, k1); - Subround(G, a1, b1, c1, d1, e1, X[ 0], 12, k1); - Subround(G, e1, a1, b1, c1, d1, X[ 9], 15, k1); - Subround(G, d1, e1, a1, b1, c1, X[ 5], 9, k1); - Subround(G, c1, d1, e1, a1, b1, X[ 2], 11, k1); - Subround(G, b1, c1, d1, e1, a1, X[14], 7, k1); - Subround(G, a1, b1, c1, d1, e1, X[11], 13, k1); - Subround(G, e1, a1, b1, c1, d1, X[ 8], 12, k1); - - Subround(H, d1, e1, a1, b1, c1, X[ 3], 11, k2); - Subround(H, c1, d1, e1, a1, b1, X[10], 13, k2); - Subround(H, b1, c1, d1, e1, a1, X[14], 6, k2); - Subround(H, a1, b1, c1, d1, e1, X[ 4], 7, k2); - Subround(H, e1, a1, b1, c1, d1, X[ 9], 14, k2); - Subround(H, d1, e1, a1, b1, c1, X[15], 9, k2); - Subround(H, c1, d1, e1, a1, b1, X[ 8], 13, k2); - Subround(H, b1, c1, d1, e1, a1, X[ 1], 15, k2); - Subround(H, a1, b1, c1, d1, e1, X[ 2], 14, k2); - Subround(H, e1, a1, b1, c1, d1, X[ 7], 8, k2); - Subround(H, d1, e1, a1, b1, c1, X[ 0], 13, k2); - Subround(H, c1, d1, e1, a1, b1, X[ 6], 6, k2); - Subround(H, b1, c1, d1, e1, a1, X[13], 5, k2); - Subround(H, a1, b1, c1, d1, e1, X[11], 12, k2); - Subround(H, e1, a1, b1, c1, d1, X[ 5], 7, k2); - Subround(H, d1, e1, a1, b1, c1, X[12], 5, k2); - - Subround(I, c1, d1, e1, a1, b1, X[ 1], 11, k3); - Subround(I, b1, c1, d1, e1, a1, X[ 9], 12, k3); - Subround(I, a1, b1, c1, d1, e1, X[11], 14, k3); - Subround(I, e1, a1, b1, c1, d1, X[10], 15, k3); - Subround(I, d1, e1, a1, b1, c1, X[ 0], 14, k3); - Subround(I, c1, d1, e1, a1, b1, X[ 8], 15, k3); - Subround(I, b1, c1, d1, e1, a1, X[12], 9, k3); - Subround(I, a1, b1, c1, d1, e1, X[ 4], 8, k3); - Subround(I, e1, a1, b1, c1, d1, X[13], 9, k3); - Subround(I, d1, e1, a1, b1, c1, X[ 3], 14, k3); - Subround(I, c1, d1, e1, a1, b1, X[ 7], 5, k3); - Subround(I, b1, c1, d1, e1, a1, X[15], 6, k3); - Subround(I, a1, b1, c1, d1, e1, X[14], 8, k3); - Subround(I, e1, a1, b1, c1, d1, X[ 5], 6, k3); - Subround(I, d1, e1, a1, b1, c1, X[ 6], 5, k3); - Subround(I, c1, d1, e1, a1, b1, X[ 2], 12, k3); - - Subround(J, b1, c1, d1, e1, a1, X[ 4], 9, k4); - Subround(J, a1, b1, c1, d1, e1, X[ 0], 15, k4); - Subround(J, e1, a1, b1, c1, d1, X[ 5], 5, k4); - Subround(J, d1, e1, a1, b1, c1, X[ 9], 11, k4); - Subround(J, c1, d1, e1, a1, b1, X[ 7], 6, k4); - Subround(J, b1, c1, d1, e1, a1, X[12], 8, k4); - Subround(J, a1, b1, c1, d1, e1, X[ 2], 13, k4); - Subround(J, e1, a1, b1, c1, d1, X[10], 12, k4); - Subround(J, d1, e1, a1, b1, c1, X[14], 5, k4); - Subround(J, c1, d1, e1, a1, b1, X[ 1], 12, k4); - Subround(J, b1, c1, d1, e1, a1, X[ 3], 13, k4); - Subround(J, a1, b1, c1, d1, e1, X[ 8], 14, k4); - Subround(J, e1, a1, b1, c1, d1, X[11], 11, k4); - Subround(J, d1, e1, a1, b1, c1, X[ 6], 8, k4); - Subround(J, c1, d1, e1, a1, b1, X[15], 5, k4); - Subround(J, b1, c1, d1, e1, a1, X[13], 6, k4); - - Subround(J, a2, b2, c2, d2, e2, X[ 5], 8, k5); - Subround(J, e2, a2, b2, c2, d2, X[14], 9, k5); - Subround(J, d2, e2, a2, b2, c2, X[ 7], 9, k5); - Subround(J, c2, d2, e2, a2, b2, X[ 0], 11, k5); - Subround(J, b2, c2, d2, e2, a2, X[ 9], 13, k5); - Subround(J, a2, b2, c2, d2, e2, X[ 2], 15, k5); - Subround(J, e2, a2, b2, c2, d2, X[11], 15, k5); - Subround(J, d2, e2, a2, b2, c2, X[ 4], 5, k5); - Subround(J, c2, d2, e2, a2, b2, X[13], 7, k5); - Subround(J, b2, c2, d2, e2, a2, X[ 6], 7, k5); - Subround(J, a2, b2, c2, d2, e2, X[15], 8, k5); - Subround(J, e2, a2, b2, c2, d2, X[ 8], 11, k5); - Subround(J, d2, e2, a2, b2, c2, X[ 1], 14, k5); - Subround(J, c2, d2, e2, a2, b2, X[10], 14, k5); - Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5); - Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5); - - Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); - Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6); - Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6); - Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6); - Subround(I, a2, b2, c2, d2, e2, X[ 0], 12, k6); - Subround(I, e2, a2, b2, c2, d2, X[13], 8, k6); - Subround(I, d2, e2, a2, b2, c2, X[ 5], 9, k6); - Subround(I, c2, d2, e2, a2, b2, X[10], 11, k6); - Subround(I, b2, c2, d2, e2, a2, X[14], 7, k6); - Subround(I, a2, b2, c2, d2, e2, X[15], 7, k6); - Subround(I, e2, a2, b2, c2, d2, X[ 8], 12, k6); - Subround(I, d2, e2, a2, b2, c2, X[12], 7, k6); - Subround(I, c2, d2, e2, a2, b2, X[ 4], 6, k6); - Subround(I, b2, c2, d2, e2, a2, X[ 9], 15, k6); - Subround(I, a2, b2, c2, d2, e2, X[ 1], 13, k6); - Subround(I, e2, a2, b2, c2, d2, X[ 2], 11, k6); - - Subround(H, d2, e2, a2, b2, c2, X[15], 9, k7); - Subround(H, c2, d2, e2, a2, b2, X[ 5], 7, k7); - Subround(H, b2, c2, d2, e2, a2, X[ 1], 15, k7); - Subround(H, a2, b2, c2, d2, e2, X[ 3], 11, k7); - Subround(H, e2, a2, b2, c2, d2, X[ 7], 8, k7); - Subround(H, d2, e2, a2, b2, c2, X[14], 6, k7); - Subround(H, c2, d2, e2, a2, b2, X[ 6], 6, k7); - Subround(H, b2, c2, d2, e2, a2, X[ 9], 14, k7); - Subround(H, a2, b2, c2, d2, e2, X[11], 12, k7); - Subround(H, e2, a2, b2, c2, d2, X[ 8], 13, k7); - Subround(H, d2, e2, a2, b2, c2, X[12], 5, k7); - Subround(H, c2, d2, e2, a2, b2, X[ 2], 14, k7); - Subround(H, b2, c2, d2, e2, a2, X[10], 13, k7); - Subround(H, a2, b2, c2, d2, e2, X[ 0], 13, k7); - Subround(H, e2, a2, b2, c2, d2, X[ 4], 7, k7); - Subround(H, d2, e2, a2, b2, c2, X[13], 5, k7); - - Subround(G, c2, d2, e2, a2, b2, X[ 8], 15, k8); - Subround(G, b2, c2, d2, e2, a2, X[ 6], 5, k8); - Subround(G, a2, b2, c2, d2, e2, X[ 4], 8, k8); - Subround(G, e2, a2, b2, c2, d2, X[ 1], 11, k8); - Subround(G, d2, e2, a2, b2, c2, X[ 3], 14, k8); - Subround(G, c2, d2, e2, a2, b2, X[11], 14, k8); - Subround(G, b2, c2, d2, e2, a2, X[15], 6, k8); - Subround(G, a2, b2, c2, d2, e2, X[ 0], 14, k8); - Subround(G, e2, a2, b2, c2, d2, X[ 5], 6, k8); - Subround(G, d2, e2, a2, b2, c2, X[12], 9, k8); - Subround(G, c2, d2, e2, a2, b2, X[ 2], 12, k8); - Subround(G, b2, c2, d2, e2, a2, X[13], 9, k8); - Subround(G, a2, b2, c2, d2, e2, X[ 9], 12, k8); - Subround(G, e2, a2, b2, c2, d2, X[ 7], 5, k8); - Subround(G, d2, e2, a2, b2, c2, X[10], 15, k8); - Subround(G, c2, d2, e2, a2, b2, X[14], 8, k8); - - Subround(F, b2, c2, d2, e2, a2, X[12], 8, k9); - Subround(F, a2, b2, c2, d2, e2, X[15], 5, k9); - Subround(F, e2, a2, b2, c2, d2, X[10], 12, k9); - Subround(F, d2, e2, a2, b2, c2, X[ 4], 9, k9); - Subround(F, c2, d2, e2, a2, b2, X[ 1], 12, k9); - Subround(F, b2, c2, d2, e2, a2, X[ 5], 5, k9); - Subround(F, a2, b2, c2, d2, e2, X[ 8], 14, k9); - Subround(F, e2, a2, b2, c2, d2, X[ 7], 6, k9); - Subround(F, d2, e2, a2, b2, c2, X[ 6], 8, k9); - Subround(F, c2, d2, e2, a2, b2, X[ 2], 13, k9); - Subround(F, b2, c2, d2, e2, a2, X[13], 6, k9); - Subround(F, a2, b2, c2, d2, e2, X[14], 5, k9); - Subround(F, e2, a2, b2, c2, d2, X[ 0], 15, k9); - Subround(F, d2, e2, a2, b2, c2, X[ 3], 13, k9); - Subround(F, c2, d2, e2, a2, b2, X[ 9], 11, k9); - Subround(F, b2, c2, d2, e2, a2, X[11], 11, k9); - - c1 = digest[1] + c1 + d2; - digest[1] = digest[2] + d1 + e2; - digest[2] = digest[3] + e1 + a2; - digest[3] = digest[4] + a1 + b2; - digest[4] = digest[0] + b1 + c2; - digest[0] = c1; -} - -#else // TC_MINIMIZE_CODE_SIZE - -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2017 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#pragma optimize ("tl", on) - -typedef unsigned __int32 uint32; -typedef unsigned __int8 byte; - -#include <stdlib.h> -#pragma intrinsic (_lrotl) - -static const byte OrderTab[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, - 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, - 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, - 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, - 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, - 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, - 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, - 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, - 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 -}; - -static const byte RolTab[] = { - 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, - 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, - 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, - 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, - 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, - 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, - 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, - 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, - 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, - 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 -}; - -static const uint32 KTab[] = { - 0x00000000UL, - 0x5A827999UL, - 0x6ED9EBA1UL, - 0x8F1BBCDCUL, - 0xA953FD4EUL, - 0x50A28BE6UL, - 0x5C4DD124UL, - 0x6D703EF3UL, - 0x7A6D76E9UL, - 0x00000000UL -}; - - -void RMD160Transform (unsigned __int32 *state, const unsigned __int32 *data) -{ - uint32 a, b, c, d, e; - uint32 a2, b2, c2, d2, e2; - byte pos; - uint32 tmp; - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - - for (pos = 0; pos < 160; ++pos) - { - tmp = a + data[OrderTab[pos]] + KTab[pos >> 4]; - - switch (pos >> 4) - { - case 0: case 9: tmp += F (b, c, d); break; - case 1: case 8: tmp += G (b, c, d); break; - case 2: case 7: tmp += H (b, c, d); break; - case 3: case 6: tmp += I (b, c, d); break; - case 4: case 5: tmp += J (b, c, d); break; - } - - tmp = _lrotl (tmp, RolTab[pos]) + e; - a = e; - e = d; - d = _lrotl (c, 10); - c = b; - b = tmp; - - if (pos == 79) - { - a2 = a; - b2 = b; - c2 = c; - d2 = d; - e2 = e; - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - } - } - - tmp = state[1] + c2 + d; - state[1] = state[2] + d2 + e; - state[2] = state[3] + e2 + a; - state[3] = state[4] + a2 + b; - state[4] = state[0] + b2 + c; - state[0] = tmp; -} - -#endif // TC_MINIMIZE_CODE_SIZE diff --git a/src/Crypto/Rmd160.h b/src/Crypto/Rmd160.h deleted file mode 100644 index 81b5d6f0..00000000 --- a/src/Crypto/Rmd160.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TC_HEADER_Crypto_Ripemd160 -#define TC_HEADER_Crypto_Ripemd160 - -#include "Common/Tcdefs.h" - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#define RIPEMD160_BLOCK_LENGTH 64 - -typedef struct RMD160Context -{ - unsigned __int32 state[5]; -#ifndef TC_WINDOWS_BOOT - uint64 count; -#else - uint32 count; -#endif - unsigned char buffer[RIPEMD160_BLOCK_LENGTH]; -} RMD160_CTX; - -void RMD160Init (RMD160_CTX *ctx); -void RMD160Transform (unsigned __int32 *state, const unsigned __int32 *data); -void RMD160Update (RMD160_CTX *ctx, const unsigned char *input, unsigned __int32 len); -void RMD160Final (unsigned char *digest, RMD160_CTX *ctx); - -#if defined(__cplusplus) -} -#endif - -#endif // TC_HEADER_Crypto_Ripemd160 diff --git a/src/Crypto/Sha2.c b/src/Crypto/Sha2.c index 505ebb05..31cba7f5 100644 --- a/src/Crypto/Sha2.c +++ b/src/Crypto/Sha2.c @@ -10,7 +10,7 @@ and released into public domain. #include "Crypto/cpu.h" #include "Crypto/misc.h" -#ifdef _UEFI +#if defined(_UEFI) || defined(CRYPTOPP_DISABLE_ASM) #define NO_OPTIMIZED_VERSIONS #endif @@ -318,7 +318,7 @@ extern "C" #endif -CRYPTOPP_ALIGN_DATA(16) uint_32t SHA256_K[64] CRYPTOPP_SECTION_ALIGN16 = { +CRYPTOPP_ALIGN_DATA(16) static const uint_32t SHA256_K[64] CRYPTOPP_SECTION_ALIGN16 = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, @@ -774,7 +774,7 @@ void sha256_begin(sha256_ctx* ctx) if (!sha256transfunc) { #ifndef NO_OPTIMIZED_VERSIONS -#ifdef _M_X64 +#if CRYPTOPP_BOOL_X64 if (g_isIntel && HasSAVX2() && HasSBMI2()) sha256transfunc = Avx2Sha256Transform; else if (g_isIntel && HasSAVX()) diff --git a/src/Crypto/Sha2.h b/src/Crypto/Sha2.h index 37625ce8..1fbcb8d1 100644 --- a/src/Crypto/Sha2.h +++ b/src/Crypto/Sha2.h @@ -12,6 +12,13 @@ #include "Common/Endian.h" #include "Crypto/config.h" +#ifdef WOLFCRYPT_BACKEND + #include <wolfssl/options.h> + #include <wolfssl/wolfcrypt/sha256.h> + #include <wolfssl/wolfcrypt/sha512.h> + #include <wolfssl/wolfcrypt/hash.h> +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -22,12 +29,16 @@ extern "C" { #define SHA512_DIGEST_SIZE 64 #define SHA512_BLOCK_SIZE 128 -#if CRYPTOPP_BOOL_X64 +#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) #define SHA2_ALIGN CRYPTOPP_ALIGN_DATA(32) #else #define SHA2_ALIGN CRYPTOPP_ALIGN_DATA(16) #endif +#ifdef WOLFCRYPT_BACKEND +typedef struct wc_Sha512 sha512_ctx; +typedef struct wc_Sha256 sha256_ctx; +#else typedef struct { uint_64t count[2]; SHA2_ALIGN uint_64t hash[8]; @@ -39,6 +50,7 @@ typedef struct SHA2_ALIGN uint_32t hash[8]; SHA2_ALIGN uint_32t wbuf[16]; } sha256_ctx; +#endif void sha512_begin(sha512_ctx* ctx); diff --git a/src/Crypto/Sources b/src/Crypto/Sources index 2db68a7a..9542d4b6 100644 --- a/src/Crypto/Sources +++ b/src/Crypto/Sources @@ -7,7 +7,6 @@ NTTARGETFILES = \ "$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).obj" \ "$(OBJ_PATH)\$(O)\Aes_hw_cpu.obj" \ "$(OBJ_PATH)\$(O)\rdrand_ml.obj" \ - "$(OBJ_PATH)\$(O)\gost89_$(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" \ @@ -22,18 +21,21 @@ NTTARGETFILES = \ SOURCES = \ Aes_$(TC_ARCH).asm \ - gost89_$(TC_ARCH).asm \ Aes_hw_cpu.asm \ rdrand_ml.asm \ + rdseed_ml.asm \ Aeskey.c \ Aestab.c \ + blake2s.c \ + blake2s_SSE2.c \ + blake2s_SSE41.c \ + blake2s_SSSE3.c \ chacha-xmm.c \ chacha256.c \ chachaRng.c \ cpu.c \ jitterentropy-base.c \ rdrand.c \ - Rmd160.c \ SerpentFast.c \ SerpentFast_simd.cpp \ Sha2.c \ @@ -42,7 +44,6 @@ SOURCES = \ t1ha2_selfcheck.c \ Twofish.c \ Twofish_$(TC_ARCH).S \ - GostCipher.c \ Streebog.c \ kuznyechik.c \ kuznyechik_simd.c \ diff --git a/src/Crypto/Streebog.c b/src/Crypto/Streebog.c index e443ecae..84991021 100644 --- a/src/Crypto/Streebog.c +++ b/src/Crypto/Streebog.c @@ -276,103 +276,6 @@ STREEBOG_ALIGN(16) static const unsigned long long C[12][8] = { }; #endif -#ifndef __GOST3411_BIG_ENDIAN__ -static const unsigned long long A[64] = { - 0x8e20faa72ba0b470ULL, 0x47107ddd9b505a38ULL, 0xad08b0e0c3282d1cULL, - 0xd8045870ef14980eULL, 0x6c022c38f90a4c07ULL, 0x3601161cf205268dULL, - 0x1b8e0b0e798c13c8ULL, 0x83478b07b2468764ULL, 0xa011d380818e8f40ULL, - 0x5086e740ce47c920ULL, 0x2843fd2067adea10ULL, 0x14aff010bdd87508ULL, - 0x0ad97808d06cb404ULL, 0x05e23c0468365a02ULL, 0x8c711e02341b2d01ULL, - 0x46b60f011a83988eULL, 0x90dab52a387ae76fULL, 0x486dd4151c3dfdb9ULL, - 0x24b86a840e90f0d2ULL, 0x125c354207487869ULL, 0x092e94218d243cbaULL, - 0x8a174a9ec8121e5dULL, 0x4585254f64090fa0ULL, 0xaccc9ca9328a8950ULL, - 0x9d4df05d5f661451ULL, 0xc0a878a0a1330aa6ULL, 0x60543c50de970553ULL, - 0x302a1e286fc58ca7ULL, 0x18150f14b9ec46ddULL, 0x0c84890ad27623e0ULL, - 0x0642ca05693b9f70ULL, 0x0321658cba93c138ULL, 0x86275df09ce8aaa8ULL, - 0x439da0784e745554ULL, 0xafc0503c273aa42aULL, 0xd960281e9d1d5215ULL, - 0xe230140fc0802984ULL, 0x71180a8960409a42ULL, 0xb60c05ca30204d21ULL, - 0x5b068c651810a89eULL, 0x456c34887a3805b9ULL, 0xac361a443d1c8cd2ULL, - 0x561b0d22900e4669ULL, 0x2b838811480723baULL, 0x9bcf4486248d9f5dULL, - 0xc3e9224312c8c1a0ULL, 0xeffa11af0964ee50ULL, 0xf97d86d98a327728ULL, - 0xe4fa2054a80b329cULL, 0x727d102a548b194eULL, 0x39b008152acb8227ULL, - 0x9258048415eb419dULL, 0x492c024284fbaec0ULL, 0xaa16012142f35760ULL, - 0x550b8e9e21f7a530ULL, 0xa48b474f9ef5dc18ULL, 0x70a6a56e2440598eULL, - 0x3853dc371220a247ULL, 0x1ca76e95091051adULL, 0x0edd37c48a08a6d8ULL, - 0x07e095624504536cULL, 0x8d70c431ac02a736ULL, 0xc83862965601dd1bULL, - 0x641c314b2b8ee083ULL -}; -#else -static const unsigned long long A[64] = { - 0x70b4a02ba7fa208eULL, 0x385a509bdd7d1047ULL, 0x1c2d28c3e0b008adULL, - 0x0e9814ef705804d8ULL, 0x074c0af9382c026cULL, 0x8d2605f21c160136ULL, - 0xc8138c790e0b8e1bULL, 0x648746b2078b4783ULL, 0x408f8e8180d311a0ULL, - 0x20c947ce40e78650ULL, 0x10eaad6720fd4328ULL, 0x0875d8bd10f0af14ULL, - 0x04b46cd00878d90aULL, 0x025a3668043ce205ULL, 0x012d1b34021e718cULL, - 0x8e98831a010fb646ULL, 0x6fe77a382ab5da90ULL, 0xb9fd3d1c15d46d48ULL, - 0xd2f0900e846ab824ULL, 0x6978480742355c12ULL, 0xba3c248d21942e09ULL, - 0x5d1e12c89e4a178aULL, 0xa00f09644f258545ULL, 0x50898a32a99cccacULL, - 0x5114665f5df04d9dULL, 0xa60a33a1a078a8c0ULL, 0x530597de503c5460ULL, - 0xa78cc56f281e2a30ULL, 0xdd46ecb9140f1518ULL, 0xe02376d20a89840cULL, - 0x709f3b6905ca4206ULL, 0x38c193ba8c652103ULL, 0xa8aae89cf05d2786ULL, - 0x5455744e78a09d43ULL, 0x2aa43a273c50c0afULL, 0x15521d9d1e2860d9ULL, - 0x842980c00f1430e2ULL, 0x429a4060890a1871ULL, 0x214d2030ca050cb6ULL, - 0x9ea81018658c065bULL, 0xb905387a88346c45ULL, 0xd28c1c3d441a36acULL, - 0x69460e90220d1b56ULL, 0xba2307481188832bULL, 0x5d9f8d248644cf9bULL, - 0xa0c1c8124322e9c3ULL, 0x50ee6409af11faefULL, 0x2877328ad9867df9ULL, - 0x9c320ba85420fae4ULL, 0x4e198b542a107d72ULL, 0x2782cb2a1508b039ULL, - 0x9d41eb1584045892ULL, 0xc0aefb8442022c49ULL, 0x6057f342210116aaULL, - 0x30a5f7219e8e0b55ULL, 0x18dcf59e4f478ba4ULL, 0x8e5940246ea5a670ULL, - 0x47a2201237dc5338ULL, 0xad511009956ea71cULL, 0xd8a6088ac437dd0eULL, - 0x6c5304456295e007ULL, 0x36a702ac31c4708dULL, 0x1bdd0156966238c8ULL, - 0x83e08e2b4b311c64ULL -}; -#endif - -static const unsigned char Tau[64] = { - 0, 8, 16, 24, 32, 40, 48, 56, - 1, 9, 17, 25, 33, 41, 49, 57, - 2, 10, 18, 26, 34, 42, 50, 58, - 3, 11, 19, 27, 35, 43, 51, 59, - 4, 12, 20, 28, 36, 44, 52, 60, - 5, 13, 21, 29, 37, 45, 53, 61, - 6, 14, 22, 30, 38, 46, 54, 62, - 7, 15, 23, 31, 39, 47, 55, 63 -}; - -static const unsigned char Pi[256] = { - 252, 238, 221, 17, 207, 110, 49, 22, - 251, 196, 250, 218, 35, 197, 4, 77, - 233, 119, 240, 219, 147, 46, 153, 186, - 23, 54, 241, 187, 20, 205, 95, 193, - 249, 24, 101, 90, 226, 92, 239, 33, - 129, 28, 60, 66, 139, 1, 142, 79, - 5, 132, 2, 174, 227, 106, 143, 160, - 6, 11, 237, 152, 127, 212, 211, 31, - 235, 52, 44, 81, 234, 200, 72, 171, - 242, 42, 104, 162, 253, 58, 206, 204, - 181, 112, 14, 86, 8, 12, 118, 18, - 191, 114, 19, 71, 156, 183, 93, 135, - 21, 161, 150, 41, 16, 123, 154, 199, - 243, 145, 120, 111, 157, 158, 178, 177, - 50, 117, 25, 61, 255, 53, 138, 126, - 109, 84, 198, 128, 195, 189, 13, 87, - 223, 245, 36, 169, 62, 168, 67, 201, - 215, 121, 214, 246, 124, 34, 185, 3, - 224, 15, 236, 222, 122, 148, 176, 188, - 220, 232, 40, 80, 78, 51, 10, 74, - 167, 151, 96, 115, 30, 0, 98, 68, - 26, 184, 56, 130, 100, 159, 38, 65, - 173, 69, 70, 146, 39, 94, 85, 47, - 140, 163, 165, 125, 105, 213, 149, 59, - 7, 88, 179, 64, 134, 172, 29, 247, - 48, 55, 107, 228, 136, 217, 231, 137, - 225, 27, 131, 73, 76, 63, 248, 254, - 141, 83, 170, 144, 202, 216, 133, 97, - 32, 113, 103, 164, 45, 43, 9, 91, - 203, 155, 37, 208, 190, 229, 108, 82, - 89, 166, 116, 210, 230, 244, 180, 192, - 209, 102, 175, 194, 57, 75, 99, 182 -}; #endif // CONSTS #if 1 @@ -1909,11 +1812,10 @@ add512(const unsigned long long *x, const unsigned long long *y, unsigned long l z[7] = x[7] ^ y[7]; \ } -#ifndef __GOST3411_BIG_ENDIAN__ #define __XLPS_FOR for (_i = 0; _i <= 7; _i++) +#ifndef __GOST3411_BIG_ENDIAN__ #define _datai _i #else -#define __XLPS_FOR for (_i = 7; _i >= 0; _i--) #define _datai 7 - _i #endif @@ -1933,14 +1835,22 @@ add512(const unsigned long long *x, const unsigned long long *y, unsigned long l \ __XLPS_FOR \ {\ - data[_datai] = Ax[0][(r0 >> (_i << 3)) & 0xFF]; \ - data[_datai] ^= Ax[1][(r1 >> (_i << 3)) & 0xFF]; \ - data[_datai] ^= Ax[2][(r2 >> (_i << 3)) & 0xFF]; \ - data[_datai] ^= Ax[3][(r3 >> (_i << 3)) & 0xFF]; \ - data[_datai] ^= Ax[4][(r4 >> (_i << 3)) & 0xFF]; \ - data[_datai] ^= Ax[5][(r5 >> (_i << 3)) & 0xFF]; \ - data[_datai] ^= Ax[6][(r6 >> (_i << 3)) & 0xFF]; \ - data[_datai] ^= Ax[7][(r7 >> (_i << 3)) & 0xFF]; \ + data[_datai] = Ax[0][r0 & 0xFF]; \ + data[_datai] ^= Ax[1][r1 & 0xFF]; \ + data[_datai] ^= Ax[2][r2 & 0xFF]; \ + data[_datai] ^= Ax[3][r3 & 0xFF]; \ + data[_datai] ^= Ax[4][r4 & 0xFF]; \ + data[_datai] ^= Ax[5][r5 & 0xFF]; \ + data[_datai] ^= Ax[6][r6 & 0xFF]; \ + data[_datai] ^= Ax[7][r7 & 0xFF]; \ + r0 >>= 8; \ + r1 >>= 8; \ + r2 >>= 8; \ + r3 >>= 8; \ + r4 >>= 8; \ + r5 >>= 8; \ + r6 >>= 8; \ + r7 >>= 8; \ }\ } @@ -1995,10 +1905,10 @@ VC_INLINE __m128i _mm_set_epi64x_a(uint64 i0, uint64 i1) { #define LOAD(P, xmm0, xmm1, xmm2, xmm3) { \ const __m128i *__m128p = (const __m128i *) &P[0]; \ - xmm0 = _mm_load_si128(&__m128p[0]); \ - xmm1 = _mm_load_si128(&__m128p[1]); \ - xmm2 = _mm_load_si128(&__m128p[2]); \ - xmm3 = _mm_load_si128(&__m128p[3]); \ + xmm0 = _mm_loadu_si128(&__m128p[0]); \ + xmm1 = _mm_loadu_si128(&__m128p[1]); \ + xmm2 = _mm_loadu_si128(&__m128p[2]); \ + xmm3 = _mm_loadu_si128(&__m128p[3]); \ } #define UNLOAD(P, xmm0, xmm1, xmm2, xmm3) { \ @@ -2018,10 +1928,10 @@ VC_INLINE __m128i _mm_set_epi64x_a(uint64 i0, uint64 i1) { #define X128M(P, xmm0, xmm1, xmm2, xmm3) { \ const __m128i *__m128p = (const __m128i *) &P[0]; \ - xmm0 = _mm_xor_si128(xmm0, _mm_load_si128(&__m128p[0])); \ - xmm1 = _mm_xor_si128(xmm1, _mm_load_si128(&__m128p[1])); \ - xmm2 = _mm_xor_si128(xmm2, _mm_load_si128(&__m128p[2])); \ - xmm3 = _mm_xor_si128(xmm3, _mm_load_si128(&__m128p[3])); \ + xmm0 = _mm_xor_si128(xmm0, _mm_loadu_si128(&__m128p[0])); \ + xmm1 = _mm_xor_si128(xmm1, _mm_loadu_si128(&__m128p[1])); \ + xmm2 = _mm_xor_si128(xmm2, _mm_loadu_si128(&__m128p[2])); \ + xmm3 = _mm_xor_si128(xmm3, _mm_loadu_si128(&__m128p[3])); \ } #define _mm_xor_64(mm0, mm1) _mm_xor_si64(mm0, _mm_cvtsi64_m64(mm1)) @@ -2065,31 +1975,6 @@ VC_INLINE __m128i _mm_set_epi64x_a(uint64 i0, uint64 i1) { xmm4 = _mm_set_epi64(mm1, mm0); \ } -#define __EXTRACT64(row, xmm0, xmm1, xmm2, xmm3, xmm4) { \ - __m128i tmm4; \ - register unsigned long long r0, r1; \ - r0 = Ax[0][_mm_extract_epi8(xmm0, row + 0)]; \ - r0 ^= Ax[1][_mm_extract_epi8(xmm0, row + 8)]; \ - r0 ^= Ax[2][_mm_extract_epi8(xmm1, row + 0)]; \ - r0 ^= Ax[3][_mm_extract_epi8(xmm1, row + 8)]; \ - r0 ^= Ax[4][_mm_extract_epi8(xmm2, row + 0)]; \ - r0 ^= Ax[5][_mm_extract_epi8(xmm2, row + 8)]; \ - r0 ^= Ax[6][_mm_extract_epi8(xmm3, row + 0)]; \ - r0 ^= Ax[7][_mm_extract_epi8(xmm3, row + 8)]; \ - \ - r1 = Ax[0][_mm_extract_epi8(xmm0, row + 1)]; \ - r1 ^= Ax[1][_mm_extract_epi8(xmm0, row + 9)]; \ - r1 ^= Ax[2][_mm_extract_epi8(xmm1, row + 1)]; \ - r1 ^= Ax[3][_mm_extract_epi8(xmm1, row + 9)]; \ - r1 ^= Ax[4][_mm_extract_epi8(xmm2, row + 1)]; \ - r1 ^= Ax[5][_mm_extract_epi8(xmm2, row + 9)]; \ - r1 ^= Ax[6][_mm_extract_epi8(xmm3, row + 1)]; \ - r1 ^= Ax[7][_mm_extract_epi8(xmm3, row + 9)]; \ - xmm4 = _mm_cvtsi64_si128((long long) r0); \ - tmm4 = _mm_cvtsi64_si128((long long) r1); \ - xmm4 = _mm_unpacklo_epi64(xmm4, tmm4); \ -} - #define EXTRACT64(row, xmm0, xmm1, xmm2, xmm3, xmm4) { \ __m128i tmm4; \ register unsigned short ax; \ diff --git a/src/Crypto/Twofish.c b/src/Crypto/Twofish.c index 8ab59081..ad93b66f 100644 --- a/src/Crypto/Twofish.c +++ b/src/Crypto/Twofish.c @@ -54,7 +54,7 @@ #define UNROLL_TWOFISH #endif -#if CRYPTOPP_BOOL_X64 +#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) /* these are 64-bit assembly implementation taken from https://github.com/jkivilin/supercop-blockciphers Copyright © 2011-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi> @@ -607,7 +607,7 @@ void twofish_set_key(TwofishInstance *instance, const u4byte in_key[]) byte S8[16]; uint32 S32[4]; } us; - int i; + unsigned int i; const byte* key = (const byte*) in_key; us.S32[0] = RS[0][key[0]] ^ RS[1][key[1]] ^ RS[2][key[2]] ^ RS[3][key[3]] ^ RS[4][key[4]] ^ RS[5][key[5]] ^ RS[6][key[6]] ^ RS[7][key[7]]; @@ -630,7 +630,7 @@ void twofish_set_key(TwofishInstance *instance, const u4byte in_key[]) uint32 b = rotl32(MDSQ[0][Q[0][Q[0][Q[1][Q[1][i + 1] ^ key[28]] ^ key[20]] ^ key[12]] ^ key[4]] ^ MDSQ[1][Q[0][Q[1][Q[1][Q[0][i + 1] ^ key[29]] ^ key[21]] ^ key[13]] ^ key[5]] ^ MDSQ[2][Q[1][Q[0][Q[0][Q[0][i + 1] ^ key[30]] ^ key[22]] ^ key[14]] ^ key[6]] ^ MDSQ[3][Q[1][Q[1][Q[0][Q[1][i + 1] ^ key[31]] ^ key[23]] ^ key[15]] ^ key[7]], 8); a += b; -#if CRYPTOPP_BOOL_X64 +#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) if (i < 8) { instance->w[i] = a; @@ -998,7 +998,7 @@ void twofish_set_key(TwofishInstance *instance, const u4byte in_key[]) #ifndef TC_MINIMIZE_CODE_SIZE -#if (CRYPTOPP_BOOL_X64 == 0) +#if (CRYPTOPP_BOOL_X64 == 0) || defined(CRYPTOPP_DISABLE_ASM) void twofish_encrypt(TwofishInstance *ks, const u4byte in_blk[4], u4byte out_blk[4]) { uint32* rk = ks->l_key; @@ -1071,7 +1071,7 @@ void twofish_encrypt(TwofishInstance *instance, const u4byte in_blk[4], u4byte o #ifndef TC_MINIMIZE_CODE_SIZE -#if (CRYPTOPP_BOOL_X64 == 0) +#if (CRYPTOPP_BOOL_X64 == 0) || defined(CRYPTOPP_DISABLE_ASM) void twofish_decrypt(TwofishInstance *ks, const u4byte in_blk[4], u4byte out_blk[4]) { uint32* rk = ks->l_key; diff --git a/src/Crypto/Twofish.h b/src/Crypto/Twofish.h index cec99c7c..e74826eb 100644 --- a/src/Crypto/Twofish.h +++ b/src/Crypto/Twofish.h @@ -35,7 +35,7 @@ extern "C" #endif typedef struct { -#if CRYPTOPP_BOOL_X64 +#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) u4byte mk_tab[4][256], w[8], k[32]; #else u4byte l_key[40]; @@ -54,7 +54,7 @@ typedef struct /* in_key must be 32-bytes long */ void twofish_set_key(TwofishInstance *instance, const u4byte in_key[]); -#if CRYPTOPP_BOOL_X64 +#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) void twofish_encrypt_blocks(TwofishInstance *instance, const byte* in_blk, byte* out_blk, uint32 blockCount); void twofish_decrypt_blocks(TwofishInstance *instance, const byte* in_blk, byte* out_blk, uint32 blockCount); #define twofish_encrypt(instance,in_blk,out_blk) twofish_encrypt_blocks(instance, (const byte*) in_blk, (byte*) out_blk, 1) diff --git a/src/Crypto/Whirlpool.c b/src/Crypto/Whirlpool.c index 35188c63..9af0cb32 100644 --- a/src/Crypto/Whirlpool.c +++ b/src/Crypto/Whirlpool.c @@ -643,6 +643,20 @@ static const uint64 Whirlpool_C[8*256+R] = { void WhirlpoolTransform(uint64 *digest, const uint64 *block) { #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE +#if defined(__GNUC__) && (CRYPTOPP_GCC_VERSION <= 40407) + /* workaround for gcc 4.4.7 bug under CentOS which causes crash + * in inline assembly. + * This dummy check that is always false since "block" is aligned. + */ + uint64 lb = (uint64) block; + if (lb % 16) + { + TC_THROW_FATAL_EXCEPTION; + } +#endif +#endif + +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE if (HasISSE()) { #ifdef __GNUC__ @@ -880,7 +894,7 @@ static uint64 HashMultipleBlocks(WHIRLPOOL_CTX * const ctx, const uint64 *input, #if BYTE_ORDER == BIG_ENDIAN WhirlpoolTransform(ctx->state, input); #else - CorrectEndianess(dataBuf, input, 64); + CorrectEndianness(dataBuf, input, 64); WhirlpoolTransform(ctx->state, dataBuf); #endif input += 8; @@ -933,7 +947,6 @@ void WHIRLPOOL_add(const unsigned char * input, HashMultipleBlocks(ctx, dataBuf, 64); input += (64-num); len -= (64-num); - num = 0; // drop through and do the rest } else @@ -995,7 +1008,7 @@ void WHIRLPOOL_finalize(WHIRLPOOL_CTX * const ctx, memset(data, 0, 32); } #if BYTE_ORDER == LITTLE_ENDIAN - CorrectEndianess(dataBuf, dataBuf, 32); + CorrectEndianness(dataBuf, dataBuf, 32); #endif dataBuf[4] = 0; @@ -1005,7 +1018,7 @@ void WHIRLPOOL_finalize(WHIRLPOOL_CTX * const ctx, WhirlpoolTransform(stateBuf, dataBuf); #if BYTE_ORDER == LITTLE_ENDIAN - CorrectEndianess(stateBuf, stateBuf, 64); + CorrectEndianness(stateBuf, stateBuf, 64); #endif memcpy(result, stateBuf, 64); } diff --git a/src/Crypto/blake2-impl.h b/src/Crypto/blake2-impl.h new file mode 100644 index 00000000..ad9d88fe --- /dev/null +++ b/src/Crypto/blake2-impl.h @@ -0,0 +1,86 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#ifndef BLAKE2_IMPL_H +#define BLAKE2_IMPL_H + +#define NATIVE_LITTLE_ENDIAN + +#include <stdint.h> +#include <string.h> + +#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) + #if defined(_MSC_VER) + #define BLAKE2_INLINE __inline + #elif defined(__GNUC__) + #define BLAKE2_INLINE __inline__ + #else + #define BLAKE2_INLINE + #endif +#else + #define BLAKE2_INLINE inline +#endif + +static BLAKE2_INLINE uint32_t load32( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + return (( uint32_t )( p[0] ) << 0) | + (( uint32_t )( p[1] ) << 8) | + (( uint32_t )( p[2] ) << 16) | + (( uint32_t )( p[3] ) << 24) ; +#endif +} + +static BLAKE2_INLINE void store16( void *dst, uint16_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + +static BLAKE2_INLINE void store32( void *dst, uint32_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); +#endif +} + +static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 32 - c ) ); +} + +/* prevents compiler optimizing out memset() */ +static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) +{ + static void *(*const volatile memset_v)(void *, int, size_t) = &memset; + memset_v(v, 0, n); +} + +#endif diff --git a/src/Crypto/blake2.h b/src/Crypto/blake2.h new file mode 100644 index 00000000..490ed43b --- /dev/null +++ b/src/Crypto/blake2.h @@ -0,0 +1,102 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + +#ifndef BLAKE2_H +#define BLAKE2_H +#include "Common/Tcdefs.h" + +#if defined(_MSC_VER) +#ifdef TC_WINDOWS_BOOT +#define BLAKE2_PACKED(x) x +#else +#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) +#endif + +#else +#define BLAKE2_PACKED(x) x __attribute__((packed)) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + enum blake2s_constant + { + BLAKE2S_BLOCKBYTES = 64, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, + BLAKE2S_PERSONALBYTES = 8 + }; + + typedef struct blake2s_state__ + { + uint32 h[8]; + uint32 t[2]; + uint32 f[2]; + uint8 buf[BLAKE2S_BLOCKBYTES]; + size_t buflen; + size_t outlen; + uint8 last_node; + } blake2s_state; + +#ifdef TC_WINDOWS_BOOT + #pragma pack(1) +#endif + + BLAKE2_PACKED(struct blake2s_param__ + { + uint8 digest_length; /* 1 */ + uint8 key_length; /* 2 */ + uint8 fanout; /* 3 */ + uint8 depth; /* 4 */ + uint32 leaf_length; /* 8 */ + uint32 node_offset; /* 12 */ + uint16 xof_length; /* 14 */ + uint8 node_depth; /* 15 */ + uint8 inner_length; /* 16 */ + /* uint8 reserved[0]; */ + uint8 salt[BLAKE2S_SALTBYTES]; /* 24 */ + uint8 personal[BLAKE2S_PERSONALBYTES]; /* 32 */ + }); + +#ifdef TC_WINDOWS_BOOT + #pragma pack() +#endif + + typedef struct blake2s_param__ blake2s_param; + + + /* Padded structs result in a compile-time error */ + enum { + BLAKE2_DUMMY_1 = 1/(int)(sizeof(blake2s_param) == BLAKE2S_OUTBYTES) + }; + + /* Streaming API */ + void blake2s_init( blake2s_state *S ); + void blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + void blake2s_update( blake2s_state *S, const void *in, size_t inlen ); + int blake2s_final( blake2s_state *S, unsigned char *out ); + + /* Simple API */ + int blake2s( void *out, const void *in, size_t inlen ); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/src/Crypto/blake2s-load-sse2.h b/src/Crypto/blake2s-load-sse2.h new file mode 100644 index 00000000..926eedda --- /dev/null +++ b/src/Crypto/blake2s-load-sse2.h @@ -0,0 +1,64 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + + +#ifndef BLAKE2S_LOAD_SSE2_H +#define BLAKE2S_LOAD_SSE2_H + +#define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0) +#define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1) +#define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m12,m10,m8,m14) +#define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m13,m11,m9,m15) +#define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14) +#define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10) +#define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m11,m0,m1,m5) +#define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m7,m2,m12,m3) +#define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11) +#define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8) +#define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m7,m3,m10,m9) +#define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m1,m6,m14,m4) +#define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7) +#define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9) +#define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m4,m5,m2,m15) +#define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m0,m10,m6,m8) +#define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9) +#define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0) +#define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m6,m11,m14,m3) +#define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m8,m12,m1,m13) +#define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2) +#define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12) +#define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m15,m7,m4,m1) +#define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m14,m5,m13,m9) +#define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12) +#define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5) +#define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m9,m6,m0,m8) +#define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m2,m3,m7,m11) +#define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13) +#define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11) +#define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m8,m15,m5,m2) +#define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m6,m4,m0,m10) +#define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6) +#define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15) +#define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m1,m13,m12,m10) +#define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m4,m7,m2,m5) +#define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10) +#define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2) +#define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m3,m9,m15,m13) +#define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m12,m14,m11,m0) + + +#endif diff --git a/src/Crypto/blake2s-load-sse41.h b/src/Crypto/blake2s-load-sse41.h new file mode 100644 index 00000000..9ac3f52a --- /dev/null +++ b/src/Crypto/blake2s-load-sse41.h @@ -0,0 +1,240 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + + +#ifndef BLAKE2S_LOAD_SSE41_H +#define BLAKE2S_LOAD_SSE41_H + +#define LOAD_MSG_0_1(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0))); + +#define LOAD_MSG_0_2(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1))); + +#define LOAD_MSG_0_3(buf) \ +t0 = _mm_shuffle_epi32(m2, _MM_SHUFFLE(3,2,0,1)); \ +t1 = _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,1,3,2)); \ +buf = _mm_blend_epi16(t0, t1, 0xC3); + +#define LOAD_MSG_0_4(buf) \ +t0 = _mm_blend_epi16(t0, t1, 0x3C); \ +buf = _mm_shuffle_epi32(t0, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_1_1(buf) \ +t0 = _mm_blend_epi16(m1, m2, 0x0C); \ +t1 = _mm_slli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); + +#define LOAD_MSG_1_2(buf) \ +t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \ +t1 = _mm_blend_epi16(m1,m3,0xC0); \ +t2 = _mm_blend_epi16(t0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_1_3(buf) \ +t0 = _mm_slli_si128(m1, 4); \ +t1 = _mm_blend_epi16(m2, t0, 0x30); \ +t2 = _mm_blend_epi16(m0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,0,1,2)); + +#define LOAD_MSG_1_4(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_slli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0, t1, 0x0C); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,0,1,2)); + +#define LOAD_MSG_2_1(buf) \ +t0 = _mm_unpackhi_epi32(m2,m3); \ +t1 = _mm_blend_epi16(m3,m1,0x0C); \ +t2 = _mm_blend_epi16(t0, t1, 0x0F); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + +#define LOAD_MSG_2_2(buf) \ +t0 = _mm_unpacklo_epi32(m2,m0); \ +t1 = _mm_blend_epi16(t0, m0, 0xF0); \ +t2 = _mm_slli_si128(m3, 8); \ +buf = _mm_blend_epi16(t1, t2, 0xC0); + +#define LOAD_MSG_2_3(buf) \ +t0 = _mm_blend_epi16(m0, m2, 0x3C); \ +t1 = _mm_srli_si128(m1, 12); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,3,2,1)); + +#define LOAD_MSG_2_4(buf) \ +t0 = _mm_slli_si128(m3, 4); \ +t1 = _mm_blend_epi16(m0, m1, 0x33); \ +t2 = _mm_blend_epi16(t1, t0, 0xC0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0)); + +#define LOAD_MSG_3_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_unpackhi_epi32(t0, m2); \ +t2 = _mm_blend_epi16(t1, m3, 0x0C); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + +#define LOAD_MSG_3_2(buf) \ +t0 = _mm_slli_si128(m2, 8); \ +t1 = _mm_blend_epi16(m3,m0,0x0C); \ +t2 = _mm_blend_epi16(t1, t0, 0xC0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); + +#define LOAD_MSG_3_3(buf) \ +t0 = _mm_blend_epi16(m0,m1,0x0F); \ +t1 = _mm_blend_epi16(t0, m3, 0xC0); \ +buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(0,1,2,3)); + +#define LOAD_MSG_3_4(buf) \ +t0 = _mm_alignr_epi8(m0, m1, 4); \ +buf = _mm_blend_epi16(t0, m2, 0x33); + +#define LOAD_MSG_4_1(buf) \ +t0 = _mm_unpacklo_epi64(m1,m2); \ +t1 = _mm_unpackhi_epi64(m0,m2); \ +t2 = _mm_blend_epi16(t0,t1,0x33); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); + +#define LOAD_MSG_4_2(buf) \ +t0 = _mm_unpackhi_epi64(m1,m3); \ +t1 = _mm_unpacklo_epi64(m0,m1); \ +buf = _mm_blend_epi16(t0,t1,0x33); + +#define LOAD_MSG_4_3(buf) \ +t0 = _mm_unpackhi_epi64(m3,m1); \ +t1 = _mm_unpackhi_epi64(m2,m0); \ +t2 = _mm_blend_epi16(t1,t0,0x33); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); + +#define LOAD_MSG_4_4(buf) \ +t0 = _mm_blend_epi16(m0,m2,0x03); \ +t1 = _mm_slli_si128(t0, 8); \ +t2 = _mm_blend_epi16(t1,m3,0x0F); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,3,1)); + +#define LOAD_MSG_5_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_unpacklo_epi32(m0,m2); \ +buf = _mm_unpacklo_epi64(t0,t1); + +#define LOAD_MSG_5_2(buf) \ +t0 = _mm_srli_si128(m2, 4); \ +t1 = _mm_blend_epi16(m0,m3,0x03); \ +buf = _mm_blend_epi16(t1,t0,0x3C); + +#define LOAD_MSG_5_3(buf) \ +t0 = _mm_blend_epi16(m1,m0,0x0C); \ +t1 = _mm_srli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0,t1,0x30); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_5_4(buf) \ +t0 = _mm_unpacklo_epi64(m2,m1); \ +t1 = _mm_shuffle_epi32(m3, _MM_SHUFFLE(2,0,1,0)); \ +t2 = _mm_srli_si128(t0, 4); \ +buf = _mm_blend_epi16(t1,t2,0x33); + +#define LOAD_MSG_6_1(buf) \ +t0 = _mm_slli_si128(m1, 12); \ +t1 = _mm_blend_epi16(m0,m3,0x33); \ +buf = _mm_blend_epi16(t1,t0,0xC0); + +#define LOAD_MSG_6_2(buf) \ +t0 = _mm_blend_epi16(m3,m2,0x30); \ +t1 = _mm_srli_si128(m1, 4); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0)); + +#define LOAD_MSG_6_3(buf) \ +t0 = _mm_unpacklo_epi64(m0,m2); \ +t1 = _mm_srli_si128(m1, 4); \ +t2 = _mm_blend_epi16(t0,t1,0x0C); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + +#define LOAD_MSG_6_4(buf) \ +t0 = _mm_unpackhi_epi32(m1,m2); \ +t1 = _mm_unpackhi_epi64(m0,t0); \ +buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(0,1,2,3)); + +#define LOAD_MSG_7_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_blend_epi16(t0,m3,0x0F); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1)); + +#define LOAD_MSG_7_2(buf) \ +t0 = _mm_blend_epi16(m2,m3,0x30); \ +t1 = _mm_srli_si128(m0,4); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3)); + +#define LOAD_MSG_7_3(buf) \ +t0 = _mm_unpackhi_epi64(m0,m3); \ +t1 = _mm_unpacklo_epi64(m1,m2); \ +t2 = _mm_blend_epi16(t0,t1,0x3C); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(2,3,1,0)); + +#define LOAD_MSG_7_4(buf) \ +t0 = _mm_unpacklo_epi32(m0,m1); \ +t1 = _mm_unpackhi_epi32(m1,m2); \ +t2 = _mm_unpacklo_epi64(t0,t1); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); + +#define LOAD_MSG_8_1(buf) \ +t0 = _mm_unpackhi_epi32(m1,m3); \ +t1 = _mm_unpacklo_epi64(t0,m0); \ +t2 = _mm_blend_epi16(t1,m2,0xC0); \ +buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2)); + +#define LOAD_MSG_8_2(buf) \ +t0 = _mm_unpackhi_epi32(m0,m3); \ +t1 = _mm_blend_epi16(m2,t0,0xF0); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3)); + +#define LOAD_MSG_8_3(buf) \ +t0 = _mm_unpacklo_epi64(m0,m3); \ +t1 = _mm_srli_si128(m2,8); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,3,2,0)); + +#define LOAD_MSG_8_4(buf) \ +t0 = _mm_blend_epi16(m1,m0,0x30); \ +buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(0,3,2,1)); + +#define LOAD_MSG_9_1(buf) \ +t0 = _mm_blend_epi16(m0,m2,0x03); \ +t1 = _mm_blend_epi16(m1,m2,0x30); \ +t2 = _mm_blend_epi16(t1,t0,0x0F); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2)); + +#define LOAD_MSG_9_2(buf) \ +t0 = _mm_slli_si128(m0,4); \ +t1 = _mm_blend_epi16(m1,t0,0xC0); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3)); + +#define LOAD_MSG_9_3(buf) \ +t0 = _mm_unpackhi_epi32(m0,m3); \ +t1 = _mm_unpacklo_epi32(m2,m3); \ +t2 = _mm_unpackhi_epi64(t0,t1); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,1,3)); + +#define LOAD_MSG_9_4(buf) \ +t0 = _mm_blend_epi16(m3,m2,0xC0); \ +t1 = _mm_unpacklo_epi32(m0,m3); \ +t2 = _mm_blend_epi16(t0,t1,0x0F); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,2,3,0)); + +#endif diff --git a/src/Crypto/blake2s-ref.c b/src/Crypto/blake2s-ref.c new file mode 100644 index 00000000..435630b9 --- /dev/null +++ b/src/Crypto/blake2s-ref.c @@ -0,0 +1,336 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + +#include <stdlib.h> +#include <STRING.H> + +#include "blake2.h" + +#pragma optimize ("tl", on) + +#pragma intrinsic(_lrotr) +#pragma intrinsic( memcpy ) +#pragma intrinsic( memset ) + +static const uint32 blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8 blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + +static void blake2s_set_lastnode( blake2s_state *S ) +{ + S->f[1] = (uint32)-1; +} + +/* Some helper functions, not necessarily useful */ +static int blake2s_is_lastblock( const blake2s_state *S ) +{ + return S->f[0] != 0; +} + +static void blake2s_set_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_set_lastnode( S ); + + S->f[0] = (uint32)-1; +} + +static void blake2s_increment_counter( blake2s_state *S, const uint32 inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +} + +static void blake2s_init0( blake2s_state *S ) +{ + size_t i; + memset( S, 0, sizeof( blake2s_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; +} + +/* init2 xors IV with input parameter block */ +void blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + const unsigned char *p = ( const unsigned char * )( P ); + size_t i; + uint32 w; + + blake2s_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + { + memcpy (&w, &p[i * 4], sizeof (w)); + S->h[i] ^= w; + } + + S->outlen = P->digest_length; +} + + +/* Sequential blake2s initialization */ +void blake2s_init( blake2s_state *S ) +{ + blake2s_param P[1]; + + P->digest_length = 32; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + P->leaf_length = 0; + P->node_offset = 0; + P->xof_length = 0; + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2s_init_param( S, P ); +} + +#ifndef TC_MINIMIZE_CODE_SIZE +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2*i+0]]; \ + d = _lrotr(d ^ a, 16); \ + c = c + d; \ + b = _lrotr(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2*i+1]]; \ + d = _lrotr(d ^ a, 8); \ + c = c + d; \ + b = _lrotr(b ^ c, 7); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) +#else +#define G_BASE(r,i,a,b,c,d) \ + do { \ + v[a] = v[a] + v[b] + m[blake2s_sigma[r][2*i+0]]; \ + v[d] = _lrotr(v[d] ^ v[a], 16); \ + v[c] = v[c] + v[d]; \ + v[b] = _lrotr(v[b] ^ v[c], 12); \ + v[a] = v[a] + v[b] + m[blake2s_sigma[r][2*i+1]]; \ + v[d] = _lrotr(v[d] ^ v[a], 8); \ + v[c] = v[c] + v[d]; \ + v[b] = _lrotr(v[b] ^ v[c], 7); \ + } while(0) + +static void G(unsigned char r, unsigned char i, uint32* m, uint32* v, unsigned char a, unsigned char b, unsigned char c, unsigned char d) +{ + G_BASE(r,i,a,b,c,d); +} + +static void round_base (unsigned char r, uint32* m, uint32* v) +{ + G(r,0,m,v, 0, 4, 8, 12); + G(r,1,m,v, 1, 5, 9,13); + G(r,2,m,v, 2, 6,10,14); + G(r,3,m,v, 3, 7,11,15); + G(r,4,m,v, 0, 5,10,15); + G(r,5,m,v, 1, 6,11,12); + G(r,6,m,v, 2, 7, 8,13); + G(r,7,m,v, 3, 4, 9,14); +} + +#define ROUND(r) round_base(r,m,v) +#endif +static void blake2s_compress( blake2s_state *S, const uint8 in[BLAKE2S_BLOCKBYTES] ) +{ + uint32 m[16]; + uint32 v[16]; + int i; + + for( i = 0; i < 16; ++i ) { + memcpy (&m[i], in + i * sizeof( m[i] ), sizeof(uint32)); + } + + for( i = 0; i < 8; ++i ) { + v[i] = S->h[i]; + } + + v[ 8] = blake2s_IV[0]; + v[ 9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = S->t[0] ^ blake2s_IV[4]; + v[13] = S->t[1] ^ blake2s_IV[5]; + v[14] = S->f[0] ^ blake2s_IV[6]; + v[15] = S->f[1] ^ blake2s_IV[7]; + + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + + for( i = 0; i < 8; ++i ) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} + +#undef G +#undef ROUND + +void blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) +{ + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = BLAKE2S_BLOCKBYTES - left; + if( inlen > fill ) + { + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2S_BLOCKBYTES) { + blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); + blake2s_compress( S, in ); + in += BLAKE2S_BLOCKBYTES; + inlen -= BLAKE2S_BLOCKBYTES; + } + } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; + } +} + +int blake2s_final( blake2s_state *S, unsigned char *out ) +{ + int i; + + if( blake2s_is_lastblock( S ) ) + return -1; + + blake2s_increment_counter( S, ( uint32 )S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + memcpy( out + sizeof( S->h[i] ) * i, &S->h[i], sizeof(uint32) ); + + return 0; +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); +} +#endif + +#if defined(BLAKE2S_SELFTEST) +#include <string.h> +#include "blake2-kat.h" +int main( void ) +{ + uint8 key[BLAKE2S_KEYBYTES]; + uint8 buf[BLAKE2_KAT_LENGTH]; + size_t i, step; + + for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8 )i; + + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + buf[i] = ( uint8 )i; + + /* Test simple API */ + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + { + uint8 hash[BLAKE2S_OUTBYTES]; + blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); + + if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + goto fail; + } + } + + /* Test streaming API */ + for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { + for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { + uint8 hash[BLAKE2S_OUTBYTES]; + blake2s_state S; + uint8 * p = buf; + size_t mlen = i; + int err = 0; + + if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { + goto fail; + } + + while (mlen >= step) { + if ( (err = blake2s_update(&S, p, step)) < 0 ) { + goto fail; + } + mlen -= step; + p += step; + } + if ( (err = blake2s_update(&S, p, mlen)) < 0) { + goto fail; + } + if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { + goto fail; + } + + if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { + goto fail; + } + } + } + + puts( "ok" ); + return 0; +fail: + puts("error"); + return -1; +} +#endif diff --git a/src/Crypto/blake2s-round.h b/src/Crypto/blake2s-round.h new file mode 100644 index 00000000..590540bb --- /dev/null +++ b/src/Crypto/blake2s-round.h @@ -0,0 +1,159 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + + +#ifndef BLAKE2S_ROUND_H +#define BLAKE2S_ROUND_H + +#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) +#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) + +#define TOF(reg) _mm_castsi128_ps((reg)) +#define TOI(reg) _mm_castps_si128((reg)) + +#define LIKELY(x) __builtin_expect((x),1) + + +/* Microarchitecture-specific macros */ +#ifndef HAVE_XOP +#ifdef HAVE_SSSE3 +#define _mm_roti_epi32(r, c) ( \ + (8==-(c)) ? _mm_shuffle_epi8(r,r8) \ + : (16==-(c)) ? _mm_shuffle_epi8(r,r16) \ + : _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) ) +#else +#define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) +#endif +#else +/* ... */ +#endif + + +#define G1(row1,row2,row3,row4,buf) \ + row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ + row4 = _mm_xor_si128( row4, row1 ); \ + row4 = _mm_roti_epi32(row4, -16); \ + row3 = _mm_add_epi32( row3, row4 ); \ + row2 = _mm_xor_si128( row2, row3 ); \ + row2 = _mm_roti_epi32(row2, -12); + +#define G2(row1,row2,row3,row4,buf) \ + row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ + row4 = _mm_xor_si128( row4, row1 ); \ + row4 = _mm_roti_epi32(row4, -8); \ + row3 = _mm_add_epi32( row3, row4 ); \ + row2 = _mm_xor_si128( row2, row3 ); \ + row2 = _mm_roti_epi32(row2, -7); + +#define DIAGONALIZE(row1,row2,row3,row4) \ + row1 = _mm_shuffle_epi32( row1, _MM_SHUFFLE(2,1,0,3) ); \ + row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(1,0,3,2) ); \ + row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(0,3,2,1) ); + +#define UNDIAGONALIZE(row1,row2,row3,row4) \ + row1 = _mm_shuffle_epi32( row1, _MM_SHUFFLE(0,3,2,1) ); \ + row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(1,0,3,2) ); \ + row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(2,1,0,3) ); + +#if defined(HAVE_XOP) +#include "blake2s-load-xop.h" +#elif defined(HAVE_SSE41) +#include "blake2s-load-sse41.h" +#else +#include "blake2s-load-sse2.h" +#endif + +#define ROUND(r) \ + LOAD_MSG_ ##r ##_1(buf1); \ + G1(row1,row2,row3,row4,buf1); \ + LOAD_MSG_ ##r ##_2(buf2); \ + G2(row1,row2,row3,row4,buf2); \ + DIAGONALIZE(row1,row2,row3,row4); \ + LOAD_MSG_ ##r ##_3(buf3); \ + G1(row1,row2,row3,row4,buf3); \ + LOAD_MSG_ ##r ##_4(buf4); \ + G2(row1,row2,row3,row4,buf4); \ + UNDIAGONALIZE(row1,row2,row3,row4); \ + +// load32 is always called in SSE case which implies little endian +#define load32(x) *((uint32*) (x)) + +extern const uint32 blake2s_IV[8]; + +#if defined(HAVE_SSE41) +void blake2s_compress_sse41( blake2s_state *S, const uint8 block[BLAKE2S_BLOCKBYTES] ) +#elif defined (HAVE_SSSE3) +void blake2s_compress_ssse3( blake2s_state *S, const uint8 block[BLAKE2S_BLOCKBYTES] ) +#else +void blake2s_compress_sse2( blake2s_state *S, const uint8 block[BLAKE2S_BLOCKBYTES] ) +#endif +{ + __m128i row1, row2, row3, row4; + __m128i buf1, buf2, buf3, buf4; +#if defined(HAVE_SSE41) + __m128i t0, t1; +#if !defined(HAVE_XOP) + __m128i t2; +#endif +#endif + __m128i ff0, ff1; +#if defined(HAVE_SSSE3) && !defined(HAVE_XOP) + const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ); + const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 ); +#endif +#if defined(HAVE_SSE41) + const __m128i m0 = LOADU( block + 00 ); + const __m128i m1 = LOADU( block + 16 ); + const __m128i m2 = LOADU( block + 32 ); + const __m128i m3 = LOADU( block + 48 ); +#else + const uint32 m0 = load32(block + 0 * sizeof(uint32)); + const uint32 m1 = load32(block + 1 * sizeof(uint32)); + const uint32 m2 = load32(block + 2 * sizeof(uint32)); + const uint32 m3 = load32(block + 3 * sizeof(uint32)); + const uint32 m4 = load32(block + 4 * sizeof(uint32)); + const uint32 m5 = load32(block + 5 * sizeof(uint32)); + const uint32 m6 = load32(block + 6 * sizeof(uint32)); + const uint32 m7 = load32(block + 7 * sizeof(uint32)); + const uint32 m8 = load32(block + 8 * sizeof(uint32)); + const uint32 m9 = load32(block + 9 * sizeof(uint32)); + const uint32 m10 = load32(block + 10 * sizeof(uint32)); + const uint32 m11 = load32(block + 11 * sizeof(uint32)); + const uint32 m12 = load32(block + 12 * sizeof(uint32)); + const uint32 m13 = load32(block + 13 * sizeof(uint32)); + const uint32 m14 = load32(block + 14 * sizeof(uint32)); + const uint32 m15 = load32(block + 15 * sizeof(uint32)); +#endif + row1 = ff0 = LOADU( &S->h[0] ); + row2 = ff1 = LOADU( &S->h[4] ); + row3 = _mm_loadu_si128( (__m128i const *)&blake2s_IV[0] ); + row4 = _mm_xor_si128( _mm_loadu_si128( (__m128i const *)&blake2s_IV[4] ), LOADU( &S->t[0] ) ); + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) ); + STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) ); +} + +#endif diff --git a/src/Crypto/blake2s.c b/src/Crypto/blake2s.c new file mode 100644 index 00000000..9850cae1 --- /dev/null +++ b/src/Crypto/blake2s.c @@ -0,0 +1,349 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + +#include "blake2.h" +#include "Common/Endian.h" +#include "Crypto/config.h" +#include "Crypto/cpu.h" +#include "Crypto/misc.h" + +// load32 is always called in SSE case which implies little endian +#define load32(x) *((uint32*) (x)) + +const uint32 blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8 blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + +/* Some helper functions */ +#define blake2s_set_lastnode(S) S->f[1] = (uint32)-1; + +#define blake2s_is_lastblock(S) (S->f[0] != 0) + +#define blake2s_set_lastblock(S) { \ + if( S->last_node ) blake2s_set_lastnode( S ); \ + S->f[0] = (uint32)-1; \ + } + +#define blake2s_increment_counter(S,inc) { \ + uint64 t = ( (( uint64 )S->t[1]) << 32 ) | S->t[0]; \ + t += (inc); \ + S->t[0] = ( uint32 )( t ); \ + S->t[1] = ( uint32 )( t >> 32 ); \ + } + +/* init2 xors IV with input parameter block */ +void blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + size_t i; + /*blake2s_init0( S ); */ + const uint8 * v = ( const uint8 * )( blake2s_IV ); + const uint8 * p = ( const uint8 * )( P ); + uint8 * h = ( uint8 * )( S->h ); + /* IV XOR ParamBlock */ + memset( S, 0, sizeof( blake2s_state ) ); + + for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + + S->outlen = P->digest_length; +} + + +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2*i+0]]; \ + d = rotr32(d ^ a, 16); \ + c = c + d; \ + b = rotr32(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2*i+1]]; \ + d = rotr32(d ^ a, 8); \ + c = c + d; \ + b = rotr32(b ^ c, 7); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + +typedef void (*blake2s_compressFn)( blake2s_state *S, const uint8 block[BLAKE2S_BLOCKBYTES] ); + +blake2s_compressFn blake2s_compress_func = NULL; +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 +extern int blake2s_has_sse2(); +extern int blake2s_has_ssse3(); +extern int blake2s_has_sse41(); +extern void blake2s_compress_sse2( blake2s_state *S, const uint8 block[BLAKE2S_BLOCKBYTES] ); +extern void blake2s_compress_ssse3( blake2s_state *S, const uint8 block[BLAKE2S_BLOCKBYTES] ); +extern void blake2s_compress_sse41( blake2s_state *S, const uint8 block[BLAKE2S_BLOCKBYTES] ); +#endif + + +static void blake2s_compress_std( blake2s_state *S, const uint8 in[BLAKE2S_BLOCKBYTES] ) +{ + uint32 m[16]; + uint32 v[16]; + size_t i; + + for( i = 0; i < 16; ++i ) { + m[i] = *((uint32*) (in + i * sizeof( m[i] ))); + } + + for( i = 0; i < 8; ++i ) { + v[i] = S->h[i]; + } + + v[ 8] = blake2s_IV[0]; + v[ 9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = S->t[0] ^ blake2s_IV[4]; + v[13] = S->t[1] ^ blake2s_IV[5]; + v[14] = S->f[0] ^ blake2s_IV[6]; + v[15] = S->f[1] ^ blake2s_IV[7]; + + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + + for( i = 0; i < 8; ++i ) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} + +#undef G +#undef ROUND + + +/* Some sort of default parameter block initialization, for sequential blake2s */ +void blake2s_init( blake2s_state *S ) +{ + blake2s_param P[1]; + + P->digest_length = BLAKE2S_OUTBYTES; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + P->leaf_length = 0; + P->node_offset = 0; + P->xof_length = 0; + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + blake2s_init_param( S, P ); + + if (!blake2s_compress_func) + { +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 + if (HasSSE2() && blake2s_has_sse2()) + { + if (HasSSE41() && blake2s_has_sse41()) + { + blake2s_compress_func = blake2s_compress_sse41; + } + else + if (HasSSSE3() && blake2s_has_ssse3()) + { + blake2s_compress_func = blake2s_compress_ssse3; + } + else + blake2s_compress_func = blake2s_compress_sse2; + } + else +#endif + blake2s_compress_func = blake2s_compress_std; + } +} + +void blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) +{ + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = BLAKE2S_BLOCKBYTES - left; + if( inlen > fill ) + { + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress_func( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2S_BLOCKBYTES) { + blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); + blake2s_compress_func( S, in ); + in += BLAKE2S_BLOCKBYTES; + inlen -= BLAKE2S_BLOCKBYTES; + } + } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; + } +} + +int blake2s_final( blake2s_state *S, unsigned char *out ) +{ + size_t i; + + if( blake2s_is_lastblock( S ) ) + return -1; + + blake2s_increment_counter( S, (uint32)S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress_func( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + { +#if BYTE_ORDER == LITTLE_ENDIAN + *((uint32*) out) = S->h[i]; +#else + uint32 w = S->h[i] ; + out[0] = (uint8)(w >> 0); + out[1] = (uint8)(w >> 8); + out[2] = (uint8)(w >> 16); + out[3] = (uint8)(w >> 24); +#endif + out += sizeof (uint32); + } + + return 0; +} + +/* inlen, at least, should be uint64. Others can be size_t. */ +int blake2s( void *out, const void *in, size_t inlen) +{ + blake2s_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + blake2s_init( S ); + + blake2s_update( S, ( const uint8 * )in, inlen ); + blake2s_final( S, (unsigned char*) out ); + return 0; +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); +} +#endif + +#if defined(BLAKE2S_SELFTEST) +#include <string.h> +#include "blake2-kat.h" +int main( void ) +{ + uint8 key[BLAKE2S_KEYBYTES]; + uint8 buf[BLAKE2_KAT_LENGTH]; + size_t i, step; + + for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8 )i; + + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + buf[i] = ( uint8 )i; + + /* Test simple API */ + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + { + uint8 hash[BLAKE2S_OUTBYTES]; + blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); + + if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + goto fail; + } + } + + /* Test streaming API */ + for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { + for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { + uint8 hash[BLAKE2S_OUTBYTES]; + blake2s_state S; + uint8 * p = buf; + size_t mlen = i; + int err = 0; + + if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { + goto fail; + } + + while (mlen >= step) { + if ( (err = blake2s_update(&S, p, step)) < 0 ) { + goto fail; + } + mlen -= step; + p += step; + } + if ( (err = blake2s_update(&S, p, mlen)) < 0) { + goto fail; + } + if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { + goto fail; + } + + if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { + goto fail; + } + } + } + + puts( "ok" ); + return 0; +fail: + puts("error"); + return -1; +} +#endif diff --git a/src/Crypto/blake2s_SSE2.c b/src/Crypto/blake2s_SSE2.c new file mode 100644 index 00000000..41ea0a6c --- /dev/null +++ b/src/Crypto/blake2s_SSE2.c @@ -0,0 +1,39 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + +#include "blake2.h" +#include "Common/Endian.h" +#include "Crypto/config.h" +#include "Crypto/cpu.h" +#include "Crypto/misc.h" + +#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE + +#include "blake2s-round.h" + +int blake2s_has_sse2() +{ + return 1; +} + +#else +int blake2s_has_sse2() +{ + return 0; +} + +#endif diff --git a/src/Crypto/blake2s_SSE41.c b/src/Crypto/blake2s_SSE41.c new file mode 100644 index 00000000..99e394c1 --- /dev/null +++ b/src/Crypto/blake2s_SSE41.c @@ -0,0 +1,52 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + +#include "blake2.h" +#include "Common/Endian.h" +#include "Crypto/config.h" +#include "Crypto/cpu.h" +#include "Crypto/misc.h" + +#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE +#if CRYPTOPP_BOOL_SSE41_INTRINSICS_AVAILABLE + +#define HAVE_SSE41 + +#if CRYPTOPP_SSSE3_AVAILABLE +#define HAVE_SSSE3 +#endif + +#include "blake2s-round.h" + +int blake2s_has_sse41() +{ + return 1; +} + +#else +int blake2s_has_sse41() +{ + return 0; +} + +#endif +#else +int blake2s_has_sse41() +{ + return 0; +} +#endif diff --git a/src/Crypto/blake2s_SSSE3.c b/src/Crypto/blake2s_SSSE3.c new file mode 100644 index 00000000..4f3252c3 --- /dev/null +++ b/src/Crypto/blake2s_SSSE3.c @@ -0,0 +1,47 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +/* Adapted for VeraCrypt */ + +#include "blake2.h" +#include "Common/Endian.h" +#include "Crypto/config.h" +#include "Crypto/cpu.h" +#include "Crypto/misc.h" + +#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE +#if CRYPTOPP_BOOL_SSSE3_INTRINSICS_AVAILABLE + +#define HAVE_SSSE3 + +#include "blake2s-round.h" + +int blake2s_has_ssse3() +{ + return 1; +} + +#else +int blake2s_has_ssse3() +{ + return 0; +} +#endif +#else +int blake2s_has_ssse3() +{ + return 0; +} +#endif diff --git a/src/Crypto/chacha-xmm.c b/src/Crypto/chacha-xmm.c index 198d0b5b..478de594 100644 --- a/src/Crypto/chacha-xmm.c +++ b/src/Crypto/chacha-xmm.c @@ -139,22 +139,15 @@ void chacha_ECRYPT_encrypt_bytes(size_t bytes, uint32* x, const uint8* m, uint8* #endif if (!bytes) return; - for (;;) { - salsa20_wordtobyte(output,x, r); - x[12] = PLUSONE(x[12]); - if (!x[12]) { - x[13] = PLUSONE(x[13]); - /* stopping at 2^70 bytes per nonce is user's responsibility */ - } - if (bytes <= 64) { - for (i = 0;i < bytes;++i) out[i] = m[i] ^ output[i]; - return; - } - for (i = 0;i < 64;++i) out[i] = m[i] ^ output[i]; - bytes -= 64; - out += 64; - m += 64; + // bytes is now guaranteed to be between 1 and 63 + salsa20_wordtobyte(output,x, r); + x[12] = PLUSONE(x[12]); + if (!x[12]) { + x[13] = PLUSONE(x[13]); + /* stopping at 2^70 bytes per nonce is user's responsibility */ } + + for (i = 0;i < bytes;++i) out[i] = m[i] ^ output[i]; } #endif diff --git a/src/Crypto/config.h b/src/Crypto/config.h index cf6f3dc3..867c13dd 100644 --- a/src/Crypto/config.h +++ b/src/Crypto/config.h @@ -113,13 +113,13 @@ #define CRYPTOPP_X64_ASM_AVAILABLE #endif -#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__)) && !defined(_M_ARM) +#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__)) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(__arm__) && !defined(__aarch64__) && !defined(__arm64__) #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 1 #else #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0 #endif -#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SSSE3) && ( \ +#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SSSE3) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(__arm__) && !defined(__aarch64__) && !defined(__arm64__) && ( \ defined(__SSSE3__) || (_MSC_VER >= 1500) || \ (CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || (__SUNPRO_CC >= 0x5110) || \ (CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000)) @@ -128,6 +128,12 @@ #define CRYPTOPP_SSSE3_AVAILABLE 0 # endif +#if !defined(CRYPTOPP_DISABLE_SSSE3) && (defined(__SSSE3__) || (_MSC_VER >= 1500)) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(__arm__) && !defined(__aarch64__) && !defined(__arm64__) + #define CRYPTOPP_BOOL_SSSE3_INTRINSICS_AVAILABLE 1 +#else + #define CRYPTOPP_BOOL_SSSE3_INTRINSICS_AVAILABLE 0 +#endif + #if !defined(CRYPTOPP_DISABLE_SSSE3) && !defined(CRYPTOPP_DISABLE_AESNI) && CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && (CRYPTOPP_GCC_VERSION >= 40400 || _MSC_FULL_VER >= 150030729 || __INTEL_COMPILER >= 1110 || defined(__AES__)) #define CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 1 #else @@ -140,7 +146,7 @@ #define CRYPTOPP_BOOL_ALIGN16 0 #endif -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE && (defined(__SSE4_1__) || defined(__INTEL_COMPILER) || defined(_MSC_VER)) +#if CRYPTOPP_BOOL_SSSE3_INTRINSICS_AVAILABLE && (defined(__SSE4_1__) || defined(__INTEL_COMPILER) || defined(_MSC_VER)) #define CRYPTOPP_BOOL_SSE41_INTRINSICS_AVAILABLE 1 #else #define CRYPTOPP_BOOL_SSE41_INTRINSICS_AVAILABLE 0 diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c index b8316962..effde6ba 100644 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -2,6 +2,9 @@ #include "cpu.h" #include "misc.h" +#if defined(_MSC_VER) && !defined(_UEFI) +#include "rdrand.h" +#endif #ifndef EXCEPTION_EXECUTE_HANDLER #define EXCEPTION_EXECUTE_HANDLER 1 @@ -218,8 +221,8 @@ VC_INLINE int IsAMD(const uint32 output[4]) { // This is the "AuthenticAMD" string return (output[1] /*EBX*/ == 0x68747541) && - (output[2] /*ECX*/ == 0x69746E65) && - (output[3] /*EDX*/ == 0x444D4163); + (output[2] /*ECX*/ == 0x444D4163) && + (output[3] /*EDX*/ == 0x69746E65); } VC_INLINE int IsHygon(const uint32 output[4]) @@ -277,7 +280,7 @@ static int Detect_MS_HyperV_AES () // when Hyper-V is enabled on older versions of Windows Server (i.e. 2008 R2), the AES-NI capability // gets masked out for all applications, even running on the host. // We try to detect Hyper-V virtual CPU and perform a dummy AES-NI operation to check its real presence - uint32 cpuid[4]; + uint32 cpuid[4] = {0}; char HvProductName[13]; CpuId(0x40000000, cpuid); @@ -327,7 +330,9 @@ void DetectX86Features() g_hasSSE42 = g_hasSSE2 && (cpuid1[2] & (1 << 20)); g_hasSSE41 = g_hasSSE2 && (cpuid1[2] & (1 << 19)); g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9)); +#ifndef CRYPTOPP_DISABLE_AESNI g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25)); +#endif g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1)); #if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) @@ -343,7 +348,6 @@ void DetectX86Features() g_hasISSE = 1; else { - uint32 cpuid2[4]; CpuId(0x080000000, cpuid2); if (cpuid2[0] >= 0x080000001) { @@ -386,33 +390,37 @@ void DetectX86Features() } } } +#if defined(_MSC_VER) && !defined(_UEFI) + /* Add check fur buggy RDRAND (AMD Ryzen case) even if we always use RDSEED instead of RDRAND when RDSEED available */ + if (g_hasRDRAND) + { + if ( RDRAND_getBytes ((unsigned char*) cpuid, sizeof (cpuid)) + && (cpuid[0] == 0xFFFFFFFF) && (cpuid[1] == 0xFFFFFFFF) + && (cpuid[2] == 0xFFFFFFFF) && (cpuid[3] == 0xFFFFFFFF) + ) + { + g_hasRDRAND = 0; + g_hasRDSEED = 0; + } + } - if (!g_cacheLineSize) - g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - - *((volatile int*)&g_x86DetectionDone) = 1; -} - -int is_aes_hw_cpu_supported () -{ - int bHasAESNI = 0; - uint32 cpuid[4]; - - if (CpuId(1, cpuid)) + if (g_hasRDSEED) { - if (cpuid[2] & (1<<25)) - bHasAESNI = 1; -#if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) - // Hypervisor = bit 31 of ECX of CPUID leaf 0x1 - // reference: http://artemonsecurity.com/vmde.pdf - if (!bHasAESNI && (cpuid[2] & (1<<31))) + if ( RDSEED_getBytes ((unsigned char*) cpuid, sizeof (cpuid)) + && (cpuid[0] == 0xFFFFFFFF) && (cpuid[1] == 0xFFFFFFFF) + && (cpuid[2] == 0xFFFFFFFF) && (cpuid[3] == 0xFFFFFFFF) + ) { - bHasAESNI = Detect_MS_HyperV_AES (); + g_hasRDRAND = 0; + g_hasRDSEED = 0; } -#endif } +#endif - return bHasAESNI; + if (!g_cacheLineSize) + g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + + *((volatile int*)&g_x86DetectionDone) = 1; } void DisableCPUExtendedFeatures () diff --git a/src/Crypto/cpu.h b/src/Crypto/cpu.h index ee8c16a8..2661bf1c 100644 --- a/src/Crypto/cpu.h +++ b/src/Crypto/cpu.h @@ -25,20 +25,24 @@ #define ATT_NOPREFIX #endif -#ifdef _MSC_VER +#if defined (_MSC_VER) && !defined (TC_WINDOWS_BOOT) #if defined(TC_WINDOWS_DRIVER) || defined (_UEFI) #if defined(__cplusplus) extern "C" { #endif +#if defined(_M_X64) || defined (_M_IX86) || defined (_M_IX86_FP) extern unsigned __int64 __rdtsc(); +#endif #if defined(__cplusplus) } #endif #else #include <intrin.h> +#if defined(_M_X64) || defined (_M_IX86) || defined (_M_IX86_FP) #pragma intrinsic(__rdtsc) #endif #endif +#endif #ifdef CRYPTOPP_GENERATE_X64_MASM @@ -130,6 +134,11 @@ extern __m128i _mm_slli_epi16(__m128i _A, int _Count); extern __m128i _mm_shuffle_epi32 (__m128i a, int imm8); extern __m128i _mm_set_epi64x (__int64 e1, __int64 e0); extern __m128i _mm_set1_epi64x (__int64 a); +extern __m128i _mm_castps_si128(__m128); +extern __m128 _mm_castsi128_ps(__m128i); +extern __m128 _mm_shuffle_ps(__m128 _A, __m128 _B, unsigned int _Imm8); +extern __m128i _mm_srli_si128(__m128i _A, int _Imm); +extern __m128i _mm_slli_si128(__m128i _A, int _Imm); #define _mm_xor_si64 _m_pxor #define _mm_empty _m_empty #define _MM_SHUFFLE(fp3,fp2,fp1,fp0) (((fp3) << 6) | ((fp2) << 4) | \ @@ -143,26 +152,29 @@ extern __m128i _mm_set1_epi64x (__int64 a); #endif #endif -#if CRYPTOPP_SSSE3_AVAILABLE || defined(__INTEL_COMPILER) +#if CRYPTOPP_BOOL_SSSE3_INTRINSICS_AVAILABLE || defined(__INTEL_COMPILER) #if defined(TC_WINDOWS_DRIVER) || defined (_UEFI) #if defined(__cplusplus) extern "C" { #endif extern __m128i _mm_shuffle_epi8 (__m128i a, __m128i b); +extern __m128i _mm_alignr_epi8 (__m128i a, __m128i b, int n); #if defined(__cplusplus) } #endif #else #include <tmmintrin.h> #endif +#endif -#if defined(__SSE4_1__) || defined(__INTEL_COMPILER) || defined(_MSC_VER) +#if CRYPTOPP_BOOL_SSE41_INTRINSICS_AVAILABLE || defined(__INTEL_COMPILER) #if defined(TC_WINDOWS_DRIVER) || defined (_UEFI) #if defined(__cplusplus) extern "C" { #endif extern int _mm_extract_epi32(__m128i src, const int ndx); extern __m128i _mm_insert_epi32(__m128i dst, int s, const int ndx); +extern __m128i _mm_blend_epi16 (__m128i v1, __m128i v2, const int mask); #if defined(_M_X64) extern __m128i _mm_insert_epi64(__m128i dst, __int64 s, const int ndx); #endif @@ -194,7 +206,6 @@ extern __m128i _mm_aesdeclast_si128(__m128i v, __m128i rkey); #include <wmmintrin.h> #endif #endif -#endif #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 @@ -203,6 +214,9 @@ extern "C" { #endif #define CRYPTOPP_CPUID_AVAILABLE +#if !defined(CRYPTOPP_DISABLE_AESNI) && !defined(WOLFCRYPT_BACKEND) +#define TC_AES_HW_CPU +#endif // these should not be used directly extern volatile int g_x86DetectionDone; @@ -224,7 +238,7 @@ extern volatile int g_isIntel; extern volatile int g_isAMD; extern volatile uint32 g_cacheLineSize; void DetectX86Features(); // must be called at the start of the program/driver -int CpuId(uint32 input, uint32 *output); +int CpuId(uint32 input, uint32 output[4]); // disable all CPU extended features (e.g. SSE, AVX, AES) that may have // been enabled by DetectX86Features. void DisableCPUExtendedFeatures (); @@ -258,8 +272,28 @@ void DisableCPUExtendedFeatures (); #else +#define HasSSE2() 0 +#define HasISSE() 0 + +#define HasMMX() 0 +#define HasSSE42() 0 +#define HasSSE41() 0 +#define HasSAVX() 0 +#define HasSAVX2() 0 +#define HasSBMI2() 0 +#define HasSSSE3() 0 +#define HasAESNI() 0 +#define HasCLMUL() 0 +#define IsP4() 0 +#define HasRDRAND() 0 +#define HasRDSEED() 0 +#define IsCpuIntel() 0 +#define IsCpuAMD() 0 #define GetCacheLineSize() CRYPTOPP_L1_CACHE_LINE_SIZE +#define DetectX86Features() +#define DisableCPUExtendedFeatures() + #endif #endif diff --git a/src/Crypto/gost89_x64.asm b/src/Crypto/gost89_x64.asm deleted file mode 100644 index 5f5892fe..00000000 --- a/src/Crypto/gost89_x64.asm +++ /dev/null @@ -1,483 +0,0 @@ -; -; GOST89 implementation x64 -; -; Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov -; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions -; of the Apache License, Version 2.0. -; -; The full text of the license may be found at -; https://opensource.org/licenses/Apache-2.0 -; -; Some ideas from article https://xakep.ru/2013/10/19/shifrovanie-gost-28147-89/ -; - -[section .bss align=16] - -;/////////////////////////////////////////////////////////////////// -;// Win64 registers to save -;/////////////////////////////////////////////////////////////////// -%macro SaveRegs 0 - sub rsp,8*8+10*16 - mov [rsp], rbx - mov [rsp+8], rbp - mov [rsp+8*2], rdi - mov [rsp+8*3], rsi - mov [rsp+8*4], r12 - mov [rsp+8*5], r13 - mov [rsp+8*6], r14 - mov [rsp+8*7], r15 -%endmacro - -%macro RestoreRegs 0 - mov rbx, [rsp] - mov rbp, [rsp+8] - mov rdi, [rsp+8*2] - mov rsi, [rsp+8*3] - mov r12, [rsp+8*4] - mov r13, [rsp+8*5] - mov r14, [rsp+8*6] - mov r15, [rsp+8*7] - add rsp,8*8+10*16 -%endmacro - -[section .text align=16] -;/////////////////////////////////////////////////////////////////// -;// Crypting 2 blocks -;/////////////////////////////////////////////////////////////////// -%macro gost_round2 2 ; 1 - pos1, 2 - pos2 - ; 1st - ; 1-2 byte - add ecx, r13d ; add key - movzx edi, cl - movzx esi, ch - xor r14d, dword [r8 + 32 + 256*3*4 + rdi*4] - xor r14d, dword [r8 + 32 + 256*2*4 + rsi*4] - shr ecx, 16 - ; 3-4 áàéò - movzx edi, cl - xor r14d, dword [r8 + 32 + 256*4 + rdi*4] - movzx esi, ch - xor r14d, dword [r8 + 32 + rsi*4] - mov edx, [r8 + %1*4] ; read key for second step - - ; 2nd - ; 1-2 byte - add eax, r10d ; read key - movzx r15d, al - movzx ebp, ah - xor r11d, dword [r8 + 32 + 256*3*4 + r15*4] - xor r11d, dword [r8 + 32 + 256*2*4 + rbp*4] - shr eax, 16 - ; 3-4 áàéò - movzx r15d, al - xor r11d, dword [r8 + 32 + 256*4 + r15*4] - movzx ebp, ah - xor r11d, dword [r8 + 32 + rbp*4] - mov ebx, [r8 + %1*4] ; read key for second step - - ; second step - ; 1st - ; 1-2 byte - add edx, r14d ; add key - movzx edi, dl - movzx esi, dh - xor r13d, dword [r8 + 32 + 256*3*4 + rdi*4] - xor r13d, dword [r8 + 32 + 256*2*4 + rsi*4] - shr edx, 16 - ; 3-4 áàéò - movzx edi, dl - xor r13d, dword [r8 + 32 + 256*4 + rdi*4] - movzx esi, dh - xor r13d, dword [r8 + 32 + rsi*4] - mov ecx, [r8 + %2*4] ; read key - - ; 2nd - ; 1-2 byte - add ebx, r11d; ; add key - movzx r15d, bl; - movzx ebp, bh; - xor r10d, dword [r8 + 32 + 256*3*4 + r15*4] - xor r10d, dword [r8 + 32 + 256*2*4 + rbp*4] - shr ebx, 16 - ; 3-4 áàéò - movzx r15d, bl - xor r10d, dword [r8 + 32 + 256*4 + r15*4] - movzx ebp, bh - xor r10d, dword [r8 + 32 + rbp*4] - mov eax, [r8 + %2*4] ; read key -%endmacro - -; input: r8 - &key, rcx - &IN -; returns: (r13) & (r10) -GostEncrypt2x64: - ; 1st - mov r13d, [rcx] - mov r14, [rcx] - shr r14, 32 - - ; 2nd - mov r10d, [rcx + 16] - mov r11, [rcx + 16] - shr r11, 32 - - mov ecx, [r8] - mov eax, ecx - - gost_round2 1, 2 - gost_round2 3, 4 - gost_round2 5, 6 - gost_round2 7, 0 - - gost_round2 1, 2 - gost_round2 3, 4 - gost_round2 5, 6 - gost_round2 7, 0 - - gost_round2 1, 2 - gost_round2 3, 4 - gost_round2 5, 6 - gost_round2 7, 7 - - gost_round2 6, 5 - gost_round2 4, 3 - gost_round2 2, 1 - gost_round2 0, 0 - - shl r13, 32 ; combine - or r13, r14 - - shl r10, 32 ; combine - or r10, r11 - ret - -; input: r8 - &key, rcx - &IN -; returns: (r13) & (r10) -GostDecrypt2x64: - ; 1st - mov r13d, [rcx] - mov r14, [rcx] - shr r14, 32 - - ; 2nd - mov r10d, [rcx + 16] - mov r11, [rcx + 16] - shr r11, 32 - - mov ecx, [r8] - mov eax, ecx - - gost_round2 1, 2 - gost_round2 3, 4 - gost_round2 5, 6 - gost_round2 7, 7 - - gost_round2 6, 5 - gost_round2 4, 3 - gost_round2 2, 1 - gost_round2 0, 7 - - gost_round2 6, 5 - gost_round2 4, 3 - gost_round2 2, 1 - gost_round2 0, 7 - - gost_round2 6, 5 - gost_round2 4, 3 - gost_round2 2, 1 - gost_round2 0, 0 - - shl r13, 32 ; combine - or r13, r14 - - shl r10, 32 ; combine - or r10, r11 -ret - -;/////////////////////////////////////////////////////////////////// -;// Crypting 1 block -;/////////////////////////////////////////////////////////////////// -%macro gost_round1 2 ; 1 - pos1, 2 - pos2 - ; 1-2 byte - add ecx, r13d ; add key - movzx edi, cl - movzx esi, ch - xor r14d, dword [r8 + 32 + 256*3*4 + rdi*4] - xor r14d, dword [r8 + 32 + 256*2*4 + rsi*4] - shr ecx, 16 - ; 3-4 áàéò - movzx edi, cl - xor r14d, dword [r8 + 32 + 256*4 + rdi*4] - movzx esi, ch - xor r14d, dword [r8 + 32 + rsi*4] - mov edx, [r8 + %1*4] ; read key for second step - - ; second step - ; 1-2 byte - add edx, r14d ; add key - movzx edi, dl - movzx esi, dh - xor r13d, dword [r8 + 32 + 256*3*4 + rdi*4] - xor r13d, dword [r8 + 32 + 256*2*4 + rsi*4] - shr edx, 16 - ; 3-4 áàéò - movzx edi, dl - xor r13d, dword [r8 + 32 + 256*4 + rdi*4] - movzx esi, dh - xor r13d, dword [r8 + 32 + rsi*4] - mov ecx, [r8 + %2*4] ; read key -%endmacro - -; input: r8 - &gost_kds rcx - &IN -; returns: r13 -GostEncrypt1x64: - mov r13d, [rcx] - mov r14, [rcx] - shr r14, 32 - mov ecx, [r8] - - gost_round1 1, 2 - gost_round1 3, 4 - gost_round1 5, 6 - gost_round1 7, 0 - - gost_round1 1, 2 - gost_round1 3, 4 - gost_round1 5, 6 - gost_round1 7, 0 - - gost_round1 1, 2 - gost_round1 3, 4 - gost_round1 5, 6 - gost_round1 7, 7 - - gost_round1 6, 5 - gost_round1 4, 3 - gost_round1 2, 1 - gost_round1 0, 0 - - shl r13, 32 ; combine - or r13, r14 -ret - -; input: r8 - &gost_kds rcx - IN -; returns: r13 -GostDecrypt1x64: - mov r13d, [rcx] - mov r14, [rcx] - shr r14, 32 - mov ecx, [r8] - - gost_round1 1, 2 - gost_round1 3, 4 - gost_round1 5, 6 - gost_round1 7, 7 - - gost_round1 6, 5 - gost_round1 4, 3 - gost_round1 2, 1 - gost_round1 0, 7 - - gost_round1 6, 5 - gost_round1 4, 3 - gost_round1 2, 1 - gost_round1 0, 7 - - gost_round1 6, 5 - gost_round1 4, 3 - gost_round1 2, 1 - gost_round1 0, 0 - - shl r13, 32 ; combine - or r13, r14 -ret - -global gost_encrypt_128_CBC_asm ; gost_encrypt_128_CBC_asm(uint64* in, uint64* out, gost_kds* kds, uint64 count); -; rcx - &in -; rdx - &out -; r8 - &gost_kds -; r9 - count -gost_encrypt_128_CBC_asm: - SaveRegs ; Saving - - sub rsp, 32 - mov [rsp], rdx ; Save out addr - mov [rsp + 8], rcx ; Save in addr - mov [rsp + 16], r8 ; key addr - -.do: - mov [rsp + 24], r9 ; Save count - cmp r9, 2 - jge .blk2 - cmp r9, 1 - jge .blk1 - jmp .end - -; One 128 block encryption -.blk1: - mov rcx, [rsp + 8] ; set in addr - call GostEncrypt1x64 - - mov rdx, [rsp] ; Restore out - mov rcx, [rsp + 8] ; restore in - - mov [rdx], r13 - mov rax, [rcx + 8] - xor rax, r13 ; CBC - - add rdx, 8 ;next 8 bytes - mov [rdx], rax - - mov rcx, rdx - call GostEncrypt1x64 - - mov rdx, [rsp] ; Restore out addr - mov rcx, [rsp+8] ; Restore in addr - - mov [rdx + 8], r13 - - add rdx,16 - mov [rsp], rdx - - add rcx, 16 - mov [rsp+8], rcx - - mov r9, [rsp + 24] - dec r9 - - jmp .do - -.blk2: - mov rcx, [rsp + 8] ; set in addr - call GostEncrypt2x64 - - mov rdx, [rsp] ; Restore out - mov rcx, [rsp + 8] ; restore in - - mov [rdx], r13 - - mov rax, [rcx + 8] - xor rax, r13 ; CBC - - mov [rdx + 16], r10 - - mov rbx, [rcx + 24] - xor rbx, r10 ; CBC - - mov [rdx + 8], rax - mov [rdx + 24], rbx - - add rdx, 8 ;next 8 bytes - - mov rcx, rdx - call GostEncrypt2x64 - - mov rdx, [rsp] ; Restore out addr - mov rcx, [rsp+8] ; Restore in addr - - mov [rdx + 8], r13 - mov [rdx + 24], r10 - - add rdx,32 - mov [rsp], rdx - - add rcx, 32 - mov [rsp+8], rcx - - mov r9, [rsp + 24] - sub r9, 2 - - jmp .do - -.end: - add rsp, 32 ; Load out addr - RestoreRegs ; Load -ret - -global gost_decrypt_128_CBC_asm ; gost_decrypt_128_CBC_asm(uint64* in, uint64* out, const gost_kds* kds, uint64 count); -; rcx - &in -; rdx - &out -; r8 - &gost_kds -; r9 - count -gost_decrypt_128_CBC_asm: - SaveRegs ; Saving - - sub rsp, 32 - mov [rsp], rdx ; Save out addr - mov [rsp+8], rcx ; Save in addr - mov [rsp+16], r8 ; key addr - -.do: - mov [rsp + 24], r9 ; Save count - cmp r9, 2 - jge .blk2 - cmp r9, 1 - jge .blk1 - jmp .end - -; One 128 block decryption -.blk1: - add rcx, 8 - call GostDecrypt1x64 - mov rdx, [rsp] ; Restore out - mov rcx, [rsp + 8] ; Restore in - mov rax, [rcx] - xor rax, r13 ; CBC - mov [rdx + 8], rax - - call GostDecrypt1x64 - - mov rdx, [rsp] ; Restore out addr - mov rcx, [rsp+8] ; Restore in addr - - mov [rdx], r13 - - add rdx,16 - mov [rsp], rdx - - add rcx, 16 - mov [rsp+8], rcx - - mov r9, [rsp + 24] - dec r9 - - jmp .do - -.blk2: - add rcx, 8 - call GostDecrypt2x64 - mov rdx, [rsp] ; Restore out - mov rcx, [rsp + 8] ; Restore in - - mov rax, [rcx] - xor rax, r13 ; CBC - mov [rdx + 8], rax - - mov rbx, [rcx+16] - xor rbx, r10 ; CBC - mov [rdx + 24], rbx - - call GostDecrypt2x64 - - mov rdx, [rsp] ; Restore out addr - mov rcx, [rsp+8] ; Restore in addr - - mov [rdx], r13 - mov [rdx+16], r10 - - add rdx,32 - mov [rsp], rdx - - add rcx,32 - mov [rsp+8], rcx - - mov r9, [rsp + 24] - sub r9, 2 - - jmp .do - -.end: - add rsp, 32 ; Load out addr - RestoreRegs ; Load -ret diff --git a/src/Crypto/jitterentropy-base-user.h b/src/Crypto/jitterentropy-base-user.h index cbb2f47e..aaefb41a 100644 --- a/src/Crypto/jitterentropy-base-user.h +++ b/src/Crypto/jitterentropy-base-user.h @@ -1,7 +1,7 @@ /* * Non-physical true random number generator based on timing jitter. * - * Copyright Stephan Mueller <smueller@chronox.de>, 2013 + * Copyright Stephan Mueller <smueller@chronox.de>, 2013 - 2019 * * License * ======= @@ -35,7 +35,7 @@ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - e USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ @@ -49,8 +49,6 @@ #include <stdlib.h> #include <string.h> -typedef uint64 __u64; - #ifdef _MSC_VER typedef uint64 uint64_t; @@ -70,17 +68,31 @@ typedef int32 ssize_t; #endif #endif -static VC_INLINE void jent_get_nstime(__u64 *out) +static VC_INLINE void jent_get_nstime(uint64 *out) { - *out = __rdtsc();; +#ifdef _M_ARM64 + LARGE_INTEGER v = { 0 }; +#ifdef TC_WINDOWS_DRIVER + v = KeQueryPerformanceCounter(NULL); +#else + QueryPerformanceCounter(&v); +#endif + * out = v.QuadPart; +#else + *out = __rdtsc(); +#endif } #else +#include <sys/types.h> + +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + /* taken from Linux kernel */ #if CRYPTOPP_BOOL_X64 #define DECLARE_ARGS(val, low, high) unsigned low, high -#define EAX_EDX_VAL(val, low, high) ((low) | ((__u64)(high) << 32)) +#define EAX_EDX_VAL(val, low, high) ((low) | ((uint64)(high) << 32)) #define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) #else #define DECLARE_ARGS(val, low, high) unsigned long long val @@ -88,16 +100,42 @@ static VC_INLINE void jent_get_nstime(__u64 *out) #define EAX_EDX_RET(val, low, high) "=A" (val) #endif -static VC_INLINE void jent_get_nstime(__u64 *out) +VC_INLINE void jent_get_nstime(uint64 *out) { DECLARE_ARGS(val, low, high); asm volatile("rdtsc" : EAX_EDX_RET(val, low, high)); *out = EAX_EDX_VAL(val, low, high); } +#else + +#include <time.h> + +VC_INLINE void jent_get_nstime(uint64 *out) +{ + /* we could use CLOCK_MONOTONIC(_RAW), but with CLOCK_REALTIME + * we get some nice extra entropy once in a while from the NTP actions + * that we want to use as well... though, we do not rely on that + * extra little entropy */ + uint64_t tmp = 0; + struct timespec time; + if (clock_gettime(CLOCK_REALTIME, &time) == 0) + { + tmp = time.tv_sec; + tmp = tmp << 32; + tmp = tmp | time.tv_nsec; + } + *out = tmp; +} + #endif -static VC_INLINE void *jent_zalloc(size_t len) +#endif + +#ifdef _MSC_VER +static +#endif +VC_INLINE void *jent_zalloc(size_t len) { void *tmp = NULL; tmp = TCalloc(len); @@ -111,7 +149,10 @@ static VC_INLINE void *jent_zalloc(size_t len) return tmp; } -static VC_INLINE void jent_zfree(void *ptr, unsigned int len) +#ifdef _MSC_VER +static +#endif +VC_INLINE void jent_zfree(void *ptr, unsigned int len) { if (len % 8) burn(ptr, len); @@ -123,9 +164,12 @@ static VC_INLINE void jent_zfree(void *ptr, unsigned int len) TCfree(ptr); } -static VC_INLINE int jent_fips_enabled(void) +#ifdef _MSC_VER +static +#endif +VC_INLINE int jent_fips_enabled(void) { - return 0; + return 1; } /* --- helpers needed in user space -- */ diff --git a/src/Crypto/jitterentropy-base.c b/src/Crypto/jitterentropy-base.c index c05f0c37..b7512532 100644 --- a/src/Crypto/jitterentropy-base.c +++ b/src/Crypto/jitterentropy-base.c @@ -1,7 +1,7 @@ /* * Non-physical true random number generator based on timing jitter. * - * Copyright Stephan Mueller <smueller@chronox.de>, 2014 - 2018 + * Copyright Stephan Mueller <smueller@chronox.de>, 2014 - 2019 * * Design * ====== @@ -11,7 +11,7 @@ * Interface * ========= * - * See documentation in doc/ folder. + * See documentation in jitterentropy(3) man page. * * License * ======= @@ -51,34 +51,44 @@ /* Adapted for VeraCrypt */ + +#ifdef TC_WINDOWS_DRIVER +#define UINT64_MAX 0xffffffffffffffffui64 +#else +#include <stdint.h> +#endif + #undef _FORTIFY_SOURCE #ifdef _MSC_VER #pragma optimize( "", off ) #pragma warning(disable:4242 4244 4334) /* disable warnings on the original code */ #else -#pragma GCC optimize ("O0") +#if defined(__clang__) + #pragma clang optimize off +#elif defined (__GNUC__) + #pragma GCC optimize ("O0") +#endif #endif #include "jitterentropy.h" -#ifndef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT - /* only check optimization in a compilation for real work */ - #ifdef __OPTIMIZE__ - #error "The CPU Jitter random number generator must not be compiled with optimizations. See documentation. Use the compiler switch -O0 for compiling jitterentropy-base.c." - #endif +#ifdef __OPTIMIZE__ + #error "The CPU Jitter random number generator must not be compiled with optimizations. See documentation. Use the compiler switch -O0 for compiling jitterentropy-base.c." #endif #define MAJVERSION 2 /* API / ABI incompatible changes, functional changes that * require consumer to be updated (as long as this number * is zero, the API is not considered stable and can * change without a bump of the major version) */ -#define MINVERSION 1 /* API compatible, ABI may change, functional +#define MINVERSION 2 /* API compatible, ABI may change, functional * enhancements only, consumer can be left unchanged if * enhancements are not considered */ -#define PATCHLEVEL 2 /* API / ABI compatible, no functional changes, no +#define PATCHLEVEL 0 /* API / ABI compatible, no functional changes, no * enhancements, bug fixes only */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + /** * jent_version() - Return machine-usable version number of jent library * @@ -90,7 +100,7 @@ * The result of this function can be used in comparing the version number * in a calling program if version-specific calls need to be make. * - * Return: Version number of jitterentropy library + * @return Version number of jitterentropy library */ JENT_PRIVATE_STATIC unsigned int jent_version(void) @@ -104,15 +114,206 @@ unsigned int jent_version(void) return version; } +/*************************************************************************** + * Adaptive Proportion Test + * + * This test complies with SP800-90B section 4.4.2. + ***************************************************************************/ + +/** + * Reset the APT counter + * + * @ec [in] Reference to entropy collector + */ +static void jent_apt_reset(struct rand_data *ec, unsigned int delta_masked) +{ + /* Reset APT counter */ + ec->apt_count = 0; + ec->apt_base = delta_masked; + ec->apt_observations = 0; +} + +/** + * Insert a new entropy event into APT + * + * @ec [in] Reference to entropy collector + * @delta_masked [in] Masked time delta to process + */ +static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked) +{ + /* Initialize the base reference */ + if (!ec->apt_base_set) { + ec->apt_base = delta_masked; + ec->apt_base_set = 1; + return; + } + + if (delta_masked == ec->apt_base) { + ec->apt_count++; + + if (ec->apt_count >= JENT_APT_CUTOFF) + ec->health_failure = 1; + } + + ec->apt_observations++; + + if (ec->apt_observations >= JENT_APT_WINDOW_SIZE) + jent_apt_reset(ec, delta_masked); +} + +/*************************************************************************** + * Stuck Test and its use as Repetition Count Test + * + * The Jitter RNG uses an enhanced version of the Repetition Count Test + * (RCT) specified in SP800-90B section 4.4.1. Instead of counting identical + * back-to-back values, the input to the RCT is the counting of the stuck + * values during the generation of one Jitter RNG output block. + * + * The RCT is applied with an alpha of 2^{-30} compliant to FIPS 140-2 IG 9.8. + * + * During the counting operation, the Jitter RNG always calculates the RCT + * cut-off value of C. If that value exceeds the allowed cut-off value, + * the Jitter RNG output block will be calculated completely but discarded at + * the end. The caller of the Jitter RNG is informed with an error code. + ***************************************************************************/ + +/** + * Repetition Count Test as defined in SP800-90B section 4.4.1 + * + * @ec [in] Reference to entropy collector + * @stuck [in] Indicator whether the value is stuck + */ +static void jent_rct_insert(struct rand_data *ec, int stuck) +{ + /* + * If we have a count less than zero, a previous RCT round identified + * a failure. We will not overwrite it. + */ + if (ec->rct_count < 0) + return; + + if (stuck) { + ec->rct_count++; + + /* + * The cutoff value is based on the following consideration: + * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8. + * In addition, we require an entropy value H of 1/OSR as this + * is the minimum entropy required to provide full entropy. + * Note, we collect 64 * OSR deltas for inserting them into + * the entropy pool which should then have (close to) 64 bits + * of entropy. + * + * Note, ec->rct_count (which equals to value B in the pseudo + * code of SP800-90B section 4.4.1) starts with zero. Hence + * we need to subtract one from the cutoff value as calculated + * following SP800-90B. + */ + if ((unsigned int)ec->rct_count >= (30 * ec->osr)) { + ec->rct_count = -1; + ec->health_failure = 1; + } + } else { + ec->rct_count = 0; + } +} + +/** + * Is there an RCT health test failure? + * + * @ec [in] Reference to entropy collector + * + * @return + * 0 No health test failure + * 1 Permanent health test failure + */ +static int jent_rct_failure(struct rand_data *ec) +{ + if (ec->rct_count < 0) + return 1; + return 0; +} + +#ifdef _MSC_VER +static +#endif +VC_INLINE uint64_t jent_delta(uint64_t prev, uint64_t next) +{ + return (prev < next) ? (next - prev) : (UINT64_MAX - prev + 1 + next); +} + +/** + * Stuck test by checking the: + * 1st derivative of the jitter measurement (time delta) + * 2nd derivative of the jitter measurement (delta of time deltas) + * 3rd derivative of the jitter measurement (delta of delta of time deltas) + * + * All values must always be non-zero. + * + * @ec [in] Reference to entropy collector + * @current_delta [in] Jitter time delta + * + * @return + * 0 jitter measurement not stuck (good bit) + * 1 jitter measurement stuck (reject bit) + */ +static int jent_stuck(struct rand_data *ec, uint64_t current_delta) +{ + uint64_t delta2 = jent_delta(ec->last_delta, current_delta); + uint64_t delta3 = jent_delta(ec->last_delta2, delta2); + unsigned int delta_masked = current_delta & JENT_APT_WORD_MASK; + + ec->last_delta = current_delta; + ec->last_delta2 = delta2; + + /* + * Insert the result of the comparison of two back-to-back time + * deltas. + */ + jent_apt_insert(ec, delta_masked); + + if (!current_delta || !delta2 || !delta3) { + /* RCT with a stuck bit */ + jent_rct_insert(ec, 1); + return 1; + } + + /* RCT with a non-stuck bit */ + jent_rct_insert(ec, 0); + + return 0; +} + +/** + * Report any health test failures + * + * @ec [in] Reference to entropy collector + * + * @return + * 0 No health test failure + * 1 Permanent health test failure + */ +static int jent_health_failure(struct rand_data *ec) +{ + /* Test is only enabled in FIPS mode */ + if (!ec->fips_enabled) + return 0; + + return ec->health_failure; +} + +/*************************************************************************** + * Noise sources + ***************************************************************************/ + /** * Update of the loop count used for the next round of * an entropy collection. * - * Input: - * @ec entropy collector struct -- may be NULL - * @bits is the number of low bits of the timer to consider - * @min is the number of bits we shift the timer value to the right at - * the end to make sure we have a guaranteed minimum value + * @ec [in] entropy collector struct -- may be NULL + * @bits [in] is the number of low bits of the timer to consider + * @min [in] is the number of bits we shift the timer value to the right at + * the end to make sure we have a guaranteed minimum value * * @return Newly calculated loop counter */ @@ -144,13 +345,9 @@ static uint64_t jent_loop_shuffle(struct rand_data *ec, * We add a lower boundary value to ensure we have a minimum * RNG loop count. */ - return (shuffle + (1<<min)); + return (shuffle + (1ULL<<min)); } -/*************************************************************************** - * Noise sources - ***************************************************************************/ - /** * CPU Jitter noise source -- this is the noise source based on the CPU * execution time jitter @@ -161,30 +358,27 @@ static uint64_t jent_loop_shuffle(struct rand_data *ec, * The code is deliberately inefficient with respect to the bit shifting * and shall stay that way. This function is the root cause why the code * shall be compiled without optimization. This function not only acts as - * folding operation, but this function's execution is used to measure + * LFSR operation, but this function's execution is used to measure * the CPU execution time jitter. Any change to the loop in this function * implies that careful retesting must be done. * - * Input: - * @ec entropy collector struct -- may be NULL - * @time time stamp to be injected - * @loop_cnt if a value not equal to 0 is set, use the given value as number of - * loops to perform the folding + * @ec [in] entropy collector struct -- may be NULL + * @time [in] time stamp to be injected + * @loop_cnt [in] if a value not equal to 0 is set, use the given value as + * number of loops to perform the LFSR * * Output: * updated ec->data - * - * @return Number of loops the folding operation is performed */ -static uint64_t jent_lfsr_time(struct rand_data *ec, uint64_t time, - uint64_t loop_cnt) +static void jent_lfsr_time(struct rand_data *ec, uint64_t time, + uint64_t loop_cnt, int stuck) { unsigned int i; uint64_t j = 0; uint64_t new = 0; #define MAX_FOLD_LOOP_BIT 4 #define MIN_FOLD_LOOP_BIT 0 - uint64_t fold_loop_cnt = + uint64_t lfsr_loop_cnt = jent_loop_shuffle(ec, MAX_FOLD_LOOP_BIT, MIN_FOLD_LOOP_BIT); /* @@ -192,8 +386,8 @@ static uint64_t jent_lfsr_time(struct rand_data *ec, uint64_t time, * needed during runtime */ if (loop_cnt) - fold_loop_cnt = loop_cnt; - for (j = 0; j < fold_loop_cnt; j++) { + lfsr_loop_cnt = loop_cnt; + for (j = 0; j < lfsr_loop_cnt; j++) { new = ec->data; for (i = 1; (DATA_SIZE_BITS) >= i; i++) { uint64_t tmp = time << (DATA_SIZE_BITS - i); @@ -220,9 +414,17 @@ static uint64_t jent_lfsr_time(struct rand_data *ec, uint64_t time, new ^= tmp; } } - ec->data = new; - return fold_loop_cnt; + /* + * If the time stamp is stuck, do not finally insert the value into + * the entropy pool. Although this operation should not do any harm + * even when the time stamp has no entropy, SP800-90B requires that + * any conditioning operation (SP800-90B considers the LFSR to be a + * conditioning operation) to have an identical amount of input + * data according to section 3.1.5. + */ + if (!stuck) + ec->data = new; } /** @@ -243,16 +445,13 @@ static uint64_t jent_lfsr_time(struct rand_data *ec, uint64_t time, * to reliably access either L3 or memory, the ec->mem memory must be quite * large which is usually not desirable. * - * Input: - * @ec Reference to the entropy collector with the memory access data -- if - * the reference to the memory block to be accessed is NULL, this noise - * source is disabled - * @loop_cnt if a value not equal to 0 is set, use the given value as number of - * loops to perform the folding - * - * @return Number of memory access operations + * @ec [in] Reference to the entropy collector with the memory access data -- if + * the reference to the memory block to be accessed is NULL, this noise + * source is disabled + * @loop_cnt [in] if a value not equal to 0 is set, use the given value as + * number of loops to perform the folding */ -static unsigned int jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) +static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) { unsigned int wrap = 0; uint64_t i = 0; @@ -262,7 +461,7 @@ static unsigned int jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); if (NULL == ec || NULL == ec->mem) - return 0; + return; wrap = ec->memblocksize * ec->memblocks; /* @@ -288,43 +487,11 @@ static unsigned int jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) ec->memlocation = ec->memlocation + ec->memblocksize - 1; ec->memlocation = ec->memlocation % wrap; } - return i; } /*************************************************************************** * Start of entropy processing logic ***************************************************************************/ - -/** - * Stuck test by checking the: - * 1st derivation of the jitter measurement (time delta) - * 2nd derivation of the jitter measurement (delta of time deltas) - * 3rd derivation of the jitter measurement (delta of delta of time deltas) - * - * All values must always be non-zero. - * - * Input: - * @ec Reference to entropy collector - * @current_delta Jitter time delta - * - * @return - * 0 jitter measurement not stuck (good bit) - * 1 jitter measurement stuck (reject bit) - */ -static int jent_stuck(struct rand_data *ec, uint64_t current_delta) -{ - int64_t delta2 = ec->last_delta - current_delta; - int64_t delta3 = delta2 - ec->last_delta2; - - ec->last_delta = current_delta; - ec->last_delta2 = delta2; - - if (!current_delta || !delta2 || !delta3) - return 1; - - return 0; -} - /** * This is the heart of the entropy generation: calculate time deltas and * use the CPU jitter in the time deltas. The jitter is injected into the @@ -334,8 +501,7 @@ static int jent_stuck(struct rand_data *ec, uint64_t current_delta) * of this function! This can be done by calling this function * and not using its result. * - * Input: - * @entropy_collector Reference to entropy collector + * @ec [in] Reference to entropy collector * * @return: result of stuck test */ @@ -343,6 +509,7 @@ static int jent_measure_jitter(struct rand_data *ec) { uint64_t time = 0; uint64_t current_delta = 0; + int stuck; /* Invoke one noise source before time measurement to add variations */ jent_memaccess(ec, 0); @@ -352,22 +519,23 @@ static int jent_measure_jitter(struct rand_data *ec) * invocation to measure the timing variations */ jent_get_nstime(&time); - current_delta = time - ec->prev_time; + current_delta = jent_delta(ec->prev_time, time); ec->prev_time = time; + /* Check whether we have a stuck measurement. */ + stuck = jent_stuck(ec, current_delta); + /* Now call the next noise sources which also injects the data */ - jent_lfsr_time(ec, current_delta, 0); + jent_lfsr_time(ec, current_delta, 0, stuck); - /* Check whether we have a stuck measurement. */ - return jent_stuck(ec, current_delta); + return stuck; } /** * Generator of one 64 bit random number * Function fills rand_data->data * - * Input: - * @ec Reference to entropy collector + * @ec [in] Reference to entropy collector */ static void jent_gen_entropy(struct rand_data *ec) { @@ -391,41 +559,6 @@ static void jent_gen_entropy(struct rand_data *ec) } /** - * The continuous test required by FIPS 140-2 -- the function automatically - * primes the test if needed. - * - * Return: - * 0 if FIPS test passed - * < 0 if FIPS test failed - */ -static int jent_fips_test(struct rand_data *ec) -{ - if (ec->fips_enabled == -1) - return 0; - - if (ec->fips_enabled == 0) { - if (!jent_fips_enabled()) { - ec->fips_enabled = -1; - return 0; - } else - ec->fips_enabled = 1; - } - - /* prime the FIPS test */ - if (!ec->old_data) { - ec->old_data = ec->data; - jent_gen_entropy(ec); - } - - if (ec->data == ec->old_data) - return -1; - - ec->old_data = ec->data; - - return 0; -} - -/** * Entry function: Obtain entropy for the caller. * * This function invokes the entropy gathering logic as often to generate @@ -435,18 +568,18 @@ static int jent_fips_test(struct rand_data *ec) * This function truncates the last 64 bit entropy value output to the exact * size specified by the caller. * - * Input: - * @ec Reference to entropy collector - * @data pointer to buffer for storing random data -- buffer must already - * exist - * @len size of the buffer, specifying also the requested number of random - * in bytes + * @ec [in] Reference to entropy collector + * @data [out] pointer to buffer for storing random data -- buffer must + * already exist + * @len [in] size of the buffer, specifying also the requested number of random + * in bytes * * @return number of bytes returned when request is fulfilled or an error * * The following error codes can occur: * -1 entropy_collector is NULL - * -2 FIPS test failed + * -2 RCT failed + * -3 Chi-Squared test failed */ JENT_PRIVATE_STATIC ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len) @@ -461,8 +594,13 @@ ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len) size_t tocopy; jent_gen_entropy(ec); - if (jent_fips_test(ec)) - return -2; + + if (jent_health_failure(ec)) { + if (jent_rct_failure(ec)) + return -2; + else + return -3; + } if ((DATA_SIZE_BITS / 8) < len) tocopy = (DATA_SIZE_BITS / 8); @@ -529,11 +667,8 @@ struct rand_data *jent_entropy_collector_alloc(unsigned int osr, osr = 1; /* minimum sampling rate is 1 */ entropy_collector->osr = osr; - entropy_collector->stir = 1; - if (flags & JENT_DISABLE_STIR) - entropy_collector->stir = 0; - if (flags & JENT_DISABLE_UNBIAS) - entropy_collector->disable_unbias = 1; + if (jent_fips_enabled()) + entropy_collector->fips_enabled = 1; /* fill the data pad with non-zero values */ jent_gen_entropy(entropy_collector); @@ -559,6 +694,7 @@ int jent_entropy_init(void) int i; uint64_t delta_sum = 0; uint64_t old_delta = 0; + unsigned int nonstuck = 0; int time_backwards = 0; int count_mod = 0; int count_stuck = 0; @@ -566,6 +702,11 @@ int jent_entropy_init(void) memset(&ec, 0, sizeof(ec)); + /* Required for RCT */ + ec.osr = 1; + if (jent_fips_enabled()) + ec.fips_enabled = 1; + /* We could perform statistical tests here, but the problem is * that we only have a few loop counts to do testing. These * loop counts may show some slight skew and we produce @@ -587,8 +728,10 @@ int jent_entropy_init(void) /* * TESTLOOPCOUNT needs some loops to identify edge systems. 100 is * definitely too little. + * + * SP800-90B requires at least 1024 initial test cycles. */ -#define TESTLOOPCOUNT 300 +#define TESTLOOPCOUNT 1024 #define CLEARCACHE 100 for (i = 0; (TESTLOOPCOUNT + CLEARCACHE) > i; i++) { uint64_t time = 0; @@ -600,13 +743,14 @@ int jent_entropy_init(void) /* Invoke core entropy collection logic */ jent_get_nstime(&time); ec.prev_time = time; - jent_lfsr_time(&ec, time, 0); + jent_memaccess(&ec, 0); + jent_lfsr_time(&ec, time, 0, 0); jent_get_nstime(&time2); /* test whether timer works */ if (!time || !time2) return ENOTIME; - delta = time2 - time; + delta = jent_delta(time, time2); /* * test whether timer is fine grained enough to provide * delta even when called shortly after each other -- this @@ -629,13 +773,35 @@ int jent_entropy_init(void) if (stuck) count_stuck++; + else { + nonstuck++; + + /* + * Ensure that the APT succeeded. + * + * With the check below that count_stuck must be less + * than 10% of the overall generated raw entropy values + * it is guaranteed that the APT is invoked at + * floor((TESTLOOPCOUNT * 0.9) / 64) == 14 times. + */ + if ((nonstuck % JENT_APT_WINDOW_SIZE) == 0) { + jent_apt_reset(&ec, + delta & JENT_APT_WORD_MASK); + if (jent_health_failure(&ec)) + return EHEALTH; + } + } + + /* Validate RCT */ + if (jent_rct_failure(&ec)) + return ERCT; /* test whether we have an increasing timer */ if (!(time2 > time)) time_backwards++; /* use 32 bit value to ensure compilation on 32 bit arches */ - lowdelta = time2 - time; + lowdelta = (uint64_t)time2 - (uint64_t)time; if (!(lowdelta % 100)) count_mod++; @@ -682,32 +848,8 @@ int jent_entropy_init(void) * If we have more than 90% stuck results, then this Jitter RNG is * likely to not work well. */ - if (JENT_STUCK_INIT_THRES(TESTLOOPCOUNT) < count_stuck) + if ((TESTLOOPCOUNT/10 * 9) < count_stuck) return ESTUCK; return 0; } - -/*************************************************************************** - * Statistical test logic not compiled for regular operation - ***************************************************************************/ - -#ifdef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -/* - * Statistical test: return the time duration for the folding operation. If min - * is set, perform the given number of LFSR ops. Otherwise, allow the - * loop count shuffling to define the number of LFSR ops. - */ -JENT_PRIVATE_STATIC -uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min) -{ - uint64_t time = 0; - uint64_t time2 = 0; - - jent_get_nstime(&time); - jent_memaccess(ec, min); - jent_lfsr_time(ec, time, min); - jent_get_nstime(&time2); - return ((time2 - time)); -} -#endif /* CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT */ diff --git a/src/Crypto/jitterentropy.h b/src/Crypto/jitterentropy.h index b6929933..3dd69017 100644 --- a/src/Crypto/jitterentropy.h +++ b/src/Crypto/jitterentropy.h @@ -1,7 +1,7 @@ /* * Non-physical true random number generator based on timing jitter. * - * Copyright Stephan Mueller <smueller@chronox.de>, 2014 + * Copyright Stephan Mueller <smueller@chronox.de>, 2014 - 2019 * * License * ======= @@ -53,32 +53,45 @@ struct rand_data * of the RNG are marked as SENSITIVE. A user must not * access that information while the RNG executes its loops to * calculate the next random value. */ - uint64_t data; /* SENSITIVE Actual random number */ - uint64_t old_data; /* SENSITIVE Previous random number */ - uint64_t prev_time; /* SENSITIVE Previous time stamp */ + uint64_t data; /* SENSITIVE Actual random number */ + uint64_t prev_time; /* SENSITIVE Previous time stamp */ #define DATA_SIZE_BITS ((sizeof(uint64_t)) * 8) - uint64_t last_delta; /* SENSITIVE stuck test */ - int64_t last_delta2; /* SENSITIVE stuck test */ - unsigned int osr; /* Oversample rate */ - int fips_enabled; /* FIPS enabled? */ - unsigned int stir:1; /* Post-processing stirring */ - unsigned int disable_unbias:1; /* Deactivate Von-Neuman unbias */ + uint64_t last_delta; /* SENSITIVE stuck test */ + uint64_t last_delta2; /* SENSITIVE stuck test */ + unsigned int osr; /* Oversampling rate */ #define JENT_MEMORY_BLOCKS 64 #define JENT_MEMORY_BLOCKSIZE 32 #define JENT_MEMORY_ACCESSLOOPS 128 #define JENT_MEMORY_SIZE (JENT_MEMORY_BLOCKS*JENT_MEMORY_BLOCKSIZE) - unsigned char *mem; /* Memory access location with size of - * memblocks * memblocksize */ - unsigned int memlocation; /* Pointer to byte in *mem */ - unsigned int memblocks; /* Number of memory blocks in *mem */ - unsigned int memblocksize; /* Size of one memory block in bytes */ - unsigned int memaccessloops; /* Number of memory accesses per random - * bit generation */ + unsigned char *mem; /* Memory access location with size of + * memblocks * memblocksize */ + unsigned int memlocation; /* Pointer to byte in *mem */ + unsigned int memblocks; /* Number of memory blocks in *mem */ + unsigned int memblocksize; /* Size of one memory block in bytes */ + unsigned int memaccessloops; /* Number of memory accesses per random + * bit generation */ + + /* Repetition Count Test */ + int rct_count; /* Number of stuck values */ + + /* Adaptive Proportion Test for a significance level of 2^-30 */ +#define JENT_APT_CUTOFF 325 /* Taken from SP800-90B sec 4.4.2 */ +#define JENT_APT_WINDOW_SIZE 512 /* Data window size */ + /* LSB of time stamp to process */ +#define JENT_APT_LSB 16 +#define JENT_APT_WORD_MASK (JENT_APT_LSB - 1) + unsigned int apt_observations; /* Number of collected observations */ + unsigned int apt_count; /* APT counter */ + unsigned int apt_base; /* APT base reference */ + unsigned int apt_base_set:1; /* APT base reference set? */ + + unsigned int fips_enabled:1; + unsigned int health_failure:1; /* Permanent health failure */ }; /* Flags that can be used to initialize the RNG */ -#define JENT_DISABLE_STIR (1<<0) /* Disable stirring the entropy pool */ -#define JENT_DISABLE_UNBIAS (1<<1) /* Disable the Von-Neuman Unbiaser */ +#define JENT_DISABLE_STIR (1<<0) /* UNUSED */ +#define JENT_DISABLE_UNBIAS (1<<1) /* UNUSED */ #define JENT_DISABLE_MEMORY_ACCESS (1<<2) /* Disable memory access for more entropy, saves MEMORY_SIZE RAM for entropy collector */ @@ -137,6 +150,8 @@ unsigned int jent_version(void); #define EMINVARVAR 6 /* Timer variations of variations is too small */ #define EPROGERR 7 /* Programming error */ #define ESTUCK 8 /* Too many stuck results during init. */ +#define EHEALTH 9 /* Health test failed during initialization */ +#define ERCT 10 /* RCT failed during initialization */ /* -- BEGIN statistical test functions only complied with CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -- */ diff --git a/src/Crypto/misc.h b/src/Crypto/misc.h index 47d0288a..25313d1d 100644 --- a/src/Crypto/misc.h +++ b/src/Crypto/misc.h @@ -151,7 +151,7 @@ VC_INLINE uint64 ByteReverseWord64(uint64 value) #endif } -VC_INLINE void CorrectEndianess(uint64 *out, const uint64 *in, size_t byteCount) +VC_INLINE void CorrectEndianness(uint64 *out, const uint64 *in, size_t byteCount) { size_t i, count = byteCount/sizeof(uint64); diff --git a/src/Crypto/rdrand_ml.asm b/src/Crypto/rdrand_ml.asm index 1579a155..4b85f7fc 100644 --- a/src/Crypto/rdrand_ml.asm +++ b/src/Crypto/rdrand_ml.asm @@ -1,9 +1,9 @@ ;; rdrand.asm - written and placed in public domain by Jeffrey Walton and Uri Blumenthal. ;; Copyright assigned to the Crypto++ project. -;; This ASM file provides RDRAND and RDSEED to downlevel Microsoft tool chains. -;; Everything "just works" under Visual Studio. Other platforms will have to -;; run MASM/MASM-64 and then link to the object files. +;; This ASM file provides RDRAND to downlevel Microsoft tool chains. +;; Everything "just works" under Visual Studio. Other platforms will +;; have to run MASM/MASM-64 and then link to the object files. ;; set ASFLAGS=/nologo /D_M_X86 /W3 /Cx /Zi /safeseh ;; set ASFLAGS64=/nologo /D_M_X64 /W3 /Cx /Zi @@ -13,11 +13,10 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -TITLE MASM_RDRAND_GenerateBlock and MASM_RDSEED_GenerateBlock -SUBTITLE Microsoft specific ASM code to utilize RDRAND and RDSEED for down level Microsoft toolchains +TITLE MASM_RDRAND_GenerateBlock source file +SUBTITLE Microsoft specific ASM code to utilize RDRAND for down level Microsoft toolchains PUBLIC MASM_RDRAND_GenerateBlock -PUBLIC MASM_RDSEED_GenerateBlock ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -38,7 +37,6 @@ IFDEF _M_X86 ;; Set via the command line ;; Fastcall calling conventions exports ALIAS <@MASM_RDRAND_GenerateBlock@8> = <MASM_RDRAND_GenerateBlock> -ALIAS <@MASM_RDSEED_GenerateBlock@8> = <MASM_RDSEED_GenerateBlock> ENDIF @@ -63,13 +61,13 @@ MASM_RDRAND_GenerateBlock PROC ;; arg1:DWORD, arg2:DWORD bsize EQU edx ;; Top of While loop -GenerateBlock_Top: +RDRAND_GenerateBlock_Top: ;; Check remaining size cmp bsize, 0 - je GenerateBlock_Return + je RDRAND_GenerateBlock_Return -Call_RDRAND_EAX: +RDRAND_Call_EAX: ;; RDRAND is not available prior to VS2012. Just emit ;; the byte codes using DB. This is `rdrand eax`. DB 0Fh, 0C7h, 0F0h @@ -78,46 +76,48 @@ Call_RDRAND_EAX: ;; If CF=0, a random number was not available. ;; Retry immediately - jnc Call_RDRAND_EAX + jnc RDRAND_Call_EAX RDRAND_succeeded: cmp bsize, MWSIZE - jb Partial_Machine_Word + jb RDRAND_Partial_Machine_Word -Full_Machine_Word: +RDRAND_Full_Machine_Word: mov DWORD PTR [buffer], eax add buffer, MWSIZE ;; No need for Intel Core 2 slow workarounds, like sub bsize, MWSIZE ;; `lea buffer,[buffer+MWSIZE]` for faster adds ;; Continue - jmp GenerateBlock_Top + jmp RDRAND_GenerateBlock_Top ;; 1,2,3 bytes remain -Partial_Machine_Word: +RDRAND_Partial_Machine_Word: ;; Test bit 1 to see if size is at least 2 test bsize, 2 - jz Bit_1_Not_Set + jz RDRAND_Bit_1_Not_Set mov WORD PTR [buffer], ax shr eax, 16 add buffer, 2 -Bit_1_Not_Set: +RDRAND_Bit_1_Not_Set: ;; Test bit 0 to see if size is at least 1 test bsize, 1 - jz Bit_0_Not_Set + jz RDRAND_Bit_0_Not_Set mov BYTE PTR [buffer], al + ;; shr ax, 8 + ;; add buffer, 1 -Bit_0_Not_Set: +RDRAND_Bit_0_Not_Set: ;; We've hit all the bits -GenerateBlock_Return: +RDRAND_GenerateBlock_Return: ;; Clear artifacts xor eax, eax @@ -127,9 +127,6 @@ MASM_RDRAND_GenerateBlock ENDP ENDIF ;; _M_X86 -OPTION PROLOGUE:PrologueDef -OPTION EPILOGUE:EpilogueDef - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -151,13 +148,13 @@ MASM_RDRAND_GenerateBlock PROC ;; arg1:QWORD, arg2:QWORD bsize EQU rdx ;; Top of While loop -GenerateBlock_Top: +RDRAND_GenerateBlock_Top: ;; Check remaining size cmp bsize, 0 - je GenerateBlock_Return + je RDRAND_GenerateBlock_Return -Call_RDRAND_RAX: +RDRAND_Call_RAX: ;; RDRAND is not available prior to VS2012. Just emit ;; the byte codes using DB. This is `rdrand rax`. DB 048h, 0Fh, 0C7h, 0F0h @@ -166,254 +163,67 @@ Call_RDRAND_RAX: ;; If CF=0, a random number was not available. ;; Retry immediately - jnc Call_RDRAND_RAX + jnc RDRAND_Call_RAX RDRAND_succeeded: cmp bsize, MWSIZE - jb Partial_Machine_Word - -Full_Machine_Word: - - mov QWORD PTR [buffer], rax - add buffer, MWSIZE - sub bsize, MWSIZE - - ;; Continue - jmp GenerateBlock_Top - - ;; 1,2,3,4,5,6,7 bytes remain -Partial_Machine_Word: - - ;; Test bit 2 to see if size is at least 4 - test bsize, 4 - jz Bit_2_Not_Set - - mov DWORD PTR [buffer], eax - shr rax, 32 - add buffer, 4 - -Bit_2_Not_Set: - - ;; Test bit 1 to see if size is at least 2 - test bsize, 2 - jz Bit_1_Not_Set - - mov WORD PTR [buffer], ax - shr eax, 16 - add buffer, 2 - -Bit_1_Not_Set: - - ;; Test bit 0 to see if size is at least 1 - test bsize, 1 - jz Bit_0_Not_Set - - mov BYTE PTR [buffer], al - -Bit_0_Not_Set: - - ;; We've hit all the bits - -GenerateBlock_Return: - - ;; Clear artifacts - xor rax, rax - ret - -MASM_RDRAND_GenerateBlock ENDP - -ENDIF ;; _M_X64 - -OPTION PROLOGUE:PrologueDef -OPTION EPILOGUE:EpilogueDef - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -IFDEF _M_X86 ;; Set via the command line - -.CODE -ALIGN 8 -OPTION PROLOGUE:NONE -OPTION EPILOGUE:NONE - -;; No need for Load_Arguments due to fastcall -;; ECX (in): arg1, byte* buffer -;; EDX (in): arg2, size_t bsize - -MASM_RDSEED_GenerateBlock PROC ;; arg1:DWORD, arg2:DWORD - - MWSIZE EQU 04h ;; machine word size - buffer EQU ecx - bsize EQU edx - - ;; Top of While loop -GenerateBlock_Top: - - ;; Check remaining size - cmp bsize, 0 - je GenerateBlock_Return - -Call_RDSEED_EAX: - ;; RDSEED is not available prior to VS2012. Just emit - ;; the byte codes using DB. This is `rdseed eax`. - DB 0Fh, 0C7h, 0F8h - - ;; If CF=1, the number returned by RDSEED is valid. - ;; If CF=0, a random number was not available. - - ;; Retry immediately - jnc Call_RDSEED_EAX - -RDSEED_succeeded: - - cmp bsize, MWSIZE - jb Partial_Machine_Word - -Full_Machine_Word: - - mov DWORD PTR [buffer], eax - add buffer, MWSIZE ;; No need for Intel Core 2 slow workarounds, like - sub bsize, MWSIZE ;; `lea buffer,[buffer+MWSIZE]` for faster adds - - ;; Continue - jmp GenerateBlock_Top - - ;; 1,2,3 bytes remain -Partial_Machine_Word: - - ;; Test bit 1 to see if size is at least 2 - test bsize, 2 - jz Bit_1_Not_Set - - mov WORD PTR [buffer], ax - shr eax, 16 - add buffer, 2 - -Bit_1_Not_Set: - - ;; Test bit 0 to see if size is at least 1 - test bsize, 1 - jz Bit_0_Not_Set - - mov BYTE PTR [buffer], al - -Bit_0_Not_Set: - - ;; We've hit all the bits - -GenerateBlock_Return: - - ;; Clear artifacts - xor eax, eax - ret - -MASM_RDSEED_GenerateBlock ENDP - -ENDIF ;; _M_X86 + jb RDRAND_Partial_Machine_Word -OPTION PROLOGUE:PrologueDef -OPTION EPILOGUE:EpilogueDef - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -IFDEF _M_X64 ;; Set via the command line - -.CODE -ALIGN 16 -OPTION PROLOGUE:NONE -OPTION EPILOGUE:NONE - -;; No need for Load_Arguments due to fastcall -;; RCX (in): arg1, byte* buffer -;; RDX (in): arg2, size_t bsize - -MASM_RDSEED_GenerateBlock PROC ;; arg1:QWORD, arg2:QWORD - - MWSIZE EQU 08h ;; machine word size - buffer EQU rcx - bsize EQU rdx - - ;; Top of While loop -GenerateBlock_Top: - - ;; Check remaining size - cmp bsize, 0 - je GenerateBlock_Return - -Call_RDSEED_RAX: - ;; RDSEED is not available prior to VS2012. Just emit - ;; the byte codes using DB. This is `rdseed rax`. - DB 048h, 0Fh, 0C7h, 0F8h - - ;; If CF=1, the number returned by RDSEED is valid. - ;; If CF=0, a random number was not available. - - ;; Retry immediately - jnc Call_RDSEED_RAX - -RDSEED_succeeded: - - cmp bsize, MWSIZE - jb Partial_Machine_Word - -Full_Machine_Word: +RDRAND_Full_Machine_Word: mov QWORD PTR [buffer], rax add buffer, MWSIZE sub bsize, MWSIZE ;; Continue - jmp GenerateBlock_Top + jmp RDRAND_GenerateBlock_Top ;; 1,2,3,4,5,6,7 bytes remain -Partial_Machine_Word: +RDRAND_Partial_Machine_Word: ;; Test bit 2 to see if size is at least 4 test bsize, 4 - jz Bit_2_Not_Set + jz RDRAND_Bit_2_Not_Set mov DWORD PTR [buffer], eax shr rax, 32 add buffer, 4 -Bit_2_Not_Set: +RDRAND_Bit_2_Not_Set: ;; Test bit 1 to see if size is at least 2 test bsize, 2 - jz Bit_1_Not_Set + jz RDRAND_Bit_1_Not_Set mov WORD PTR [buffer], ax shr eax, 16 add buffer, 2 -Bit_1_Not_Set: +RDRAND_Bit_1_Not_Set: ;; Test bit 0 to see if size is at least 1 test bsize, 1 - jz Bit_0_Not_Set + jz RDRAND_Bit_0_Not_Set mov BYTE PTR [buffer], al + ;; shr ax, 8 + ;; add buffer, 1 -Bit_0_Not_Set: +RDRAND_Bit_0_Not_Set: ;; We've hit all the bits -GenerateBlock_Return: +RDRAND_GenerateBlock_Return: ;; Clear artifacts xor rax, rax ret -MASM_RDSEED_GenerateBlock ENDP +MASM_RDRAND_GenerateBlock ENDP ENDIF ;; _M_X64 -OPTION PROLOGUE:PrologueDef -OPTION EPILOGUE:EpilogueDef - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/Crypto/rdseed_ml.asm b/src/Crypto/rdseed_ml.asm new file mode 100644 index 00000000..60704230 --- /dev/null +++ b/src/Crypto/rdseed_ml.asm @@ -0,0 +1,230 @@ +;; rdrand.asm - written and placed in public domain by Jeffrey Walton and Uri Blumenthal. +;; Copyright assigned to the Crypto++ project. + +;; This ASM file provides RDSEED to downlevel Microsoft tool chains. +;; Everything "just works" under Visual Studio. Other platforms will +;; have to run MASM/MASM-64 and then link to the object files. + +;; set ASFLAGS=/nologo /D_M_X86 /W3 /Cx /Zi /safeseh +;; set ASFLAGS64=/nologo /D_M_X64 /W3 /Cx /Zi +;; "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\ml.exe" %ASFLAGS% /Fo rdrand-x86.obj /c rdrand.asm +;; "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\ml64.exe" %ASFLAGS64% /Fo rdrand-x64.obj /c rdrand.asm + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +TITLE MASM_RDSEED_GenerateBlock source file +SUBTITLE Microsoft specific ASM code to utilize RDSEED for down level Microsoft toolchains + +PUBLIC MASM_RDSEED_GenerateBlock + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; C/C++ Function prototypes (both are fastcall) +;; X86: +;; extern "C" void __fastcall MASM_RDSEED_GenerateBlock(byte* ptr, size_t size); +;; X64: +;; extern "C" void __fastcall MASM_RDSEED_GenerateBlock(byte* ptr, size_t size); + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +IFDEF _M_X86 ;; Set via the command line + +.486 +.MODEL FLAT + +;; Fastcall calling conventions exports +ALIAS <@MASM_RDSEED_GenerateBlock@8> = <MASM_RDSEED_GenerateBlock> + +ENDIF + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +IFDEF _M_X86 ;; Set via the command line + +.CODE +ALIGN 8 +OPTION PROLOGUE:NONE +OPTION EPILOGUE:NONE + +;; No need for Load_Arguments due to fastcall +;; ECX (in): arg1, byte* buffer +;; EDX (in): arg2, size_t bsize + +MASM_RDSEED_GenerateBlock PROC ;; arg1:DWORD, arg2:DWORD + + MWSIZE EQU 04h ;; machine word size + buffer EQU ecx + bsize EQU edx + + ;; Top of While loop +RDSEED_GenerateBlock_Top: + + ;; Check remaining size + cmp bsize, 0 + je RDSEED_GenerateBlock_Return + +RDSEED_Call_EAX: + ;; RDSEED is not available prior to VS2012. Just emit + ;; the byte codes using DB. This is `rdseed eax`. + DB 0Fh, 0C7h, 0F8h + + ;; If CF=1, the number returned by RDSEED is valid. + ;; If CF=0, a random number was not available. + + ;; Retry immediately + jnc RDSEED_Call_EAX + +RDSEED_succeeded: + + cmp bsize, MWSIZE + jb RDSEED_Partial_Machine_Word + +RDSEED_Full_Machine_Word: + + mov DWORD PTR [buffer], eax + add buffer, MWSIZE ;; No need for Intel Core 2 slow workarounds, like + sub bsize, MWSIZE ;; `lea buffer,[buffer+MWSIZE]` for faster adds + + ;; Continue + jmp RDSEED_GenerateBlock_Top + + ;; 1,2,3 bytes remain +RDSEED_Partial_Machine_Word: + + ;; Test bit 1 to see if size is at least 2 + test bsize, 2 + jz RDSEED_Bit_1_Not_Set + + mov WORD PTR [buffer], ax + shr eax, 16 + add buffer, 2 + +RDSEED_Bit_1_Not_Set: + + ;; Test bit 0 to see if size is at least 1 + test bsize, 1 + jz RDSEED_Bit_0_Not_Set + + mov BYTE PTR [buffer], al + ;; shr ax, 8 + ;; add buffer, 1 + +RDSEED_Bit_0_Not_Set: + + ;; We've hit all the bits + +RDSEED_GenerateBlock_Return: + + ;; Clear artifacts + xor eax, eax + ret + +MASM_RDSEED_GenerateBlock ENDP + +ENDIF ;; _M_X86 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +IFDEF _M_X64 ;; Set via the command line + +.CODE +ALIGN 16 +OPTION PROLOGUE:NONE +OPTION EPILOGUE:NONE + +;; No need for Load_Arguments due to fastcall +;; RCX (in): arg1, byte* buffer +;; RDX (in): arg2, size_t bsize + +MASM_RDSEED_GenerateBlock PROC ;; arg1:QWORD, arg2:QWORD + + MWSIZE EQU 08h ;; machine word size + buffer EQU rcx + bsize EQU rdx + + ;; Top of While loop +RDSEED_GenerateBlock_Top: + + ;; Check remaining size + cmp bsize, 0 + je RDSEED_GenerateBlock_Return + +RDSEED_Call_RAX: + ;; RDSEED is not available prior to VS2012. Just emit + ;; the byte codes using DB. This is `rdseed rax`. + DB 048h, 0Fh, 0C7h, 0F8h + + ;; If CF=1, the number returned by RDSEED is valid. + ;; If CF=0, a random number was not available. + + ;; Retry immediately + jnc RDSEED_Call_RAX + +RDSEED_succeeded: + + cmp bsize, MWSIZE + jb RDSEED_Partial_Machine_Word + +RDSEED_Full_Machine_Word: + + mov QWORD PTR [buffer], rax + add buffer, MWSIZE + sub bsize, MWSIZE + + ;; Continue + jmp RDSEED_GenerateBlock_Top + + ;; 1,2,3,4,5,6,7 bytes remain +RDSEED_Partial_Machine_Word: + + ;; Test bit 2 to see if size is at least 4 + test bsize, 4 + jz RDSEED_Bit_2_Not_Set + + mov DWORD PTR [buffer], eax + shr rax, 32 + add buffer, 4 + +RDSEED_Bit_2_Not_Set: + + ;; Test bit 1 to see if size is at least 2 + test bsize, 2 + jz RDSEED_Bit_1_Not_Set + + mov WORD PTR [buffer], ax + shr eax, 16 + add buffer, 2 + +RDSEED_Bit_1_Not_Set: + + ;; Test bit 0 to see if size is at least 1 + test bsize, 1 + jz RDSEED_Bit_0_Not_Set + + mov BYTE PTR [buffer], al + ;; shr ax, 8 + ;; add buffer, 1 + +RDSEED_Bit_0_Not_Set: + + ;; We've hit all the bits + +RDSEED_GenerateBlock_Return: + + ;; Clear artifacts + xor rax, rax + ret + +MASM_RDSEED_GenerateBlock ENDP + +ENDIF ;; _M_X64 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +END diff --git a/src/Crypto/t1ha_bits.h b/src/Crypto/t1ha_bits.h index b78c4129..c9355143 100644 --- a/src/Crypto/t1ha_bits.h +++ b/src/Crypto/t1ha_bits.h @@ -193,7 +193,9 @@ #pragma warning(disable : 4702) /* unreachable code */ #define __GNUC_PREREQ(a,b) 0 +#ifndef UINT64_C #define UINT64_C(value) value ## ULL +#endif #endif /* Compiler */ diff --git a/src/Crypto/wolfCrypt.c b/src/Crypto/wolfCrypt.c new file mode 100644 index 00000000..39ab93a7 --- /dev/null +++ b/src/Crypto/wolfCrypt.c @@ -0,0 +1,243 @@ +/* See src/Crypto/wolfCrypt.md */ + +#include "Aes.h" +#include "Sha2.h" +#include "../Common/Crypto.h" +#include <wolfssl/wolfcrypt/hmac.h> + + +AES_RETURN aes_init() +{ +#if defined( AES_ERR_CHK ) + return EXIT_SUCCESS; +#else + return; +#endif +} + +AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) +{ + int ret = 0; + + ret = wc_AesInit(&cx->wc_enc_aes, NULL, INVALID_DEVID); + + if (key_len == 128 || key_len == 192 || key_len == 256) + key_len = key_len/8; + + if (ret == 0) { + ret = wc_AesSetKey(&cx->wc_enc_aes, key, key_len, NULL, AES_ENCRYPTION); + } + +#if defined( AES_ERR_CHK ) + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +#else + return; +#endif +} + +AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) +{ + int ret = 0; + + ret = wc_AesInit(&cx->wc_dec_aes, NULL, INVALID_DEVID); + + if (key_len == 128 || key_len == 192 || key_len == 256) + key_len = key_len/8; + + if (ret == 0) { + ret = wc_AesSetKey(&cx->wc_dec_aes, key, key_len, NULL, AES_DECRYPTION); + } + +#if defined( AES_ERR_CHK ) + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +#else + return; +#endif +} + +AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ + return aes_encrypt_key(key, 128, cx); +} + +AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ + return aes_encrypt_key(key, 192, cx); +} + +AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ + return aes_encrypt_key(key, 256, cx); +} + +AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ + return aes_decrypt_key(key, 128, cx); +} + +AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ + return aes_decrypt_key(key, 192, cx); +} + +AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ + return aes_decrypt_key(key, 256, cx); +} + +AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]) +{ + int ret = wc_AesEncryptDirect(&cx->wc_enc_aes, out, in); +#if defined( AES_ERR_CHK ) + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +#else + return; +#endif + +} + +AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]) +{ + int ret = wc_AesDecryptDirect(&cx->wc_dec_aes, out, in); +#if defined( AES_ERR_CHK ) + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +#else + return; +#endif + +} + +AES_RETURN xts_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) +{ + int ret = 0; + + cx->wc_enc_xts.aes = cx->wc_enc_aes; + + ret = wc_AesInit(&cx->wc_enc_xts.tweak, NULL, INVALID_DEVID); + + if (key_len == 128 || key_len == 192 || key_len == 256) + key_len = key_len/8; + + if (ret == 0) { + ret = wc_AesSetKey(&cx->wc_enc_xts.tweak, key, key_len, NULL, AES_ENCRYPTION); + } +#if defined( AES_ERR_CHK ) + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +#else + return; +#endif +} + +AES_RETURN xts_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) +{ + int ret = 0; + + cx->wc_dec_xts.aes = cx->wc_dec_aes; + + ret = wc_AesInit(&cx->wc_dec_xts.tweak, NULL, INVALID_DEVID); + + if (key_len == 128 || key_len == 192 || key_len == 256) + key_len = key_len/8; + + if (ret == 0) { + ret = wc_AesSetKey(&cx->wc_dec_xts.tweak, key, key_len, NULL, AES_ENCRYPTION); + } + +#if defined( AES_ERR_CHK ) + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +#else + return; +#endif +} + +AES_RETURN xts_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ + return xts_encrypt_key(key, 256, cx); +} + +AES_RETURN xts_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ + return xts_decrypt_key(key, 256, cx); +} + +AES_RETURN xts_encrypt(const unsigned char *in, unsigned char *out, word64 length, word64 sector, const aes_encrypt_ctx cx[1]) +{ + int ret = wc_AesXtsEncryptConsecutiveSectors(&cx->wc_enc_xts, out, in, length, sector, ENCRYPTION_DATA_UNIT_SIZE); + +#if defined( AES_ERR_CHK ) + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +#else + return; +#endif + +} + +AES_RETURN xts_decrypt(const unsigned char *in, unsigned char *out, word64 length, word64 sector, const aes_decrypt_ctx cx[1]) +{ + int ret = wc_AesXtsDecryptConsecutiveSectors(&cx->wc_dec_xts, out, in, length, sector, ENCRYPTION_DATA_UNIT_SIZE); + +#if defined( AES_ERR_CHK ) + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +#else + return; +#endif +} + + +void sha256_begin(sha256_ctx* ctx) +{ + wc_InitSha256(ctx); +} + +void sha256_hash(const unsigned char * source, uint_32t sourceLen, sha256_ctx *ctx) +{ + wc_Sha256Update(ctx, source, sourceLen); +} + +void sha256_end(unsigned char * result, sha256_ctx* ctx) +{ + wc_Sha256Final(ctx, result); +} + +void sha256(unsigned char * result, const unsigned char* source, uint_32t sourceLen) +{ + wc_Sha256 sha256; + wc_InitSha256(&sha256); + wc_Sha256Update(&sha256, source, sourceLen); + wc_Sha256Final(&sha256, result); + wc_Sha256Free(&sha256); +} + +void sha512_begin(sha512_ctx* ctx) +{ + wc_InitSha512(ctx); +} + +void sha512_hash(const unsigned char * source, uint_64t sourceLen, sha512_ctx *ctx) +{ + wc_Sha512Update(ctx, source, sourceLen); +} + +void sha512_end(unsigned char * result, sha512_ctx* ctx) +{ + wc_Sha512Final(ctx, result); +} + +void sha512(unsigned char * result, const unsigned char* source, uint_64t sourceLen) +{ + wc_Sha512 sha512; + wc_InitSha512(&sha512); + wc_Sha512Update(&sha512, source, sourceLen); + wc_Sha512Final(&sha512, result); + wc_Sha512Free(&sha512); +} + +void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) { + (void) iterations; + wc_HKDF(WC_SHA512, (byte*)pwd, (word32)pwd_len, (byte*)salt, (word32)salt_len, NULL, 0, (byte*)dk, (word32)dklen); +} + +void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) { + (void) iterations; + wc_HKDF(WC_SHA256, (byte*)pwd, (word32)pwd_len, (byte*)salt, (word32)salt_len, NULL, 0, (byte*)dk, (word32)dklen); +} diff --git a/src/Crypto/wolfCrypt.md b/src/Crypto/wolfCrypt.md new file mode 100644 index 00000000..32ccf242 --- /dev/null +++ b/src/Crypto/wolfCrypt.md @@ -0,0 +1,25 @@ +# wolfSSL as crypto provider for VeraCrypt + +[wolfCrypt](https://www.wolfssl.com/products/wolfcrypt/) is wolfSSL's cutting edge crypto engine and a +potential FIPS solution for users of VeraCrypt. Follow the steps below to setup VeraCrypt with wolfCrypt. + +## Building wolfSSL + +Clone wolfSSL and build it as shown below. + +``` +git clone https://github.com/wolfssl/wolfssl && cd wolfssl +./autogen.sh +./configure --enable-xts CFLAGS="-DNO_OLD_WC_NAMES" +make +sudo make install +``` + +## Building VeraCrypt with wolfSSL + +Build VeraCrypt with the `WOLFCRYPT` command line option. + +``` +make WXSTATIC=1 wxbuild && make WXSTATIC=1 clean && make WXSTATIC=1 WOLFCRYPT=1 && make WXSTATIC=1 WOLFCRYPT=1 package +``` + |