mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-10 13:13:34 +01:00
Windows: Add Magma cipher (GOST-89)
This commit is contained in:
parent
460f552a41
commit
0b2c8b09c6
@ -23,6 +23,7 @@
|
|||||||
#include "Volumes.h"
|
#include "Volumes.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
|
#pragma warning (disable:4706) // assignment within conditional expression
|
||||||
/* Update the following when adding a new cipher or EA:
|
/* Update the following when adding a new cipher or EA:
|
||||||
|
|
||||||
Crypto.h:
|
Crypto.h:
|
||||||
@ -54,6 +55,9 @@ static Cipher Ciphers[] =
|
|||||||
{ SERPENT, L"Serpent", 16, 32, 140*4 },
|
{ SERPENT, L"Serpent", 16, 32, 140*4 },
|
||||||
{ TWOFISH, L"Twofish", 16, 32, TWOFISH_KS },
|
{ TWOFISH, L"Twofish", 16, 32, TWOFISH_KS },
|
||||||
{ CAMELLIA, L"Camellia", 16, 32, CAMELLIA_KS },
|
{ CAMELLIA, L"Camellia", 16, 32, CAMELLIA_KS },
|
||||||
|
#if defined(CIPHER_GOST89)
|
||||||
|
{ GOST89, L"GOST89", 16, 32, GOST_KS },
|
||||||
|
#endif // defined(CIPHER_GOST89)
|
||||||
#endif
|
#endif
|
||||||
{ 0, 0, 0, 0, 0 }
|
{ 0, 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
@ -71,6 +75,9 @@ static EncryptionAlgorithm EncryptionAlgorithms[] =
|
|||||||
{ { SERPENT, 0 }, { XTS, 0 }, 1 },
|
{ { SERPENT, 0 }, { XTS, 0 }, 1 },
|
||||||
{ { TWOFISH, 0 }, { XTS, 0 }, 1 },
|
{ { TWOFISH, 0 }, { XTS, 0 }, 1 },
|
||||||
{ { CAMELLIA, 0 }, { XTS, 0 }, 1 },
|
{ { CAMELLIA, 0 }, { XTS, 0 }, 1 },
|
||||||
|
#if defined(CIPHER_GOST89)
|
||||||
|
{ { GOST89, 0 }, { XTS, 0 }, 1 },
|
||||||
|
#endif // defined(CIPHER_GOST89)
|
||||||
{ { TWOFISH, AES, 0 }, { XTS, 0 }, 1 },
|
{ { TWOFISH, AES, 0 }, { XTS, 0 }, 1 },
|
||||||
{ { SERPENT, TWOFISH, AES, 0 }, { XTS, 0 }, 1 },
|
{ { SERPENT, TWOFISH, AES, 0 }, { XTS, 0 }, 1 },
|
||||||
{ { AES, SERPENT, 0 }, { XTS, 0 }, 1 },
|
{ { AES, SERPENT, 0 }, { XTS, 0 }, 1 },
|
||||||
@ -143,6 +150,14 @@ int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(TC_WINDOWS_BOOT)
|
||||||
|
#if defined(CIPHER_GOST89)
|
||||||
|
case GOST89:
|
||||||
|
gost_set_key(key, (gost_kds*)ks);
|
||||||
|
break;
|
||||||
|
#endif // && defined(CIPHER_GOST89)
|
||||||
|
#endif // !defined(TC_WINDOWS_BOOT)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Unknown/wrong cipher ID
|
// Unknown/wrong cipher ID
|
||||||
return ERR_CIPHER_INIT_FAILURE;
|
return ERR_CIPHER_INIT_FAILURE;
|
||||||
@ -170,6 +185,11 @@ void EncipherBlock(int cipher, void *data, void *ks)
|
|||||||
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
|
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
|
||||||
case CAMELLIA: camellia_encrypt (data, data, ks); break;
|
case CAMELLIA: camellia_encrypt (data, data, ks); break;
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(TC_WINDOWS_BOOT)
|
||||||
|
#if defined(CIPHER_GOST89)
|
||||||
|
case GOST89: gost_encrypt(data, data, ks, 1); break;
|
||||||
|
#endif // defined(CIPHER_GOST89)
|
||||||
|
#endif // !defined(TC_WINDOWS_BOOT)
|
||||||
default: TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
|
default: TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,6 +223,9 @@ void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
|
|||||||
KeRestoreFloatingPointState (&floatingPointState);
|
KeRestoreFloatingPointState (&floatingPointState);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if (cipher == GOST89) {
|
||||||
|
gost_encrypt(data, data, ks, (int)blockCount);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t blockSize = CipherGetBlockSize (cipher);
|
size_t blockSize = CipherGetBlockSize (cipher);
|
||||||
@ -225,6 +248,13 @@ void DecipherBlock(int cipher, void *data, void *ks)
|
|||||||
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
|
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
|
||||||
case CAMELLIA: camellia_decrypt (data, data, ks); break;
|
case CAMELLIA: camellia_decrypt (data, data, ks); break;
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(TC_WINDOWS_BOOT)
|
||||||
|
#if defined(CIPHER_GOST89)
|
||||||
|
case GOST89: gost_decrypt(data, data, ks, 1); break;
|
||||||
|
#endif // defined(CIPHER_GOST89)
|
||||||
|
#endif // !defined(TC_WINDOWS_BOOT)
|
||||||
|
|
||||||
|
|
||||||
#ifndef TC_WINDOWS_BOOT
|
#ifndef TC_WINDOWS_BOOT
|
||||||
|
|
||||||
case AES:
|
case AES:
|
||||||
@ -272,6 +302,9 @@ void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
|
|||||||
KeRestoreFloatingPointState (&floatingPointState);
|
KeRestoreFloatingPointState (&floatingPointState);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if (cipher == GOST89) {
|
||||||
|
gost_decrypt(data, data, ks, (int)blockCount);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t blockSize = CipherGetBlockSize (cipher);
|
size_t blockSize = CipherGetBlockSize (cipher);
|
||||||
@ -340,7 +373,8 @@ int CipherGetKeyScheduleSize (int cipherId)
|
|||||||
|
|
||||||
BOOL CipherSupportsIntraDataUnitParallelization (int cipher)
|
BOOL CipherSupportsIntraDataUnitParallelization (int cipher)
|
||||||
{
|
{
|
||||||
return cipher == AES && IsAesHwCpuSupported();
|
return cipher == AES && IsAesHwCpuSupported() ||
|
||||||
|
cipher == GOST89;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -107,7 +107,8 @@ enum
|
|||||||
AES,
|
AES,
|
||||||
SERPENT,
|
SERPENT,
|
||||||
TWOFISH,
|
TWOFISH,
|
||||||
CAMELLIA
|
CAMELLIA,
|
||||||
|
GOST89
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -189,9 +190,10 @@ typedef struct
|
|||||||
#ifndef TC_WINDOWS_BOOT
|
#ifndef TC_WINDOWS_BOOT
|
||||||
# include "Sha2.h"
|
# include "Sha2.h"
|
||||||
# include "Whirlpool.h"
|
# include "Whirlpool.h"
|
||||||
# include "Camellia.h"
|
# include "GostCipher.h"
|
||||||
|
# include "Camellia.h"
|
||||||
#else
|
#else
|
||||||
# include "CamelliaSmall.h"
|
# include "CamelliaSmall.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "GfMul.h"
|
#include "GfMul.h"
|
||||||
|
@ -497,7 +497,11 @@ void CipherInit2(int cipher, void* key, void* ks, int key_len)
|
|||||||
case CAMELLIA:
|
case CAMELLIA:
|
||||||
CipherInit(cipher,key,ks);
|
CipherInit(cipher,key,ks);
|
||||||
break;
|
break;
|
||||||
|
#if defined(CIPHER_GOST89)
|
||||||
|
case GOST89:
|
||||||
|
CipherInit(cipher,key,ks);
|
||||||
|
break;
|
||||||
|
#endif // defined(CIPHER_GOST89)
|
||||||
default:
|
default:
|
||||||
/* Unknown/wrong ID */
|
/* Unknown/wrong ID */
|
||||||
TC_THROW_FATAL_EXCEPTION;
|
TC_THROW_FATAL_EXCEPTION;
|
||||||
@ -925,8 +929,11 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
|
|||||||
|
|
||||||
nTestsPerformed++;
|
nTestsPerformed++;
|
||||||
}
|
}
|
||||||
|
#if defined(CIPHER_GOST89)
|
||||||
return (nTestsPerformed == 90);
|
return (nTestsPerformed == 100);
|
||||||
|
#else
|
||||||
|
return (nTestsPerformed == 95);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL DoAutoTestAlgorithms (void)
|
static BOOL DoAutoTestAlgorithms (void)
|
||||||
|
@ -199,6 +199,16 @@
|
|||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">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 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>
|
||||||
|
<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>
|
</Command>
|
||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
@ -208,6 +218,7 @@
|
|||||||
<ClCompile Include="Aestab.c" />
|
<ClCompile Include="Aestab.c" />
|
||||||
<ClCompile Include="Camellia.c" />
|
<ClCompile Include="Camellia.c" />
|
||||||
<ClCompile Include="cpu.c" />
|
<ClCompile Include="cpu.c" />
|
||||||
|
<ClCompile Include="GostCipher.c" />
|
||||||
<ClCompile Include="Rmd160.c" />
|
<ClCompile Include="Rmd160.c" />
|
||||||
<ClCompile Include="Serpent.c" />
|
<ClCompile Include="Serpent.c" />
|
||||||
<ClCompile Include="Sha2.c" />
|
<ClCompile Include="Sha2.c" />
|
||||||
@ -222,6 +233,7 @@
|
|||||||
<ClInclude Include="Camellia.h" />
|
<ClInclude Include="Camellia.h" />
|
||||||
<ClInclude Include="config.h" />
|
<ClInclude Include="config.h" />
|
||||||
<ClInclude Include="cpu.h" />
|
<ClInclude Include="cpu.h" />
|
||||||
|
<ClInclude Include="GostCipher.h" />
|
||||||
<ClInclude Include="misc.h" />
|
<ClInclude Include="misc.h" />
|
||||||
<ClInclude Include="Rmd160.h" />
|
<ClInclude Include="Rmd160.h" />
|
||||||
<ClInclude Include="Serpent.h" />
|
<ClInclude Include="Serpent.h" />
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
<ClCompile Include="Whirlpool.c">
|
<ClCompile Include="Whirlpool.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="GostCipher.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Aes.h">
|
<ClInclude Include="Aes.h">
|
||||||
@ -83,6 +86,9 @@
|
|||||||
<ClInclude Include="Whirlpool.h">
|
<ClInclude Include="Whirlpool.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="GostCipher.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="Aes_hw_cpu.asm">
|
<CustomBuild Include="Aes_hw_cpu.asm">
|
||||||
@ -94,5 +100,8 @@
|
|||||||
<CustomBuild Include="Aes_x86.asm">
|
<CustomBuild Include="Aes_x86.asm">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="Gost89_x64.asm">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</CustomBuild>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
269
src/Crypto/GostCipher.c
Normal file
269
src/Crypto/GostCipher.c
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/** @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 "common\Tcdefs.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef GOST_DYNAMIC_SBOXES
|
||||||
|
static void xor_s_box(byte s_box[8][16], byte *seed)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
s_box[1][i] ^= (seed[ (i * 4) + 0 ] ) & 0xF;
|
||||||
|
s_box[2][i] ^= (seed[ (i * 4) + 0 ]>>4) & 0xF;
|
||||||
|
s_box[3][i] ^= (seed[ (i * 4) + 1 ] ) & 0xF;
|
||||||
|
s_box[4][i] ^= (seed[ (i * 4) + 1 ]>>4) & 0xF;
|
||||||
|
s_box[5][i] ^= (seed[ (i * 4) + 2 ] ) & 0xF;
|
||||||
|
s_box[6][i] ^= (seed[ (i * 4) + 2 ]>>4) & 0xF;
|
||||||
|
s_box[7][i] ^= (seed[ (i * 4) + 3 ] ) & 0xF;
|
||||||
|
s_box[8][i] ^= (seed[ (i * 4) + 3 ]>>4) & 0xF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void gost_set_key(byte *key, gost_kds *ks)
|
||||||
|
{
|
||||||
|
#ifdef GOST_DYNAMIC_SBOXES
|
||||||
|
STREEBOG_CTX sctx;
|
||||||
|
byte sbox_seed[64];
|
||||||
|
#if defined (DEVICE_DRIVER) && !defined (_WIN64)
|
||||||
|
KFLOATING_SAVE floatingPointState;
|
||||||
|
NTSTATUS saveStatus = STATUS_SUCCESS;
|
||||||
|
if (HasSSE2() || HasSSE41())
|
||||||
|
saveStatus = KeSaveFloatingPointState (&floatingPointState);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memcpy(ks->key, key, GOST_KEYSIZE);
|
||||||
|
memcpy(ks->sbox, S_TC26, sizeof(ks->sbox));
|
||||||
|
|
||||||
|
#ifdef GOST_DYNAMIC_SBOXES
|
||||||
|
//Generate pseudorandom data based on the key
|
||||||
|
STREEBOG_init(&sctx);
|
||||||
|
STREEBOG_add(&sctx, key, 32);
|
||||||
|
STREEBOG_finalize(&sctx, sbox_seed);
|
||||||
|
|
||||||
|
#if defined (DEVICE_DRIVER) && !defined (_WIN64)
|
||||||
|
if (NT_SUCCESS (saveStatus) && (HasSSE2() || HasSSE41()))
|
||||||
|
KeRestoreFloatingPointState (&floatingPointState);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
xor_s_box(ks->sbox, sbox_seed);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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(byte *in, byte *out, gost_kds *ks, uint64 count);
|
||||||
|
void gost_decrypt_128_CBC_asm(byte *in, byte *out, gost_kds *ks, uint64 count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void gost_encrypt(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(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
|
61
src/Crypto/GostCipher.h
Normal file
61
src/Crypto/GostCipher.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
//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)
|
||||||
|
|
||||||
|
#ifndef rotl32
|
||||||
|
#define rotl32(b, shift) ((b << shift) | (b >> (32 - shift)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
#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
|
||||||
|
{
|
||||||
|
byte key[32];
|
||||||
|
gst_udword sbox_cvt[256 * 4];
|
||||||
|
byte sbox[8][16];
|
||||||
|
} gost_kds;
|
||||||
|
|
||||||
|
#define GOST_KS (sizeof(gost_kds))
|
||||||
|
|
||||||
|
void gost_encrypt(byte *in, byte *out, gost_kds *ks, int count);
|
||||||
|
void gost_decrypt(byte *in, byte *out, gost_kds *ks, int count);
|
||||||
|
void gost_set_key(byte *key, gost_kds *ks);
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define GOST_KS (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -8,6 +8,9 @@ TC_ASFLAGS = $(TC_ASFLAGS) -f win64
|
|||||||
|
|
||||||
TC_ASM_ERR_LOG = ..\Driver\build_errors_asm.log
|
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
|
"$(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)
|
nasm.exe $(TC_ASFLAGS) -o "$@" -l "$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).lst" Aes_$(TC_ARCH).asm 2>$(TC_ASM_ERR_LOG)
|
||||||
|
|
||||||
|
@ -5,10 +5,12 @@ INCLUDES = ..
|
|||||||
|
|
||||||
NTTARGETFILES = \
|
NTTARGETFILES = \
|
||||||
"$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).obj" \
|
"$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).obj" \
|
||||||
"$(OBJ_PATH)\$(O)\Aes_hw_cpu.obj"
|
"$(OBJ_PATH)\$(O)\Aes_hw_cpu.obj" \
|
||||||
|
"$(OBJ_PATH)\$(O)\gost89_$(TC_ARCH).obj"
|
||||||
|
|
||||||
SOURCES = \
|
SOURCES = \
|
||||||
Aes_$(TC_ARCH).asm \
|
Aes_$(TC_ARCH).asm \
|
||||||
|
gost89_$(TC_ARCH).asm \
|
||||||
Aes_hw_cpu.asm \
|
Aes_hw_cpu.asm \
|
||||||
Aeskey.c \
|
Aeskey.c \
|
||||||
Aestab.c \
|
Aestab.c \
|
||||||
@ -17,5 +19,6 @@ SOURCES = \
|
|||||||
Serpent.c \
|
Serpent.c \
|
||||||
Sha2.c \
|
Sha2.c \
|
||||||
Twofish.c \
|
Twofish.c \
|
||||||
|
GostCipher.c \
|
||||||
Whirlpool.c \
|
Whirlpool.c \
|
||||||
Camellia.c
|
Camellia.c
|
||||||
|
481
src/Crypto/gost89_x64.asm
Normal file
481
src/Crypto/gost89_x64.asm
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
;
|
||||||
|
; 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, rdx - &IN
|
||||||
|
; returns: (r13) & (r10)
|
||||||
|
GostEncrypt2x64:
|
||||||
|
; 1st
|
||||||
|
mov r13d, [rdx]
|
||||||
|
mov r14, [rdx]
|
||||||
|
shr r14, 32
|
||||||
|
|
||||||
|
; 2nd
|
||||||
|
mov r10d, [rdx + 16]
|
||||||
|
mov r11, [rdx + 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, rdx - &IN
|
||||||
|
; returns: (r13) & (r10)
|
||||||
|
GostDecrypt2x64:
|
||||||
|
; 1st
|
||||||
|
mov r13d, [rdx]
|
||||||
|
mov r14, [rdx]
|
||||||
|
shr r14, 32
|
||||||
|
|
||||||
|
; 2nd
|
||||||
|
mov r10d, [rdx + 16]
|
||||||
|
mov r11, [rdx + 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 rdx - &IN
|
||||||
|
; returns: r13
|
||||||
|
GostEncrypt1x64:
|
||||||
|
mov r13d, [rdx]
|
||||||
|
mov r14, [rdx]
|
||||||
|
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 rdx - IN
|
||||||
|
; returns: r13
|
||||||
|
GostDecrypt1x64:
|
||||||
|
mov r13d, [rdx]
|
||||||
|
mov r14, [rdx]
|
||||||
|
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* out, uint64* in, gost_kds* kds, uint64 count);
|
||||||
|
; rcx - &out
|
||||||
|
; rdx - &in
|
||||||
|
; r8 - &gost_kds
|
||||||
|
; r9 - count
|
||||||
|
gost_encrypt_128_CBC_asm:
|
||||||
|
SaveRegs ; Saving
|
||||||
|
|
||||||
|
sub rsp, 32
|
||||||
|
mov [rsp], rcx ; Save out addr
|
||||||
|
mov [rsp + 8], rdx ; 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 rdx, [rsp + 8] ; set in addr
|
||||||
|
call GostEncrypt1x64
|
||||||
|
|
||||||
|
mov rcx, [rsp] ; Restore out
|
||||||
|
mov rdx, [rsp + 8] ; restore in
|
||||||
|
|
||||||
|
mov [rcx], r13
|
||||||
|
mov rax, [rdx + 8]
|
||||||
|
xor rax, r13 ; CBC
|
||||||
|
|
||||||
|
add rcx, 8 ;next 8 bytes
|
||||||
|
mov [rcx], rax
|
||||||
|
|
||||||
|
mov rdx, rcx
|
||||||
|
call GostEncrypt1x64
|
||||||
|
|
||||||
|
mov rcx, [rsp] ; Restore out addr
|
||||||
|
mov rdx, [rsp+8] ; Restore in addr
|
||||||
|
|
||||||
|
mov [rcx + 8], r13
|
||||||
|
|
||||||
|
add rcx,16
|
||||||
|
mov [rsp], rcx
|
||||||
|
|
||||||
|
add rdx, 16
|
||||||
|
mov [rsp+8], rdx
|
||||||
|
|
||||||
|
mov r9, [rsp + 24]
|
||||||
|
dec r9
|
||||||
|
|
||||||
|
jmp .do
|
||||||
|
|
||||||
|
.blk2:
|
||||||
|
mov rdx, [rsp + 8] ; set in addr
|
||||||
|
call GostEncrypt2x64
|
||||||
|
|
||||||
|
mov rcx, [rsp] ; Restore out
|
||||||
|
mov rdx, [rsp + 8] ; restore in
|
||||||
|
|
||||||
|
mov [rcx], r13
|
||||||
|
|
||||||
|
mov rax, [rdx + 8]
|
||||||
|
xor rax, r13 ; CBC
|
||||||
|
|
||||||
|
mov [rcx + 16], r10
|
||||||
|
|
||||||
|
mov rbx, [rdx + 24]
|
||||||
|
xor rbx, r10 ; CBC
|
||||||
|
|
||||||
|
mov [rcx + 8], rax
|
||||||
|
mov [rcx + 24], rbx
|
||||||
|
|
||||||
|
add rcx, 8 ;next 8 bytes
|
||||||
|
|
||||||
|
mov rdx, rcx
|
||||||
|
call GostEncrypt2x64
|
||||||
|
|
||||||
|
mov rcx, [rsp] ; Restore out addr
|
||||||
|
mov rdx, [rsp+8] ; Restore in addr
|
||||||
|
|
||||||
|
mov [rcx + 8], r13
|
||||||
|
mov [rcx + 24], r10
|
||||||
|
|
||||||
|
add rcx,32
|
||||||
|
mov [rsp], rcx
|
||||||
|
|
||||||
|
add rdx, 32
|
||||||
|
mov [rsp+8], rdx
|
||||||
|
|
||||||
|
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* out, uint64* in, const gost_kds* kds, uint64 count);
|
||||||
|
; rcx - &out
|
||||||
|
; rdx - &in
|
||||||
|
; 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 rdx, 8
|
||||||
|
call GostDecrypt1x64
|
||||||
|
mov rcx, [rsp] ; Restore out
|
||||||
|
mov rdx, [rsp + 8] ; Restore in
|
||||||
|
mov rax, [rdx]
|
||||||
|
xor rax, r13 ; CBC
|
||||||
|
mov [rcx + 8], rax
|
||||||
|
|
||||||
|
call GostDecrypt1x64
|
||||||
|
|
||||||
|
mov rcx, [rsp] ; Restore out addr
|
||||||
|
mov rdx, [rsp+8] ; Restore in addr
|
||||||
|
|
||||||
|
mov [rcx], r13
|
||||||
|
|
||||||
|
add rcx,16
|
||||||
|
mov [rsp], rcx
|
||||||
|
|
||||||
|
add rdx, 16
|
||||||
|
mov [rsp+8], rdx
|
||||||
|
|
||||||
|
mov r9, [rsp + 24]
|
||||||
|
dec r9
|
||||||
|
|
||||||
|
jmp .do
|
||||||
|
|
||||||
|
.blk2:
|
||||||
|
add rdx, 8
|
||||||
|
call GostDecrypt2x64
|
||||||
|
mov rcx, [rsp] ; Restore out
|
||||||
|
mov rdx, [rsp + 8] ; Restore in
|
||||||
|
|
||||||
|
mov rax, [rdx]
|
||||||
|
xor rax, r13 ; CBC
|
||||||
|
mov [rcx + 8], rax
|
||||||
|
|
||||||
|
mov rbx, [rdx+16]
|
||||||
|
xor rbx, r10 ; CBC
|
||||||
|
mov [rcx + 24], rbx
|
||||||
|
|
||||||
|
call GostDecrypt2x64
|
||||||
|
|
||||||
|
mov rcx, [rsp] ; Restore out addr
|
||||||
|
mov rdx, [rsp+8] ; Restore in addr
|
||||||
|
|
||||||
|
mov [rcx], r13
|
||||||
|
mov [rcx+16], r10
|
||||||
|
|
||||||
|
add rcx,32
|
||||||
|
mov [rsp], rcx
|
||||||
|
|
||||||
|
add rdx,32
|
||||||
|
mov [rsp+8], rdx
|
||||||
|
|
||||||
|
mov r9, [rsp + 24]
|
||||||
|
sub r9, 2
|
||||||
|
|
||||||
|
jmp .do
|
||||||
|
|
||||||
|
.end:
|
||||||
|
add rsp, 32 ; Load out addr
|
||||||
|
RestoreRegs ; Load
|
||||||
|
ret
|
0
src/Crypto/gost89_x86.asm
Normal file
0
src/Crypto/gost89_x86.asm
Normal file
Loading…
Reference in New Issue
Block a user