mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 19:08:26 -06:00
Windows: Add option to avoid PIM prompt in pre-boot authentication by storing PIM value unencrypted in MBR.
This commit is contained in:
@@ -1300,7 +1300,7 @@ namespace VeraCrypt
|
||||
}
|
||||
|
||||
|
||||
void BootEncryption::WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage)
|
||||
void BootEncryption::WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim)
|
||||
{
|
||||
Device device (GetSystemDriveConfiguration().DevicePath);
|
||||
device.CheckOpened (SRC_POS);
|
||||
@@ -1326,6 +1326,15 @@ namespace VeraCrypt
|
||||
|
||||
memcpy (mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, customUserMessage.c_str(), customUserMessage.size());
|
||||
}
|
||||
|
||||
if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
|
||||
{
|
||||
// PIM for pre-boot authentication can be encoded on two bytes since its maximum
|
||||
// value is 65535 (0xFFFF)
|
||||
memcpy (mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &pim, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
|
||||
}
|
||||
else
|
||||
memset (mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, 0, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
|
||||
|
||||
device.SeekAt (0);
|
||||
device.Write (mbr, sizeof (mbr));
|
||||
@@ -1494,7 +1503,7 @@ namespace VeraCrypt
|
||||
InstallBootLoader (device, preserveUserConfig, hiddenOSCreation);
|
||||
}
|
||||
|
||||
void BootEncryption::InstallBootLoader (Device& device, bool preserveUserConfig, bool hiddenOSCreation)
|
||||
void BootEncryption::InstallBootLoader (Device& device, bool preserveUserConfig, bool hiddenOSCreation, int pim)
|
||||
{
|
||||
byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE] = {0};
|
||||
CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, hiddenOSCreation);
|
||||
@@ -1512,6 +1521,16 @@ namespace VeraCrypt
|
||||
{
|
||||
bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
|
||||
memcpy (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
|
||||
|
||||
if (bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
|
||||
{
|
||||
if (pim >= 0)
|
||||
{
|
||||
memcpy (bootLoaderBuf + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &pim, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
|
||||
}
|
||||
else
|
||||
memcpy (bootLoaderBuf + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2499,17 +2518,32 @@ namespace VeraCrypt
|
||||
|
||||
if (headerUpdated)
|
||||
{
|
||||
bool storedPimUpdateNeeded = false;
|
||||
ReopenBootVolumeHeaderRequest reopenRequest;
|
||||
reopenRequest.VolumePassword = *newPassword;
|
||||
reopenRequest.pkcs5_prf = cryptoInfo->pkcs5;
|
||||
reopenRequest.pim = pim;
|
||||
finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });
|
||||
|
||||
if (old_pim != pim)
|
||||
{
|
||||
try
|
||||
{
|
||||
// check if PIM is stored in MBR
|
||||
byte userConfig;
|
||||
ReadBootSectorConfig (nullptr, 0, &userConfig);
|
||||
if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
|
||||
storedPimUpdateNeeded = true;
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// force update of bootloader if fingerprint doesn't match
|
||||
if (!CheckBootloaderFingerprint (true))
|
||||
InstallBootLoader (device, true);
|
||||
// force update of bootloader if fingerprint doesn't match or if the stored PIM changed
|
||||
if (storedPimUpdateNeeded || !CheckBootloaderFingerprint (true))
|
||||
InstallBootLoader (device, true, false, pim);
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace VeraCrypt
|
||||
void GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties);
|
||||
SystemDriveConfiguration GetSystemDriveConfiguration ();
|
||||
void Install (bool hiddenSystem);
|
||||
void InstallBootLoader (Device& device, bool preserveUserConfig = false, bool hiddenOSCreation = false);
|
||||
void InstallBootLoader (Device& device, bool preserveUserConfig = false, bool hiddenOSCreation = false, int pim = -1);
|
||||
void InstallBootLoader (bool preserveUserConfig = false, bool hiddenOSCreation = false);
|
||||
bool CheckBootloaderFingerprint (bool bSilent = false);
|
||||
void InvalidateCachedSysDriveProperties ();
|
||||
@@ -206,7 +206,7 @@ namespace VeraCrypt
|
||||
void WipeHiddenOSCreationConfig ();
|
||||
void WriteBootDriveSector (uint64 offset, byte *data);
|
||||
void WriteBootSectorConfig (const byte newConfig[]);
|
||||
void WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage);
|
||||
void WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim);
|
||||
void WriteLocalMachineRegistryDwordValue (wchar_t *keyPath, wchar_t *valueName, DWORD value);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -1394,6 +1394,8 @@
|
||||
<string lang="en" key="VOLUME_ID_INVALID">The Volume ID value is invalid</string>
|
||||
<string lang="en" key="VOLUME_ID_NOT_FOUND">No Volume with the specified ID was found on the system</string>
|
||||
<string lang="en" key="IDPM_COPY_VALUE_TO_CLIPBOARD">Copy Value to Clipboard...</string>
|
||||
<control lang="en" key="IDC_DISABLE_BOOT_LOADER_PIM_PROMPT">Do not request PIM in the pre-boot authentication screen (PIM value is stored unencrypted on disk)</control>
|
||||
<string lang="en" key="DISABLE_BOOT_LOADER_PIM_PROMPT">WARNING: Please keep in mind that if you enable this option, the PIM value will be stored unencrypted on the disk.\n\nAre you sure you want to enable this option?</string>
|
||||
</localization>
|
||||
<!-- XML Schema -->
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
@@ -590,6 +590,7 @@ void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderS
|
||||
{
|
||||
// compute Whirlpool+SHA512 fingerprint of bootloader including MBR
|
||||
// we skip user configuration fields:
|
||||
// TC_BOOT_SECTOR_PIM_VALUE_OFFSET = 400
|
||||
// TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET = 402
|
||||
// => TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE = 4
|
||||
// TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = 406
|
||||
@@ -604,8 +605,8 @@ void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderS
|
||||
WHIRLPOOL_init (&whirlpool);
|
||||
sha512_begin (&sha2);
|
||||
|
||||
WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET * 8, &whirlpool);
|
||||
sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET, &sha2);
|
||||
WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET * 8, &whirlpool);
|
||||
sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2);
|
||||
|
||||
WHIRLPOOL_add (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)) * 8, &whirlpool);
|
||||
sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2);
|
||||
|
||||
Reference in New Issue
Block a user