mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 19:08:26 -06:00
Windows: Fix vulnerability inherited from TrueCrypt that allows an attacker to detect with high probability if a hidden volume is present. Vulnerability reported by Ivanov Alexey Mikhailovich.
This commit is contained in:
@@ -566,10 +566,63 @@ begin_format:
|
|||||||
// Fill reserved header sectors (including the backup header area) with random data
|
// Fill reserved header sectors (including the backup header area) with random data
|
||||||
if (!volParams->hiddenVol)
|
if (!volParams->hiddenVol)
|
||||||
{
|
{
|
||||||
|
BOOL bUpdateBackup = FALSE;
|
||||||
|
|
||||||
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE);
|
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE);
|
||||||
|
|
||||||
if (nStatus != ERR_SUCCESS)
|
if (nStatus != ERR_SUCCESS)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
// write fake hidden volume header to protect against attacks that use statistical entropy
|
||||||
|
// analysis to detect presence of hidden volumes.
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
PCRYPTO_INFO dummyInfo = NULL;
|
||||||
|
LARGE_INTEGER hiddenOffset;
|
||||||
|
|
||||||
|
hiddenOffset.QuadPart = bUpdateBackup ? dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE + TC_HIDDEN_VOLUME_HEADER_OFFSET: TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||||
|
|
||||||
|
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
||||||
|
header,
|
||||||
|
volParams->ea,
|
||||||
|
FIRST_MODE_OF_OPERATION_ID,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&dummyInfo,
|
||||||
|
dataAreaSize,
|
||||||
|
dataAreaSize,
|
||||||
|
dataOffset,
|
||||||
|
dataAreaSize,
|
||||||
|
0,
|
||||||
|
volParams->headerFlags,
|
||||||
|
FormatSectorSize,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
if (nStatus != ERR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
crypto_close (dummyInfo);
|
||||||
|
|
||||||
|
if (!SetFilePointerEx ((HANDLE) dev, hiddenOffset, NULL, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bUpdateBackup)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bUpdateBackup = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
|
|||||||
@@ -437,9 +437,51 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
|
|||||||
&& (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) != 0
|
&& (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) != 0
|
||||||
&& (cryptoInfo->HeaderFlags & ~TC_HEADER_FLAG_NONSYS_INPLACE_ENC) == 0)
|
&& (cryptoInfo->HeaderFlags & ~TC_HEADER_FLAG_NONSYS_INPLACE_ENC) == 0)
|
||||||
{
|
{
|
||||||
|
PCRYPTO_INFO dummyInfo = NULL;
|
||||||
|
LARGE_INTEGER hiddenOffset;
|
||||||
|
|
||||||
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, cryptoInfo->VolumeSize.Value, !backupHeader, backupHeader);
|
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, cryptoInfo->VolumeSize.Value, !backupHeader, backupHeader);
|
||||||
if (nStatus != ERR_SUCCESS)
|
if (nStatus != ERR_SUCCESS)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
// write fake hidden volume header to protect against attacks that use statistical entropy
|
||||||
|
// analysis to detect presence of hidden volumes
|
||||||
|
hiddenOffset.QuadPart = backupHeader ? cryptoInfo->VolumeSize.Value + TC_VOLUME_HEADER_GROUP_SIZE + TC_HIDDEN_VOLUME_HEADER_OFFSET: TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||||
|
|
||||||
|
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
||||||
|
buffer,
|
||||||
|
cryptoInfo->ea,
|
||||||
|
cryptoInfo->mode,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&dummyInfo,
|
||||||
|
cryptoInfo->VolumeSize.Value,
|
||||||
|
cryptoInfo->VolumeSize.Value,
|
||||||
|
cryptoInfo->EncryptedAreaStart.Value,
|
||||||
|
cryptoInfo->EncryptedAreaLength.Value,
|
||||||
|
truecryptMode? 0 : cryptoInfo->RequiredProgramVersion,
|
||||||
|
cryptoInfo->HeaderFlags,
|
||||||
|
cryptoInfo->SectorSize,
|
||||||
|
wipePass < wipePassCount - 1);
|
||||||
|
|
||||||
|
if (nStatus != ERR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
crypto_close (dummyInfo);
|
||||||
|
|
||||||
|
if (!SetFilePointerEx ((HANDLE) dev, hiddenOffset, NULL, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteEffectiveVolumeHeader (bDevice, dev, buffer))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushFileBuffers (dev);
|
FlushFileBuffers (dev);
|
||||||
|
|||||||
@@ -809,7 +809,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|
|||||||
unsigned char *p = (unsigned char *) header;
|
unsigned char *p = (unsigned char *) header;
|
||||||
static CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo;
|
static CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo;
|
||||||
|
|
||||||
int nUserKeyLen = password->Length;
|
int nUserKeyLen = password? password->Length : 0;
|
||||||
PCRYPTO_INFO cryptoInfo = crypto_open ();
|
PCRYPTO_INFO cryptoInfo = crypto_open ();
|
||||||
static char dk[MASTER_KEYDATA_SIZE];
|
static char dk[MASTER_KEYDATA_SIZE];
|
||||||
int x;
|
int x;
|
||||||
@@ -844,7 +844,10 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!RandgetBytes (hwndDlg, keyInfo.master_keydata, bytesNeeded, TRUE))
|
if (!RandgetBytes (hwndDlg, keyInfo.master_keydata, bytesNeeded, TRUE))
|
||||||
|
{
|
||||||
|
crypto_close (cryptoInfo);
|
||||||
return ERR_CIPHER_INIT_WEAK_KEY;
|
return ERR_CIPHER_INIT_WEAK_KEY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -853,9 +856,17 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// User key
|
// User key
|
||||||
memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
|
if (password)
|
||||||
keyInfo.keyLength = nUserKeyLen;
|
{
|
||||||
keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, FALSE, bBoot);
|
memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
|
||||||
|
keyInfo.keyLength = nUserKeyLen;
|
||||||
|
keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, FALSE, bBoot);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyInfo.keyLength = 0;
|
||||||
|
keyInfo.noIterations = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// User selected encryption algorithm
|
// User selected encryption algorithm
|
||||||
cryptoInfo->ea = ea;
|
cryptoInfo->ea = ea;
|
||||||
@@ -871,34 +882,51 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|
|||||||
|
|
||||||
// Salt for header key derivation
|
// Salt for header key derivation
|
||||||
if (!RandgetBytes (hwndDlg, keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
|
if (!RandgetBytes (hwndDlg, keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
|
||||||
return ERR_CIPHER_INIT_WEAK_KEY;
|
|
||||||
|
|
||||||
// PBKDF2 (PKCS5) is used to derive primary header key(s) and secondary header key(s) (XTS) from the password/keyfiles
|
|
||||||
switch (pkcs5_prf)
|
|
||||||
{
|
{
|
||||||
case SHA512:
|
crypto_close (cryptoInfo);
|
||||||
derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
return ERR_CIPHER_INIT_WEAK_KEY;
|
||||||
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case SHA256:
|
if (password)
|
||||||
derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
{
|
||||||
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
// PBKDF2 (PKCS5) is used to derive primary header key(s) and secondary header key(s) (XTS) from the password/keyfiles
|
||||||
break;
|
switch (pkcs5_prf)
|
||||||
|
{
|
||||||
|
case SHA512:
|
||||||
|
derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
||||||
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
|
break;
|
||||||
|
|
||||||
case RIPEMD160:
|
case SHA256:
|
||||||
derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
||||||
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WHIRLPOOL:
|
case RIPEMD160:
|
||||||
derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
||||||
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case WHIRLPOOL:
|
||||||
// Unknown/wrong ID
|
derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
|
||||||
TC_THROW_FATAL_EXCEPTION;
|
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Unknown/wrong ID
|
||||||
|
crypto_close (cryptoInfo);
|
||||||
|
TC_THROW_FATAL_EXCEPTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// generate a random key
|
||||||
|
if (!RandgetBytes(hwndDlg, dk, GetMaxPkcs5OutSize(), !bWipeMode))
|
||||||
|
{
|
||||||
|
crypto_close (cryptoInfo);
|
||||||
|
return ERR_CIPHER_INIT_WEAK_KEY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header setup */
|
/* Header setup */
|
||||||
@@ -950,6 +978,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|
|||||||
|| sectorSize > TC_MAX_VOLUME_SECTOR_SIZE
|
|| sectorSize > TC_MAX_VOLUME_SECTOR_SIZE
|
||||||
|| sectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
|
|| sectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
|
||||||
{
|
{
|
||||||
|
crypto_close (cryptoInfo);
|
||||||
TC_THROW_FATAL_EXCEPTION;
|
TC_THROW_FATAL_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -978,11 +1007,17 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|
|||||||
|
|
||||||
retVal = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
|
retVal = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
|
||||||
if (retVal != ERR_SUCCESS)
|
if (retVal != ERR_SUCCESS)
|
||||||
|
{
|
||||||
|
crypto_close (cryptoInfo);
|
||||||
return retVal;
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
// Mode of operation
|
// Mode of operation
|
||||||
if (!EAInitMode (cryptoInfo))
|
if (!EAInitMode (cryptoInfo))
|
||||||
|
{
|
||||||
|
crypto_close (cryptoInfo);
|
||||||
return ERR_OUTOFMEMORY;
|
return ERR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Encrypt the entire header (except the salt)
|
// Encrypt the entire header (except the salt)
|
||||||
@@ -996,7 +1031,10 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|
|||||||
// Init with the master key(s)
|
// Init with the master key(s)
|
||||||
retVal = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
|
retVal = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
|
||||||
if (retVal != ERR_SUCCESS)
|
if (retVal != ERR_SUCCESS)
|
||||||
|
{
|
||||||
|
crypto_close (cryptoInfo);
|
||||||
return retVal;
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
|
memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
|
||||||
|
|
||||||
@@ -1010,7 +1048,10 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|
|||||||
|
|
||||||
// Mode of operation
|
// Mode of operation
|
||||||
if (!EAInitMode (cryptoInfo))
|
if (!EAInitMode (cryptoInfo))
|
||||||
|
{
|
||||||
|
crypto_close (cryptoInfo);
|
||||||
return ERR_OUTOFMEMORY;
|
return ERR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef VOLFORMAT
|
#ifdef VOLFORMAT
|
||||||
|
|||||||
@@ -804,7 +804,7 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
|
|||||||
cryptoInfo->RequiredProgramVersion,
|
cryptoInfo->RequiredProgramVersion,
|
||||||
cryptoInfo->HeaderFlags,
|
cryptoInfo->HeaderFlags,
|
||||||
cryptoInfo->SectorSize,
|
cryptoInfo->SectorSize,
|
||||||
TRUE ); // use slow poll
|
FALSE ); // use slow poll
|
||||||
|
|
||||||
if (ci != NULL)
|
if (ci != NULL)
|
||||||
crypto_close (ci);
|
crypto_close (ci);
|
||||||
@@ -818,8 +818,7 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
nStatus = _lwrite ((HFILE) dev, buffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
|
if (!WriteEffectiveVolumeHeader (bDevice, dev, buffer))
|
||||||
if (nStatus != TC_VOLUME_HEADER_EFFECTIVE_SIZE)
|
|
||||||
{
|
{
|
||||||
nStatus = ERR_OS_ERROR;
|
nStatus = ERR_OS_ERROR;
|
||||||
goto error;
|
goto error;
|
||||||
@@ -835,9 +834,51 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
//DebugAddProgressDlgStatus(hwndDlg, L"WriteRandomDataToReservedHeaderAreas() ...\r\n");
|
//DebugAddProgressDlgStatus(hwndDlg, L"WriteRandomDataToReservedHeaderAreas() ...\r\n");
|
||||||
|
PCRYPTO_INFO dummyInfo = NULL;
|
||||||
|
LARGE_INTEGER hiddenOffset;
|
||||||
|
|
||||||
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, newDataAreaSize, !backupHeader, backupHeader);
|
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, newDataAreaSize, !backupHeader, backupHeader);
|
||||||
if (nStatus != ERR_SUCCESS)
|
if (nStatus != ERR_SUCCESS)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
// write fake hidden volume header to protect against attacks that use statistical entropy
|
||||||
|
// analysis to detect presence of hidden volumes
|
||||||
|
hiddenOffset.QuadPart = headerOffset.QuadPart + TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||||
|
|
||||||
|
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
||||||
|
buffer,
|
||||||
|
cryptoInfo->ea,
|
||||||
|
cryptoInfo->mode,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&dummyInfo,
|
||||||
|
newDataAreaSize,
|
||||||
|
newDataAreaSize, // hiddenVolumeSize
|
||||||
|
cryptoInfo->EncryptedAreaStart.Value,
|
||||||
|
newDataAreaSize,
|
||||||
|
cryptoInfo->RequiredProgramVersion,
|
||||||
|
cryptoInfo->HeaderFlags,
|
||||||
|
cryptoInfo->SectorSize,
|
||||||
|
FALSE ); // use slow poll
|
||||||
|
|
||||||
|
if (nStatus != ERR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
crypto_close (dummyInfo);
|
||||||
|
|
||||||
|
if (!SetFilePointerEx ((HANDLE) dev, hiddenOffset, NULL, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteEffectiveVolumeHeader (bDevice, dev, buffer))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushFileBuffers (dev);
|
FlushFileBuffers (dev);
|
||||||
|
|||||||
@@ -566,6 +566,8 @@ int EncryptPartitionInPlaceBegin (volatile FORMAT_VOL_PARAMETERS *volParams, vol
|
|||||||
// Prepare the backup header
|
// Prepare the backup header
|
||||||
for (int wipePass = 0; wipePass < (wipeAlgorithm == TC_WIPE_NONE ? 1 : PRAND_HEADER_WIPE_PASSES); wipePass++)
|
for (int wipePass = 0; wipePass < (wipeAlgorithm == TC_WIPE_NONE ? 1 : PRAND_HEADER_WIPE_PASSES); wipePass++)
|
||||||
{
|
{
|
||||||
|
PCRYPTO_INFO dummyInfo = NULL;
|
||||||
|
|
||||||
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
||||||
header,
|
header,
|
||||||
volParams->ea,
|
volParams->ea,
|
||||||
@@ -607,6 +609,47 @@ int EncryptPartitionInPlaceBegin (volatile FORMAT_VOL_PARAMETERS *volParams, vol
|
|||||||
|
|
||||||
if (nStatus != ERR_SUCCESS)
|
if (nStatus != ERR_SUCCESS)
|
||||||
goto closing_seq;
|
goto closing_seq;
|
||||||
|
|
||||||
|
// write fake hidden volume header to protect against attacks that use statistical entropy
|
||||||
|
// analysis to detect presence of hidden volumes
|
||||||
|
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
||||||
|
header,
|
||||||
|
volParams->ea,
|
||||||
|
FIRST_MODE_OF_OPERATION_ID,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&dummyInfo,
|
||||||
|
dataAreaSize,
|
||||||
|
dataAreaSize,
|
||||||
|
TC_VOLUME_DATA_OFFSET + dataAreaSize, // Start of the encrypted area = the first byte of the backup heeader (encrypting from the end)
|
||||||
|
dataAreaSize, // No data is encrypted yet
|
||||||
|
0,
|
||||||
|
volParams->headerFlags | TC_HEADER_FLAG_NONSYS_INPLACE_ENC,
|
||||||
|
volParams->sectorSize,
|
||||||
|
wipeAlgorithm == TC_WIPE_NONE ? FALSE : (wipePass < PRAND_HEADER_WIPE_PASSES - 1));
|
||||||
|
|
||||||
|
if (nStatus != ERR_SUCCESS)
|
||||||
|
goto closing_seq;
|
||||||
|
|
||||||
|
crypto_close (dummyInfo);
|
||||||
|
|
||||||
|
offset.QuadPart += TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||||
|
|
||||||
|
if (!SetFilePointerEx (dev, offset, NULL, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto closing_seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the fake hidden backup header to the partition
|
||||||
|
if (!WriteEffectiveVolumeHeader (TRUE, dev, (byte *) header))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto closing_seq;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1045,6 +1088,8 @@ inplace_enc_read:
|
|||||||
|
|
||||||
for (int wipePass = 0; wipePass < (wipeAlgorithm == TC_WIPE_NONE ? 1 : PRAND_HEADER_WIPE_PASSES); wipePass++)
|
for (int wipePass = 0; wipePass < (wipeAlgorithm == TC_WIPE_NONE ? 1 : PRAND_HEADER_WIPE_PASSES); wipePass++)
|
||||||
{
|
{
|
||||||
|
PCRYPTO_INFO dummyInfo = NULL;
|
||||||
|
|
||||||
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
||||||
header,
|
header,
|
||||||
headerCryptoInfo->ea,
|
headerCryptoInfo->ea,
|
||||||
@@ -1081,6 +1126,40 @@ inplace_enc_read:
|
|||||||
|
|
||||||
if (nStatus != ERR_SUCCESS)
|
if (nStatus != ERR_SUCCESS)
|
||||||
goto closing_seq;
|
goto closing_seq;
|
||||||
|
|
||||||
|
// write fake hidden volume header to protect against attacks that use statistical entropy
|
||||||
|
// analysis to detect presence of hidden volumes
|
||||||
|
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
|
||||||
|
header,
|
||||||
|
headerCryptoInfo->ea,
|
||||||
|
headerCryptoInfo->mode,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&dummyInfo,
|
||||||
|
masterCryptoInfo->VolumeSize.Value,
|
||||||
|
masterCryptoInfo->VolumeSize.Value,
|
||||||
|
masterCryptoInfo->EncryptedAreaStart.Value,
|
||||||
|
masterCryptoInfo->EncryptedAreaLength.Value,
|
||||||
|
masterCryptoInfo->RequiredProgramVersion,
|
||||||
|
masterCryptoInfo->HeaderFlags | TC_HEADER_FLAG_NONSYS_INPLACE_ENC,
|
||||||
|
masterCryptoInfo->SectorSize,
|
||||||
|
wipeAlgorithm == TC_WIPE_NONE ? FALSE : (wipePass < PRAND_HEADER_WIPE_PASSES - 1));
|
||||||
|
|
||||||
|
if (nStatus != ERR_SUCCESS)
|
||||||
|
goto closing_seq;
|
||||||
|
|
||||||
|
crypto_close (dummyInfo);
|
||||||
|
|
||||||
|
offset.QuadPart += TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||||
|
|
||||||
|
if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0
|
||||||
|
|| !WriteEffectiveVolumeHeader (TRUE, dev, (byte *) header))
|
||||||
|
{
|
||||||
|
nStatus = ERR_OS_ERROR;
|
||||||
|
goto closing_seq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the configuration files
|
// Update the configuration files
|
||||||
|
|||||||
Reference in New Issue
Block a user