diff options
Diffstat (limited to 'src/ExpandVolume/ExpandVolume.c')
-rw-r--r-- | src/ExpandVolume/ExpandVolume.c | 26 |
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); |