mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
Merge pull request #20790 from poettering/boot-fixes
various EFI/boot fixes
This commit is contained in:
commit
f0c6333d4e
@ -912,14 +912,11 @@ static VOID config_add_entry(Config *config, ConfigEntry *entry) {
|
||||
assert(entry);
|
||||
|
||||
if ((config->entry_count & 15) == 0) {
|
||||
UINTN i;
|
||||
|
||||
i = config->entry_count + 16;
|
||||
if (config->entry_count == 0)
|
||||
config->entries = AllocatePool(sizeof(VOID *) * i);
|
||||
else
|
||||
config->entries = ReallocatePool(config->entries,
|
||||
sizeof(VOID *) * config->entry_count, sizeof(VOID *) * i);
|
||||
UINTN i = config->entry_count + 16;
|
||||
config->entries = ReallocatePool(
|
||||
config->entries,
|
||||
sizeof(VOID *) * config->entry_count,
|
||||
sizeof(VOID *) * i);
|
||||
}
|
||||
config->entries[config->entry_count++] = entry;
|
||||
}
|
||||
@ -1492,7 +1489,7 @@ static VOID config_load_entries(
|
||||
EFI_FILE *root_dir,
|
||||
CHAR16 *loaded_image_path) {
|
||||
|
||||
EFI_FILE_HANDLE entries_dir;
|
||||
_cleanup_(FileHandleClosep) EFI_FILE_HANDLE entries_dir = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(config);
|
||||
@ -1501,34 +1498,34 @@ static VOID config_load_entries(
|
||||
assert(loaded_image_path);
|
||||
|
||||
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &entries_dir, (CHAR16*) L"\\loader\\entries", EFI_FILE_MODE_READ, 0ULL);
|
||||
if (!EFI_ERROR(err)) {
|
||||
for (;;) {
|
||||
CHAR16 buf[256];
|
||||
UINTN bufsize;
|
||||
EFI_FILE_INFO *f;
|
||||
_cleanup_freepool_ CHAR8 *content = NULL;
|
||||
if (EFI_ERROR(err))
|
||||
return;
|
||||
|
||||
bufsize = sizeof(buf);
|
||||
err = uefi_call_wrapper(entries_dir->Read, 3, entries_dir, &bufsize, buf);
|
||||
if (bufsize == 0 || EFI_ERROR(err))
|
||||
break;
|
||||
for (;;) {
|
||||
CHAR16 buf[256];
|
||||
UINTN bufsize;
|
||||
EFI_FILE_INFO *f;
|
||||
_cleanup_freepool_ CHAR8 *content = NULL;
|
||||
|
||||
f = (EFI_FILE_INFO *) buf;
|
||||
if (f->FileName[0] == '.')
|
||||
continue;
|
||||
if (f->Attribute & EFI_FILE_DIRECTORY)
|
||||
continue;
|
||||
bufsize = sizeof(buf);
|
||||
err = uefi_call_wrapper(entries_dir->Read, 3, entries_dir, &bufsize, buf);
|
||||
if (bufsize == 0 || EFI_ERROR(err))
|
||||
break;
|
||||
|
||||
if (!endswith_no_case(f->FileName, L".conf"))
|
||||
continue;
|
||||
if (startswith(f->FileName, L"auto-"))
|
||||
continue;
|
||||
f = (EFI_FILE_INFO *) buf;
|
||||
if (f->FileName[0] == '.')
|
||||
continue;
|
||||
if (f->Attribute & EFI_FILE_DIRECTORY)
|
||||
continue;
|
||||
|
||||
err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL);
|
||||
if (!EFI_ERROR(err))
|
||||
config_entry_add_from_file(config, device, root_dir, L"\\loader\\entries", f->FileName, content, loaded_image_path);
|
||||
}
|
||||
uefi_call_wrapper(entries_dir->Close, 1, entries_dir);
|
||||
if (!endswith_no_case(f->FileName, L".conf"))
|
||||
continue;
|
||||
if (startswith(f->FileName, L"auto-"))
|
||||
continue;
|
||||
|
||||
err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL);
|
||||
if (!EFI_ERROR(err))
|
||||
config_entry_add_from_file(config, device, root_dir, L"\\loader\\entries", f->FileName, content, loaded_image_path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1980,7 +1977,7 @@ static VOID config_entry_add_linux(
|
||||
EFI_HANDLE *device,
|
||||
EFI_FILE *root_dir) {
|
||||
|
||||
EFI_FILE_HANDLE linux_dir;
|
||||
_cleanup_(FileHandleClosep) EFI_FILE_HANDLE linux_dir = NULL;
|
||||
EFI_STATUS err;
|
||||
ConfigEntry *entry;
|
||||
|
||||
@ -2110,8 +2107,6 @@ static VOID config_entry_add_linux(
|
||||
FreePool(os_build_id);
|
||||
FreePool(content);
|
||||
}
|
||||
|
||||
uefi_call_wrapper(linux_dir->Close, 1, linux_dir);
|
||||
}
|
||||
|
||||
#define XBOOTLDR_GUID \
|
||||
|
@ -7,260 +7,102 @@
|
||||
|
||||
#include "macro-fundamental.h"
|
||||
#include "measure.h"
|
||||
#include "missing_efi.h"
|
||||
#include "util.h"
|
||||
|
||||
#define EFI_TCG_GUID \
|
||||
&(const EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }
|
||||
static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
|
||||
const EFI_TCG *tcg,
|
||||
UINT32 pcrindex,
|
||||
EFI_PHYSICAL_ADDRESS buffer,
|
||||
UINTN buffer_size,
|
||||
const CHAR16 *description) {
|
||||
|
||||
typedef struct _TCG_VERSION {
|
||||
UINT8 Major;
|
||||
UINT8 Minor;
|
||||
UINT8 RevMajor;
|
||||
UINT8 RevMinor;
|
||||
} TCG_VERSION;
|
||||
|
||||
typedef struct tdEFI_TCG2_VERSION {
|
||||
UINT8 Major;
|
||||
UINT8 Minor;
|
||||
} EFI_TCG2_VERSION;
|
||||
|
||||
typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
|
||||
UINT8 Size;
|
||||
struct _TCG_VERSION StructureVersion;
|
||||
struct _TCG_VERSION ProtocolSpecVersion;
|
||||
UINT8 HashAlgorithmBitmap;
|
||||
BOOLEAN TPMPresentFlag;
|
||||
BOOLEAN TPMDeactivatedFlag;
|
||||
} TCG_BOOT_SERVICE_CAPABILITY;
|
||||
|
||||
typedef struct tdTREE_BOOT_SERVICE_CAPABILITY {
|
||||
UINT8 Size;
|
||||
EFI_TCG2_VERSION StructureVersion;
|
||||
EFI_TCG2_VERSION ProtocolVersion;
|
||||
UINT32 HashAlgorithmBitmap;
|
||||
UINT32 SupportedEventLogs;
|
||||
BOOLEAN TrEEPresentFlag;
|
||||
UINT16 MaxCommandSize;
|
||||
UINT16 MaxResponseSize;
|
||||
UINT32 ManufacturerID;
|
||||
} TREE_BOOT_SERVICE_CAPABILITY;
|
||||
|
||||
typedef UINT32 TCG_ALGORITHM_ID;
|
||||
#define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm
|
||||
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
typedef struct _TCG_DIGEST {
|
||||
UINT8 Digest[SHA1_DIGEST_SIZE];
|
||||
} TCG_DIGEST;
|
||||
|
||||
#define EV_IPL 13
|
||||
|
||||
typedef struct _TCG_PCR_EVENT {
|
||||
UINT32 PCRIndex;
|
||||
UINT32 EventType;
|
||||
struct _TCG_DIGEST digest;
|
||||
UINT32 EventSize;
|
||||
UINT8 Event[1];
|
||||
} TCG_PCR_EVENT;
|
||||
|
||||
INTERFACE_DECL(_EFI_TCG);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_STATUS_CHECK) (IN struct _EFI_TCG * This,
|
||||
OUT struct _TCG_BOOT_SERVICE_CAPABILITY * ProtocolCapability,
|
||||
OUT UINT32 * TCGFeatureFlags,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_ALL) (IN struct _EFI_TCG * This,
|
||||
IN UINT8 * HashData,
|
||||
IN UINT64 HashDataLen,
|
||||
IN TCG_ALGORITHM_ID AlgorithmId,
|
||||
IN OUT UINT64 * HashedDataLen, IN OUT UINT8 ** HashedDataResult);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_LOG_EVENT) (IN struct _EFI_TCG * This,
|
||||
IN struct _TCG_PCR_EVENT * TCGLogData,
|
||||
IN OUT UINT32 * EventNumber, IN UINT32 Flags);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_PASS_THROUGH_TO_TPM) (IN struct _EFI_TCG * This,
|
||||
IN UINT32 TpmInputParameterBlockSize,
|
||||
IN UINT8 * TpmInputParameterBlock,
|
||||
IN UINT32 TpmOutputParameterBlockSize,
|
||||
IN UINT8 * TpmOutputParameterBlock);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_LOG_EXTEND_EVENT) (IN struct _EFI_TCG * This,
|
||||
IN EFI_PHYSICAL_ADDRESS HashData,
|
||||
IN UINT64 HashDataLen,
|
||||
IN TCG_ALGORITHM_ID AlgorithmId,
|
||||
IN struct _TCG_PCR_EVENT * TCGLogData,
|
||||
IN OUT UINT32 * EventNumber,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
|
||||
|
||||
typedef struct _EFI_TCG {
|
||||
EFI_TCG_STATUS_CHECK StatusCheck;
|
||||
EFI_TCG_HASH_ALL HashAll;
|
||||
EFI_TCG_LOG_EVENT LogEvent;
|
||||
EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTPM;
|
||||
EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
|
||||
} EFI_TCG;
|
||||
|
||||
#define EFI_TCG2_GUID \
|
||||
&(const EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
|
||||
|
||||
typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
|
||||
|
||||
typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
|
||||
typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
|
||||
typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
|
||||
|
||||
typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
|
||||
UINT8 Size;
|
||||
EFI_TCG2_VERSION StructureVersion;
|
||||
EFI_TCG2_VERSION ProtocolVersion;
|
||||
EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
|
||||
EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
|
||||
BOOLEAN TPMPresentFlag;
|
||||
UINT16 MaxCommandSize;
|
||||
UINT16 MaxResponseSize;
|
||||
UINT32 ManufacturerID;
|
||||
UINT32 NumberOfPCRBanks;
|
||||
EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
|
||||
} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
|
||||
|
||||
#define EFI_TCG2_EVENT_HEADER_VERSION 1
|
||||
|
||||
typedef struct {
|
||||
UINT32 HeaderSize;
|
||||
UINT16 HeaderVersion;
|
||||
UINT32 PCRIndex;
|
||||
UINT32 EventType;
|
||||
} _packed_ EFI_TCG2_EVENT_HEADER;
|
||||
|
||||
typedef struct tdEFI_TCG2_EVENT {
|
||||
UINT32 Size;
|
||||
EFI_TCG2_EVENT_HEADER Header;
|
||||
UINT8 Event[1];
|
||||
} _packed_ EFI_TCG2_EVENT;
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This,
|
||||
IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_EVENT_LOG) (IN EFI_TCG2_PROTOCOL * This,
|
||||
IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry,
|
||||
OUT BOOLEAN * EventLogTruncated);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_HASH_LOG_EXTEND_EVENT) (IN EFI_TCG2_PROTOCOL * This,
|
||||
IN UINT64 Flags,
|
||||
IN EFI_PHYSICAL_ADDRESS DataToHash,
|
||||
IN UINT64 DataToHashLen, IN EFI_TCG2_EVENT * EfiTcgEvent);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_SUBMIT_COMMAND) (IN EFI_TCG2_PROTOCOL * This,
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 * InputParameterBlock,
|
||||
IN UINT32 OutputParameterBlockSize, IN UINT8 * OutputParameterBlock);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, OUT UINT32 * ActivePcrBanks);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, IN UINT32 ActivePcrBanks);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This,
|
||||
OUT UINT32 * OperationPresent, OUT UINT32 * Response);
|
||||
|
||||
typedef struct tdEFI_TCG2_PROTOCOL {
|
||||
EFI_TCG2_GET_CAPABILITY GetCapability;
|
||||
EFI_TCG2_GET_EVENT_LOG GetEventLog;
|
||||
EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
|
||||
EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
|
||||
EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
|
||||
EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
|
||||
EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
|
||||
} EFI_TCG2;
|
||||
|
||||
static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
|
||||
UINTN buffer_size, const CHAR16 *description) {
|
||||
EFI_STATUS status;
|
||||
TCG_PCR_EVENT *tcg_event;
|
||||
UINT32 event_number;
|
||||
_cleanup_freepool_ TCG_PCR_EVENT *tcg_event = NULL;
|
||||
EFI_PHYSICAL_ADDRESS event_log_last;
|
||||
UINT32 event_number = 1;
|
||||
UINTN desc_len;
|
||||
|
||||
assert(tcg);
|
||||
assert(description);
|
||||
|
||||
desc_len = StrSize(description);
|
||||
tcg_event = AllocateZeroPool(desc_len + sizeof(TCG_PCR_EVENT));
|
||||
|
||||
tcg_event = AllocateZeroPool(OFFSETOF(TCG_PCR_EVENT, Event) + desc_len);
|
||||
if (!tcg_event)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
tcg_event->EventSize = desc_len;
|
||||
CopyMem((VOID *) & tcg_event->Event[0], (VOID *) description, desc_len);
|
||||
*tcg_event = (TCG_PCR_EVENT) {
|
||||
.EventSize = desc_len,
|
||||
.PCRIndex = pcrindex,
|
||||
.EventType = EV_IPL,
|
||||
};
|
||||
CopyMem(tcg_event->Event, description, desc_len);
|
||||
|
||||
tcg_event->PCRIndex = pcrindex;
|
||||
tcg_event->EventType = EV_IPL;
|
||||
|
||||
event_number = 1;
|
||||
status = uefi_call_wrapper(tcg->HashLogExtendEvent, 7,
|
||||
(EFI_TCG *) tcg, buffer, buffer_size, TCG_ALG_SHA, tcg_event, &event_number, &event_log_last);
|
||||
|
||||
if (EFI_ERROR(status))
|
||||
return status;
|
||||
|
||||
uefi_call_wrapper(BS->FreePool, 1, tcg_event);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
return uefi_call_wrapper(
|
||||
tcg->HashLogExtendEvent, 7,
|
||||
(EFI_TCG *) tcg,
|
||||
buffer, buffer_size,
|
||||
TCG_ALG_SHA,
|
||||
tcg_event,
|
||||
&event_number,
|
||||
&event_log_last);
|
||||
}
|
||||
|
||||
static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
|
||||
UINT64 buffer_size, const CHAR16 *description) {
|
||||
EFI_STATUS status;
|
||||
EFI_TCG2_EVENT *tcg_event;
|
||||
static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
|
||||
EFI_TCG2 *tcg,
|
||||
UINT32 pcrindex,
|
||||
EFI_PHYSICAL_ADDRESS buffer,
|
||||
UINT64 buffer_size,
|
||||
const CHAR16 *description) {
|
||||
|
||||
_cleanup_freepool_ EFI_TCG2_EVENT *tcg_event = NULL;
|
||||
UINTN desc_len;
|
||||
|
||||
assert(tcg);
|
||||
assert(description);
|
||||
|
||||
desc_len = StrSize(description);
|
||||
tcg_event = AllocateZeroPool(sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len);
|
||||
|
||||
tcg_event = AllocateZeroPool(OFFSETOF(EFI_TCG2_EVENT, Event) + desc_len);
|
||||
if (!tcg_event)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
tcg_event->Size = sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len;
|
||||
tcg_event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
|
||||
tcg_event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
|
||||
tcg_event->Header.PCRIndex = pcrindex;
|
||||
tcg_event->Header.EventType = EV_IPL;
|
||||
*tcg_event = (EFI_TCG2_EVENT) {
|
||||
.Size = OFFSETOF(EFI_TCG2_EVENT, Event) + desc_len,
|
||||
.Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER),
|
||||
.Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION,
|
||||
.Header.PCRIndex = pcrindex,
|
||||
.Header.EventType = EV_IPL,
|
||||
};
|
||||
|
||||
CopyMem((VOID *) tcg_event->Event, (VOID *) description, desc_len);
|
||||
CopyMem(tcg_event->Event, description, desc_len);
|
||||
|
||||
status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, (UINT64) buffer_size, tcg_event);
|
||||
|
||||
uefi_call_wrapper(BS->FreePool, 1, tcg_event);
|
||||
|
||||
if (EFI_ERROR(status))
|
||||
return status;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
return uefi_call_wrapper(
|
||||
tcg->HashLogExtendEvent, 5,
|
||||
tcg,
|
||||
0,
|
||||
buffer, buffer_size,
|
||||
tcg_event);
|
||||
}
|
||||
|
||||
static EFI_TCG * tcg1_interface_check(void) {
|
||||
static EFI_TCG *tcg1_interface_check(void) {
|
||||
EFI_PHYSICAL_ADDRESS event_log_location, event_log_last_entry;
|
||||
TCG_BOOT_SERVICE_CAPABILITY capability = {
|
||||
.Size = sizeof(capability),
|
||||
};
|
||||
EFI_STATUS status;
|
||||
EFI_TCG *tcg;
|
||||
TCG_BOOT_SERVICE_CAPABILITY capability;
|
||||
UINT32 features;
|
||||
EFI_PHYSICAL_ADDRESS event_log_location;
|
||||
EFI_PHYSICAL_ADDRESS event_log_last_entry;
|
||||
EFI_TCG *tcg;
|
||||
|
||||
status = LibLocateProtocol((EFI_GUID*) EFI_TCG_GUID, (void **) &tcg);
|
||||
|
||||
if (EFI_ERROR(status))
|
||||
return NULL;
|
||||
|
||||
capability.Size = (UINT8) sizeof(capability);
|
||||
status = uefi_call_wrapper(tcg->StatusCheck, 5, tcg, &capability, &features, &event_log_location, &event_log_last_entry);
|
||||
|
||||
status = uefi_call_wrapper(
|
||||
tcg->StatusCheck, 5,
|
||||
tcg,
|
||||
&capability,
|
||||
&features,
|
||||
&event_log_location,
|
||||
&event_log_last_entry);
|
||||
if (EFI_ERROR(status))
|
||||
return NULL;
|
||||
|
||||
@ -274,25 +116,24 @@ static EFI_TCG * tcg1_interface_check(void) {
|
||||
}
|
||||
|
||||
static EFI_TCG2 * tcg2_interface_check(void) {
|
||||
EFI_TCG2_BOOT_SERVICE_CAPABILITY capability = {
|
||||
.Size = sizeof(capability),
|
||||
};
|
||||
EFI_STATUS status;
|
||||
EFI_TCG2 *tcg;
|
||||
EFI_TCG2_BOOT_SERVICE_CAPABILITY capability;
|
||||
|
||||
status = LibLocateProtocol((EFI_GUID*) EFI_TCG2_GUID, (void **) &tcg);
|
||||
|
||||
if (EFI_ERROR(status))
|
||||
return NULL;
|
||||
|
||||
capability.Size = (UINT8) sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);
|
||||
status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, &capability);
|
||||
|
||||
if (EFI_ERROR(status))
|
||||
return NULL;
|
||||
|
||||
if (capability.StructureVersion.Major == 1 &&
|
||||
capability.StructureVersion.Minor == 0) {
|
||||
TCG_BOOT_SERVICE_CAPABILITY *caps_1_0;
|
||||
caps_1_0 = (TCG_BOOT_SERVICE_CAPABILITY *)&capability;
|
||||
TCG_BOOT_SERVICE_CAPABILITY *caps_1_0 =
|
||||
(TCG_BOOT_SERVICE_CAPABILITY*) &capability;
|
||||
if (caps_1_0->TPMPresentFlag)
|
||||
return tcg;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <efi.h>
|
||||
|
||||
#include "macro-fundamental.h"
|
||||
|
||||
#ifndef EFI_RNG_PROTOCOL_GUID
|
||||
|
||||
#define EFI_RNG_PROTOCOL_GUID \
|
||||
@ -159,4 +161,173 @@ struct _EFI_DT_FIXUP_PROTOCOL {
|
||||
EFI_DT_FIXUP Fixup;
|
||||
};
|
||||
|
||||
#define EFI_TCG_GUID \
|
||||
&(const EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }
|
||||
|
||||
typedef struct _TCG_VERSION {
|
||||
UINT8 Major;
|
||||
UINT8 Minor;
|
||||
UINT8 RevMajor;
|
||||
UINT8 RevMinor;
|
||||
} TCG_VERSION;
|
||||
|
||||
typedef struct tdEFI_TCG2_VERSION {
|
||||
UINT8 Major;
|
||||
UINT8 Minor;
|
||||
} EFI_TCG2_VERSION;
|
||||
|
||||
typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
|
||||
UINT8 Size;
|
||||
struct _TCG_VERSION StructureVersion;
|
||||
struct _TCG_VERSION ProtocolSpecVersion;
|
||||
UINT8 HashAlgorithmBitmap;
|
||||
BOOLEAN TPMPresentFlag;
|
||||
BOOLEAN TPMDeactivatedFlag;
|
||||
} TCG_BOOT_SERVICE_CAPABILITY;
|
||||
|
||||
typedef struct tdTREE_BOOT_SERVICE_CAPABILITY {
|
||||
UINT8 Size;
|
||||
EFI_TCG2_VERSION StructureVersion;
|
||||
EFI_TCG2_VERSION ProtocolVersion;
|
||||
UINT32 HashAlgorithmBitmap;
|
||||
UINT32 SupportedEventLogs;
|
||||
BOOLEAN TrEEPresentFlag;
|
||||
UINT16 MaxCommandSize;
|
||||
UINT16 MaxResponseSize;
|
||||
UINT32 ManufacturerID;
|
||||
} TREE_BOOT_SERVICE_CAPABILITY;
|
||||
|
||||
typedef UINT32 TCG_ALGORITHM_ID;
|
||||
#define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm
|
||||
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
typedef struct _TCG_DIGEST {
|
||||
UINT8 Digest[SHA1_DIGEST_SIZE];
|
||||
} TCG_DIGEST;
|
||||
|
||||
#define EV_IPL 13
|
||||
|
||||
typedef struct _TCG_PCR_EVENT {
|
||||
UINT32 PCRIndex;
|
||||
UINT32 EventType;
|
||||
struct _TCG_DIGEST digest;
|
||||
UINT32 EventSize;
|
||||
UINT8 Event[1];
|
||||
} TCG_PCR_EVENT;
|
||||
|
||||
INTERFACE_DECL(_EFI_TCG);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_STATUS_CHECK) (IN struct _EFI_TCG * This,
|
||||
OUT struct _TCG_BOOT_SERVICE_CAPABILITY * ProtocolCapability,
|
||||
OUT UINT32 * TCGFeatureFlags,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_ALL) (IN struct _EFI_TCG * This,
|
||||
IN UINT8 * HashData,
|
||||
IN UINT64 HashDataLen,
|
||||
IN TCG_ALGORITHM_ID AlgorithmId,
|
||||
IN OUT UINT64 * HashedDataLen, IN OUT UINT8 ** HashedDataResult);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_LOG_EVENT) (IN struct _EFI_TCG * This,
|
||||
IN struct _TCG_PCR_EVENT * TCGLogData,
|
||||
IN OUT UINT32 * EventNumber, IN UINT32 Flags);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_PASS_THROUGH_TO_TPM) (IN struct _EFI_TCG * This,
|
||||
IN UINT32 TpmInputParameterBlockSize,
|
||||
IN UINT8 * TpmInputParameterBlock,
|
||||
IN UINT32 TpmOutputParameterBlockSize,
|
||||
IN UINT8 * TpmOutputParameterBlock);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_LOG_EXTEND_EVENT) (IN struct _EFI_TCG * This,
|
||||
IN EFI_PHYSICAL_ADDRESS HashData,
|
||||
IN UINT64 HashDataLen,
|
||||
IN TCG_ALGORITHM_ID AlgorithmId,
|
||||
IN struct _TCG_PCR_EVENT * TCGLogData,
|
||||
IN OUT UINT32 * EventNumber,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
|
||||
|
||||
typedef struct _EFI_TCG {
|
||||
EFI_TCG_STATUS_CHECK StatusCheck;
|
||||
EFI_TCG_HASH_ALL HashAll;
|
||||
EFI_TCG_LOG_EVENT LogEvent;
|
||||
EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTPM;
|
||||
EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
|
||||
} EFI_TCG;
|
||||
|
||||
#define EFI_TCG2_GUID \
|
||||
&(const EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
|
||||
|
||||
typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
|
||||
|
||||
typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
|
||||
typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
|
||||
typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
|
||||
|
||||
typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
|
||||
UINT8 Size;
|
||||
EFI_TCG2_VERSION StructureVersion;
|
||||
EFI_TCG2_VERSION ProtocolVersion;
|
||||
EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
|
||||
EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
|
||||
BOOLEAN TPMPresentFlag;
|
||||
UINT16 MaxCommandSize;
|
||||
UINT16 MaxResponseSize;
|
||||
UINT32 ManufacturerID;
|
||||
UINT32 NumberOfPCRBanks;
|
||||
EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
|
||||
} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
|
||||
|
||||
#define EFI_TCG2_EVENT_HEADER_VERSION 1
|
||||
|
||||
typedef struct {
|
||||
UINT32 HeaderSize;
|
||||
UINT16 HeaderVersion;
|
||||
UINT32 PCRIndex;
|
||||
UINT32 EventType;
|
||||
} _packed_ EFI_TCG2_EVENT_HEADER;
|
||||
|
||||
typedef struct tdEFI_TCG2_EVENT {
|
||||
UINT32 Size;
|
||||
EFI_TCG2_EVENT_HEADER Header;
|
||||
UINT8 Event[1];
|
||||
} _packed_ EFI_TCG2_EVENT;
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This,
|
||||
IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_EVENT_LOG) (IN EFI_TCG2_PROTOCOL * This,
|
||||
IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
|
||||
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry,
|
||||
OUT BOOLEAN * EventLogTruncated);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_HASH_LOG_EXTEND_EVENT) (IN EFI_TCG2_PROTOCOL * This,
|
||||
IN UINT64 Flags,
|
||||
IN EFI_PHYSICAL_ADDRESS DataToHash,
|
||||
IN UINT64 DataToHashLen, IN EFI_TCG2_EVENT * EfiTcgEvent);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_SUBMIT_COMMAND) (IN EFI_TCG2_PROTOCOL * This,
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 * InputParameterBlock,
|
||||
IN UINT32 OutputParameterBlockSize, IN UINT8 * OutputParameterBlock);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, OUT UINT32 * ActivePcrBanks);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, IN UINT32 ActivePcrBanks);
|
||||
|
||||
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This,
|
||||
OUT UINT32 * OperationPresent, OUT UINT32 * Response);
|
||||
|
||||
typedef struct tdEFI_TCG2_PROTOCOL {
|
||||
EFI_TCG2_GET_CAPABILITY GetCapability;
|
||||
EFI_TCG2_GET_EVENT_LOG GetEventLog;
|
||||
EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
|
||||
EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
|
||||
EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
|
||||
EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
|
||||
EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
|
||||
} EFI_TCG2;
|
||||
|
||||
#endif
|
||||
|
@ -17,17 +17,28 @@ static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub
|
||||
|
||||
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
EFI_LOADED_IMAGE *loaded_image;
|
||||
const CHAR8 *sections[] = {
|
||||
(CHAR8 *)".cmdline",
|
||||
(CHAR8 *)".linux",
|
||||
(CHAR8 *)".initrd",
|
||||
(CHAR8 *)".splash",
|
||||
NULL
|
||||
|
||||
enum {
|
||||
SECTION_CMDLINE,
|
||||
SECTION_LINUX,
|
||||
SECTION_INITRD,
|
||||
SECTION_SPLASH,
|
||||
_SECTION_MAX,
|
||||
};
|
||||
UINTN addrs[ELEMENTSOF(sections)-1] = {};
|
||||
UINTN szs[ELEMENTSOF(sections)-1] = {};
|
||||
|
||||
const CHAR8* const sections[] = {
|
||||
[SECTION_CMDLINE] = (const CHAR8*) ".cmdline",
|
||||
[SECTION_LINUX] = (const CHAR8*) ".linux",
|
||||
[SECTION_INITRD] = (const CHAR8*) ".initrd",
|
||||
[SECTION_SPLASH] = (const CHAR8*) ".splash",
|
||||
NULL,
|
||||
};
|
||||
|
||||
EFI_PHYSICAL_ADDRESS linux_base, initrd_base;
|
||||
UINTN cmdline_len = 0, initrd_size;
|
||||
UINTN addrs[_SECTION_MAX] = {};
|
||||
UINTN szs[_SECTION_MAX] = {};
|
||||
CHAR8 *cmdline = NULL;
|
||||
UINTN cmdline_len;
|
||||
CHAR16 uuid[37];
|
||||
EFI_STATUS err;
|
||||
|
||||
@ -38,14 +49,14 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
|
||||
err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, szs);
|
||||
err = pe_memory_locate_sections(loaded_image->ImageBase, (const CHAR8**) sections, addrs, szs);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
|
||||
|
||||
if (szs[0] > 0)
|
||||
cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0];
|
||||
|
||||
cmdline_len = szs[0];
|
||||
if (szs[SECTION_CMDLINE] > 0) {
|
||||
cmdline = (CHAR8*) loaded_image->ImageBase + addrs[SECTION_CMDLINE];
|
||||
cmdline_len = szs[SECTION_CMDLINE];
|
||||
}
|
||||
|
||||
/* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */
|
||||
if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 &&
|
||||
@ -109,12 +120,15 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
if (efivar_get_raw(LOADER_GUID, L"StubInfo", NULL, NULL) != EFI_SUCCESS)
|
||||
efivar_set(LOADER_GUID, L"StubInfo", L"systemd-stub " GIT_VERSION, 0);
|
||||
|
||||
if (szs[3] > 0)
|
||||
graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL);
|
||||
if (szs[SECTION_SPLASH] > 0)
|
||||
graphics_splash((UINT8*) (UINTN) loaded_image->ImageBase + addrs[SECTION_SPLASH], szs[SECTION_SPLASH], NULL);
|
||||
|
||||
err = linux_exec(image, cmdline, cmdline_len,
|
||||
(UINTN)loaded_image->ImageBase + addrs[1],
|
||||
(UINTN)loaded_image->ImageBase + addrs[2], szs[2]);
|
||||
linux_base = (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->ImageBase + addrs[SECTION_LINUX];
|
||||
|
||||
initrd_size = szs[SECTION_INITRD];
|
||||
initrd_base = initrd_size != 0 ? (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->ImageBase + addrs[SECTION_INITRD] : 0;
|
||||
|
||||
err = linux_exec(image, cmdline, cmdline_len, linux_base, initrd_base, initrd_size);
|
||||
|
||||
graphics_mode(FALSE);
|
||||
return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err);
|
||||
|
Loading…
Reference in New Issue
Block a user