Windows: Make EFI System Encryption PostOOBE code more robust to failure to access "\\\\?\\GLOBALROOT" disk namespace

This commit is contained in:
Mounir IDRASSI 2019-10-27 00:09:44 +02:00
parent ca46cf928a
commit 89e2547851
No known key found for this signature in database
GPG Key ID: 02C30AE90FAE4A6F
2 changed files with 105 additions and 93 deletions

View File

@ -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
{ {

View File

@ -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;