diff options
-rw-r--r-- | DcsBoot/DcsBoot.c | 38 | ||||
-rw-r--r-- | DcsBoot/DcsBoot.inf | 1 | ||||
-rw-r--r-- | DcsCfg/DcsCfgCrypt.c | 6 | ||||
-rw-r--r-- | DcsRe/DcsRe.c | 2 | ||||
-rw-r--r-- | Include/Library/CommonLib.h | 37 | ||||
-rw-r--r-- | Library/CommonLib/CommonLib.inf | 1 | ||||
-rw-r--r-- | Library/CommonLib/GptRead.c | 215 | ||||
-rw-r--r-- | Library/DcsCfgLib/GptEdit.c | 202 |
8 files changed, 297 insertions, 205 deletions
diff --git a/DcsBoot/DcsBoot.c b/DcsBoot/DcsBoot.c index 60c8eed..108da0c 100644 --- a/DcsBoot/DcsBoot.c +++ b/DcsBoot/DcsBoot.c @@ -16,7 +16,9 @@ https://opensource.org/licenses/LGPL-3.0 #include <Library/CommonLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
#include "DcsConfig.h"
+#include <Guid/Gpt.h>
EFI_GUID ImagePartGuid;
EFI_GUID *gEfiExecPartGuid = &ImagePartGuid;
@@ -43,6 +45,7 @@ DcsBootMain( UINTN len;
UINT32 attr;
int drvInst;
+ BOOLEAN searchOnESP = FALSE;
InitBio();
res = InitFS();
if (EFI_ERROR(res)) {
@@ -51,8 +54,8 @@ DcsBootMain( drvInst = ConfigReadInt("DcsDriver", 0);
- if (!FileExist(NULL, L"\\EFI\\VeraCrypt\\PlatformInfo") &&
- !FileExist(NULL, L"\\EFI\\VeraCrypt\\DcsInfo.dcs")) {
+ if (EFI_ERROR(FileExist(NULL, L"\\EFI\\VeraCrypt\\PlatformInfo")) &&
+ !EFI_ERROR(FileExist(NULL, L"\\EFI\\VeraCrypt\\DcsInfo.dcs"))) {
res = EfiExec(NULL, L"\\EFI\\VeraCrypt\\DcsInfo.dcs");
}
// Load all drivers
@@ -83,11 +86,40 @@ DcsBootMain( gEfiExecCmd = gEfiExecCmdDefault;
}
+ searchOnESP = CompareGuid(gEfiExecPartGuid, &ImagePartGuid) &&
+ EFI_ERROR(FileExist(NULL, gEfiExecCmd));
+
// Find new start partition
ConnectAllEfi();
InitBio();
res = InitFS();
-// OUT_PRINT(L".");
+
+ // Default load of bootmgfw?
+ if (searchOnESP) {
+ // gEfiExecCmd is not found on start partition. Try from ESP
+ EFI_BLOCK_IO_PROTOCOL *bio = NULL;
+ EFI_PARTITION_TABLE_HEADER *gptHdr = NULL;
+ EFI_PARTITION_ENTRY *gptEntry = NULL;
+ HARDDRIVE_DEVICE_PATH hdp;
+ EFI_HANDLE disk;
+ if (!EFI_ERROR(res = EfiGetPartDetails(gFileRootHandle, &hdp, &disk))) {
+ if ((bio = EfiGetBlockIO(disk)) != NULL) {
+ if (!EFI_ERROR(res = GptReadHeader(bio, 1, &gptHdr)) &&
+ !EFI_ERROR(res = GptReadEntryArray(bio, gptHdr, &gptEntry))) {
+ UINT32 i;
+ for (i = 0; i < gptHdr->NumberOfPartitionEntries; ++i) {
+ if (CompareGuid(&gptEntry[i].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)) {
+ // select ESP GUID
+ CopyGuid(gEfiExecPartGuid, &gptEntry[i].UniquePartitionGUID);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // OUT_PRINT(L".");
res = EfiFindPartByGUID(gEfiExecPartGuid, &gFileRootHandle);
if (EFI_ERROR(res)) {
ERR_PRINT(L"\nCan't find start partition %g\n", gEfiExecPartGuid);
diff --git a/DcsBoot/DcsBoot.inf b/DcsBoot/DcsBoot.inf index 14d8d0d..34c78f3 100644 --- a/DcsBoot/DcsBoot.inf +++ b/DcsBoot/DcsBoot.inf @@ -47,6 +47,7 @@ gEfiGlobalVariableGuid
gEfiDcsVariableGuid
gEfiFileInfoGuid
+ gEfiPartTypeSystemPartGuid
[Protocols]
gEfiBlockIoProtocolGuid
diff --git a/DcsCfg/DcsCfgCrypt.c b/DcsCfg/DcsCfgCrypt.c index 0e892dd..45523dd 100644 --- a/DcsCfg/DcsCfgCrypt.c +++ b/DcsCfg/DcsCfgCrypt.c @@ -187,9 +187,9 @@ ChangePassword( if (AskConfirm("Change range of encrypted sectors[N]?", 1)) {
modified = TRUE;
- cryptoInfo->VolumeSize.Value = AskUINT64("Volume size", cryptoInfo->VolumeSize.Value >> 9) << 9;
- cryptoInfo->EncryptedAreaStart.Value = AskUINT64("Encrypted area start", cryptoInfo->EncryptedAreaStart.Value >> 9) << 9;
- cryptoInfo->EncryptedAreaLength.Value = AskUINT64("Encrypted area length", cryptoInfo->EncryptedAreaLength.Value >> 9) << 9;
+ cryptoInfo->VolumeSize.Value = AskUINT64("Volume size:", cryptoInfo->VolumeSize.Value >> 9) << 9;
+ cryptoInfo->EncryptedAreaStart.Value = AskUINT64("Encrypted area start:", cryptoInfo->EncryptedAreaStart.Value >> 9) << 9;
+ cryptoInfo->EncryptedAreaLength.Value = AskUINT64("Encrypted area length:", cryptoInfo->EncryptedAreaLength.Value >> 9) << 9;
}
if (modified) {
diff --git a/DcsRe/DcsRe.c b/DcsRe/DcsRe.c index 1f71f11..7f4096f 100644 --- a/DcsRe/DcsRe.c +++ b/DcsRe/DcsRe.c @@ -80,8 +80,8 @@ SelectEfiVolume() else {
OUT_PRINT(L"%V [Boot] %N");
}
- EfiPrintDevicePath(gFSHandles[i]);
}
+ EfiPrintDevicePath(gFSHandles[i]);
OUT_PRINT(L"\n");
}
diff --git a/Include/Library/CommonLib.h b/Include/Library/CommonLib.h index 950406f..98e93db 100644 --- a/Include/Library/CommonLib.h +++ b/Include/Library/CommonLib.h @@ -21,6 +21,7 @@ https://opensource.org/licenses/LGPL-3.0 #include <Protocol/UsbIo.h>
#include <Protocol/AbsolutePointer.h>
#include <Guid/FileInfo.h>
+#include <Uefi/UefiGpt.h>
//////////////////////////////////////////////////////////////////////////
// Check error
@@ -137,6 +138,42 @@ EfiFindPartByGUID( );
//////////////////////////////////////////////////////////////////////////
+// GPT
+//////////////////////////////////////////////////////////////////////////
+
+BOOLEAN
+GptHeaderCheckCrc(
+ IN UINTN MaxSize,
+ IN OUT EFI_TABLE_HEADER *Hdr
+ );
+
+EFI_STATUS
+GptCheckEntryArray(
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ IN EFI_PARTITION_ENTRY *Entrys
+ );
+
+EFI_STATUS
+GptUpdateCRC(
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ IN EFI_PARTITION_ENTRY *Entrys
+ );
+
+EFI_STATUS
+GptReadEntryArray(
+ IN EFI_BLOCK_IO_PROTOCOL* BlockIo,
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ OUT EFI_PARTITION_ENTRY **Entrys
+ );
+
+EFI_STATUS
+GptReadHeader(
+ IN EFI_BLOCK_IO_PROTOCOL* BlockIo,
+ IN EFI_LBA HeaderLba,
+ OUT EFI_PARTITION_TABLE_HEADER **PartHeader
+ );
+
+//////////////////////////////////////////////////////////////////////////
// Bluetooth
//////////////////////////////////////////////////////////////////////////
extern EFI_HANDLE* gBluetoothIoHandles;
diff --git a/Library/CommonLib/CommonLib.inf b/Library/CommonLib/CommonLib.inf index b5758f5..dde5c61 100644 --- a/Library/CommonLib/CommonLib.inf +++ b/Library/CommonLib/CommonLib.inf @@ -38,6 +38,7 @@ EfiTouch.c
EfiBluetooth.c
EfiTpm.c
+ GptRead.c
[Sources.IA32]
IA32/EfiCpuHalt.asm
diff --git a/Library/CommonLib/GptRead.c b/Library/CommonLib/GptRead.c new file mode 100644 index 0000000..0eab963 --- /dev/null +++ b/Library/CommonLib/GptRead.c @@ -0,0 +1,215 @@ +/** @file
+GPT low level actions
+
+Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
+
+The full text of the license may be found at
+https://opensource.org/licenses/LGPL-3.0
+**/
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Uefi/UefiGpt.h>
+#include <Guid/Gpt.h>
+
+#include <Library/CommonLib.h>
+
+/**
+Checks the CRC32 value in the table header.
+
+@param MaxSize Max Size limit
+@param Size The size of the table
+@param Hdr Table to check
+
+@return TRUE CRC Valid
+@return FALSE CRC Invalid
+
+**/
+BOOLEAN
+GptHeaderCheckCrcAltSize(
+ IN UINTN MaxSize,
+ IN UINTN Size,
+ IN OUT EFI_TABLE_HEADER *Hdr
+ )
+{
+ UINT32 Crc;
+ UINT32 OrgCrc;
+ EFI_STATUS Status;
+
+ Crc = 0;
+
+ if (Size == 0) {
+ //
+ // If header size is 0 CRC will pass so return FALSE here
+ //
+ return FALSE;
+ }
+
+ if ((MaxSize != 0) && (Size > MaxSize)) {
+ return FALSE;
+ }
+ //
+ // clear old crc from header
+ //
+ OrgCrc = Hdr->CRC32;
+ Hdr->CRC32 = 0;
+
+ Status = gBS->CalculateCrc32((UINT8 *)Hdr, Size, &Crc);
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+ //
+ // set results
+ //
+ Hdr->CRC32 = OrgCrc;
+
+ return (BOOLEAN)(OrgCrc == Crc);
+}
+
+/**
+Checks the CRC32 value in the table header.
+
+@param MaxSize Max Size limit
+@param Hdr Table to check
+
+@return TRUE CRC Valid
+@return FALSE CRC Invalid
+
+**/
+BOOLEAN
+GptHeaderCheckCrc(
+ IN UINTN MaxSize,
+ IN OUT EFI_TABLE_HEADER *Hdr
+ )
+{
+ return GptHeaderCheckCrcAltSize(MaxSize, Hdr->HeaderSize, Hdr);
+}
+
+EFI_STATUS
+GptCheckEntryArray(
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ IN EFI_PARTITION_ENTRY *Entrys
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Crc;
+ UINTN Size;
+
+ Size = (UINTN)PartHeader->NumberOfPartitionEntries * (UINTN)PartHeader->SizeOfPartitionEntry;
+ Status = gBS->CalculateCrc32(Entrys, Size, &Crc);
+ if (EFI_ERROR(Status)) {
+ return EFI_CRC_ERROR;
+ }
+ Status = (PartHeader->PartitionEntryArrayCRC32 == Crc) ? EFI_SUCCESS : EFI_CRC_ERROR;
+ return Status;
+}
+
+EFI_STATUS
+GptUpdateCRC(
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ IN EFI_PARTITION_ENTRY *Entrys
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Crc;
+ UINTN Size;
+
+ Size = (UINTN)PartHeader->NumberOfPartitionEntries * (UINTN)PartHeader->SizeOfPartitionEntry;
+ Status = gBS->CalculateCrc32(Entrys, Size, &Crc);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ PartHeader->PartitionEntryArrayCRC32 = Crc;
+ PartHeader->Header.CRC32 = 0;
+
+ Status = gBS->CalculateCrc32((UINT8 *)PartHeader, PartHeader->Header.HeaderSize, &Crc);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ PartHeader->Header.CRC32 = Crc;
+ return Status;
+}
+
+/**
+Read GPT
+Check if the CRC field in the Partition table header is valid
+for Partition entry array.
+
+@param[in] BlockIo Disk Io Protocol.
+@param[in] PartHeader Partition table header structure
+
+@retval EFI_SUCCESS the CRC is valid
+**/
+EFI_STATUS
+GptReadEntryArray(
+ IN EFI_BLOCK_IO_PROTOCOL* BlockIo,
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ OUT EFI_PARTITION_ENTRY **Entrys
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Ptr;
+
+ //
+ // Read the EFI Partition Entries
+ //
+ Ptr = MEM_ALLOC(PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
+ if (Ptr == NULL) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Status = BlockIo->ReadBlocks(
+ BlockIo,
+ BlockIo->Media->MediaId,
+ PartHeader->PartitionEntryLBA,
+ PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
+ Ptr
+ );
+ if (EFI_ERROR(Status)) {
+ MEM_FREE(Ptr);
+ return Status;
+ }
+
+ *Entrys = (EFI_PARTITION_ENTRY*)Ptr;
+ return GptCheckEntryArray(PartHeader, *Entrys);
+}
+
+EFI_STATUS
+GptReadHeader(
+ IN EFI_BLOCK_IO_PROTOCOL* BlockIo,
+ IN EFI_LBA HeaderLba,
+ OUT EFI_PARTITION_TABLE_HEADER **PartHeader
+ )
+{
+ EFI_STATUS res = EFI_SUCCESS;
+ UINT32 BlockSize;
+ EFI_PARTITION_TABLE_HEADER *PartHdr;
+ UINT32 MediaId;
+
+ BlockSize = BlockIo->Media->BlockSize;
+ MediaId = BlockIo->Media->MediaId;
+ PartHdr = MEM_ALLOC(BlockSize);
+
+ res = BlockIo->ReadBlocks(BlockIo, MediaId, HeaderLba, BlockSize, PartHdr);
+ if (EFI_ERROR(res)) {
+ MEM_FREE(PartHdr);
+ return res;
+ }
+
+ // Check header
+ if ((PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
+ !GptHeaderCheckCrc(BlockSize, &PartHdr->Header) ||
+ PartHdr->MyLBA != HeaderLba ||
+ (PartHdr->SizeOfPartitionEntry < sizeof(EFI_PARTITION_ENTRY))
+ ) {
+ MEM_FREE(PartHdr);
+ return EFI_CRC_ERROR;
+ }
+ *PartHeader = PartHdr;
+ return EFI_SUCCESS;
+}
diff --git a/Library/DcsCfgLib/GptEdit.c b/Library/DcsCfgLib/GptEdit.c index ea016f1..e1d6d2a 100644 --- a/Library/DcsCfgLib/GptEdit.c +++ b/Library/DcsCfgLib/GptEdit.c @@ -61,200 +61,6 @@ UINTN MirrorPartIdx; // Partitions
//////////////////////////////////////////////////////////////////////////
-
-/**
-Checks the CRC32 value in the table header.
-
-@param MaxSize Max Size limit
-@param Size The size of the table
-@param Hdr Table to check
-
-@return TRUE CRC Valid
-@return FALSE CRC Invalid
-
-**/
-BOOLEAN
-GptHeaderCheckCrcAltSize(
- IN UINTN MaxSize,
- IN UINTN Size,
- IN OUT EFI_TABLE_HEADER *Hdr
- )
-{
- UINT32 Crc;
- UINT32 OrgCrc;
- EFI_STATUS Status;
-
- Crc = 0;
-
- if (Size == 0) {
- //
- // If header size is 0 CRC will pass so return FALSE here
- //
- return FALSE;
- }
-
- if ((MaxSize != 0) && (Size > MaxSize)) {
- return FALSE;
- }
- //
- // clear old crc from header
- //
- OrgCrc = Hdr->CRC32;
- Hdr->CRC32 = 0;
-
- Status = gBS->CalculateCrc32((UINT8 *)Hdr, Size, &Crc);
- if (EFI_ERROR(Status)) {
- return FALSE;
- }
- //
- // set results
- //
- Hdr->CRC32 = OrgCrc;
-
- return (BOOLEAN)(OrgCrc == Crc);
-}
-
-/**
-Checks the CRC32 value in the table header.
-
-@param MaxSize Max Size limit
-@param Hdr Table to check
-
-@return TRUE CRC Valid
-@return FALSE CRC Invalid
-
-**/
-BOOLEAN
-GptHeaderCheckCrc(
- IN UINTN MaxSize,
- IN OUT EFI_TABLE_HEADER *Hdr
- )
-{
- return GptHeaderCheckCrcAltSize(MaxSize, Hdr->HeaderSize, Hdr);
-}
-
-EFI_STATUS
-GptCheckEntryArray(
- IN EFI_PARTITION_TABLE_HEADER *PartHeader,
- IN EFI_PARTITION_ENTRY *Entrys
- )
-{
- EFI_STATUS Status;
- UINT32 Crc;
- UINTN Size;
-
- Size = (UINTN) PartHeader->NumberOfPartitionEntries * (UINTN) PartHeader->SizeOfPartitionEntry;
- Status = gBS->CalculateCrc32(Entrys, Size, &Crc);
- if (EFI_ERROR(Status)) {
- return EFI_CRC_ERROR;
- }
- Status = (PartHeader->PartitionEntryArrayCRC32 == Crc) ? EFI_SUCCESS : EFI_CRC_ERROR;
- return Status;
-}
-
-EFI_STATUS
-GptUpdateCRC(
- IN EFI_PARTITION_TABLE_HEADER *PartHeader,
- IN EFI_PARTITION_ENTRY *Entrys
- )
-{
- EFI_STATUS Status;
- UINT32 Crc;
- UINTN Size;
-
- Size = (UINTN) PartHeader->NumberOfPartitionEntries * (UINTN) PartHeader->SizeOfPartitionEntry;
- Status = gBS->CalculateCrc32(Entrys, Size, &Crc);
- if (EFI_ERROR(Status)) {
- return Status;
- }
- PartHeader->PartitionEntryArrayCRC32 = Crc;
- PartHeader->Header.CRC32 = 0;
-
- Status = gBS->CalculateCrc32((UINT8 *)PartHeader, PartHeader->Header.HeaderSize, &Crc);
- if (EFI_ERROR(Status)) {
- return Status;
- }
- PartHeader->Header.CRC32 = Crc;
- return Status;
-}
-
-/**
-Read GPT
-Check if the CRC field in the Partition table header is valid
-for Partition entry array.
-
-@param[in] DiskIo Disk Io Protocol.
-@param[in] PartHeader Partition table header structure
-
-@retval EFI_SUCCESS the CRC is valid
-**/
-EFI_STATUS
-GptReadEntryArray(
- IN EFI_PARTITION_TABLE_HEADER *PartHeader,
- OUT EFI_PARTITION_ENTRY **Entrys
- )
-{
- EFI_STATUS Status;
- UINT8 *Ptr;
-
- //
- // Read the EFI Partition Entries
- //
- Ptr = MEM_ALLOC(PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
- if (Ptr == NULL) {
- return EFI_BUFFER_TOO_SMALL;
- }
-
- Status = BlockIo->ReadBlocks(
- BlockIo,
- BlockIo->Media->MediaId,
- PartHeader->PartitionEntryLBA,
- PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
- Ptr
- );
- if (EFI_ERROR(Status)) {
- MEM_FREE(Ptr);
- return Status;
- }
-
- *Entrys = (EFI_PARTITION_ENTRY*)Ptr;
- return GptCheckEntryArray(PartHeader, *Entrys);
-}
-
-EFI_STATUS
-GptReadHeader(
- IN EFI_LBA HeaderLba,
- OUT EFI_PARTITION_TABLE_HEADER **PartHeader
- )
-{
- EFI_STATUS res = EFI_SUCCESS;
- UINT32 BlockSize;
- EFI_PARTITION_TABLE_HEADER *PartHdr;
- UINT32 MediaId;
-
- BlockSize = BlockIo->Media->BlockSize;
- MediaId = BlockIo->Media->MediaId;
- PartHdr = MEM_ALLOC(BlockSize);
-
- res = BlockIo->ReadBlocks(BlockIo, MediaId, HeaderLba, BlockSize, PartHdr);
- if (EFI_ERROR(res)) {
- MEM_FREE(PartHdr);
- return res;
- }
-
- // Check header
- if ((PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
- !GptHeaderCheckCrc(BlockSize, &PartHdr->Header) ||
- PartHdr->MyLBA != HeaderLba ||
- (PartHdr->SizeOfPartitionEntry < sizeof(EFI_PARTITION_ENTRY))
- ) {
- MEM_FREE(PartHdr);
- return EFI_CRC_ERROR;
- }
- *PartHeader = PartHdr;
- return EFI_SUCCESS;
-}
-
VOID
GptPrint(
IN EFI_PARTITION_TABLE_HEADER *PartHdr,
@@ -298,26 +104,26 @@ GptLoadFromDisk( return EFI_NOT_FOUND;
}
- res = GptReadHeader(1, &GptMainHdr);
+ res = GptReadHeader(BlockIo, 1, &GptMainHdr);
if (EFI_ERROR(res)) {
ERR_PRINT(L"Can't read main GPT header: %r\n", res);
goto error;
}
- res = GptReadHeader(GptMainHdr->AlternateLBA, &GptAltHdr);
+ res = GptReadHeader(BlockIo, GptMainHdr->AlternateLBA, &GptAltHdr);
if (EFI_ERROR(res)) {
ERR_PRINT(L"Can't read alt GPT header: %r\n", res);
goto error;
}
- res = GptReadEntryArray(GptMainHdr, &GptMainEntrys);
+ res = GptReadEntryArray(BlockIo, GptMainHdr, &GptMainEntrys);
// Read GPT
if (EFI_ERROR(res)) {
ERR_PRINT(L"Main GPT error: %r\n", res);
goto error;
}
- res = GptReadEntryArray(GptAltHdr, &GptAltEntrys);
+ res = GptReadEntryArray(BlockIo, GptAltHdr, &GptAltEntrys);
// Read GPT
if (EFI_ERROR(res)) {
ERR_PRINT(L"Alt GPT error: %r\n", res);
|