mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-30 23:13:31 +01:00
Windows: Make EFI System Encryption PostOOBE code more robust to failure to access "\\\\?\\GLOBALROOT" disk namespace
This commit is contained in:
parent
ca46cf928a
commit
89e2547851
@ -2579,6 +2579,7 @@ namespace VeraCrypt
|
|||||||
ZeroMemory (&sdn, sizeof (sdn));
|
ZeroMemory (&sdn, sizeof (sdn));
|
||||||
ZeroMemory (&partInfo, sizeof (partInfo));
|
ZeroMemory (&partInfo, sizeof (partInfo));
|
||||||
m_bMounted = false;
|
m_bMounted = false;
|
||||||
|
bDeviceInfoValid = false;
|
||||||
bBootVolumePathSelected = false;
|
bBootVolumePathSelected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2611,7 +2612,7 @@ namespace VeraCrypt
|
|||||||
bBootVolumePathSelected = true;
|
bBootVolumePathSelected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EfiBoot::PrepareBootPartition() {
|
void EfiBoot::PrepareBootPartition(bool bDisableException) {
|
||||||
if (!bBootVolumePathSelected) {
|
if (!bBootVolumePathSelected) {
|
||||||
SelectBootVolumeESP();
|
SelectBootVolumeESP();
|
||||||
}
|
}
|
||||||
@ -2625,18 +2626,22 @@ namespace VeraCrypt
|
|||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
throw;
|
if (!bDisableException)
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bSuccess = dev.IoCtl(IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn))
|
if (dev.IsOpened())
|
||||||
&& dev.IoCtl(IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partInfo, sizeof(partInfo));
|
|
||||||
DWORD dwLastError = GetLastError ();
|
|
||||||
dev.Close();
|
|
||||||
if (!bSuccess)
|
|
||||||
{
|
{
|
||||||
SetLastError (dwLastError);
|
bDeviceInfoValid = dev.IoCtl(IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn))
|
||||||
throw SystemException(SRC_POS);
|
&& dev.IoCtl(IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partInfo, sizeof(partInfo));
|
||||||
}
|
DWORD dwLastError = GetLastError ();
|
||||||
|
dev.Close();
|
||||||
|
if (!bDeviceInfoValid && !bDisableException)
|
||||||
|
{
|
||||||
|
SetLastError (dwLastError);
|
||||||
|
throw SystemException(SRC_POS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EfiBoot::IsEfiBoot() {
|
bool EfiBoot::IsEfiBoot() {
|
||||||
@ -2701,97 +2706,100 @@ namespace VeraCrypt
|
|||||||
throw ErrorException(L"can not detect EFI environment", SRC_POS);
|
throw ErrorException(L"can not detect EFI environment", SRC_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 varSize = 56;
|
if (bDeviceInfoValid)
|
||||||
varSize += ((uint32) description.length()) * 2 + 2;
|
{
|
||||||
varSize += ((uint32) execPath.length()) * 2 + 2;
|
uint32 varSize = 56;
|
||||||
byte *startVar = new byte[varSize];
|
varSize += ((uint32) description.length()) * 2 + 2;
|
||||||
byte *pVar = startVar;
|
varSize += ((uint32) execPath.length()) * 2 + 2;
|
||||||
|
byte *startVar = new byte[varSize];
|
||||||
|
byte *pVar = startVar;
|
||||||
|
|
||||||
// Attributes (1b Active, 1000b - Hidden)
|
// Attributes (1b Active, 1000b - Hidden)
|
||||||
*(uint32 *)pVar = attr;
|
*(uint32 *)pVar = attr;
|
||||||
pVar += sizeof(uint32);
|
pVar += sizeof(uint32);
|
||||||
|
|
||||||
// Size Of device path + file path
|
// Size Of device path + file path
|
||||||
*(uint16 *)pVar = (uint16)(50 + execPath.length() * 2 + 2);
|
*(uint16 *)pVar = (uint16)(50 + execPath.length() * 2 + 2);
|
||||||
pVar += sizeof(uint16);
|
|
||||||
|
|
||||||
// description
|
|
||||||
for (uint32 i = 0; i < description.length(); i++) {
|
|
||||||
*(uint16 *)pVar = description[i];
|
|
||||||
pVar += sizeof(uint16);
|
pVar += sizeof(uint16);
|
||||||
}
|
|
||||||
*(uint16 *)pVar = 0;
|
|
||||||
pVar += sizeof(uint16);
|
|
||||||
|
|
||||||
/* EFI_DEVICE_PATH_PROTOCOL (HARDDRIVE_DEVICE_PATH \ FILE_PATH \ END) */
|
// description
|
||||||
|
for (uint32 i = 0; i < description.length(); i++) {
|
||||||
|
*(uint16 *)pVar = description[i];
|
||||||
|
pVar += sizeof(uint16);
|
||||||
|
}
|
||||||
|
*(uint16 *)pVar = 0;
|
||||||
|
pVar += sizeof(uint16);
|
||||||
|
|
||||||
// Type
|
/* EFI_DEVICE_PATH_PROTOCOL (HARDDRIVE_DEVICE_PATH \ FILE_PATH \ END) */
|
||||||
*(byte *)pVar = 0x04;
|
|
||||||
pVar += sizeof(byte);
|
|
||||||
|
|
||||||
// SubType
|
// Type
|
||||||
*(byte *)pVar = 0x01;
|
*(byte *)pVar = 0x04;
|
||||||
pVar += sizeof(byte);
|
pVar += sizeof(byte);
|
||||||
|
|
||||||
// HDD dev path length
|
// SubType
|
||||||
*(uint16 *)pVar = 0x2A; // 42
|
*(byte *)pVar = 0x01;
|
||||||
pVar += sizeof(uint16);
|
pVar += sizeof(byte);
|
||||||
|
|
||||||
|
// HDD dev path length
|
||||||
|
*(uint16 *)pVar = 0x2A; // 42
|
||||||
|
pVar += sizeof(uint16);
|
||||||
|
|
||||||
// PartitionNumber
|
// PartitionNumber
|
||||||
*(uint32 *)pVar = (uint32)partInfo.PartitionNumber;
|
*(uint32 *)pVar = (uint32)partInfo.PartitionNumber;
|
||||||
pVar += sizeof(uint32);
|
pVar += sizeof(uint32);
|
||||||
|
|
||||||
// PartitionStart
|
// PartitionStart
|
||||||
*(uint64 *)pVar = partInfo.StartingOffset.QuadPart >> 9;
|
*(uint64 *)pVar = partInfo.StartingOffset.QuadPart >> 9;
|
||||||
pVar += sizeof(uint64);
|
pVar += sizeof(uint64);
|
||||||
|
|
||||||
// PartitiontSize
|
// PartitiontSize
|
||||||
*(uint64 *)pVar = partInfo.PartitionLength.QuadPart >> 9;
|
*(uint64 *)pVar = partInfo.PartitionLength.QuadPart >> 9;
|
||||||
pVar += sizeof(uint64);
|
pVar += sizeof(uint64);
|
||||||
|
|
||||||
// GptGuid
|
// GptGuid
|
||||||
memcpy(pVar, &partInfo.Gpt.PartitionId, 16);
|
memcpy(pVar, &partInfo.Gpt.PartitionId, 16);
|
||||||
pVar += 16;
|
pVar += 16;
|
||||||
|
|
||||||
// MbrType
|
// MbrType
|
||||||
*(byte *)pVar = 0x02;
|
*(byte *)pVar = 0x02;
|
||||||
pVar += sizeof(byte);
|
pVar += sizeof(byte);
|
||||||
|
|
||||||
// SigType
|
// SigType
|
||||||
*(byte *)pVar = 0x02;
|
*(byte *)pVar = 0x02;
|
||||||
pVar += sizeof(byte);
|
pVar += sizeof(byte);
|
||||||
|
|
||||||
// Type and sub type 04 04 (file path)
|
// Type and sub type 04 04 (file path)
|
||||||
*(uint16 *)pVar = 0x0404;
|
*(uint16 *)pVar = 0x0404;
|
||||||
pVar += sizeof(uint16);
|
|
||||||
|
|
||||||
// SizeOfFilePath ((CHAR16)FullPath.length + sizeof(EndOfrecord marker) )
|
|
||||||
*(uint16 *)pVar = (uint16)(execPath.length() * 2 + 2 + sizeof(uint32));
|
|
||||||
pVar += sizeof(uint16);
|
|
||||||
|
|
||||||
// FilePath
|
|
||||||
for (uint32 i = 0; i < execPath.length(); i++) {
|
|
||||||
*(uint16 *)pVar = execPath[i];
|
|
||||||
pVar += sizeof(uint16);
|
pVar += sizeof(uint16);
|
||||||
|
|
||||||
|
// SizeOfFilePath ((CHAR16)FullPath.length + sizeof(EndOfrecord marker) )
|
||||||
|
*(uint16 *)pVar = (uint16)(execPath.length() * 2 + 2 + sizeof(uint32));
|
||||||
|
pVar += sizeof(uint16);
|
||||||
|
|
||||||
|
// FilePath
|
||||||
|
for (uint32 i = 0; i < execPath.length(); i++) {
|
||||||
|
*(uint16 *)pVar = execPath[i];
|
||||||
|
pVar += sizeof(uint16);
|
||||||
|
}
|
||||||
|
*(uint16 *)pVar = 0;
|
||||||
|
pVar += sizeof(uint16);
|
||||||
|
|
||||||
|
// EndOfrecord
|
||||||
|
*(uint32 *)pVar = 0x04ff7f;
|
||||||
|
pVar += sizeof(uint32);
|
||||||
|
|
||||||
|
// Set variable
|
||||||
|
wchar_t varName[256];
|
||||||
|
StringCchPrintfW(varName, ARRAYSIZE (varName), L"%s%04X", type == NULL ? L"Boot" : type, statrtOrderNum);
|
||||||
|
|
||||||
|
// only set value if it doesn't already exist
|
||||||
|
byte* existingVar = new byte[varSize];
|
||||||
|
DWORD existingVarLen = GetFirmwareEnvironmentVariableW (varName, EfiVarGuid, existingVar, varSize);
|
||||||
|
if ((existingVarLen != varSize) || (0 != memcmp (existingVar, startVar, varSize)))
|
||||||
|
SetFirmwareEnvironmentVariable(varName, EfiVarGuid, startVar, varSize);
|
||||||
|
delete [] startVar;
|
||||||
|
delete [] existingVar;
|
||||||
}
|
}
|
||||||
*(uint16 *)pVar = 0;
|
|
||||||
pVar += sizeof(uint16);
|
|
||||||
|
|
||||||
// EndOfrecord
|
|
||||||
*(uint32 *)pVar = 0x04ff7f;
|
|
||||||
pVar += sizeof(uint32);
|
|
||||||
|
|
||||||
// Set variable
|
|
||||||
wchar_t varName[256];
|
|
||||||
StringCchPrintfW(varName, ARRAYSIZE (varName), L"%s%04X", type == NULL ? L"Boot" : type, statrtOrderNum);
|
|
||||||
|
|
||||||
// only set value if it doesn't already exist
|
|
||||||
byte* existingVar = new byte[varSize];
|
|
||||||
DWORD existingVarLen = GetFirmwareEnvironmentVariableW (varName, EfiVarGuid, existingVar, varSize);
|
|
||||||
if ((existingVarLen != varSize) || (0 != memcmp (existingVar, startVar, varSize)))
|
|
||||||
SetFirmwareEnvironmentVariable(varName, EfiVarGuid, startVar, varSize);
|
|
||||||
delete [] startVar;
|
|
||||||
delete [] existingVar;
|
|
||||||
|
|
||||||
// Update order
|
// Update order
|
||||||
wstring order = L"Order";
|
wstring order = L"Order";
|
||||||
@ -2810,12 +2818,15 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
// Create new entry if absent
|
// Create new entry if absent
|
||||||
if (startOrderNumPos == UINT_MAX) {
|
if (startOrderNumPos == UINT_MAX) {
|
||||||
for (uint32 i = startOrderLen / 2; i > 0; --i) {
|
if (bDeviceInfoValid)
|
||||||
startOrder[i] = startOrder[i - 1];
|
{
|
||||||
|
for (uint32 i = startOrderLen / 2; i > 0; --i) {
|
||||||
|
startOrder[i] = startOrder[i - 1];
|
||||||
|
}
|
||||||
|
startOrder[0] = statrtOrderNum;
|
||||||
|
startOrderLen += 2;
|
||||||
|
startOrderUpdate = true;
|
||||||
}
|
}
|
||||||
startOrder[0] = statrtOrderNum;
|
|
||||||
startOrderLen += 2;
|
|
||||||
startOrderUpdate = true;
|
|
||||||
} else if (startOrderNumPos > 0) {
|
} else if (startOrderNumPos > 0) {
|
||||||
for (uint32 i = startOrderNumPos; i > 0; --i) {
|
for (uint32 i = startOrderNumPos; i > 0; --i) {
|
||||||
startOrder[i] = startOrder[i - 1];
|
startOrder[i] = startOrder[i - 1];
|
||||||
@ -3318,7 +3329,7 @@ namespace VeraCrypt
|
|||||||
if (!DcsInfoImg)
|
if (!DcsInfoImg)
|
||||||
throw ErrorException(L"Out of resource DcsInfo", SRC_POS);
|
throw ErrorException(L"Out of resource DcsInfo", SRC_POS);
|
||||||
|
|
||||||
EfiBootInst.PrepareBootPartition();
|
EfiBootInst.PrepareBootPartition(PostOOBEMode);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -201,7 +201,7 @@ namespace VeraCrypt
|
|||||||
public:
|
public:
|
||||||
EfiBoot();
|
EfiBoot();
|
||||||
|
|
||||||
void PrepareBootPartition();
|
void PrepareBootPartition(bool bDisableException = false);
|
||||||
bool IsEfiBoot();
|
bool IsEfiBoot();
|
||||||
|
|
||||||
void DeleteStartExec(uint16 statrtOrderNum = 0xDC5B, wchar_t* type = NULL);
|
void DeleteStartExec(uint16 statrtOrderNum = 0xDC5B, wchar_t* type = NULL);
|
||||||
@ -222,13 +222,14 @@ namespace VeraCrypt
|
|||||||
BOOL WriteConfig (const wchar_t* name, bool preserveUserConfig, int pim, int hashAlgo, const char* passPromptMsg, HWND hwndDlg);
|
BOOL WriteConfig (const wchar_t* name, bool preserveUserConfig, int pim, int hashAlgo, const char* passPromptMsg, HWND hwndDlg);
|
||||||
BOOL DelDir(const wchar_t* name);
|
BOOL DelDir(const wchar_t* name);
|
||||||
void SelectBootVolumeESP();
|
void SelectBootVolumeESP();
|
||||||
PSTORAGE_DEVICE_NUMBER GetStorageDeviceNumber () { return &sdn;}
|
PSTORAGE_DEVICE_NUMBER GetStorageDeviceNumber () { if (bDeviceInfoValid) return &sdn; else { SetLastError (ERROR_INVALID_DRIVE); throw SystemException(SRC_POS);}}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool m_bMounted;
|
bool m_bMounted;
|
||||||
std::wstring EfiBootPartPath;
|
std::wstring EfiBootPartPath;
|
||||||
STORAGE_DEVICE_NUMBER sdn;
|
STORAGE_DEVICE_NUMBER sdn;
|
||||||
PARTITION_INFORMATION_EX partInfo;
|
PARTITION_INFORMATION_EX partInfo;
|
||||||
|
bool bDeviceInfoValid;
|
||||||
WCHAR tempBuf[1024];
|
WCHAR tempBuf[1024];
|
||||||
bool bBootVolumePathSelected;
|
bool bBootVolumePathSelected;
|
||||||
std::wstring BootVolumePath;
|
std::wstring BootVolumePath;
|
||||||
|
Loading…
Reference in New Issue
Block a user