📄 bootencryption.cpp
字号:
"HKR,,\"UpperFilters\",0x00018002,\"truecrypt\"\r\n";
infFile.Write ((byte *) infTxt.c_str(), infTxt.size());
infFile.Close();
HINF hInf = SetupOpenInfFile (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
throw_sys_if (hInf == INVALID_HANDLE_VALUE);
finally_do_arg (HINF, hInf, { SetupCloseInfFile (finally_arg); });
throw_sys_if (!SetupInstallFromInfSection (ParentWindow, hInf, "truecrypt", SPINST_REGISTRY, classRegKey, NULL, 0, NULL, NULL, NULL, NULL));
}
}
void BootEncryption::RegisterFilterDriver (bool registerDriver, bool volumeClass)
{
if (!IsAdmin() && IsUacSupported())
{
Elevator::RegisterFilterDriver (registerDriver, volumeClass);
return;
}
if (volumeClass)
{
RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_VOLUME);
RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_FLOPPYDISK);
}
else
{
RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_DISKDRIVE);
}
}
#ifndef SETUP
void BootEncryption::CheckRequirements ()
{
if (nCurrentOS == WIN_2000)
throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS");
if (IsNonInstallMode())
throw ErrorException ("FEATURE_REQUIRES_INSTALLATION");
SystemDriveConfiguration config = GetSystemDriveConfiguration ();
if (config.SystemPartition.IsGPT)
throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED");
if (SystemDriveIsDynamic())
throw ErrorException ("SYSENC_UNSUPPORTED_FOR_DYNAMIC_DISK");
if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE)
throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER");
DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);
if (geometry.BytesPerSector != SECTOR_SIZE)
throw ErrorException ("LARGE_SECTOR_UNSUPPORTED");
if (!config.SystemLoaderPresent)
throw ErrorException ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR");
if (!config.SystemPartition.IsGPT)
{
// Determine whether there is an Active partition on the system drive
bool activePartitionFound = false;
foreach (const Partition &partition, config.Partitions)
{
if (partition.Info.BootIndicator)
{
activePartitionFound = true;
break;
}
}
if (!activePartitionFound)
throw ErrorException ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR");
}
}
void BootEncryption::CheckRequirementsHiddenOS ()
{
// It is assumed that CheckRequirements() had been called (so we don't check e.g. whether it's GPT).
// The user may have modified/added/deleted partitions since the partition table was last scanned.
InvalidateCachedSysDriveProperties ();
GetPartitionForHiddenOS ();
}
void BootEncryption::InitialSecurityChecksForHiddenOS ()
{
char windowsDrive = toupper (GetWindowsDirectory()[0]);
// Paging files
if (IsPagingFileActive (TRUE))
{
throw ErrorException (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION"))
+ GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"));
}
char pagingFileRegData[65536];
DWORD pagingFileRegDataSize = sizeof (pagingFileRegData);
if (ReadLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", pagingFileRegData, &pagingFileRegDataSize)
&& pagingFileRegDataSize > 4)
{
for (size_t i = 1; i < pagingFileRegDataSize - 2; ++i)
{
if (memcmp (pagingFileRegData + i, ":\\", 2) == 0 && toupper (pagingFileRegData[i - 1]) != windowsDrive)
{
throw ErrorException (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION"))
+ GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"));
}
}
}
// User profile
char *configPath = GetConfigPath ("dummy");
if (configPath && toupper (configPath[0]) != windowsDrive)
{
throw ErrorException (wstring (GetString ("USER_PROFILE_NOT_ON_SYS_PARTITION"))
+ GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"));
}
// Temporary files
if (toupper (GetTempPath()[0]) != windowsDrive)
{
throw ErrorException (wstring (GetString ("TEMP_NOT_ON_SYS_PARTITION"))
+ GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"));
}
}
void BootEncryption::Deinstall ()
{
BootEncryptionStatus encStatus = GetStatus();
if (encStatus.DriveEncrypted || encStatus.DriveMounted)
throw ParameterIncorrect (SRC_POS);
SystemDriveConfiguration config = GetSystemDriveConfiguration ();
if (encStatus.VolumeHeaderPresent)
{
// Verify CRC of header salt
Device device (config.DevicePath, true);
byte header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
device.Read (header, sizeof (header));
if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE))
throw ParameterIncorrect (SRC_POS);
}
RegisterFilterDriver (false, false);
RegisterFilterDriver (false, true);
SetDriverServiceStartType (SERVICE_SYSTEM_START);
SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); // In case RestoreSystemLoader() fails
try
{
RestoreSystemLoader ();
}
catch (Exception &e)
{
e.Show (ParentWindow);
throw ErrorException ("SYS_LOADER_RESTORE_FAILED");
}
}
int BootEncryption::ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5)
{
BootEncryptionStatus encStatus = GetStatus();
if (encStatus.SetupInProgress)
throw ParameterIncorrect (SRC_POS);
SystemDriveConfiguration config = GetSystemDriveConfiguration ();
char header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
Device device (config.DevicePath);
// Only one algorithm is currently supported
if (pkcs5 != 0)
throw ParameterIncorrect (SRC_POS);
int64 headerOffset = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET;
int64 backupHeaderOffset = -1;
if (encStatus.HiddenSystem)
{
headerOffset = encStatus.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET;
// Find hidden system partition
foreach (const Partition &partition, config.Partitions)
{
if (partition.Info.StartingOffset.QuadPart == encStatus.HiddenSystemPartitionStart)
{
backupHeaderOffset = partition.Info.StartingOffset.QuadPart + partition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_SIZE;
break;
}
}
if (backupHeaderOffset == -1)
throw ParameterIncorrect (SRC_POS);
}
device.SeekAt (headerOffset);
device.Read ((byte *) header, sizeof (header));
PCRYPTO_INFO cryptoInfo = NULL;
int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, &cryptoInfo, NULL);
finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); });
if (status != 0)
{
handleError (ParentWindow, status);
return status;
}
// Change the PKCS-5 PRF if requested by user
if (pkcs5 != 0)
cryptoInfo->pkcs5 = pkcs5;
throw_sys_if (Randinit () != 0);
/* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using
techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
recommends. During each pass we will write a valid working header. Each pass will use the same master
key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
item that will be different for each pass will be the salt. This is sufficient to cause each "version"
of the header to differ substantially and in a random manner from the versions written during the
other passes. */
bool headerUpdated = false;
int result = ERR_SUCCESS;
try
{
BOOL backupHeader = FALSE;
while (TRUE)
{
for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
{
PCRYPTO_INFO tmpCryptoInfo = NULL;
status = CreateVolumeHeaderInMemory (!encStatus.HiddenSystem,
header,
cryptoInfo->ea,
cryptoInfo->mode,
newPassword,
cryptoInfo->pkcs5,
(char *) cryptoInfo->master_keydata,
&tmpCryptoInfo,
cryptoInfo->VolumeSize.Value,
cryptoInfo->hiddenVolumeSize,
cryptoInfo->EncryptedAreaStart.Value,
cryptoInfo->EncryptedAreaLength.Value,
cryptoInfo->RequiredProgramVersion,
cryptoInfo->HeaderFlags | TC_HEADER_FLAG_ENCRYPTED_SYSTEM,
wipePass < PRAND_DISK_WIPE_PASSES - 1);
if (tmpCryptoInfo)
crypto_close (tmpCryptoInfo);
if (status != 0)
{
handleError (ParentWindow, status);
return status;
}
device.SeekAt (headerOffset);
device.Write ((byte *) header, sizeof (header));
headerUpdated = true;
}
if (!encStatus.HiddenSystem || backupHeader)
break;
backupHeader = TRUE;
headerOffset = backupHeaderOffset;
}
}
catch (Exception &e)
{
e.Show (ParentWindow);
result = ERR_OS_ERROR;
}
if (headerUpdated)
{
ReopenBootVolumeHeaderRequest reopenRequest;
reopenRequest.VolumePassword = *newPassword;
finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });
CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest));
}
return result;
}
void BootEncryption::CheckEncryptionSetupResult ()
{
CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
}
void BootEncryption::Install (bool hiddenSystem)
{
BootEncryptionStatus encStatus = GetStatus();
if (encStatus.DriveMounted)
throw ParameterIncorrect (SRC_POS);
try
{
InstallBootLoader (false, hiddenSystem);
if (!hiddenSystem)
InstallVolumeHeader ();
RegisterBootDriver (hiddenSystem);
}
catch (Exception &)
{
try
{
RestoreSystemLoader ();
}
catch (Exception &e)
{
e.Show (ParentWindow);
}
throw;
}
}
void BootEncryption::PrepareHiddenOSCreation (int ea, int mode, int pkcs5)
{
BootEncryptionStatus encStatus = GetStatus();
if (encStatus.DriveMounted)
throw ParameterIncorrect (SRC_POS);
CheckRequirements();
BackupSystemLoader();
SelectedEncryptionAlgorithmId = ea;
}
void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath)
{
BootEncryptionStatus encStatus = GetStatus();
if (encStatus.DriveMounted)
throw ParameterIncorrect (SRC_POS);
CheckRequirements ();
SystemDriveConfiguration config = GetSystemDriveConfiguration();
// Some chipset drivers may prevent access to the last sector of the drive
if (!systemPartitionOnly)
{
DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);
Buffer sector (geometry.BytesPerSector);
Device device (config.DevicePath);
try
{
device.SeekAt (config.DrivePartition.Info.PartitionLength.QuadPart - geometry.BytesPerSector);
device.Read (sector.Ptr(), sector.Size());
}
catch (SystemException &e)
{
if (e.ErrorCode != ERROR_CRC)
{
e.Show (ParentWindow);
Error ("WHOLE_DRIVE_ENCRYPTION_PREVENTED_BY_DRIVERS");
throw UserAbort (SRC_POS);
}
}
}
BackupSystemLoader ();
uint64 volumeSize;
uint64 encryptedAreaStart;
if (systemPartitionOnly)
{
volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart;
encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart;
}
else
{
volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE;
encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE;
}
SelectedEncryptionAlgorithmId = ea;
CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5);
if (!rescueIsoImagePath.empty())
CreateRescueIsoImage (true, rescueIsoImagePath);
}
bool BootEncryption::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
{
if (!IsAdmin() && IsUacSupported())
return Elevator::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false;
return ::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false;
}
void BootEncryption::WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value)
{
if (!IsAdmin() && IsUacSupported())
{
Elevator::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value);
return;
}
throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value));
}
void BootEncryption::StartDecryption ()
{
BootEncryptionStatus encStatus = GetStatus();
if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
throw ParameterIncorrect (SRC_POS);
BootEncryptionSetupRequest request;
ZeroMemory (&request, sizeof (request));
request.SetupMode = SetupDecryption;
CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
}
void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors)
{
BootEncryptionStatus encStatus = GetStatus();
if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
throw ParameterIncorrect (SRC_POS);
BootEncryptionSetupRequest request;
ZeroMemory (&request, sizeof (request));
request.SetupMode = SetupEncryption;
request.WipeAlgorithm = wipeAlgorithm;
request.ZeroUnreadableSectors = zeroUnreadableSectors;
CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
}
#endif // !SETUP
void BootEncryption::WriteBootDriveSector (uint64 offset, byte *data)
{
WriteBootDriveSectorRequest request;
request.Offset.QuadPart = offset;
memcpy (request.Data, data, sizeof (request.Data));
CallDriver (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR, &request, sizeof (request), NULL, 0);
}
void BootEncryption::RegisterBootDriver (bool hiddenSystem)
{
SetDriverServiceStartType (SERVICE_BOOT_START);
try
{
RegisterFilterDriver (false, false);
RegisterFilterDriver (false, true);
}
catch (...) { }
RegisterFilterDriver (true, false);
if (hiddenSystem)
RegisterFilterDriver (true, true);
}
bool BootEncryption::RestartComputer (void)
{
return (::RestartComputer() != FALSE);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -