diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index e1a7dd1f32e..c88a6db9dee 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -13,6 +13,7 @@ #include "measure.h" #include "pe.h" #include "random-seed.h" +#include "secure-boot.h" #include "shim.h" #include "util.h" @@ -23,8 +24,6 @@ /* magic string to find in the binary image */ static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####"; -static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; - enum loader_type { LOADER_UNDEFINED, LOADER_EFI, @@ -119,17 +118,17 @@ static BOOLEAN line_edit( while (!exit) { EFI_STATUS err; UINT64 key; - UINTN i; + UINTN j; - i = len - first; - if (i >= x_max-1) - i = x_max-1; - CopyMem(print, line + first, i * sizeof(CHAR16)); - while (clear > 0 && i < x_max-1) { + j = len - first; + if (j >= x_max-1) + j = x_max-1; + CopyMem(print, line + first, j * sizeof(CHAR16)); + while (clear > 0 && j < x_max-1) { clear--; - print[i++] = ' '; + print[j++] = ' '; } - print[i] = '\0'; + print[j] = '\0'; uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, y_pos); uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, print); @@ -213,12 +212,14 @@ static BOOLEAN line_edit( case KEYPRESS(EFI_ALT_PRESSED, 0, 'd'): /* kill-word */ clear = 0; - for (i = first + cursor; i < len && line[i] == ' '; i++) + + UINTN k; + for (k = first + cursor; k < len && line[k] == ' '; k++) clear++; - for (; i < len && line[i] != ' '; i++) + for (; k < len && line[k] != ' '; k++) clear++; - for (i = first + cursor; i + clear < len; i++) + for (UINTN i = first + cursor; i + clear < len; i++) line[i] = line[i + clear]; len -= clear; line[len] = '\0'; @@ -243,7 +244,7 @@ static BOOLEAN line_edit( } uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos); - for (i = first + cursor; i + clear < len; i++) + for (UINTN i = first + cursor; i + clear < len; i++) line[i] = line[i + clear]; len -= clear; line[len] = '\0'; @@ -256,7 +257,7 @@ static BOOLEAN line_edit( continue; if (first + cursor == len) continue; - for (i = first + cursor; i < len; i++) + for (UINTN i = first + cursor; i < len; i++) line[i] = line[i+1]; clear = 1; len--; @@ -285,7 +286,7 @@ static BOOLEAN line_edit( continue; if (first == 0 && cursor == 0) continue; - for (i = first + cursor-1; i < len; i++) + for (UINTN i = first + cursor-1; i < len; i++) line[i] = line[i+1]; clear = 1; len--; @@ -313,7 +314,7 @@ static BOOLEAN line_edit( case KEYPRESS(0, 0, 0x80) ... KEYPRESS(0, 0, 0xffff): if (len+1 == size) continue; - for (i = len; i > first + cursor; i--) + for (UINTN i = len; i > first + cursor; i--) line[i] = line[i-1]; line[first + cursor] = KEYCHAR(key); len++; @@ -331,25 +332,23 @@ static BOOLEAN line_edit( } static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) { - UINTN i; - if (key == 0) return -1; /* select entry by number key */ if (key >= '1' && key <= '9') { - i = key - '0'; + UINTN i = key - '0'; if (i > config->entry_count) i = config->entry_count; return i-1; } /* find matching key in config entries */ - for (i = start; i < config->entry_count; i++) + for (UINTN i = start; i < config->entry_count; i++) if (config->entries[i]->key == key) return i; - for (i = 0; i < start; i++) + for (UINTN i = 0; i < start; i++) if (config->entries[i]->key == key) return i; @@ -357,11 +356,11 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) { } static VOID print_status(Config *config, CHAR16 *loaded_image_path) { - UINT64 key; - UINTN i; - _cleanup_freepool_ CHAR8 *bootvar = NULL, *modevar = NULL, *indvar = NULL; + UINT64 key, indvar; + UINTN timeout; + BOOLEAN modevar; _cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL; - UINTN x, y, size; + UINTN x, y; uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK); uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); @@ -376,17 +375,16 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { if (uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &x, &y) == EFI_SUCCESS) Print(L"console size: %d x %d\n", x, y); - if (efivar_get_raw(&global_guid, L"SecureBoot", &bootvar, &size) == EFI_SUCCESS) - Print(L"SecureBoot: %s\n", yes_no(*bootvar > 0)); + Print(L"SecureBoot: %s\n", yes_no(secure_boot_enabled())); - if (efivar_get_raw(&global_guid, L"SetupMode", &modevar, &size) == EFI_SUCCESS) - Print(L"SetupMode: %s\n", *modevar > 0 ? L"setup" : L"user"); + if (efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &modevar) == EFI_SUCCESS) + Print(L"SetupMode: %s\n", modevar ? L"setup" : L"user"); if (shim_loaded()) Print(L"Shim: present\n"); - if (efivar_get_raw(&global_guid, L"OsIndicationsSupported", &indvar, &size) == EFI_SUCCESS) - Print(L"OsIndicationsSupported: %d\n", (UINT64)*indvar); + if (efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &indvar) == EFI_SUCCESS) + Print(L"OsIndicationsSupported: %d\n", indvar); Print(L"\n--- press key ---\n\n"); console_key_read(&key, TRUE); @@ -423,20 +421,20 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"entry EFI var idx: %d\n", config->idx_default_efivar); Print(L"\n"); - if (efivar_get_int(L"LoaderConfigTimeout", &i) == EFI_SUCCESS) - Print(L"LoaderConfigTimeout: %u\n", i); + if (efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &timeout) == EFI_SUCCESS) + Print(L"LoaderConfigTimeout: %u\n", timeout); if (config->entry_oneshot) Print(L"LoaderEntryOneShot: %s\n", config->entry_oneshot); - if (efivar_get(L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS) + if (efivar_get(LOADER_GUID, L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS) Print(L"LoaderDevicePartUUID: %s\n", partstr); - if (efivar_get(L"LoaderEntryDefault", &defaultstr) == EFI_SUCCESS) + if (efivar_get(LOADER_GUID, L"LoaderEntryDefault", &defaultstr) == EFI_SUCCESS) Print(L"LoaderEntryDefault: %s\n", defaultstr); Print(L"\n--- press key ---\n\n"); console_key_read(&key, TRUE); - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { ConfigEntry *entry; if (key == KEYPRESS(0, SCAN_ESC, 0) || key == KEYPRESS(0, 0, 'q')) @@ -503,7 +501,6 @@ static BOOLEAN menu_run( UINTN idx_last; BOOLEAN refresh; BOOLEAN highlight; - UINTN i; UINTN line_width; CHAR16 **lines; UINTN x_start; @@ -564,7 +561,7 @@ static BOOLEAN menu_run( /* length of the longest entry */ line_width = 5; - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { UINTN entry_len; entry_len = StrLen(config->entries[i]->title_show); @@ -583,14 +580,14 @@ static BOOLEAN menu_run( /* menu entries title lines */ lines = AllocatePool(sizeof(CHAR16 *) * config->entry_count); - for (i = 0; i < config->entry_count; i++) { - UINTN j, k; + for (UINTN i = 0; i < config->entry_count; i++) { + UINTN j; lines[i] = AllocatePool(((x_max+1) * sizeof(CHAR16))); for (j = 0; j < x_start; j++) lines[i][j] = ' '; - for (k = 0; config->entries[i]->title_show[k] != '\0' && j < x_max; j++, k++) + for (UINTN k = 0; config->entries[i]->title_show[k] != '\0' && j < x_max; j++, k++) lines[i][j] = config->entries[i]->title_show[k]; for (; j < x_max; j++) @@ -600,15 +597,15 @@ static BOOLEAN menu_run( status = NULL; clearline = AllocatePool((x_max+1) * sizeof(CHAR16)); - for (i = 0; i < x_max; i++) + for (UINTN i = 0; i < x_max; i++) clearline[i] = ' '; - clearline[i] = 0; + clearline[x_max] = 0; while (!exit) { UINT64 key; if (refresh) { - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { if (i < idx_first || i > idx_last) continue; uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, y_start + i - idx_first); @@ -764,12 +761,16 @@ static BOOLEAN menu_run( case KEYPRESS(0, 0, 'd'): if (config->idx_default_efivar != (INTN)idx_highlight) { /* store the selected entry in a persistent EFI variable */ - efivar_set(L"LoaderEntryDefault", config->entries[idx_highlight]->id, TRUE); + efivar_set( + LOADER_GUID, + L"LoaderEntryDefault", + config->entries[idx_highlight]->id, + TRUE); config->idx_default_efivar = idx_highlight; status = StrDuplicate(L"Default boot entry selected."); } else { /* clear the default entry EFI variable */ - efivar_set(L"LoaderEntryDefault", NULL, TRUE); + efivar_set(LOADER_GUID, L"LoaderEntryDefault", NULL, TRUE); config->idx_default_efivar = -1; status = StrDuplicate(L"Default boot entry cleared."); } @@ -780,14 +781,15 @@ static BOOLEAN menu_run( case KEYPRESS(0, 0, 'T'): if (config->timeout_sec_efivar > 0) { config->timeout_sec_efivar--; - efivar_set_int(L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); + efivar_set_uint_string( + LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); if (config->timeout_sec_efivar > 0) status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar); else status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu."); } else if (config->timeout_sec_efivar <= 0){ config->timeout_sec_efivar = -1; - efivar_set(L"LoaderConfigTimeout", NULL, TRUE); + efivar_set(LOADER_GUID, L"LoaderConfigTimeout", NULL, TRUE); if (config->timeout_sec_config > 0) status = PoolPrint(L"Menu timeout of %d sec is defined by configuration file.", config->timeout_sec_config); @@ -801,7 +803,7 @@ static BOOLEAN menu_run( if (config->timeout_sec_efivar == -1 && config->timeout_sec_config == 0) config->timeout_sec_efivar++; config->timeout_sec_efivar++; - efivar_set_int(L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); + efivar_set_uint_string(LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); if (config->timeout_sec_efivar > 0) status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar); @@ -863,7 +865,7 @@ static BOOLEAN menu_run( *chosen_entry = config->entries[idx_highlight]; - for (i = 0; i < config->entry_count; i++) + for (UINTN i = 0; i < config->entry_count; i++) FreePool(lines[i]); FreePool(lines); FreePool(clearline); @@ -1293,7 +1295,7 @@ static VOID config_entry_bump_counters( /* Let's tell the OS that we renamed this file, so that it knows what to rename to the counter-less name on * success */ new_path = PoolPrint(L"%s\\%s", entry->path, entry->next_name); - efivar_set(L"LoaderBootCountPath", new_path, FALSE); + efivar_set(LOADER_GUID, L"LoaderBootCountPath", new_path, FALSE); /* If the file we just renamed is the loader path, then let's update that. */ if (StrCmp(entry->loader, old_path) == 0) { @@ -1458,17 +1460,17 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) { if (!EFI_ERROR(err)) config_defaults_load_from_file(config, content); - err = efivar_get_int(L"LoaderConfigTimeout", &sec); + err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &sec); if (!EFI_ERROR(err)) { config->timeout_sec_efivar = sec > INTN_MAX ? INTN_MAX : sec; config->timeout_sec = sec; } else config->timeout_sec_efivar = -1; - err = efivar_get_int(L"LoaderConfigTimeoutOneShot", &sec); + err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &sec); if (!EFI_ERROR(err)) { /* Unset variable now, after all it's "one shot". */ - (void) efivar_set(L"LoaderConfigTimeoutOneShot", NULL, TRUE); + (void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, TRUE); config->timeout_sec = sec; config->force_menu = TRUE; /* force the menu when this is set */ @@ -1491,7 +1493,6 @@ static VOID config_load_entries( UINTN bufsize; EFI_FILE_INFO *f; _cleanup_freepool_ CHAR8 *content = NULL; - UINTN len; bufsize = sizeof(buf); err = uefi_call_wrapper(entries_dir->Read, 3, entries_dir, &bufsize, buf); @@ -1504,12 +1505,9 @@ static VOID config_load_entries( if (f->Attribute & EFI_FILE_DIRECTORY) continue; - len = StrLen(f->FileName); - if (len < 6) + if (!endswith_no_case(f->FileName, L".conf")) continue; - if (StriCmp(f->FileName + len - 5, L".conf") != 0) - continue; - if (StrnCmp(f->FileName, L"auto-", 5) == 0) + if (startswith(f->FileName, L"auto-")) continue; err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL); @@ -1553,14 +1551,11 @@ static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) { } static VOID config_sort_entries(Config *config) { - UINTN i; - - for (i = 1; i < config->entry_count; i++) { + for (UINTN i = 1; i < config->entry_count; i++) { BOOLEAN more; - UINTN k; more = FALSE; - for (k = 0; k < config->entry_count - i; k++) { + for (UINTN k = 0; k < config->entry_count - i; k++) { ConfigEntry *entry; if (config_entry_compare(config->entries[k], config->entries[k+1]) <= 0) @@ -1577,9 +1572,7 @@ static VOID config_sort_entries(Config *config) { } static INTN config_entry_find(Config *config, CHAR16 *id) { - UINTN i; - - for (i = 0; i < config->entry_count; i++) + for (UINTN i = 0; i < config->entry_count; i++) if (StrCmp(config->entries[i]->id, id) == 0) return (INTN) i; @@ -1595,11 +1588,11 @@ static VOID config_default_entry_select(Config *config) { * The EFI variable to specify a boot entry for the next, and only the * next reboot. The variable is always cleared directly after it is read. */ - err = efivar_get(L"LoaderEntryOneShot", &entry_oneshot); + err = efivar_get(LOADER_GUID, L"LoaderEntryOneShot", &entry_oneshot); if (!EFI_ERROR(err)) { config->entry_oneshot = StrDuplicate(entry_oneshot); - efivar_set(L"LoaderEntryOneShot", NULL, TRUE); + efivar_set(LOADER_GUID, L"LoaderEntryOneShot", NULL, TRUE); i = config_entry_find(config, entry_oneshot); if (i >= 0) { @@ -1614,7 +1607,7 @@ static VOID config_default_entry_select(Config *config) { * the 'd' key in the loader selection menu, the entry is marked with * an '*'. */ - err = efivar_get(L"LoaderEntryDefault", &entry_default); + err = efivar_get(LOADER_GUID, L"LoaderEntryDefault", &entry_default); if (!EFI_ERROR(err)) { i = config_entry_find(config, entry_default); @@ -1660,13 +1653,12 @@ static VOID config_default_entry_select(Config *config) { static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) { BOOLEAN non_unique = FALSE; - UINTN i, k; - for (i = 0; i < entry_count; i++) + for (UINTN i = 0; i < entry_count; i++) entries[i]->non_unique = FALSE; - for (i = 0; i < entry_count; i++) - for (k = 0; k < entry_count; k++) { + for (UINTN i = 0; i < entry_count; i++) + for (UINTN k = 0; k < entry_count; k++) { if (i == k) continue; if (StrCmp(entries[i]->title_show, entries[k]->title_show) != 0) @@ -1680,10 +1672,8 @@ static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) { /* generate a unique title, avoiding non-distinguishable menu entries */ static VOID config_title_generate(Config *config) { - UINTN i; - /* set title */ - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { CHAR16 *title; FreePool(config->entries[i]->title_show); @@ -1697,7 +1687,7 @@ static VOID config_title_generate(Config *config) { return; /* add version to non-unique titles */ - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { CHAR16 *s; if (!config->entries[i]->non_unique) @@ -1714,7 +1704,7 @@ static VOID config_title_generate(Config *config) { return; /* add machine-id to non-unique titles */ - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { CHAR16 *s; _cleanup_freepool_ CHAR16 *m = NULL; @@ -1734,7 +1724,7 @@ static VOID config_title_generate(Config *config) { return; /* add file name to non-unique titles */ - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { CHAR16 *s; if (!config->entries[i]->non_unique) @@ -1826,14 +1816,10 @@ static BOOLEAN config_entry_add_loader_auto( /* look for systemd-boot magic string */ err = file_read(root_dir, loader, 0, 100*1024, &content, &len); - if (!EFI_ERROR(err)) { - CHAR8 *start = content; - CHAR8 *last = content + len - sizeof(magic) - 1; - - for (; start <= last; start++) + if (!EFI_ERROR(err)) + for (CHAR8 *start = content; start <= content + len - sizeof(magic) - 1; start++) if (start[0] == magic[0] && CompareMem(start, magic, sizeof(magic) - 1) == 0) return FALSE; - } } /* check existence */ @@ -1862,9 +1848,7 @@ static VOID config_entry_add_osx(Config *config) { err = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &handle_count, &handles); if (!EFI_ERROR(err)) { - UINTN i; - - for (i = 0; i < handle_count; i++) { + for (UINTN i = 0; i < handle_count; i++) { EFI_FILE *root; BOOLEAN found; @@ -1906,7 +1890,6 @@ static VOID config_entry_add_linux( UINTN szs[ELEMENTSOF(sections)-1] = {}; UINTN addrs[ELEMENTSOF(sections)-1] = {}; CHAR8 *content = NULL; - UINTN len; CHAR8 *line; UINTN pos = 0; CHAR8 *key, *value; @@ -1926,12 +1909,9 @@ static VOID config_entry_add_linux( continue; if (f->Attribute & EFI_FILE_DIRECTORY) continue; - len = StrLen(f->FileName); - if (len < 5) + if (!endswith_no_case(f->FileName, L".efi")) continue; - if (StriCmp(f->FileName + len - 4, L".efi") != 0) - continue; - if (StrnCmp(f->FileName, L"auto-", 5) == 0) + if (startswith(f->FileName, L"auto-")) continue; /* look for .osrel and .cmdline sections in the .efi binary */ @@ -2020,10 +2000,8 @@ static VOID config_entry_add_linux( uefi_call_wrapper(linux_dir->Close, 1, linux_dir); } -/* Note that this is in GUID format, i.e. the first 32bit, and the following pair of 16bit are byteswapped. */ -static const UINT8 xbootldr_guid[16] = { - 0xff, 0xc2, 0x13, 0xbc, 0xe6, 0x59, 0x62, 0x42, 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 -}; +#define XBOOTLDR_GUID \ + &(const EFI_GUID) { 0xbc13c2ff, 0x59e6, 0x4262, { 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 } } static EFI_DEVICE_PATH *path_parent(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node) { EFI_DEVICE_PATH *parent; @@ -2041,7 +2019,7 @@ static VOID config_load_xbootldr( Config *config, EFI_HANDLE *device) { - EFI_DEVICE_PATH *partition_path, *node, *disk_path, *copy; + EFI_DEVICE_PATH *partition_path, *disk_path, *copy; UINT32 found_partition_number = (UINT32) -1; UINT64 found_partition_start = (UINT64) -1; UINT64 found_partition_size = (UINT64) -1; @@ -2054,11 +2032,10 @@ static VOID config_load_xbootldr( if (!partition_path) return; - for (node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { + for (EFI_DEVICE_PATH *node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { EFI_HANDLE disk_handle; EFI_BLOCK_IO *block_io; EFI_DEVICE_PATH *p; - UINTN nr; /* First, Let's look for the SCSI/SATA/USB/… device path node, i.e. one above the media * devices */ @@ -2085,7 +2062,7 @@ static VOID config_load_xbootldr( continue; /* Try both copies of the GPT header, in case one is corrupted */ - for (nr = 0; nr < 2; nr++) { + for (UINTN nr = 0; nr < 2; nr++) { _cleanup_freepool_ EFI_PARTITION_ENTRY* entries = NULL; union { EFI_PARTITION_TABLE_HEADER gpt_header; @@ -2093,7 +2070,7 @@ static VOID config_load_xbootldr( } gpt_header_buffer; const EFI_PARTITION_TABLE_HEADER *h = &gpt_header_buffer.gpt_header; UINT64 where; - UINTN i, sz; + UINTN sz; UINT32 c; if (nr == 0) @@ -2163,12 +2140,12 @@ static VOID config_load_xbootldr( if (c != h->PartitionEntryArrayCRC32) continue; - for (i = 0; i < h->NumberOfPartitionEntries; i++) { + for (UINTN i = 0; i < h->NumberOfPartitionEntries; i++) { EFI_PARTITION_ENTRY *entry; entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + h->SizeOfPartitionEntry * i); - if (CompareMem(&entry->PartitionTypeGUID, xbootldr_guid, 16) == 0) { + if (CompareMem(&entry->PartitionTypeGUID, XBOOTLDR_GUID, 16) == 0) { UINT64 end; /* Let's use memcpy(), in case the structs are not aligned (they really should be though) */ @@ -2197,7 +2174,7 @@ found: copy = DuplicateDevicePath(partition_path); /* Patch in the data we found */ - for (node = copy; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { + for (EFI_DEVICE_PATH *node = copy; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { HARDDRIVE_DEVICE_PATH *hd; if (DevicePathType(node) != MEDIA_DEVICE_PATH) @@ -2282,7 +2259,7 @@ static EFI_STATUS image_start( #endif } - efivar_set_time_usec(L"LoaderTimeExecUSec", 0); + efivar_set_time_usec(LOADER_GUID, L"LoaderTimeExecUSec", 0); err = uefi_call_wrapper(BS->StartImage, 3, image, NULL, NULL); out_unload: uefi_call_wrapper(BS->UnloadImage, 1, image); @@ -2290,18 +2267,16 @@ out_unload: } static EFI_STATUS reboot_into_firmware(VOID) { - _cleanup_freepool_ CHAR8 *b = NULL; - UINTN size; - UINT64 osind; + UINT64 old, new; EFI_STATUS err; - osind = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; + new = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; - err = efivar_get_raw(&global_guid, L"OsIndications", &b, &size); + err = efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndications", &old); if (!EFI_ERROR(err)) - osind |= (UINT64)*b; + new |= old; - err = efivar_set_raw(&global_guid, L"OsIndications", &osind, sizeof(UINT64), TRUE); + err = efivar_set_uint64_le(EFI_GLOBAL_GUID, L"OsIndications", new, TRUE); if (EFI_ERROR(err)) return err; @@ -2312,9 +2287,7 @@ static EFI_STATUS reboot_into_firmware(VOID) { } static VOID config_free(Config *config) { - UINTN i; - - for (i = 0; i < config->entry_count; i++) + for (UINTN i = 0; i < config->entry_count; i++) config_entry_free(config->entries[i]); FreePool(config->entries); FreePool(config->entry_default_pattern); @@ -2324,15 +2297,15 @@ static VOID config_free(Config *config) { static VOID config_write_entries_to_variable(Config *config) { _cleanup_freepool_ CHAR16 *buffer = NULL; - UINTN i, sz = 0; + UINTN sz = 0; CHAR16 *p; - for (i = 0; i < config->entry_count; i++) + for (UINTN i = 0; i < config->entry_count; i++) sz += StrLen(config->entries[i]->id) + 1; p = buffer = AllocatePool(sz * sizeof(CHAR16)); - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { UINTN l; l = StrLen(config->entries[i]->id) + 1; @@ -2342,7 +2315,7 @@ static VOID config_write_entries_to_variable(Config *config) { } /* Store the full list of discovered entries. */ - (void) efivar_set_raw(&loader_guid, L"LoaderEntries", buffer, (UINT8*) p - (UINT8*) buffer, FALSE); + (void) efivar_set_raw(LOADER_GUID, L"LoaderEntries", buffer, (UINT8*) p - (UINT8*) buffer, FALSE); } EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { @@ -2357,8 +2330,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 0; _cleanup_freepool_ CHAR16 *infostr = NULL, *typestr = NULL; - CHAR8 *b; - UINTN size; + UINT64 osind = 0; EFI_LOADED_IMAGE *loaded_image; EFI_FILE *root_dir; CHAR16 *loaded_image_path; @@ -2370,16 +2342,16 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { InitializeLib(image, sys_table); init_usec = time_usec(); - efivar_set_time_usec(L"LoaderTimeInitUSec", init_usec); - efivar_set(L"LoaderInfo", L"systemd-boot " GIT_VERSION, FALSE); + efivar_set_time_usec(LOADER_GUID, L"LoaderTimeInitUSec", init_usec); + efivar_set(LOADER_GUID, L"LoaderInfo", L"systemd-boot " GIT_VERSION, FALSE); infostr = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); - efivar_set(L"LoaderFirmwareInfo", infostr, FALSE); + efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", infostr, FALSE); typestr = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); - efivar_set(L"LoaderFirmwareType", typestr, FALSE); + efivar_set(LOADER_GUID, L"LoaderFirmwareType", typestr, FALSE); - (void) efivar_set_raw(&loader_guid, L"LoaderFeatures", &loader_features, sizeof(loader_features), FALSE); + (void) efivar_set_uint64_le(LOADER_GUID, L"LoaderFeatures", loader_features, FALSE); err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); @@ -2391,7 +2363,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { /* export the device path this image is started from */ if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS) - efivar_set(L"LoaderDevicePartUUID", uuid, FALSE); + efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, FALSE); root_dir = LibOpenRoot(loaded_image->DeviceHandle); if (!root_dir) { @@ -2411,7 +2383,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { /* the filesystem path to this image, to prevent adding ourselves to the menu */ loaded_image_path = DevicePathToStr(loaded_image->FilePath); - efivar_set(L"LoaderImageIdentifier", loaded_image_path, FALSE); + efivar_set(LOADER_GUID, L"LoaderImageIdentifier", loaded_image_path, FALSE); config_load_defaults(&config, root_dir); @@ -2436,15 +2408,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { L"auto-efi-default", '\0', L"EFI Default Loader", L"\\EFI\\Boot\\boot" EFI_MACHINE_TYPE_NAME ".efi"); config_entry_add_osx(&config); - if (config.auto_firmware && efivar_get_raw(&global_guid, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) { - UINT64 osind = (UINT64)*b; - + if (config.auto_firmware && efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &osind) == EFI_SUCCESS) { if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) config_entry_add_call(&config, L"auto-reboot-to-firmware-setup", L"Reboot Into Firmware Interface", reboot_into_firmware); - FreePool(b); } if (config.entry_count == 0) { @@ -2497,7 +2466,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { entry = config.entries[config.idx_default]; if (menu) { - efivar_set_time_usec(L"LoaderTimeMenuUSec", 0); + efivar_set_time_usec(LOADER_GUID, L"LoaderTimeMenuUSec", 0); uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x10000, 0, NULL); if (!menu_run(&config, &entry, loaded_image_path)) break; @@ -2512,7 +2481,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { config_entry_bump_counters(entry, root_dir); /* Export the selected boot entry to the system */ - (VOID) efivar_set(L"LoaderEntrySelected", entry->id, FALSE); + (VOID) efivar_set(LOADER_GUID, L"LoaderEntrySelected", entry->id, FALSE); /* Optionally, read a random seed off the ESP and pass it to the OS */ (VOID) process_random_seed(root_dir, config.random_seed_mode); diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c index 2dd4543d515..e3de27fee5c 100644 --- a/src/boot/efi/console.c +++ b/src/boot/efi/console.c @@ -9,8 +9,8 @@ #define SYSTEM_FONT_WIDTH 8 #define SYSTEM_FONT_HEIGHT 19 -#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ - { 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } } +#define EFI_SIMPLE_TEXT_INPUT_EX_GUID \ + &(EFI_GUID) { 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } } struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; @@ -67,7 +67,6 @@ typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL { } EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) { - EFI_GUID EfiSimpleTextInputExProtocolGuid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; static BOOLEAN checked; UINTN index; @@ -75,7 +74,7 @@ EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) { EFI_STATUS err; if (!checked) { - err = LibLocateProtocol(&EfiSimpleTextInputExProtocolGuid, (VOID **)&TextInputEx); + err = LibLocateProtocol(EFI_SIMPLE_TEXT_INPUT_EX_GUID, (VOID **)&TextInputEx); if (EFI_ERROR(err)) TextInputEx = NULL; diff --git a/src/boot/efi/crc32.c b/src/boot/efi/crc32.c index 5dfd3db265f..c9e5501ffa7 100644 --- a/src/boot/efi/crc32.c +++ b/src/boot/efi/crc32.c @@ -128,9 +128,8 @@ UINT32 crc32_exclude_offset( const UINT8 *p = buf; UINT32 crc = seed; - UINTN i; - for (i = 0; i < len; i++) { + for (UINTN i = 0; i < len; i++) { UINT8 x = *p++; if (i >= exclude_off && i < exclude_off + exclude_len) diff --git a/src/boot/efi/disk.c b/src/boot/efi/disk.c index cc752956c34..122f08dd5cd 100644 --- a/src/boot/efi/disk.c +++ b/src/boot/efi/disk.c @@ -13,10 +13,9 @@ EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[static 37]) { device_path = DevicePathFromHandle(handle); if (device_path) { _cleanup_freepool_ EFI_DEVICE_PATH *paths = NULL; - EFI_DEVICE_PATH *path; paths = UnpackDevicePath(device_path); - for (path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) { + for (EFI_DEVICE_PATH *path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) { HARDDRIVE_DEVICE_PATH *drive; if (DevicePathType(path) != MEDIA_DEVICE_PATH) diff --git a/src/boot/efi/graphics.c b/src/boot/efi/graphics.c index f36ecb35b5b..ddfe68cc774 100644 --- a/src/boot/efi/graphics.c +++ b/src/boot/efi/graphics.c @@ -10,9 +10,10 @@ #include "graphics.h" #include "util.h" +#define EFI_CONSOLE_CONTROL_GUID \ + &(EFI_GUID) { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } } + EFI_STATUS graphics_mode(BOOLEAN on) { - #define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \ - { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } }; struct _EFI_CONSOLE_CONTROL_PROTOCOL; @@ -45,7 +46,6 @@ EFI_STATUS graphics_mode(BOOLEAN on) { EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn; } EFI_CONSOLE_CONTROL_PROTOCOL; - EFI_GUID ConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; EFI_CONSOLE_CONTROL_SCREEN_MODE new; EFI_CONSOLE_CONTROL_SCREEN_MODE current; @@ -53,7 +53,7 @@ EFI_STATUS graphics_mode(BOOLEAN on) { BOOLEAN stdin_locked; EFI_STATUS err; - err = LibLocateProtocol(&ConsoleControlProtocolGuid, (VOID **)&ConsoleControl); + err = LibLocateProtocol(EFI_CONSOLE_CONTROL_GUID, (VOID **)&ConsoleControl); if (EFI_ERROR(err)) /* console control protocol is nonstandard and might not exist. */ return err == EFI_NOT_FOUND ? EFI_SUCCESS : err; diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index ff876a6c5b3..c272d085537 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -4,9 +4,11 @@ #include #include + #include "measure.h" -#define EFI_TCG_PROTOCOL_GUID { 0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd} } +#define EFI_TCG_GUID \ + &(EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } } typedef struct _TCG_VERSION { UINT8 Major; @@ -100,7 +102,8 @@ typedef struct _EFI_TCG { EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent; } EFI_TCG; -#define EFI_TCG2_PROTOCOL_GUID {0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }} +#define EFI_TCG2_GUID \ + &(EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } } typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL; @@ -238,7 +241,6 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 } static EFI_TCG * tcg1_interface_check(void) { - EFI_GUID tpm_guid = EFI_TCG_PROTOCOL_GUID; EFI_STATUS status; EFI_TCG *tcg; TCG_BOOT_SERVICE_CAPABILITY capability; @@ -246,7 +248,7 @@ static EFI_TCG * tcg1_interface_check(void) { EFI_PHYSICAL_ADDRESS event_log_location; EFI_PHYSICAL_ADDRESS event_log_last_entry; - status = LibLocateProtocol(&tpm_guid, (void **) &tcg); + status = LibLocateProtocol(EFI_TCG_GUID, (void **) &tcg); if (EFI_ERROR(status)) return NULL; @@ -267,12 +269,11 @@ static EFI_TCG * tcg1_interface_check(void) { } static EFI_TCG2 * tcg2_interface_check(void) { - EFI_GUID tpm2_guid = EFI_TCG2_PROTOCOL_GUID; EFI_STATUS status; EFI_TCG2 *tcg; EFI_TCG2_BOOT_SERVICE_CAPABILITY capability; - status = LibLocateProtocol(&tpm2_guid, (void **) &tcg); + status = LibLocateProtocol(EFI_TCG2_GUID, (void **) &tcg); if (EFI_ERROR(status)) return NULL; diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 24177f93840..177957e76ac 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -21,6 +21,7 @@ common_sources = ''' graphics.c measure.c pe.c + secure-boot.c util.c '''.split() @@ -133,8 +134,8 @@ endif if have_gnu_efi compile_args = ['-Wall', '-Wextra', - '-std=gnu90', - '-nostdinc', + '-std=gnu99', + '-nostdlib', '-fpic', '-fshort-wchar', '-ffreestanding', diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c index f99ecd0eda0..cb358380721 100644 --- a/src/boot/efi/pe.c +++ b/src/boot/efi/pe.c @@ -62,7 +62,6 @@ struct PeSectionHeader { EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) { struct DosFileHeader *dos; struct PeHeader *pe; - UINTN i; UINTN offset; dos = (struct DosFileHeader *)base; @@ -85,12 +84,11 @@ EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs offset = dos->ExeHeader + sizeof(*pe) + pe->FileHeader.SizeOfOptionalHeader; - for (i = 0; i < pe->FileHeader.NumberOfSections; i++) { + for (UINTN i = 0; i < pe->FileHeader.NumberOfSections; i++) { struct PeSectionHeader *sect; - UINTN j; sect = (struct PeSectionHeader *)&base[offset]; - for (j = 0; sections[j]; j++) { + for (UINTN j = 0; sections[j]; j++) { if (CompareMem(sect->Name, sections[j], strlena(sections[j])) != 0) continue; diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c index 895c85445ef..cd402526078 100644 --- a/src/boot/efi/random-seed.c +++ b/src/boot/efi/random-seed.c @@ -5,14 +5,14 @@ #include "missing_efi.h" #include "random-seed.h" +#include "secure-boot.h" #include "sha256.h" #include "util.h" -#include "shim.h" #define RANDOM_MAX_SIZE_MIN (32U) #define RANDOM_MAX_SIZE_MAX (32U*1024U) -static const EFI_GUID rng_protocol_guid = EFI_RNG_PROTOCOL_GUID; +#define EFI_RNG_GUID &(EFI_GUID) EFI_RNG_PROTOCOL_GUID /* SHA256 gives us 256/8=32 bytes */ #define HASH_VALUE_SIZE 32 @@ -24,7 +24,7 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) { /* Try to acquire the specified number of bytes from the UEFI RNG */ - err = LibLocateProtocol((EFI_GUID*) &rng_protocol_guid, (VOID**) &rng); + err = LibLocateProtocol(EFI_RNG_GUID, (VOID**) &rng); if (EFI_ERROR(err)) return err; if (!rng) @@ -86,7 +86,6 @@ static EFI_STATUS hash_many( VOID **ret) { _cleanup_freepool_ VOID *output = NULL; - UINTN i; /* Hashes the specified parameters in counter mode, generating n hash values, with the counter in the * range counter_start…counter_start+n-1. */ @@ -95,7 +94,7 @@ static EFI_STATUS hash_many( if (!output) return log_oom(); - for (i = 0; i < n; i++) + for (UINTN i = 0; i < n; i++) hash_once(old_seed, rng, size, system_token, system_token_size, counter_start + i, @@ -147,7 +146,7 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) { EFI_STATUS err; UINTN size; - err = efivar_get_raw(&loader_guid, L"LoaderSystemToken", &data, &size); + err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size); if (EFI_ERROR(err)) { if (err != EFI_NOT_FOUND) Print(L"Failed to read LoaderSystemToken EFI variable: %r", err); @@ -201,9 +200,7 @@ static VOID validate_sha256(void) { 0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1 }}, }; - UINTN i; - - for (i = 0; i < ELEMENTSOF(array); i++) { + for (UINTN i = 0; i < ELEMENTSOF(array); i++) { struct sha256_ctx hash; uint8_t result[HASH_VALUE_SIZE]; @@ -318,7 +315,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { } /* We are good to go */ - err = efivar_set_raw(&loader_guid, L"LoaderRandomSeed", for_kernel, size, FALSE); + err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, FALSE); if (EFI_ERROR(err)) { Print(L"Failed to write random seed to EFI variable: %r\n", err); return err; diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c new file mode 100644 index 00000000000..cacf3b6a7b8 --- /dev/null +++ b/src/boot/efi/secure-boot.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "secure-boot.h" +#include "util.h" + +BOOLEAN secure_boot_enabled(void) { + BOOLEAN secure; + EFI_STATUS err; + + err = efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SecureBoot", &secure); + + return !EFI_ERROR(err) && secure; +} diff --git a/src/boot/efi/secure-boot.h b/src/boot/efi/secure-boot.h new file mode 100644 index 00000000000..d06a7deaaa3 --- /dev/null +++ b/src/boot/efi/secure-boot.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +BOOLEAN secure_boot_enabled(void); diff --git a/src/boot/efi/sha256.c b/src/boot/efi/sha256.c index f23066d0acf..774f0eeb6c0 100644 --- a/src/boot/efi/sha256.c +++ b/src/boot/efi/sha256.c @@ -94,7 +94,7 @@ void sha256_init_ctx(struct sha256_ctx *ctx) { void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) { /* Take yet unprocessed bytes into account. */ UINT32 bytes = ctx->buflen; - UINTN pad, i; + UINTN pad; /* Now count remaining bytes. */ ctx->total64 += bytes; @@ -111,7 +111,7 @@ void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) { sha256_process_block (ctx->buffer, bytes + pad + 8, ctx); /* Put result from CTX in first 32 bytes following RESBUF. */ - for (i = 0; i < 8; ++i) + for (UINTN i = 0; i < 8; ++i) ((UINT32 *) resbuf)[i] = SWAP (ctx->H[i]); return resbuf; @@ -214,7 +214,6 @@ static void sha256_process_block(const void *buffer, UINTN len, struct sha256_ct UINT32 f_save = f; UINT32 g_save = g; UINT32 h_save = h; - UINTN t; /* Operators defined in FIPS 180-2:4.1.2. */ #define Ch(x, y, z) ((x & y) ^ (~x & z)) @@ -229,15 +228,15 @@ static void sha256_process_block(const void *buffer, UINTN len, struct sha256_ct #define CYCLIC(w, s) ((w >> s) | (w << (32 - s))) /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ - for (t = 0; t < 16; ++t) { + for (UINTN t = 0; t < 16; ++t) { W[t] = SWAP (*words); ++words; } - for (t = 16; t < 64; ++t) + for (UINTN t = 16; t < 64; ++t) W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ - for (t = 0; t < 64; ++t) { + for (UINTN t = 0; t < 64; ++t) { UINT32 T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; UINT32 T2 = S0 (a) + Maj (a, b, c); h = g; diff --git a/src/boot/efi/shim.c b/src/boot/efi/shim.c index 3dc10089c6c..48602627bb7 100644 --- a/src/boot/efi/shim.c +++ b/src/boot/efi/shim.c @@ -30,17 +30,18 @@ struct ShimLock { EFI_STATUS __sysv_abi__ (*read_header) (VOID *data, UINT32 datasize, VOID *context); }; -static const EFI_GUID simple_fs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL; -static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; - -static const EFI_GUID security_protocol_guid = { 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } }; -static const EFI_GUID security2_protocol_guid = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }; -static const EFI_GUID shim_lock_guid = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }; +#define SIMPLE_FS_GUID &(EFI_GUID) SIMPLE_FILE_SYSTEM_PROTOCOL +#define SECURITY_PROTOCOL_GUID \ + &(EFI_GUID) { 0xa46423e3, 0x4617, 0x49f1, { 0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } } +#define SECURITY_PROTOCOL2_GUID \ + &(EFI_GUID) { 0x94ab2f58, 0x1438, 0x4ef1, { 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } } +#define SHIM_LOCK_GUID \ + &(EFI_GUID) { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } } BOOLEAN shim_loaded(void) { struct ShimLock *shim_lock; - return uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS; + return uefi_call_wrapper(BS->LocateProtocol, 3, SHIM_LOCK_GUID, NULL, (VOID**) &shim_lock) == EFI_SUCCESS; } static BOOLEAN shim_validate(VOID *data, UINT32 size) { @@ -49,7 +50,7 @@ static BOOLEAN shim_validate(VOID *data, UINT32 size) { if (!data) return FALSE; - if (uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) != EFI_SUCCESS) + if (uefi_call_wrapper(BS->LocateProtocol, 3, SHIM_LOCK_GUID, NULL, (VOID**) &shim_lock) != EFI_SUCCESS) return FALSE; if (!shim_lock) @@ -58,16 +59,6 @@ static BOOLEAN shim_validate(VOID *data, UINT32 size) { return shim_lock->shim_verify(data, size) == EFI_SUCCESS; } -BOOLEAN secure_boot_enabled(void) { - _cleanup_freepool_ CHAR8 *b = NULL; - UINTN size; - - if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) - return *b > 0; - - return FALSE; -} - /* * See the UEFI Platform Initialization manual (Vol2: DXE) for this */ @@ -157,7 +148,7 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT dev_path = DuplicateDevicePath((EFI_DEVICE_PATH*) device_path_const); - status = uefi_call_wrapper(BS->LocateDevicePath, 3, (EFI_GUID*) &simple_fs_guid, &dev_path, &h); + status = uefi_call_wrapper(BS->LocateDevicePath, 3, SIMPLE_FS_GUID, &dev_path, &h); if (status != EFI_SUCCESS) return status; @@ -191,9 +182,9 @@ EFI_STATUS security_policy_install(void) { * to fail, since SECURITY2 was introduced in PI 1.2.1. * Use security2_protocol == NULL as indicator. */ - uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security2_protocol_guid, NULL, (VOID**) &security2_protocol); + uefi_call_wrapper(BS->LocateProtocol, 3, SECURITY_PROTOCOL2_GUID, NULL, (VOID**) &security2_protocol); - status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security_protocol_guid, NULL, (VOID**) &security_protocol); + status = uefi_call_wrapper(BS->LocateProtocol, 3, SECURITY_PROTOCOL_GUID, NULL, (VOID**) &security_protocol); /* This one is mandatory, so there's a serious problem */ if (status != EFI_SUCCESS) return status; diff --git a/src/boot/efi/shim.h b/src/boot/efi/shim.h index e24fcdac540..d682994b9e5 100644 --- a/src/boot/efi/shim.h +++ b/src/boot/efi/shim.h @@ -13,6 +13,4 @@ BOOLEAN shim_loaded(void); -BOOLEAN secure_boot_enabled(void); - EFI_STATUS security_policy_install(void); diff --git a/src/boot/efi/splash.c b/src/boot/efi/splash.c index 552c45cff49..5e085ec45c2 100644 --- a/src/boot/efi/splash.c +++ b/src/boot/efi/splash.c @@ -151,22 +151,18 @@ static EFI_STATUS bmp_to_blt(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf, struct bmp_dib *dib, struct bmp_map *map, UINT8 *pixmap) { UINT8 *in; - UINTN y; /* transform and copy pixels */ in = pixmap; - for (y = 0; y < dib->y; y++) { + for (UINTN y = 0; y < dib->y; y++) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL *out; UINTN row_size; - UINTN x; out = &buf[(dib->y - y - 1) * dib->x]; - for (x = 0; x < dib->x; x++, in++, out++) { + for (UINTN x = 0; x < dib->x; x++, in++, out++) { switch (dib->depth) { case 1: { - UINTN i; - - for (i = 0; i < 8 && x < dib->x; i++) { + for (UINTN i = 0; i < 8 && x < dib->x; i++) { out->Red = map[((*in) >> (7 - i)) & 1].red; out->Green = map[((*in) >> (7 - i)) & 1].green; out->Blue = map[((*in) >> (7 - i)) & 1].blue; diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index a09f47c7119..0bef6b1c44f 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -8,19 +8,15 @@ #include "linux.h" #include "measure.h" #include "pe.h" +#include "secure-boot.h" #include "splash.h" #include "util.h" /* magic string to find in the binary image */ static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####"; -static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; - EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { EFI_LOADED_IMAGE *loaded_image; - _cleanup_freepool_ CHAR8 *b = NULL; - UINTN size; - BOOLEAN secure = FALSE; CHAR8 *sections[] = { (CHAR8 *)".cmdline", (CHAR8 *)".linux", @@ -46,10 +42,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { return err; } - if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) - if (*b > 0) - secure = TRUE; - err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs); if (EFI_ERROR(err)) { Print(L"Unable to locate embedded .linux section: %r ", err); @@ -58,20 +50,20 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { } if (szs[0] > 0) - cmdline = (CHAR8 *)(loaded_image->ImageBase + addrs[0]); + cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0]; cmdline_len = szs[0]; /* 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 || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 && *(CHAR16 *)loaded_image->LoadOptions > 0x1F) { + if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 && + *(CHAR16 *) loaded_image->LoadOptions > 0x1F) { CHAR16 *options; CHAR8 *line; - UINTN i; options = (CHAR16 *)loaded_image->LoadOptions; cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8); line = AllocatePool(cmdline_len); - for (i = 0; i < cmdline_len; i++) + for (UINTN i = 0; i < cmdline_len; i++) line[i] = options[i]; cmdline = line; @@ -88,37 +80,37 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { } /* Export the device path this image is started from, if it's not set yet */ - if (efivar_get_raw(&loader_guid, L"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS) + if (efivar_get_raw(LOADER_GUID, L"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS) if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS) - efivar_set(L"LoaderDevicePartUUID", uuid, FALSE); + efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, FALSE); /* if LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from UEFI */ - if (efivar_get_raw(&loader_guid, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) { + if (efivar_get_raw(LOADER_GUID, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) { _cleanup_freepool_ CHAR16 *s; s = DevicePathToStr(loaded_image->FilePath); - efivar_set(L"LoaderImageIdentifier", s, FALSE); + efivar_set(LOADER_GUID, L"LoaderImageIdentifier", s, FALSE); } /* if LoaderFirmwareInfo is not set, let's set it */ - if (efivar_get_raw(&loader_guid, L"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) { + if (efivar_get_raw(LOADER_GUID, L"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) { _cleanup_freepool_ CHAR16 *s; s = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); - efivar_set(L"LoaderFirmwareInfo", s, FALSE); + efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", s, FALSE); } /* ditto for LoaderFirmwareType */ - if (efivar_get_raw(&loader_guid, L"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) { + if (efivar_get_raw(LOADER_GUID, L"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) { _cleanup_freepool_ CHAR16 *s; s = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); - efivar_set(L"LoaderFirmwareType", s, FALSE); + efivar_set(LOADER_GUID, L"LoaderFirmwareType", s, FALSE); } /* add StubInfo */ - if (efivar_get_raw(&loader_guid, L"StubInfo", NULL, NULL) != EFI_SUCCESS) - efivar_set(L"StubInfo", L"systemd-stub " GIT_VERSION, FALSE); + if (efivar_get_raw(LOADER_GUID, L"StubInfo", NULL, NULL) != EFI_SUCCESS) + efivar_set(LOADER_GUID, L"StubInfo", L"systemd-stub " GIT_VERSION, FALSE); if (szs[3] > 0) graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL); diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 2712c2d3f0e..8adf3f5fe45 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -5,13 +5,6 @@ #include "util.h" -/* - * Allocated random UUID, intended to be shared across tools that implement - * the (ESP)\loader\entries\-.conf convention and the - * associated EFI variables. - */ -const EFI_GUID loader_guid = { 0x4a67b082, 0x0a4c, 0x41cf, {0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f} }; - #ifdef __x86_64__ UINT64 ticks_read(VOID) { UINT64 a, d; @@ -92,24 +85,51 @@ EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID return uefi_call_wrapper(RT->SetVariable, 5, (CHAR16*) name, (EFI_GUID *)vendor, flags, size, (VOID*) buf); } -EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent) { - return efivar_set_raw(&loader_guid, name, value, value ? (StrLen(value)+1) * sizeof(CHAR16) : 0, persistent); +EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent) { + return efivar_set_raw( + vendor, name, value, value ? (StrLen(value) + 1) * sizeof(CHAR16) : 0, persistent); } -EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent) { +EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent) { CHAR16 str[32]; SPrint(str, 32, L"%u", i); - return efivar_set(name, str, persistent); + return efivar_set(vendor, name, str, persistent); } -EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value) { +EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, CHAR16 *name, UINT32 value, BOOLEAN persistent) { + UINT8 buf[4]; + + buf[0] = (UINT8)(value >> 0U & 0xFF); + buf[1] = (UINT8)(value >> 8U & 0xFF); + buf[2] = (UINT8)(value >> 16U & 0xFF); + buf[3] = (UINT8)(value >> 24U & 0xFF); + + return efivar_set_raw(vendor, name, buf, sizeof(buf), persistent); +} + +EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, CHAR16 *name, UINT64 value, BOOLEAN persistent) { + UINT8 buf[8]; + + buf[0] = (UINT8)(value >> 0U & 0xFF); + buf[1] = (UINT8)(value >> 8U & 0xFF); + buf[2] = (UINT8)(value >> 16U & 0xFF); + buf[3] = (UINT8)(value >> 24U & 0xFF); + buf[4] = (UINT8)(value >> 32U & 0xFF); + buf[5] = (UINT8)(value >> 40U & 0xFF); + buf[6] = (UINT8)(value >> 48U & 0xFF); + buf[7] = (UINT8)(value >> 56U & 0xFF); + + return efivar_set_raw(vendor, name, buf, sizeof(buf), persistent); +} + +EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value) { _cleanup_freepool_ CHAR8 *buf = NULL; EFI_STATUS err; CHAR16 *val; UINTN size; - err = efivar_get_raw(&loader_guid, name, &buf, &size); + err = efivar_get_raw(vendor, name, &buf, &size); if (EFI_ERROR(err)) return err; @@ -138,17 +158,52 @@ EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value) { return EFI_SUCCESS; } -EFI_STATUS efivar_get_int(const CHAR16 *name, UINTN *i) { +EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i) { _cleanup_freepool_ CHAR16 *val = NULL; EFI_STATUS err; - err = efivar_get(name, &val); + err = efivar_get(vendor, name, &val); if (!EFI_ERROR(err) && i) *i = Atoi(val); return err; } +EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret) { + _cleanup_freepool_ CHAR8 *buf = NULL; + UINTN size; + EFI_STATUS err; + + err = efivar_get_raw(vendor, name, &buf, &size); + if (!EFI_ERROR(err) && ret) { + if (size != sizeof(UINT32)) + return EFI_BUFFER_TOO_SMALL; + + *ret = (UINT32) buf[0] << 0U | (UINT32) buf[1] << 8U | (UINT32) buf[2] << 16U | + (UINT32) buf[3] << 24U; + } + + return err; +} + +EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret) { + _cleanup_freepool_ CHAR8 *buf = NULL; + UINTN size; + EFI_STATUS err; + + err = efivar_get_raw(vendor, name, &buf, &size); + if (!EFI_ERROR(err) && ret) { + if (size != sizeof(UINT64)) + return EFI_BUFFER_TOO_SMALL; + + *ret = (UINT64) buf[0] << 0U | (UINT64) buf[1] << 8U | (UINT64) buf[2] << 16U | + (UINT64) buf[3] << 24U | (UINT64) buf[4] << 32U | (UINT64) buf[5] << 40U | + (UINT64) buf[6] << 48U | (UINT64) buf[7] << 56U; + } + + return err; +} + EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size) { _cleanup_freepool_ CHAR8 *buf = NULL; UINTN l; @@ -172,7 +227,19 @@ EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **bu return err; } -VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec) { +EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret) { + _cleanup_freepool_ CHAR8 *b = NULL; + UINTN size; + EFI_STATUS err; + + err = efivar_get_raw(vendor, name, &b, &size); + if (!EFI_ERROR(err)) + *ret = *b > 0; + + return err; +} + +VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec) { CHAR16 str[32]; if (usec == 0) @@ -181,13 +248,12 @@ VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec) { return; SPrint(str, 32, L"%ld", usec); - efivar_set(name, str, FALSE); + efivar_set(vendor, name, str, FALSE); } static INTN utf8_to_16(CHAR8 *stra, CHAR16 *c) { CHAR16 unichar; UINTN len; - UINTN i; if (!(stra[0] & 0x80)) len = 1; @@ -225,7 +291,7 @@ static INTN utf8_to_16(CHAR8 *stra, CHAR16 *c) { break; } - for (i = 1; i < len; i++) { + for (UINTN i = 1; i < len; i++) { if ((stra[i] & 0xc0) != 0x80) return -1; unichar <<= 6; @@ -309,6 +375,62 @@ CHAR8 *strchra(CHAR8 *s, CHAR8 c) { return NULL; } +const CHAR16 *startswith(const CHAR16 *s, const CHAR16 *prefix) { + UINTN l; + + l = StrLen(prefix); + if (StrnCmp(s, prefix, l) == 0) + return s + l; + + return NULL; +} + +const CHAR16 *endswith(const CHAR16 *s, const CHAR16 *postfix) { + UINTN sl, pl; + + sl = StrLen(s); + pl = StrLen(postfix); + + if (pl == 0) + return s + sl; + + if (sl < pl) + return NULL; + + if (StrnCmp(s + sl - pl, postfix, pl) != 0) + return NULL; + + return s + sl - pl; +} + +const CHAR16 *startswith_no_case(const CHAR16 *s, const CHAR16 *prefix) { + UINTN l; + + l = StrLen(prefix); + if (StriCmp(s, prefix) == 0) + return s + l; + + return NULL; +} + +const CHAR16 *endswith_no_case(const CHAR16 *s, const CHAR16 *postfix) { + UINTN sl, pl; + + sl = StrLen(s); + pl = StrLen(postfix); + + if (pl == 0) + return s + sl; + + if (sl < pl) + return NULL; + + if (StriCmp(s + sl - pl, postfix) != 0) + return NULL; + + return s + sl - pl; +} + EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **ret, UINTN *ret_size) { _cleanup_(FileHandleClosep) EFI_FILE_HANDLE handle = NULL; _cleanup_freepool_ CHAR8 *buf = NULL; diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index 916519cdf83..f2be857d427 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -21,19 +21,30 @@ UINT64 ticks_read(void); UINT64 ticks_freq(void); UINT64 time_usec(void); -EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent); +EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent); EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, BOOLEAN persistent); -EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent); -VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec); +EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent); +EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, CHAR16 *NAME, UINT32 value, BOOLEAN persistent); +EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, CHAR16 *name, UINT64 value, BOOLEAN persistent); +VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec); -EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value); +EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value); EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size); -EFI_STATUS efivar_get_int(const CHAR16 *name, UINTN *i); +EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i); +EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret); +EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret); +EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret); CHAR8 *strchra(CHAR8 *s, CHAR8 c); CHAR16 *stra_to_path(CHAR8 *stra); CHAR16 *stra_to_str(CHAR8 *stra); +const CHAR16 *startswith(const CHAR16 *s, const CHAR16 *prefix); +const CHAR16 *endswith(const CHAR16 *s, const CHAR16 *postfix); + +const CHAR16 *startswith_no_case(const CHAR16 *s, const CHAR16 *prefix); +const CHAR16 *endswith_no_case(const CHAR16 *s, const CHAR16 *postfix); + EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size); static inline void FreePoolp(void *p) { @@ -55,7 +66,14 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) { uefi_call_wrapper((*handle)->Close, 1, *handle); } -extern const EFI_GUID loader_guid; +/* + * Allocated random UUID, intended to be shared across tools that implement + * the (ESP)\loader\entries\-.conf convention and the + * associated EFI variables. + */ +#define LOADER_GUID \ + &(const EFI_GUID) { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } } +#define EFI_GLOBAL_GUID &(const EFI_GUID) EFI_GLOBAL_VARIABLE #define UINTN_MAX (~(UINTN)0) #define INTN_MAX ((INTN)(UINTN_MAX>>1))