diff options
Diffstat (limited to 'src/Format/InPlace.c')
-rw-r--r-- | src/Format/InPlace.c | 73 |
1 files changed, 38 insertions, 35 deletions
diff --git a/src/Format/InPlace.c b/src/Format/InPlace.c index 877ff7eb..361b8aeb 100644 --- a/src/Format/InPlace.c +++ b/src/Format/InPlace.c @@ -573,107 +573,107 @@ int EncryptPartitionInPlaceBegin (volatile FORMAT_VOL_PARAMETERS *volParams, vol nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, header, volParams->ea, FIRST_MODE_OF_OPERATION_ID, volParams->password, volParams->pkcs5, volParams->pim, wipePass == 0 ? NULL : (char *) cryptoInfo->master_keydata, &cryptoInfo, dataAreaSize, 0, TC_VOLUME_DATA_OFFSET + dataAreaSize, // Start of the encrypted area = the first byte of the backup heeader (encrypting from the end) 0, // 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 != 0) goto closing_seq; offset.QuadPart = TC_VOLUME_DATA_OFFSET + dataAreaSize; if (!MoveFilePointer (dev, offset)) { nStatus = ERR_OS_ERROR; goto closing_seq; } // Write the backup header to the partition - if (!WriteEffectiveVolumeHeader (TRUE, dev, (byte *) header)) + if (!WriteEffectiveVolumeHeader (TRUE, dev, (uint8 *) header)) { nStatus = ERR_OS_ERROR; goto closing_seq; } // Fill the reserved sectors of the backup header area with random data nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, TRUE); if (nStatus != ERR_SUCCESS) 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 (!MoveFilePointer (dev, offset)) { nStatus = ERR_OS_ERROR; goto closing_seq; } // Write the fake hidden backup header to the partition - if (!WriteEffectiveVolumeHeader (TRUE, dev, (byte *) header)) + if (!WriteEffectiveVolumeHeader (TRUE, dev, (uint8 *) header)) { nStatus = ERR_OS_ERROR; goto closing_seq; } } /* Now we will try to decrypt the backup header to verify it has been correctly written. */ nStatus = OpenBackupHeader (dev, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, &cryptoInfo2, NULL, deviceSize); if (nStatus != ERR_SUCCESS || cryptoInfo->EncryptedAreaStart.Value != cryptoInfo2->EncryptedAreaStart.Value || cryptoInfo2->EncryptedAreaStart.Value == 0) { if (nStatus == ERR_SUCCESS) nStatus = ERR_PARAMETER_INCORRECT; goto closing_seq; } // The backup header is valid so we know we should be able to safely resume in-place encryption // of this partition even if the system/app crashes. /* Conceal the NTFS filesystem (by performing an easy-to-undo modification). This will prevent Windows and apps from interfering with the volume until it has been fully encrypted. */ @@ -727,108 +727,108 @@ closing_seq: if (cryptoInfo2 != NULL) { crypto_close (cryptoInfo2); cryptoInfo2 = NULL; } burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); TCfree (header); if (dosDev[0]) RemoveFakeDosName (volParams->volumePath, dosDev); *outHandle = dev; if (nStatus != ERR_SUCCESS) SetLastError (dwError); return nStatus; } int EncryptPartitionInPlaceResume (HANDLE dev, volatile FORMAT_VOL_PARAMETERS *volParams, WipeAlgorithmId wipeAlgorithm, volatile BOOL *bTryToCorrectReadErrors) { PCRYPTO_INFO masterCryptoInfo = NULL, headerCryptoInfo = NULL, tmpCryptoInfo = NULL; UINT64_STRUCT unitNo; char *buf = NULL, *header = NULL; - byte *wipeBuffer = NULL; - byte wipeRandChars [TC_WIPE_RAND_CHAR_COUNT]; - byte wipeRandCharsUpdate [TC_WIPE_RAND_CHAR_COUNT]; + uint8 *wipeBuffer = NULL; + uint8 wipeRandChars [TC_WIPE_RAND_CHAR_COUNT]; + uint8 wipeRandCharsUpdate [TC_WIPE_RAND_CHAR_COUNT]; WCHAR dosDev[TC_MAX_PATH] = {0}; WCHAR devName[MAX_PATH] = {0}; WCHAR deviceName[MAX_PATH]; int nStatus = ERR_SUCCESS; __int64 deviceSize; uint64 remainingBytes, lastHeaderUpdateDistance = 0, zeroedSectorCount = 0; uint32 workChunkSize; DWORD dwError, dwResult; BOOL bPause = FALSE, bEncryptedAreaSizeChanged = FALSE; LARGE_INTEGER offset; int sectorSize; int i; DWORD n; WCHAR *devicePath = volParams->volumePath; Password *password = volParams->password; int pkcs5_prf = volParams->pkcs5; int pim = volParams->pim; DISK_GEOMETRY driveGeometry; HWND hwndDlg = volParams->hwndDlg; #ifdef _WIN64 BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled(); #endif bInPlaceEncNonSysResumed = TRUE; buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); if (!buf) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } header = (char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (!header) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (wipeAlgorithm != TC_WIPE_NONE) { - wipeBuffer = (byte *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); + wipeBuffer = (uint8 *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); if (!wipeBuffer) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } } headerCryptoInfo = crypto_open(); if (headerCryptoInfo == NULL) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } deviceSize = GetDeviceSize (devicePath); if (deviceSize < 0) { // Cannot determine the size of the partition nStatus = ERR_OS_ERROR; goto closing_seq; } if (dev == INVALID_HANDLE_VALUE) { StringCchCopyW (deviceName, ARRAYSIZE(deviceName), devicePath); if (FakeDosNameForDevice (deviceName, dosDev, sizeof(dosDev),devName, sizeof(devName),FALSE) != 0) { nStatus = ERR_OS_ERROR; @@ -947,135 +947,135 @@ inplace_enc_read: if (nStatus != ERR_SUCCESS) { // Due to write errors, we can't correct the read errors nStatus = ERR_OS_ERROR; goto closing_seq; } goto inplace_enc_read; } } SetLastError (dwTmpErr); // Preserve the original error code nStatus = ERR_OS_ERROR; goto closing_seq; } if (remainingBytes - workChunkSize < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE) { // We reached the inital portion of the filesystem, which we had concealed (in order to prevent // Windows from interfering with the volume). Now we need to undo that modification. for (i = 0; i < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE - (remainingBytes - workChunkSize); i++) buf[i] ^= TC_NTFS_CONCEAL_CONSTANT; } // Encrypt the plaintext in RAM - EncryptDataUnits ((byte *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); + EncryptDataUnits ((uint8 *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); // If enabled, wipe the area to which we will write the ciphertext if (wipeAlgorithm != TC_WIPE_NONE) { - byte wipePass; + uint8 wipePass; int wipePassCount = GetWipePassCount (wipeAlgorithm); if (wipePassCount <= 0) { SetLastError (ERROR_INVALID_PARAMETER); nStatus = ERR_PARAMETER_INCORRECT; goto closing_seq; } offset.QuadPart = masterCryptoInfo->EncryptedAreaStart.Value - workChunkSize; for (wipePass = 1; wipePass <= wipePassCount; ++wipePass) { if (!WipeBuffer (wipeAlgorithm, wipeRandChars, wipePass, wipeBuffer, workChunkSize)) { ULONG i; for (i = 0; i < workChunkSize; ++i) { wipeBuffer[i] = buf[i] + wipePass; } EncryptDataUnits (wipeBuffer, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); memcpy (wipeRandCharsUpdate, wipeBuffer, sizeof (wipeRandCharsUpdate)); } if (MoveFilePointer (dev, offset) == 0 || WriteFile (dev, wipeBuffer, workChunkSize, &n, NULL) == 0) { // Write error dwError = GetLastError(); // Undo failed write operation if (workChunkSize > TC_VOLUME_DATA_OFFSET && MoveFilePointer (dev, offset)) { - DecryptDataUnits ((byte *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); + DecryptDataUnits ((uint8 *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); WriteFile (dev, buf + TC_VOLUME_DATA_OFFSET, workChunkSize - TC_VOLUME_DATA_OFFSET, &n, NULL); } SetLastError (dwError); nStatus = ERR_OS_ERROR; goto closing_seq; } } memcpy (wipeRandChars, wipeRandCharsUpdate, sizeof (wipeRandCharsUpdate)); } // Write the ciphertext offset.QuadPart = masterCryptoInfo->EncryptedAreaStart.Value - workChunkSize; if (MoveFilePointer (dev, offset) == 0) { nStatus = ERR_OS_ERROR; goto closing_seq; } if (WriteFile (dev, buf, workChunkSize, &n, NULL) == 0) { // Write error dwError = GetLastError(); // Undo failed write operation if (workChunkSize > TC_VOLUME_DATA_OFFSET && MoveFilePointer (dev, offset)) { - DecryptDataUnits ((byte *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); + DecryptDataUnits ((uint8 *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); WriteFile (dev, buf + TC_VOLUME_DATA_OFFSET, workChunkSize - TC_VOLUME_DATA_OFFSET, &n, NULL); } SetLastError (dwError); nStatus = ERR_OS_ERROR; goto closing_seq; } masterCryptoInfo->EncryptedAreaStart.Value -= workChunkSize; masterCryptoInfo->EncryptedAreaLength.Value += workChunkSize; remainingBytes -= workChunkSize; lastHeaderUpdateDistance += workChunkSize; bEncryptedAreaSizeChanged = TRUE; if (lastHeaderUpdateDistance >= TC_NONSYS_INPLACE_ENC_HEADER_UPDATE_INTERVAL) { nStatus = FastVolumeHeaderUpdate (dev, headerCryptoInfo, masterCryptoInfo, deviceSize); if (nStatus != ERR_SUCCESS) goto closing_seq; lastHeaderUpdateDistance = 0; } ExportProgressStats (masterCryptoInfo->EncryptedAreaLength.Value, masterCryptoInfo->VolumeSize.Value); if (bVolTransformThreadCancel) @@ -1122,120 +1122,120 @@ inplace_enc_read: password, masterCryptoInfo->pkcs5, pim, (char *) masterCryptoInfo->master_keydata, &tmpCryptoInfo, masterCryptoInfo->VolumeSize.Value, 0, 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)); #ifdef _WIN64 if (bIsRamEncryptionEnabled) { masterCryptoInfo = cryptoInfoBackup; burn (&tmpCI, sizeof (CRYPTO_INFO)); VirtualUnlock (&tmpCI, sizeof(tmpCI)); } #endif if (nStatus != ERR_SUCCESS) goto closing_seq; offset.QuadPart = TC_VOLUME_HEADER_OFFSET; if (MoveFilePointer (dev, offset) == 0 - || !WriteEffectiveVolumeHeader (TRUE, dev, (byte *) header)) + || !WriteEffectiveVolumeHeader (TRUE, dev, (uint8 *) header)) { nStatus = ERR_OS_ERROR; goto closing_seq; } #ifdef _WIN64 if (bIsRamEncryptionEnabled) { VirtualLock (&tmpCI, sizeof(tmpCI)); memcpy (&tmpCI, headerCryptoInfo, sizeof (CRYPTO_INFO)); VcUnprotectKeys (&tmpCI, VcGetEncryptionID (headerCryptoInfo)); cryptoInfoBackup = headerCryptoInfo; headerCryptoInfo = &tmpCI; } #endif // Fill the reserved sectors of the header area with random data nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, headerCryptoInfo, masterCryptoInfo->VolumeSize.Value, TRUE, FALSE); #ifdef _WIN64 if (bIsRamEncryptionEnabled) { headerCryptoInfo = cryptoInfoBackup; burn (&tmpCI, sizeof (CRYPTO_INFO)); VirtualUnlock (&tmpCI, sizeof(tmpCI)); } #endif if (nStatus != ERR_SUCCESS) 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 (MoveFilePointer (dev, offset) == 0 - || !WriteEffectiveVolumeHeader (TRUE, dev, (byte *) header)) + || !WriteEffectiveVolumeHeader (TRUE, dev, (uint8 *) header)) { nStatus = ERR_OS_ERROR; goto closing_seq; } } // Update the configuration files SaveNonSysInPlaceEncSettings (-1, wipeAlgorithm, FALSE); SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_FINISHED); nStatus = ERR_SUCCESS; } else { // The process has been paused by the user or aborted by the wizard (e.g. on app exit) nStatus = ERR_USER_ABORT; SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_PAUSED); } closing_seq: dwError = GetLastError(); @@ -1289,61 +1289,61 @@ closing_seq: if (wipeBuffer != NULL) TCfree (wipeBuffer); if (zeroedSectorCount > 0) { wchar_t msg[30000] = {0}; wchar_t sizeStr[500] = {0}; GetSizeString (zeroedSectorCount * sectorSize, sizeStr, sizeof(sizeStr)); StringCbPrintfW (msg, sizeof(msg), GetString ("ZEROED_BAD_SECTOR_COUNT"), zeroedSectorCount, sizeStr); WarningDirect (msg, hwndDlg); } if (nStatus != ERR_SUCCESS && nStatus != ERR_USER_ABORT) SetLastError (dwError); return nStatus; } int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile BOOL *DiscardUnreadableEncryptedSectors) { HANDLE dev = INVALID_HANDLE_VALUE; PCRYPTO_INFO masterCryptoInfo = NULL, headerCryptoInfo = NULL; UINT64_STRUCT unitNo; char *buf = NULL; - byte *tmpSectorBuf = NULL; + uint8 *tmpSectorBuf = NULL; WCHAR dosDev[TC_MAX_PATH] = {0}; WCHAR devName[MAX_PATH] = {0}; WCHAR deviceName[MAX_PATH]; int nStatus = ERR_SUCCESS; __int64 deviceSize; uint64 remainingBytes, workChunkStartByteOffset, lastHeaderUpdateDistance = 0, skippedBadSectorCount = 0; uint32 workChunkSize; DWORD dwError, dwResult; BOOL bPause = FALSE, bEncryptedAreaSizeChanged = FALSE; LARGE_INTEGER offset; int sectorSize; int i; DWORD n; WCHAR *devicePath = volParams->volumePath; Password *password = volParams->password; HWND hwndDlg = volParams->hwndDlg; int pkcs5_prf = volParams->pkcs5; int pim = volParams->pim; DISK_GEOMETRY driveGeometry; #ifdef _WIN64 BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled(); #endif buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); if (!buf) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } @@ -1405,61 +1405,61 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile // This should never be needed, but is still performed for extra safety (without checking the result) DeviceIoControl (dev, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwResult, NULL); if (!DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveGeometry, sizeof (driveGeometry), &dwResult, NULL)) { nStatus = ERR_OS_ERROR; goto closing_seq; } if ( (driveGeometry.BytesPerSector == 0) || (driveGeometry.BytesPerSector > TC_MAX_VOLUME_SECTOR_SIZE) || (driveGeometry.BytesPerSector % ENCRYPTION_DATA_UNIT_SIZE != 0) ) { Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg); nStatus = ERR_DONT_REPORT; goto closing_seq; } sectorSize = driveGeometry.BytesPerSector; - tmpSectorBuf = (byte *) TCalloc (sectorSize); + tmpSectorBuf = (uint8 *) TCalloc (sectorSize); if (!tmpSectorBuf) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } nStatus = OpenBackupHeader (dev, devicePath, password, pkcs5_prf, pim, &masterCryptoInfo, headerCryptoInfo, deviceSize); if (nStatus != ERR_SUCCESS) goto closing_seq; #ifdef _WIN64 if (bIsRamEncryptionEnabled) { VcProtectKeys (masterCryptoInfo, VcGetEncryptionID (masterCryptoInfo)); VcProtectKeys (headerCryptoInfo, VcGetEncryptionID (headerCryptoInfo)); } #endif if (masterCryptoInfo->LegacyVolume) { Error ("NONSYS_INPLACE_DECRYPTION_BAD_VOL_FORMAT", hwndDlg); nStatus = ERR_DONT_REPORT; goto closing_seq; } if (masterCryptoInfo->hiddenVolume) { Error ("NONSYS_INPLACE_DECRYPTION_CANT_DECRYPT_HID_VOL", hwndDlg); @@ -1593,61 +1593,61 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile memset (tmpSectorBuf, 0, sectorSize); skippedBadSectorCount++; } memcpy (buf + tmpBufOffset, tmpSectorBuf, sectorSize); tmpSectorOffset.QuadPart += sectorSize; tmpBufOffset += sectorSize; } } else { SetLastError (dwTmpErr); // Preserve the original error code nStatus = ERR_OS_ERROR; goto closing_seq; } } else { SetLastError (dwTmpErr); // Preserve the original error code nStatus = ERR_OS_ERROR; goto closing_seq; } } // Decrypt the ciphertext in RAM - DecryptDataUnits ((byte *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); + DecryptDataUnits ((uint8 *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo); // Conceal initial portion of the filesystem if (workChunkStartByteOffset - TC_VOLUME_DATA_OFFSET < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE) { // We are decrypting the initial TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE bytes of the filesystem. We will // conceal this portion to prevent Windows and applications from interfering with the volume. for (i = 0; i < min (TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE, workChunkStartByteOffset - TC_VOLUME_DATA_OFFSET + workChunkSize); i++) buf[i] ^= TC_NTFS_CONCEAL_CONSTANT; } // Write the plaintext offset.QuadPart = workChunkStartByteOffset - TC_VOLUME_DATA_OFFSET; if (MoveFilePointer (dev, offset) == 0) { nStatus = ERR_OS_ERROR; goto closing_seq; } if (WriteFile (dev, buf, workChunkSize, &n, NULL) == 0) { // Write error nStatus = ERR_OS_ERROR; goto closing_seq; @@ -1816,125 +1816,125 @@ closing_seq: TCfree (tmpSectorBuf); tmpSectorBuf = NULL; } if (skippedBadSectorCount > 0) { wchar_t msg[30000] = {0}; wchar_t sizeStr[500] = {0}; GetSizeString (skippedBadSectorCount * sectorSize, sizeStr, sizeof(sizeStr)); StringCbPrintfW (msg, sizeof(msg), GetString ("SKIPPED_BAD_SECTOR_COUNT"), skippedBadSectorCount, sizeStr); WarningDirect (msg, hwndDlg); } if (nStatus != ERR_SUCCESS && nStatus != ERR_USER_ABORT) SetLastError (dwError); return nStatus; } int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_INFO *masterCryptoInfo, __int64 deviceSize) { LARGE_INTEGER offset; DWORD n; int nStatus = ERR_SUCCESS; - byte *header; + uint8 *header; DWORD dwError; uint32 headerCrc32; - byte *fieldPos; + uint8 *fieldPos; PCRYPTO_INFO pCryptoInfo = headerCryptoInfo; #ifdef _WIN64 BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled(); #endif - header = (byte *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); + header = (uint8 *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (!header) return ERR_OUTOFMEMORY; VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); - fieldPos = (byte *) header + TC_HEADER_OFFSET_ENCRYPTED_AREA_START; + fieldPos = (uint8 *) header + TC_HEADER_OFFSET_ENCRYPTED_AREA_START; offset.QuadPart = deviceSize - TC_VOLUME_HEADER_GROUP_SIZE; if (MoveFilePointer (dev, offset) == 0 || !ReadEffectiveVolumeHeader (TRUE, dev, header, &n) || n < TC_VOLUME_HEADER_EFFECTIVE_SIZE) { nStatus = ERR_OS_ERROR; goto closing_seq; } #ifdef _WIN64 if (bIsRamEncryptionEnabled) { pCryptoInfo = crypto_open(); if (!pCryptoInfo) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } memcpy (pCryptoInfo, headerCryptoInfo, sizeof (CRYPTO_INFO)); VcUnprotectKeys (pCryptoInfo, VcGetEncryptionID (headerCryptoInfo)); } #endif DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, pCryptoInfo); if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241) { nStatus = ERR_PARAMETER_INCORRECT; goto closing_seq; } mputInt64 (fieldPos, (masterCryptoInfo->EncryptedAreaStart.Value)); mputInt64 (fieldPos, (masterCryptoInfo->EncryptedAreaLength.Value)); // We need to ensure the TC_HEADER_FLAG_NONSYS_INPLACE_ENC flag bit is set, because if volumes created by TC-format // were decrypted in place, it would be possible to mount them partially encrypted and it wouldn't be possible // to resume interrupted decryption after the wizard exits. masterCryptoInfo->HeaderFlags |= TC_HEADER_FLAG_NONSYS_INPLACE_ENC; - fieldPos = (byte *) header + TC_HEADER_OFFSET_FLAGS; + fieldPos = (uint8 *) header + TC_HEADER_OFFSET_FLAGS; mputLong (fieldPos, (masterCryptoInfo->HeaderFlags)); headerCrc32 = GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC); - fieldPos = (byte *) header + TC_HEADER_OFFSET_HEADER_CRC; + fieldPos = (uint8 *) header + TC_HEADER_OFFSET_HEADER_CRC; mputLong (fieldPos, headerCrc32); EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, pCryptoInfo); if (MoveFilePointer (dev, offset) == 0 || !WriteEffectiveVolumeHeader (TRUE, dev, header)) { nStatus = ERR_OS_ERROR; goto closing_seq; } closing_seq: dwError = GetLastError(); #ifdef _WIN64 if (bIsRamEncryptionEnabled && pCryptoInfo) { crypto_close(pCryptoInfo); } #endif burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); TCfree (header); if (nStatus != ERR_SUCCESS) SetLastError (dwError); @@ -2181,94 +2181,97 @@ BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId newWipeAlgorithm, } else if (!bDecrypt) { if (newWipeAlgorithm != TC_WIPE_NONE) { StringCbPrintfA (str, sizeof(str), "%d", (int) newWipeAlgorithm); SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE), (DWORD) strlen(str), FALSE, FALSE); } else if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE))) { _wremove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE)); } } StringCbPrintfA (str, sizeof(str), "%d", count); return SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC), (DWORD) strlen(str), FALSE, FALSE); } // This function moves the file pointer to the given offset. It first retrieves the current // file position using SetFilePointerEx() with FILE_CURRENT as the reference point, and then // calculates the difference between the current position and the desired position. Subsequently, // it moves the file pointer by the difference calculated using SetFilePointerEx() again. // // This approach of moving the file pointer relatively (instead of absolutely) was implemented // as a workaround to address the performance issues related to in-place encryption. When using // SetFilePointerEx() with FILE_BEGIN as the reference point, reaching the end of large drives // during in-place encryption can cause significant slowdowns. By moving the file pointer // relatively, these performance issues are mitigated. +// +// We fall back to absolute positioning if the relative positioning fails. BOOL MoveFilePointer (HANDLE dev, LARGE_INTEGER offset) { LARGE_INTEGER currOffset; LARGE_INTEGER diffOffset; currOffset.QuadPart = 0; - if (SetFilePointerEx (dev, currOffset, &currOffset, FILE_CURRENT) == 0) - return FALSE; - - diffOffset.QuadPart = offset.QuadPart - currOffset.QuadPart; - if (diffOffset.QuadPart == 0) - return TRUE; + if (SetFilePointerEx (dev, currOffset, &currOffset, FILE_CURRENT)) + { + diffOffset.QuadPart = offset.QuadPart - currOffset.QuadPart; + if (diffOffset.QuadPart == 0) + return TRUE; - // Moves the file pointer by the difference between current and desired positions - if (SetFilePointerEx (dev, diffOffset, NULL, FILE_CURRENT) == 0) - return FALSE; + // Moves the file pointer by the difference between current and desired positions + if (SetFilePointerEx (dev, diffOffset, NULL, FILE_CURRENT)) + return TRUE; + } - return TRUE; + // An error occurred, fallback to absolute positioning + return SetFilePointerEx (dev, offset, NULL, FILE_BEGIN); } // Repairs damaged sectors (i.e. those with read errors) by zeroing them. // Note that this operating fails if there are any write errors. int ZeroUnreadableSectors (HANDLE dev, LARGE_INTEGER startOffset, int64 size, int sectorSize, uint64 *zeroedSectorCount) { int nStatus; DWORD n; int64 sectorCount; LARGE_INTEGER workOffset; - byte *sectorBuffer = NULL; + uint8 *sectorBuffer = NULL; DWORD dwError; workOffset.QuadPart = startOffset.QuadPart; - sectorBuffer = (byte *) TCalloc (sectorSize); + sectorBuffer = (uint8 *) TCalloc (sectorSize); if (!sectorBuffer) return ERR_OUTOFMEMORY; if (!MoveFilePointer(dev, workOffset)) { nStatus = ERR_OS_ERROR; goto closing_seq; } for (sectorCount = size / sectorSize; sectorCount > 0; --sectorCount) { if (ReadFile (dev, sectorBuffer, sectorSize, &n, NULL) == 0) { memset (sectorBuffer, 0, sectorSize); // If ReadFile failed, move back to start of the unreadable sector if (MoveFilePointer (dev, workOffset) == 0) { nStatus = ERR_OS_ERROR; goto closing_seq; } if (WriteFile (dev, sectorBuffer, sectorSize, &n, NULL) == 0) { nStatus = ERR_OS_ERROR; goto closing_seq; } ++(*zeroedSectorCount); @@ -2285,93 +2288,93 @@ closing_seq: if (sectorBuffer != NULL) TCfree (sectorBuffer); if (nStatus != ERR_SUCCESS) SetLastError (dwError); return nStatus; } static int OpenBackupHeader (HANDLE dev, const wchar_t *devicePath, Password *password, int pkcs5, int pim, PCRYPTO_INFO *retMasterCryptoInfo, CRYPTO_INFO *headerCryptoInfo, __int64 deviceSize) { LARGE_INTEGER offset; DWORD n; int nStatus = ERR_SUCCESS; char *header; DWORD dwError; header = (char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (!header) return ERR_OUTOFMEMORY; VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); offset.QuadPart = deviceSize - TC_VOLUME_HEADER_GROUP_SIZE; if (MoveFilePointer (dev, offset) == 0 - || !ReadEffectiveVolumeHeader (TRUE, dev, (byte *) header, &n) || n < TC_VOLUME_HEADER_EFFECTIVE_SIZE) + || !ReadEffectiveVolumeHeader (TRUE, dev, (uint8 *) header, &n) || n < TC_VOLUME_HEADER_EFFECTIVE_SIZE) { nStatus = ERR_OS_ERROR; goto closing_seq; } nStatus = ReadVolumeHeader (FALSE, header, password, pkcs5, pim, retMasterCryptoInfo, headerCryptoInfo); if (nStatus != ERR_SUCCESS) goto closing_seq; closing_seq: dwError = GetLastError(); burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); TCfree (header); dwError = GetLastError(); if (nStatus != ERR_SUCCESS) SetLastError (dwError); return nStatus; } static BOOL GetFreeClusterBeforeThreshold (HANDLE volumeHandle, int64 *freeCluster, int64 clusterThreshold) { const int bitmapSize = 65536; - byte bitmapBuffer[bitmapSize + sizeof (VOLUME_BITMAP_BUFFER)]; + uint8 bitmapBuffer[bitmapSize + sizeof (VOLUME_BITMAP_BUFFER)]; VOLUME_BITMAP_BUFFER *bitmap = (VOLUME_BITMAP_BUFFER *) bitmapBuffer; STARTING_LCN_INPUT_BUFFER startLcn; startLcn.StartingLcn.QuadPart = 0; DWORD bytesReturned; while (DeviceIoControl (volumeHandle, FSCTL_GET_VOLUME_BITMAP, &startLcn, sizeof (startLcn), &bitmapBuffer, sizeof (bitmapBuffer), &bytesReturned, NULL) || GetLastError() == ERROR_MORE_DATA) { for (int64 bitmapIndex = 0; bitmapIndex < min (bitmapSize, (bitmap->BitmapSize.QuadPart / 8)); ++bitmapIndex) { if (bitmap->StartingLcn.QuadPart + bitmapIndex * 8 >= clusterThreshold) goto err; if (bitmap->Buffer[bitmapIndex] != 0xff) { for (int bit = 0; bit < 8; ++bit) { if ((bitmap->Buffer[bitmapIndex] & (1 << bit)) == 0) { *freeCluster = bitmap->StartingLcn.QuadPart + bitmapIndex * 8 + bit; if (*freeCluster >= clusterThreshold) goto err; return TRUE; } } } } |