diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index af02cfb7e91..074a8565982 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -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 \ diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index 3e64ab6be94..fbca67bbf15 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -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; } diff --git a/src/boot/efi/missing_efi.h b/src/boot/efi/missing_efi.h index 91bf3e65d7a..badf0017ad4 100644 --- a/src/boot/efi/missing_efi.h +++ b/src/boot/efi/missing_efi.h @@ -3,6 +3,8 @@ #include +#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 diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 5758b5cd948..9a3c9982d9b 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -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);