mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Add support for SHA-256 in key derivation for bootloader encryption. Create separate bootloader images for SHA-256 and RIPEMD-160. Set SHA-256 as the default PRF for boot encryption and SHA-512 as default PRF for all other cases. Depricate RIPEMD-160.
This commit is contained in:
@@ -24,9 +24,9 @@
|
|||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCNMakeTool"
|
Name="VCNMakeTool"
|
||||||
BuildCommandLine="md Release 2>NUL:
nmake.exe /nologo RELEASE=1

md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

md Rescue 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

md Rescue_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1"
|
BuildCommandLine="md Release 2>NUL:
nmake.exe /nologo RELEASE=1

md Release_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2

md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

md Release_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2

md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

md Release_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2

md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

md Release_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2

md Rescue 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

md Rescue_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

md Rescue_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

md Rescue_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1

md Rescue_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
|
||||||
ReBuildCommandLine="del /q /s Release >NUL:
md Release 2>NUL:
nmake.exe /nologo RELEASE=1

del /q /s Release_AES >NUL:
md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

del /q /s Release_Serpent >NUL:
md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

del /q /s Release_Twofish >NUL:
md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

del /q /s Rescue >NUL:
md Rescue 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

del /q /s Rescue_AES >NUL:
md Rescue_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

del /q /s Rescue_Serpent >NUL:
md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

del /q /s Rescue_Twofish >NUL:
md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1"
|
ReBuildCommandLine="del /q /s Release >NUL:
md Release 2>NUL:
nmake.exe /nologo RELEASE=1

del /q /s Release_SHA2 >NUL:
md Release_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2

del /q /s Release_AES >NUL:
md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

del /q /s Release_AES_SHA2 >NUL:
md Release_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2

del /q /s Release_Serpent >NUL:
md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

del /q /s Release_Serpent_SHA2 >NUL:
md Release_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2

del /q /s Release_Twofish >NUL:
md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

del /q /s Release_Twofish_SHA2 >NUL:
md Release_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2

del /q /s Rescue >NUL:
md Rescue 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

del /q /s Rescue_SHA2 >NUL:
md Rescue_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_AES >NUL:
md Rescue_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

del /q /s Rescue_AES_SHA2 >NUL:
md Rescue_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Serpent >NUL:
md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

del /q /s Rescue_Serpent_SHA2 >NUL:
md Rescue_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Twofish >NUL:
md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1

del /q /s Rescue_Twofish_SHA2 >NUL:
md Rescue_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
|
||||||
CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish Rescue Rescue_AES Rescue_Serpent Rescue_Twofish >NUL:"
|
CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish Rescue Rescue_AES Rescue_Serpent Rescue_Twofish >NUL:
del /q /s Release_SHA2 Release_AES_SHA2 Release_Serpent_SHA2 Release_Twofish_SHA2 Rescue_SHA2 Rescue_AES_SHA2 Rescue_Serpent_SHA2 Rescue_Twofish_SHA2 >NUL:
"
|
||||||
Output="Release\BootLoader.com"
|
Output="Release\BootLoader.com"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG"
|
PreprocessorDefinitions="WIN32;NDEBUG"
|
||||||
IncludeSearchPath=""$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(MSVC16_ROOT)\Include""
|
IncludeSearchPath=""$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(MSVC16_ROOT)\Include""
|
||||||
@@ -164,6 +164,10 @@
|
|||||||
RelativePath="..\..\Crypto\Serpent.c"
|
RelativePath="..\..\Crypto\Serpent.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\Crypto\Sha2Small.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\Crypto\Twofish.c"
|
RelativePath="..\..\Crypto\Twofish.c"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -39,6 +39,13 @@ OBJDIR = $(OBJDIR)_$(SINGLE_CIPHER)
|
|||||||
CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE /D TC_WINDOWS_BOOT_$(SINGLE_CIPHER)
|
CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE /D TC_WINDOWS_BOOT_$(SINGLE_CIPHER)
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
|
!ifdef SINGLE_PRF
|
||||||
|
OBJDIR = $(OBJDIR)_$(SINGLE_PRF)
|
||||||
|
CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_$(SINGLE_PRF)
|
||||||
|
!else
|
||||||
|
CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RIPEMD160
|
||||||
|
!endif
|
||||||
|
|
||||||
OUTDIR = $(OBJDIR)
|
OUTDIR = $(OBJDIR)
|
||||||
TARGETEXT = com
|
TARGETEXT = com
|
||||||
TARGETS = $(OUTDIR)\BootDefs.i $(OUTDIR)\BootSector.bin $(OUTDIR)\Decompressor.com
|
TARGETS = $(OUTDIR)\BootDefs.i $(OUTDIR)\BootSector.bin $(OUTDIR)\Decompressor.com
|
||||||
@@ -72,7 +79,11 @@ OBJS = $(OBJS) $(OUTDIR)\Pkcs5.obj
|
|||||||
OBJS = $(OBJS) $(OUTDIR)\Volumes.obj
|
OBJS = $(OBJS) $(OUTDIR)\Volumes.obj
|
||||||
OBJS = $(OBJS) $(OUTDIR)\Xts.obj
|
OBJS = $(OBJS) $(OUTDIR)\Xts.obj
|
||||||
|
|
||||||
|
!if "$(SINGLE_PRF)" == "SHA2"
|
||||||
|
OBJS = $(OBJS) $(OUTDIR)\Sha2Small.obj
|
||||||
|
!else
|
||||||
OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj
|
OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj
|
||||||
|
!endif
|
||||||
|
|
||||||
!if !DEFINED (SINGLE_CIPHER)
|
!if !DEFINED (SINGLE_CIPHER)
|
||||||
OBJS = $(OBJS) $(OUTDIR)\AesSmall.obj
|
OBJS = $(OBJS) $(OUTDIR)\AesSmall.obj
|
||||||
|
|||||||
@@ -90,11 +90,12 @@ static EncryptionAlgorithm EncryptionAlgorithms[] =
|
|||||||
// Hash algorithms
|
// Hash algorithms
|
||||||
static Hash Hashes[] =
|
static Hash Hashes[] =
|
||||||
{ // ID Name Deprecated System Encryption
|
{ // ID Name Deprecated System Encryption
|
||||||
{ RIPEMD160, "RIPEMD-160", FALSE, TRUE },
|
|
||||||
#ifndef TC_WINDOWS_BOOT
|
#ifndef TC_WINDOWS_BOOT
|
||||||
{ SHA512, "SHA-512", FALSE, FALSE },
|
{ SHA512, "SHA-512", FALSE, FALSE },
|
||||||
{ WHIRLPOOL, "Whirlpool", FALSE, FALSE },
|
{ WHIRLPOOL, "Whirlpool", FALSE, FALSE },
|
||||||
#endif
|
#endif
|
||||||
|
{ SHA256, "SHA-256", FALSE, TRUE },
|
||||||
|
{ RIPEMD160, "RIPEMD-160", TRUE, TRUE },
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -651,17 +652,42 @@ char *HashGetName (int hashId)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TC_WINDOWS_BOOT
|
||||||
|
void HashGetName2 (char *buf, int hashId)
|
||||||
|
{
|
||||||
|
Hash* pHash = HashGet(hashId);
|
||||||
|
if (pHash)
|
||||||
|
strcpy(buf, pHash -> Name);
|
||||||
|
else
|
||||||
|
buf[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
BOOL HashIsDeprecated (int hashId)
|
BOOL HashIsDeprecated (int hashId)
|
||||||
{
|
{
|
||||||
#ifdef TC_WINDOWS_BOOT
|
|
||||||
return HashGet(hashId) -> Deprecated;
|
|
||||||
#else
|
|
||||||
Hash* pHash = HashGet(hashId);
|
Hash* pHash = HashGet(hashId);
|
||||||
return pHash? pHash -> Deprecated : FALSE;
|
return pHash? pHash -> Deprecated : FALSE;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL HashForSystemEncryption (int hashId)
|
||||||
|
{
|
||||||
|
Hash* pHash = HashGet(hashId);
|
||||||
|
return pHash? pHash -> SystemEncryption : FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the maximum number of bytes necessary to be generated by the PBKDF2 (PKCS #5)
|
||||||
|
int GetMaxPkcs5OutSize (void)
|
||||||
|
{
|
||||||
|
int size = 32;
|
||||||
|
|
||||||
|
size = max (size, EAGetLargestKeyForMode (XTS) * 2); // Sizes of primary + secondary keys
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
|
#endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
|
||||||
|
|
||||||
@@ -904,17 +930,6 @@ void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *s
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns the maximum number of bytes necessary to be generated by the PBKDF2 (PKCS #5)
|
|
||||||
int GetMaxPkcs5OutSize (void)
|
|
||||||
{
|
|
||||||
int size = 32;
|
|
||||||
|
|
||||||
size = max (size, EAGetLargestKeyForMode (XTS) * 2); // Sizes of primary + secondary keys
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#else // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
|
#else // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,11 +48,10 @@ extern "C" {
|
|||||||
// Hash algorithms (pseudorandom functions).
|
// Hash algorithms (pseudorandom functions).
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
RIPEMD160 = FIRST_PRF_ID,
|
SHA512 = FIRST_PRF_ID,
|
||||||
#ifndef TC_WINDOWS_BOOT
|
|
||||||
SHA512,
|
|
||||||
WHIRLPOOL,
|
WHIRLPOOL,
|
||||||
#endif
|
SHA256,
|
||||||
|
RIPEMD160,
|
||||||
HASH_ENUM_END_ID
|
HASH_ENUM_END_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -62,6 +61,9 @@ enum
|
|||||||
#define RIPEMD160_BLOCKSIZE 64
|
#define RIPEMD160_BLOCKSIZE 64
|
||||||
#define RIPEMD160_DIGESTSIZE 20
|
#define RIPEMD160_DIGESTSIZE 20
|
||||||
|
|
||||||
|
#define SHA256_BLOCKSIZE 64
|
||||||
|
#define SHA256_DIGESTSIZE 32
|
||||||
|
|
||||||
#define SHA512_BLOCKSIZE 128
|
#define SHA512_BLOCKSIZE 128
|
||||||
#define SHA512_DIGESTSIZE 64
|
#define SHA512_DIGESTSIZE 64
|
||||||
|
|
||||||
@@ -71,7 +73,7 @@ enum
|
|||||||
#define MAX_DIGESTSIZE WHIRLPOOL_DIGESTSIZE
|
#define MAX_DIGESTSIZE WHIRLPOOL_DIGESTSIZE
|
||||||
|
|
||||||
#define DEFAULT_HASH_ALGORITHM FIRST_PRF_ID
|
#define DEFAULT_HASH_ALGORITHM FIRST_PRF_ID
|
||||||
#define DEFAULT_HASH_ALGORITHM_BOOT RIPEMD160
|
#define DEFAULT_HASH_ALGORITHM_BOOT SHA256
|
||||||
|
|
||||||
// The mode of operation used for newly created volumes and first to try when mounting
|
// The mode of operation used for newly created volumes and first to try when mounting
|
||||||
#define FIRST_MODE_OF_OPERATION_ID 1
|
#define FIRST_MODE_OF_OPERATION_ID 1
|
||||||
@@ -207,8 +209,7 @@ typedef struct CRYPTO_INFO_t
|
|||||||
unsigned __int8 master_keydata[MASTER_KEYDATA_SIZE]; /* This holds the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
|
unsigned __int8 master_keydata[MASTER_KEYDATA_SIZE]; /* This holds the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
|
||||||
unsigned __int8 k2[MASTER_KEYDATA_SIZE]; /* For XTS, this contains the secondary key (if cascade, multiple concatenated). For LRW (deprecated/legacy), it contains the tweak key. For CBC (deprecated/legacy), it contains the IV seed. */
|
unsigned __int8 k2[MASTER_KEYDATA_SIZE]; /* For XTS, this contains the secondary key (if cascade, multiple concatenated). For LRW (deprecated/legacy), it contains the tweak key. For CBC (deprecated/legacy), it contains the IV seed. */
|
||||||
unsigned __int8 salt[PKCS5_SALT_SIZE];
|
unsigned __int8 salt[PKCS5_SALT_SIZE];
|
||||||
int noIterations;
|
int noIterations;
|
||||||
int pkcs5;
|
|
||||||
|
|
||||||
uint64 volume_creation_time; // Legacy
|
uint64 volume_creation_time; // Legacy
|
||||||
uint64 header_creation_time; // Legacy
|
uint64 header_creation_time; // Legacy
|
||||||
@@ -239,6 +240,7 @@ typedef struct CRYPTO_INFO_t
|
|||||||
UINT64_STRUCT EncryptedAreaLength;
|
UINT64_STRUCT EncryptedAreaLength;
|
||||||
|
|
||||||
uint32 HeaderFlags;
|
uint32 HeaderFlags;
|
||||||
|
int pkcs5;
|
||||||
|
|
||||||
} CRYPTO_INFO, *PCRYPTO_INFO;
|
} CRYPTO_INFO, *PCRYPTO_INFO;
|
||||||
|
|
||||||
@@ -292,9 +294,14 @@ BOOL EAIsModeSupported (int ea, int testedMode);
|
|||||||
const
|
const
|
||||||
#endif
|
#endif
|
||||||
char *HashGetName (int hash_algo_id);
|
char *HashGetName (int hash_algo_id);
|
||||||
BOOL HashIsDeprecated (int hashId);
|
|
||||||
|
|
||||||
|
#ifndef TC_WINDOWS_BOOT
|
||||||
|
void HashGetName2 (char *buf, int hashId);
|
||||||
|
BOOL HashIsDeprecated (int hashId);
|
||||||
|
BOOL HashForSystemEncryption (int hashId);
|
||||||
int GetMaxPkcs5OutSize (void);
|
int GetMaxPkcs5OutSize (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci);
|
void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci);
|
||||||
void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci);
|
void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci);
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
#ifndef TC_WINDOWS_BOOT
|
#ifndef TC_WINDOWS_BOOT
|
||||||
#include "Sha2.h"
|
#include "Sha2.h"
|
||||||
#include "Whirlpool.h"
|
#include "Whirlpool.h"
|
||||||
|
#else
|
||||||
|
#include "Sha2Small.h"
|
||||||
#endif
|
#endif
|
||||||
#include "Pkcs5.h"
|
#include "Pkcs5.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
@@ -32,6 +34,155 @@ void hmac_truncate
|
|||||||
d2[i] = d1[i];
|
d2[i] = d1[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_SHA2)
|
||||||
|
|
||||||
|
void hmac_sha256
|
||||||
|
(
|
||||||
|
char *k, /* secret key */
|
||||||
|
int lk, /* length of the key in bytes */
|
||||||
|
char *d, /* data */
|
||||||
|
int ld, /* length of data in bytes */
|
||||||
|
char *out /* output buffer, at least "t" bytes */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
sha256_ctx ictx, octx;
|
||||||
|
char isha[SHA256_DIGESTSIZE], osha[SHA256_DIGESTSIZE];
|
||||||
|
char key[SHA256_DIGESTSIZE];
|
||||||
|
char buf[SHA256_BLOCKSIZE];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* If the key is longer than the hash algorithm block size,
|
||||||
|
let key = sha256(key), as per HMAC specifications. */
|
||||||
|
if (lk > SHA256_BLOCKSIZE)
|
||||||
|
{
|
||||||
|
sha256_ctx tctx;
|
||||||
|
|
||||||
|
sha256_begin (&tctx);
|
||||||
|
sha256_hash ((unsigned char *) k, lk, &tctx);
|
||||||
|
sha256_end ((unsigned char *) key, &tctx);
|
||||||
|
|
||||||
|
k = key;
|
||||||
|
lk = SHA256_DIGESTSIZE;
|
||||||
|
|
||||||
|
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** Inner Digest ****/
|
||||||
|
|
||||||
|
sha256_begin (&ictx);
|
||||||
|
|
||||||
|
/* Pad the key for inner digest */
|
||||||
|
for (i = 0; i < lk; ++i)
|
||||||
|
buf[i] = (char) (k[i] ^ 0x36);
|
||||||
|
for (i = lk; i < SHA256_BLOCKSIZE; ++i)
|
||||||
|
buf[i] = 0x36;
|
||||||
|
|
||||||
|
sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, &ictx);
|
||||||
|
sha256_hash ((unsigned char *) d, ld, &ictx);
|
||||||
|
|
||||||
|
sha256_end ((unsigned char *) isha, &ictx);
|
||||||
|
|
||||||
|
/**** Outer Digest ****/
|
||||||
|
|
||||||
|
sha256_begin (&octx);
|
||||||
|
|
||||||
|
for (i = 0; i < lk; ++i)
|
||||||
|
buf[i] = (char) (k[i] ^ 0x5C);
|
||||||
|
for (i = lk; i < SHA256_BLOCKSIZE; ++i)
|
||||||
|
buf[i] = 0x5C;
|
||||||
|
|
||||||
|
sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, &octx);
|
||||||
|
sha256_hash ((unsigned char *) isha, SHA256_DIGESTSIZE, &octx);
|
||||||
|
|
||||||
|
sha256_end ((unsigned char *) osha, &octx);
|
||||||
|
|
||||||
|
/* truncate and print the results */
|
||||||
|
hmac_truncate (osha, out, SHA256_DIGESTSIZE);
|
||||||
|
|
||||||
|
/* Prevent leaks */
|
||||||
|
burn (&ictx, sizeof(ictx));
|
||||||
|
burn (&octx, sizeof(octx));
|
||||||
|
burn (isha, sizeof(isha));
|
||||||
|
burn (osha, sizeof(osha));
|
||||||
|
burn (buf, sizeof(buf));
|
||||||
|
burn (key, sizeof(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void derive_u_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||||
|
{
|
||||||
|
char j[SHA256_DIGESTSIZE], k[SHA256_DIGESTSIZE];
|
||||||
|
char init[128];
|
||||||
|
char counter[4];
|
||||||
|
uint32 c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (iterations == 2000)
|
||||||
|
c = 200000;
|
||||||
|
else
|
||||||
|
c = 500000;
|
||||||
|
|
||||||
|
/* iteration 1 */
|
||||||
|
memset (counter, 0, 4);
|
||||||
|
counter[3] = (char) b;
|
||||||
|
memcpy (init, salt, salt_len); /* salt */
|
||||||
|
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||||
|
hmac_sha256 (pwd, pwd_len, init, salt_len + 4, j);
|
||||||
|
memcpy (u, j, SHA256_DIGESTSIZE);
|
||||||
|
|
||||||
|
/* remaining iterations */
|
||||||
|
while (c > 1)
|
||||||
|
{
|
||||||
|
hmac_sha256 (pwd, pwd_len, j, SHA256_DIGESTSIZE, k);
|
||||||
|
for (i = 0; i < SHA256_DIGESTSIZE; i++)
|
||||||
|
{
|
||||||
|
u[i] ^= k[i];
|
||||||
|
j[i] = k[i];
|
||||||
|
}
|
||||||
|
c--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent possible leaks. */
|
||||||
|
burn (j, sizeof(j));
|
||||||
|
burn (k, sizeof(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||||
|
{
|
||||||
|
char u[SHA256_DIGESTSIZE];
|
||||||
|
int b, l, r;
|
||||||
|
|
||||||
|
if (dklen % SHA256_DIGESTSIZE)
|
||||||
|
{
|
||||||
|
l = 1 + dklen / SHA256_DIGESTSIZE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l = dklen / SHA256_DIGESTSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dklen - (l - 1) * SHA256_DIGESTSIZE;
|
||||||
|
|
||||||
|
/* first l - 1 blocks */
|
||||||
|
for (b = 1; b < l; b++)
|
||||||
|
{
|
||||||
|
derive_u_sha256 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||||
|
memcpy (dk, u, SHA256_DIGESTSIZE);
|
||||||
|
dk += SHA256_DIGESTSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last block */
|
||||||
|
derive_u_sha256 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||||
|
memcpy (dk, u, r);
|
||||||
|
|
||||||
|
|
||||||
|
/* Prevent possible leaks. */
|
||||||
|
burn (u, sizeof(u));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TC_WINDOWS_BOOT
|
#ifndef TC_WINDOWS_BOOT
|
||||||
|
|
||||||
void hmac_sha512
|
void hmac_sha512
|
||||||
@@ -176,6 +327,8 @@ void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int it
|
|||||||
|
|
||||||
#endif // TC_WINDOWS_BOOT
|
#endif // TC_WINDOWS_BOOT
|
||||||
|
|
||||||
|
#if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_RIPEMD160)
|
||||||
|
|
||||||
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest)
|
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest)
|
||||||
{
|
{
|
||||||
RMD160_CTX context;
|
RMD160_CTX context;
|
||||||
@@ -319,6 +472,7 @@ void derive_key_ripemd160 (BOOL bNotTest, char *pwd, int pwd_len, char *salt, in
|
|||||||
/* Prevent possible leaks. */
|
/* Prevent possible leaks. */
|
||||||
burn (u, sizeof(u));
|
burn (u, sizeof(u));
|
||||||
}
|
}
|
||||||
|
#endif // TC_WINDOWS_BOOT
|
||||||
|
|
||||||
#ifndef TC_WINDOWS_BOOT
|
#ifndef TC_WINDOWS_BOOT
|
||||||
|
|
||||||
@@ -468,6 +622,9 @@ char *get_pkcs5_prf_name (int pkcs5_prf_id)
|
|||||||
case SHA512:
|
case SHA512:
|
||||||
return "HMAC-SHA-512";
|
return "HMAC-SHA-512";
|
||||||
|
|
||||||
|
case SHA256:
|
||||||
|
return "HMAC-SHA-256";
|
||||||
|
|
||||||
case RIPEMD160:
|
case RIPEMD160:
|
||||||
return "HMAC-RIPEMD-160";
|
return "HMAC-RIPEMD-160";
|
||||||
|
|
||||||
@@ -488,7 +645,7 @@ int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot)
|
|||||||
{
|
{
|
||||||
|
|
||||||
case RIPEMD160:
|
case RIPEMD160:
|
||||||
return bBoot? 16384 : 32767; /* we multiply this number by 10 inside derive_u_ripemd160 */
|
return bBoot? 16384 : 32767; /* it will be changed to 327661 and 655331 respectively inside derive_u_ripemd160 */
|
||||||
|
|
||||||
#ifndef TC_WINDOWS_BOOT
|
#ifndef TC_WINDOWS_BOOT
|
||||||
|
|
||||||
@@ -499,6 +656,9 @@ int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot)
|
|||||||
return 500000;
|
return 500000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case SHA256:
|
||||||
|
return bBoot? 2000 : 5000; /* it will be changed to 200000 and 500000 respectively inside derive_u_sha256 */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
|
TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
void hmac_sha256 (char *k, int lk, char *d, int ld, char *out);
|
||||||
|
void derive_u_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||||
|
void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||||
|
|
||||||
void hmac_sha512 (char *k, int lk, char *d, int ld, char *out, int t);
|
void hmac_sha512 (char *k, int lk, char *d, int ld, char *out, int t);
|
||||||
void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||||
|
|||||||
@@ -316,6 +316,11 @@ KeyReady: ;
|
|||||||
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SHA256:
|
||||||
|
derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
||||||
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Unknown/wrong ID
|
// Unknown/wrong ID
|
||||||
TC_THROW_FATAL_EXCEPTION;
|
TC_THROW_FATAL_EXCEPTION;
|
||||||
@@ -561,8 +566,13 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO
|
|||||||
cryptoInfo = *retInfo = crypto_open ();
|
cryptoInfo = *retInfo = crypto_open ();
|
||||||
|
|
||||||
// PKCS5 PRF
|
// PKCS5 PRF
|
||||||
|
#ifdef TC_WINDOWS_BOOT_SHA2
|
||||||
|
derive_key_sha256 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
|
||||||
|
PKCS5_SALT_SIZE, bBoot ? 2000 : 5000, dk, sizeof (dk));
|
||||||
|
#else
|
||||||
derive_key_ripemd160 (TRUE, password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
|
derive_key_ripemd160 (TRUE, password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
|
||||||
PKCS5_SALT_SIZE, bBoot ? 16384 : 32767, dk, sizeof (dk));
|
PKCS5_SALT_SIZE, bBoot ? 16384 : 32767, dk, sizeof (dk));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Mode of operation
|
// Mode of operation
|
||||||
cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
|
cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
|
||||||
@@ -606,6 +616,12 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO
|
|||||||
// Flags
|
// Flags
|
||||||
cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);
|
cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);
|
||||||
|
|
||||||
|
#ifdef TC_WINDOWS_BOOT_SHA2
|
||||||
|
cryptoInfo->pkcs5 = SHA256;
|
||||||
|
#else
|
||||||
|
cryptoInfo->pkcs5 = RIPEMD160;
|
||||||
|
#endif
|
||||||
|
|
||||||
memcpy (masterKey, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (masterKey));
|
memcpy (masterKey, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (masterKey));
|
||||||
EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
|
EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
|
||||||
|
|
||||||
@@ -703,6 +719,9 @@ int CreateVolumeHeaderInMemory (BOOL bBoot, char *header, int ea, int mode, Pass
|
|||||||
// User selected encryption algorithm
|
// User selected encryption algorithm
|
||||||
cryptoInfo->ea = ea;
|
cryptoInfo->ea = ea;
|
||||||
|
|
||||||
|
// User selected PRF
|
||||||
|
cryptoInfo->pkcs5 = pkcs5_prf;
|
||||||
|
|
||||||
// Mode of operation
|
// Mode of operation
|
||||||
cryptoInfo->mode = mode;
|
cryptoInfo->mode = mode;
|
||||||
|
|
||||||
@@ -718,6 +737,11 @@ int CreateVolumeHeaderInMemory (BOOL bBoot, char *header, int ea, int mode, Pass
|
|||||||
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SHA256:
|
||||||
|
derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
||||||
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
|
break;
|
||||||
|
|
||||||
case RIPEMD160:
|
case RIPEMD160:
|
||||||
derive_key_ripemd160 (TRUE, keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
derive_key_ripemd160 (TRUE, keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
||||||
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
|
|||||||
Reference in New Issue
Block a user