1
0
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:
Mounir IDRASSI
2014-10-14 17:09:18 +02:00
parent bd7d151abf
commit f38cf0b694
7 changed files with 252 additions and 28 deletions

View File

@@ -24,9 +24,9 @@
> >
<Tool <Tool
Name="VCNMakeTool" Name="VCNMakeTool"
BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1" BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue &gt;NUL:&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES &gt;NUL:&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1" ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue &gt;NUL:&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES &gt;NUL:&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;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 &gt;NUL:" CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish Rescue Rescue_AES Rescue_Serpent Rescue_Twofish &gt;NUL:&#x0D;&#x0A;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 &gt;NUL:&#x0D;&#x0A;"
Output="Release\BootLoader.com" Output="Release\BootLoader.com"
PreprocessorDefinitions="WIN32;NDEBUG" PreprocessorDefinitions="WIN32;NDEBUG"
IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;" IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
@@ -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"
> >

View File

@@ -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

View File

@@ -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

View File

@@ -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
@@ -208,7 +210,6 @@ typedef struct CRYPTO_INFO_t
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);

View File

@@ -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
} }

View File

@@ -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);

View File

@@ -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());