VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/ExpandVolume/ExpandVolume.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ExpandVolume/ExpandVolume.c')
-rw-r--r--src/ExpandVolume/ExpandVolume.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/ExpandVolume/ExpandVolume.c b/src/ExpandVolume/ExpandVolume.c
index 424948ea..34184dda 100644
--- a/src/ExpandVolume/ExpandVolume.c
+++ b/src/ExpandVolume/ExpandVolume.c
@@ -481,70 +481,71 @@ error:
lpszVolume : char *
[in] Pointer to a string that contains the path to the truecrypt volume
pVolumePassword : Password *
[in] Pointer to the volume password
newHostSize : uint64
[in] new value of the volume host size (can be zero for devices,
which means the volume should use all space of the host device)
initFreeSpace : BOOL
[in] if true, the new volume space will be initalized with random data
Return value:
int with Truecrypt error code (ERR_SUCCESS on success)
Remarks: a lot of code is from TrueCrypt 'Common\Password.c' :: ChangePwd()
*/
static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePassword, int VolumePkcs5, int VolumePim, uint64 newHostSize, BOOL initFreeSpace, BOOL bQuickExpand)
{
int nDosLinkCreated = 1, nStatus = ERR_OS_ERROR;
wchar_t szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH];
wchar_t szDosDevice[TC_MAX_PATH];
char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
PCRYPTO_INFO cryptoInfo = NULL, ci = NULL;
void *dev = INVALID_HANDLE_VALUE;
DWORD dwError;
+ DWORD bytesRead;
BOOL bDevice;
uint64 hostSize=0, newDataAreaSize, currentVolSize;
DWORD HostSectorSize;
FILETIME ftCreationTime;
FILETIME ftLastWriteTime;
FILETIME ftLastAccessTime;
BOOL bTimeStampValid = FALSE;
LARGE_INTEGER headerOffset;
BOOL backupHeader;
- byte *wipeBuffer = NULL;
+ uint8 *wipeBuffer = NULL;
uint32 workChunkSize = TC_VOLUME_HEADER_GROUP_SIZE;
#ifdef _WIN64
CRYPTO_INFO tmpCI;
PCRYPTO_INFO cryptoInfoBackup = NULL;
BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled();
#endif
if (pVolumePassword->Length == 0) return -1;
WaitCursor ();
CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), lpszVolume, &bDevice);
if (bDevice == FALSE)
{
StringCchCopyW (szCFDevice, ARRAYSIZE(szCFDevice), szDiskFile);
}
else
{
nDosLinkCreated = FakeDosNameForDevice (szDiskFile, szDosDevice, sizeof(szDosDevice), szCFDevice, sizeof(szCFDevice), FALSE);
if (nDosLinkCreated != 0) // note: nStatus == ERR_OS_ERROR
goto error;
}
dev = CreateFile (szCFDevice, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (dev == INVALID_HANDLE_VALUE)
goto error;
else if (!bDevice && bPreserveTimestamp)
@@ -645,73 +646,84 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
if (!GetFileSizeEx (dev, &fileSize))
{
nStatus = ERR_OS_ERROR;
goto error;
}
hostSize = fileSize.QuadPart;
HostSectorSize = TC_SECTOR_SIZE_FILE_HOSTED_VOLUME; //TO DO: get the real host disk sector size
}
if (Randinit ())
{
if (CryptoAPILastError == ERROR_SUCCESS)
nStatus = ERR_RAND_INIT_FAILED;
else
nStatus = ERR_CAPI_INIT_FAILED;
goto error;
}
// Seek the volume header
headerOffset.QuadPart = TC_VOLUME_HEADER_OFFSET;
if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
{
nStatus = ERR_OS_ERROR;
goto error;
}
/* Read in volume header */
- nStatus = _lread ((HFILE) dev, buffer, sizeof (buffer));
- if (nStatus != sizeof (buffer))
+ if (!ReadEffectiveVolumeHeader (bDevice, dev, buffer, &bytesRead))
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+
+ if (bytesRead != sizeof (buffer))
{
// Windows may report EOF when reading sectors from the last cluster of a device formatted as NTFS
memset (buffer, 0, sizeof (buffer));
}
/* Try to decrypt the header */
nStatus = ReadVolumeHeader (FALSE, buffer, pVolumePassword, VolumePkcs5, VolumePim, &cryptoInfo, NULL);
if (nStatus == ERR_CIPHER_INIT_WEAK_KEY)
nStatus = 0; // We can ignore this error here
+ // if the volume master key is vulnerable, print a warning to inform the user
+ if ((nStatus == 0) && cryptoInfo->bVulnerableMasterKey)
+ {
+ DebugAddProgressDlgStatus(hwndDlg, GetString ("ERR_XTS_MASTERKEY_VULNERABLE_SHORT"));
+ }
+
if (nStatus != 0)
{
cryptoInfo = NULL;
goto error;
}
#ifdef _WIN64
if (bIsRamEncryptionEnabled)
{
VcProtectKeys (cryptoInfo, VcGetEncryptionID (cryptoInfo));
}
#endif
if (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM)
{
nStatus = ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG;
goto error;
}
if (bDevice && newHostSize == 0)
{
// this means we shall take all host space as new volume size
newHostSize = hostSize;
}
if ( newHostSize % cryptoInfo->SectorSize != 0 || newHostSize > TC_MAX_VOLUME_SIZE || (bDevice && newHostSize > hostSize) )
{
// 1. must be multiple of sector size
// 2. truecrypt volume size limit
// 3. for devices volume size can't be larger than host size
@@ -990,78 +1002,78 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
}
if (!WriteEffectiveVolumeHeader (bDevice, dev, buffer))
{
nStatus = ERR_OS_ERROR;
goto error;
}
}
FlushFileBuffers (dev);
if (!backupHeader)
break;
backupHeader = FALSE;
headerOffset.QuadPart = TC_VOLUME_HEADER_OFFSET; // offset for main header
}
/* header successfully updated */
nStatus = ERR_SUCCESS;
if (bVolTransformThreadCancel)
{
nStatus = ERR_USER_ABORT;
goto error;
}
/* wipe old backup header */
if ( !cryptoInfo->LegacyVolume )
{
- byte wipeRandChars [TC_WIPE_RAND_CHAR_COUNT];
- byte wipeRandCharsUpdate [TC_WIPE_RAND_CHAR_COUNT];
- byte wipePass;
+ uint8 wipeRandChars [TC_WIPE_RAND_CHAR_COUNT];
+ uint8 wipeRandCharsUpdate [TC_WIPE_RAND_CHAR_COUNT];
+ uint8 wipePass;
UINT64_STRUCT unitNo;
LARGE_INTEGER offset;
WipeAlgorithmId wipeAlgorithm = TC_WIPE_35_GUTMANN;
if ( !RandgetBytes (hwndDlg, wipeRandChars, TC_WIPE_RAND_CHAR_COUNT, TRUE)
|| !RandgetBytes (hwndDlg, wipeRandCharsUpdate, TC_WIPE_RAND_CHAR_COUNT, TRUE)
)
{
nStatus = ERR_OS_ERROR;
goto error;
}
DebugAddProgressDlgStatus(hwndDlg, GetString("EXPANDER_WIPING_OLD_HEADER"));
- wipeBuffer = (byte *) TCalloc (workChunkSize);
+ wipeBuffer = (uint8 *) TCalloc (workChunkSize);
if (!wipeBuffer)
{
nStatus = ERR_OUTOFMEMORY;
goto error;
}
offset.QuadPart = currentVolSize - TC_VOLUME_HEADER_GROUP_SIZE;
unitNo.Value = offset.QuadPart;
for (wipePass = 1; wipePass <= GetWipePassCount (wipeAlgorithm); ++wipePass)
{
if (!WipeBuffer (wipeAlgorithm, wipeRandChars, wipePass, wipeBuffer, workChunkSize))
{
ULONG i;
for (i = 0; i < workChunkSize; ++i)
{
wipeBuffer[i] = wipePass;
}
EncryptDataUnits (wipeBuffer, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, cryptoInfo);
memcpy (wipeRandCharsUpdate, wipeBuffer, sizeof (wipeRandCharsUpdate));
}
if ( !SetFilePointerEx (dev, offset, NULL, FILE_BEGIN)
|| _lwrite ((HFILE)dev, (LPCSTR)wipeBuffer, workChunkSize) == HFILE_ERROR
)
{
// Write error
DebugAddProgressDlgStatus(hwndDlg, L"Warning: Failed to wipe old backup header\r\n");
MessageBoxW (hwndDlg, L"WARNING: Failed to wipe old backup header!\n\nIt may be possible to use the current volume password to decrypt the old backup header even after a future password change.\n", lpszTitle, MB_OK | MB_ICONEXCLAMATION);