diff options
-rw-r--r-- | cmd/Kconfig | 8 | ||||
-rw-r--r-- | cmd/Makefile | 1 | ||||
-rw-r--r-- | cmd/fitupd.c | 30 | ||||
-rw-r--r-- | cmd/lsblk.c | 2 | ||||
-rw-r--r-- | cmd/nvedit.c | 7 | ||||
-rw-r--r-- | cmd/nvedit_efi.c | 106 | ||||
-rw-r--r-- | configs/sandbox_defconfig | 1 | ||||
-rw-r--r-- | doc/README.dfutftp | 2 | ||||
-rw-r--r-- | doc/README.update | 5 | ||||
-rw-r--r-- | doc/uefi/uefi.rst | 9 | ||||
-rw-r--r-- | include/asm-generic/sections.h | 2 | ||||
-rw-r--r-- | include/efi_variable.h | 40 | ||||
-rw-r--r-- | include/mm_communication.h | 43 | ||||
-rw-r--r-- | lib/efi_loader/Kconfig | 53 | ||||
-rw-r--r-- | lib/efi_loader/Makefile | 6 | ||||
-rw-r--r-- | lib/efi_loader/efi_var_common.c | 182 | ||||
-rw-r--r-- | lib/efi_loader/efi_var_file.c | 8 | ||||
-rw-r--r-- | lib/efi_loader/efi_var_seed.S | 17 | ||||
-rw-r--r-- | lib/efi_loader/efi_variable.c | 203 | ||||
-rw-r--r-- | lib/efi_loader/efi_variable_tee.c | 150 | ||||
-rw-r--r-- | test/py/tests/test_efi_loader.py | 16 |
21 files changed, 552 insertions, 339 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig index 846c905c9c..bfe6c163dc 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -378,6 +378,7 @@ config CMD_BOOTEFI_HELLO_COMPILE config CMD_BOOTEFI_HELLO bool "Allow booting a standard EFI hello world for testing" depends on CMD_BOOTEFI_HELLO_COMPILE + default y if CMD_BOOTEFI_SELFTEST help This adds a standard EFI hello world application to U-Boot so that it can be used with the 'bootefi hello' command. This is useful @@ -489,13 +490,6 @@ config CMD_SPL_WRITE_SIZE flash used by Falcon-mode boot. See the documentation until CMD_SPL for detail. -config CMD_FITUPD - bool "fitImage update command" - depends on UPDATE_TFTP - help - Implements the 'fitupd' command, which allows to automatically - store software updates present on a TFTP server in NOR Flash - config CMD_THOR_DOWNLOAD bool "thor - TIZEN 'thor' download" select DFU diff --git a/cmd/Makefile b/cmd/Makefile index dc412d1106..7952138dc2 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -62,7 +62,6 @@ obj-$(CONFIG_CMD_EXT4) += ext4.o obj-$(CONFIG_CMD_EXT2) += ext2.o obj-$(CONFIG_CMD_FAT) += fat.o obj-$(CONFIG_CMD_FDT) += fdt.o -obj-$(CONFIG_CMD_FITUPD) += fitupd.o obj-$(CONFIG_CMD_FLASH) += flash.o obj-$(CONFIG_CMD_FPGA) += fpga.o obj-$(CONFIG_CMD_FPGAD) += fpgad.o diff --git a/cmd/fitupd.c b/cmd/fitupd.c deleted file mode 100644 index 0f490c58fc..0000000000 --- a/cmd/fitupd.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2011 - * Andreas Pretzsch, carpe noctem engineering, apr@cn-eng.de - */ - -#include <common.h> -#include <command.h> -#include <net.h> - -static int do_fitupd(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - ulong addr = 0UL; - - if (argc > 2) - return CMD_RET_USAGE; - - if (argc == 2) - addr = simple_strtoul(argv[1], NULL, 16); - - return update_tftp(addr, NULL, NULL); -} - -U_BOOT_CMD(fitupd, 2, 0, do_fitupd, - "update from FIT image", - "[addr]\n" - "\t- run update from FIT image at addr\n" - "\t or from tftp 'updatefile'" -); diff --git a/cmd/lsblk.c b/cmd/lsblk.c index ece8bbf108..653dffce04 100644 --- a/cmd/lsblk.c +++ b/cmd/lsblk.c @@ -5,6 +5,8 @@ */ #include <common.h> +#include <blk.h> +#include <command.h> #include <dm.h> static int do_lsblk(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 49338b4d36..ca0be92fc3 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -1410,7 +1410,7 @@ static char env_help_text[] = #endif "env print [-a | name ...] - print environment\n" #if defined(CONFIG_CMD_NVEDIT_EFI) - "env print -e [-guid guid|-all][-n] [name ...] - print UEFI environment\n" + "env print -e [-guid guid] [-n] [name ...] - print UEFI environment\n" #endif #if defined(CONFIG_CMD_RUN) "env run var [...] - run commands in an environment variable\n" @@ -1452,8 +1452,9 @@ U_BOOT_CMD_COMPLETE( "print environment variables", "[-a]\n - print [all] values of all environment variables\n" #if defined(CONFIG_CMD_NVEDIT_EFI) - "printenv -e [-guid guid|-all][-n] [name ...]\n" + "printenv -e [-guid guid][-n] [name ...]\n" " - print UEFI variable 'name' or all the variables\n" + " \"-guid\": GUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n" " \"-n\": suppress dumping variable's value\n" #endif "printenv name ...\n" @@ -1487,7 +1488,7 @@ U_BOOT_CMD_COMPLETE( "-e [-guid guid][-nv][-bs][-rt][-at][-a][-v]\n" " [-i addr,size name], or [name [value ...]]\n" " - set UEFI variable 'name' to 'value' ...'\n" - " \"-guid\": set vendor guid\n" + " \"-guid\": GUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n" " \"-nv\": set non-volatile attribute\n" " \"-bs\": set boot-service attribute\n" " \"-rt\": set runtime attribute\n" diff --git a/cmd/nvedit_efi.c b/cmd/nvedit_efi.c index 3f61d5d6cc..8e31f43e1f 100644 --- a/cmd/nvedit_efi.c +++ b/cmd/nvedit_efi.c @@ -52,8 +52,7 @@ static const struct { {EFI_CERT_TYPE_PKCS7_GUID, "EFI_CERT_TYPE_PKCS7_GUID"}, }; -/* "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */ -static char unknown_guid[37]; +static const char unknown_guid[] = ""; /** * efi_guid_to_str() - convert guid to readable name @@ -71,9 +70,6 @@ static const char *efi_guid_to_str(const efi_guid_t *guid) if (!guidcmp(guid, &efi_guid_text[i].guid)) return efi_guid_text[i].text; - uuid_bin_to_str((unsigned char *)guid->b, unknown_guid, - UUID_STR_FORMAT_GUID); - return unknown_guid; } @@ -115,7 +111,7 @@ static void efi_dump_single_var(u16 *name, const efi_guid_t *guid, bool verbose) goto out; rtc_to_tm(time, &tm); - printf("%ls:\n %s:\n", name, efi_guid_to_str(guid)); + printf("%ls:\n %pUl %s\n", name, guid, efi_guid_to_str(guid)); if (attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) printf(" %04d-%02d-%02d %02d:%02d:%02d\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); @@ -136,50 +132,6 @@ out: free(data); } -/** - * efi_dump_vars() - show information about named UEFI variables - * - * @argc: Number of arguments (variables) - * @argv: Argument (variable name) array - * @verbose: if true, dump data - * Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE - * - * Show information encoded in named UEFI variables - */ -static int efi_dump_vars(int argc, char *const argv[], - const efi_guid_t *guid, bool verbose) -{ - u16 *var_name16, *p; - efi_uintn_t buf_size, size; - - buf_size = 128; - var_name16 = malloc(buf_size); - if (!var_name16) - return CMD_RET_FAILURE; - - for (; argc > 0; argc--, argv++) { - size = (utf8_utf16_strlen(argv[0]) + 1) * sizeof(u16); - if (buf_size < size) { - buf_size = size; - p = realloc(var_name16, buf_size); - if (!p) { - free(var_name16); - return CMD_RET_FAILURE; - } - var_name16 = p; - } - - p = var_name16; - utf8_utf16_strcpy(&p, argv[0]); - - efi_dump_single_var(var_name16, guid, verbose); - } - - free(var_name16); - - return CMD_RET_SUCCESS; -} - static bool match_name(int argc, char *const argv[], u16 *var_name16) { char *buf, *p; @@ -225,10 +177,7 @@ static int efi_dump_var_all(int argc, char *const argv[], efi_uintn_t buf_size, size; efi_guid_t guid; efi_status_t ret; - - if (argc && guid_p) - /* simplified case */ - return efi_dump_vars(argc, argv, guid_p, verbose); + bool match = false; buf_size = 128; var_name16 = malloc(buf_size); @@ -259,13 +208,18 @@ static int efi_dump_var_all(int argc, char *const argv[], return CMD_RET_FAILURE; } - if ((!guid_p || !guidcmp(guid_p, &guid)) && - (!argc || match_name(argc, argv, var_name16))) + if (guid_p && guidcmp(guid_p, &guid)) + continue; + if (!argc || match_name(argc, argv, var_name16)) { + match = true; efi_dump_single_var(var_name16, &guid, verbose); + } } - free(var_name16); + if (!match && argc == 1) + printf("Error: \"%s\" not defined\n", argv[0]); + return CMD_RET_SUCCESS; } @@ -286,9 +240,8 @@ static int efi_dump_var_all(int argc, char *const argv[], int do_env_print_efi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - efi_guid_t guid; - const efi_guid_t *guid_p; - bool default_guid, guid_any, verbose; + const efi_guid_t *guid_p = NULL; + bool verbose = true; efi_status_t ret; /* Initialize EFI drivers */ @@ -299,31 +252,18 @@ int do_env_print_efi(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } - default_guid = true; - guid_any = false; - verbose = true; for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { if (!strcmp(argv[0], "-guid")) { - if (argc == 1) - return CMD_RET_USAGE; + efi_guid_t guid; - /* -a already specified */ - if (!default_guid && guid_any) + if (argc == 1) return CMD_RET_USAGE; - argc--; argv++; if (uuid_str_to_bin(argv[0], guid.b, UUID_STR_FORMAT_GUID)) return CMD_RET_USAGE; - default_guid = false; - } else if (!strcmp(argv[0], "-all")) { - /* -guid already specified */ - if (!default_guid && !guid_any) - return CMD_RET_USAGE; - - guid_any = true; - default_guid = false; + guid_p = (const efi_guid_t *)guid.b; } else if (!strcmp(argv[0], "-n")) { verbose = false; } else { @@ -331,13 +271,6 @@ int do_env_print_efi(struct cmd_tbl *cmdtp, int flag, int argc, } } - if (guid_any) - guid_p = NULL; - else if (default_guid) - guid_p = &efi_global_variable_guid; - else - guid_p = (const efi_guid_t *)guid.b; - /* enumerate and show all UEFI variables */ return efi_dump_var_all(argc, argv, guid_p, verbose); } @@ -518,8 +451,7 @@ int do_env_set_efi(struct cmd_tbl *cmdtp, int flag, int argc, argv++; if (uuid_str_to_bin(argv[0], guid.b, UUID_STR_FORMAT_GUID)) { - printf("## Guid not specified or in XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format\n"); - return CMD_RET_FAILURE; + return CMD_RET_USAGE; } default_guid = false; } else if (!strcmp(argv[0], "-bs")) { @@ -567,8 +499,8 @@ int do_env_set_efi(struct cmd_tbl *cmdtp, int flag, int argc, } if (verbose) { - printf("GUID: %s\n", efi_guid_to_str((const efi_guid_t *) - &guid)); + printf("GUID: %pUl %s\n", &guid, + efi_guid_to_str((const efi_guid_t *)&guid)); printf("Attributes: 0x%x\n", attributes); } diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 9b74e404bb..d43d78df6f 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -48,6 +48,7 @@ CONFIG_CMD_GPT=y CONFIG_CMD_GPT_RENAME=y CONFIG_CMD_IDE=y CONFIG_CMD_I2C=y +CONFIG_CMD_LSBLK=y CONFIG_CMD_OSD=y CONFIG_CMD_PCI=y CONFIG_CMD_READ=y diff --git a/doc/README.dfutftp b/doc/README.dfutftp index 127d2d6abc..a3341bbb61 100644 --- a/doc/README.dfutftp +++ b/doc/README.dfutftp @@ -42,8 +42,6 @@ for USB based DFU (CONFIG_DFU_*) and DFU TFTP update The "dfu" command has been extended to support transfer via TFTP - one needs to type for example "dfu tftp 0 mmc 0" -This feature does not depend on "fitupd" command enabled. - As of this writing (SHA1:8d77576371381ade83de475bb639949b44941e8c v2015.10-rc2) the update.c code is not enabled (CONFIG_UPDATE_TFTP) by any board in the contemporary u-boot tree. diff --git a/doc/README.update b/doc/README.update index d37f2c4d4a..bf4379279e 100644 --- a/doc/README.update +++ b/doc/README.update @@ -51,11 +51,6 @@ the mkimage tool. dtc tool with support for binary includes, e.g. in version to be prepared. Refer to the doc/uImage.FIT/ directory for more details on FIT images. -This mechanism can be also triggered by the command "fitupd". -If an optional, non-zero address is provided as argument, the TFTP transfer -is skipped and the image at this address is used. -The fitupd command is enabled by CONFIG_CMD_FITUPD. - Example .its files ------------------ diff --git a/doc/uefi/uefi.rst b/doc/uefi/uefi.rst index 03d6fd0c6a..a72e729cc8 100644 --- a/doc/uefi/uefi.rst +++ b/doc/uefi/uefi.rst @@ -188,6 +188,15 @@ on the sandbox cd <U-Boot source directory> pytest.py test/py/tests/test_efi_secboot/test_signed.py --bd sandbox +UEFI binaries may be signed by Microsoft using the following certificates: + +* KEK: Microsoft Corporation KEK CA 2011 + http://go.microsoft.com/fwlink/?LinkId=321185. +* db: Microsoft Windows Production PCA 2011 + http://go.microsoft.com/fwlink/p/?linkid=321192. +* db: Microsoft Corporation UEFI CA 2011 + http://go.microsoft.com/fwlink/p/?linkid=321194. + Using OP-TEE for EFI variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 17a31ec788..0577238d60 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -25,6 +25,8 @@ extern char __initdata_begin[], __initdata_end[]; extern char __start_rodata[], __end_rodata[]; extern char __efi_helloworld_begin[]; extern char __efi_helloworld_end[]; +extern char __efi_var_file_begin[]; +extern char __efi_var_file_end[]; /* Start and end of .ctors section - used for constructor calls. */ extern char __ctors_start[], __ctors_end[]; diff --git a/include/efi_variable.h b/include/efi_variable.h index bc5985cfdb..2c629e4dca 100644 --- a/include/efi_variable.h +++ b/include/efi_variable.h @@ -10,6 +10,16 @@ #define EFI_VARIABLE_READ_ONLY BIT(31) +enum efi_auth_var_type { + EFI_AUTH_VAR_NONE = 0, + EFI_AUTH_VAR_PK, + EFI_AUTH_VAR_KEK, + EFI_AUTH_VAR_DB, + EFI_AUTH_VAR_DBX, + EFI_AUTH_VAR_DBT, + EFI_AUTH_VAR_DBR, +}; + /** * efi_get_variable() - retrieve value of a UEFI variable * @@ -83,6 +93,10 @@ efi_status_t efi_query_variable_info_int(u32 attributes, #define EFI_VAR_BUF_SIZE 0x4000 +/* + * This constant identifies the file format for storing UEFI variables in + * struct efi_var_file. + */ #define EFI_VAR_FILE_MAGIC 0x0161566966456255 /* UbEfiVa, version 1 */ /** @@ -106,7 +120,7 @@ struct efi_var_entry { * struct efi_var_file - file for storing UEFI variables * * @reserved: unused, may be overwritten by memory probing - * @magic: identifies file format + * @magic: identifies file format, takes value %EFI_VAR_FILE_MAGIC * @length: length including header * @crc32: CRC32 without header * @var: variables @@ -129,6 +143,14 @@ struct efi_var_file { efi_status_t efi_var_to_file(void); /** + * efi_var_restore() - restore EFI variables from buffer + * + * @buf: buffer + * Return: status code + */ +efi_status_t efi_var_restore(struct efi_var_file *buf); + +/** * efi_var_from_file() - read variables from file * * File ubootefi.var is read from the EFI system partitions and the variables @@ -195,4 +217,20 @@ efi_status_t efi_var_mem_ins(u16 *variable_name, */ u64 efi_var_mem_free(void); +/** + * efi_init_secure_state - initialize secure boot state + * + * Return: status code + */ +efi_status_t efi_init_secure_state(void); + +/** + * efi_auth_var_get_type() - convert variable name and guid to enum + * + * @name: name of UEFI variable + * @guid: guid of UEFI variable + * Return: identifier for authentication related variables + */ +enum efi_auth_var_type efi_auth_var_get_type(u16 *name, const efi_guid_t *guid); + #endif diff --git a/include/mm_communication.h b/include/mm_communication.h index 193c4d1578..f9c05bb7f1 100644 --- a/include/mm_communication.h +++ b/include/mm_communication.h @@ -205,4 +205,47 @@ struct smm_variable_query_info { u32 attr; }; +#define VAR_CHECK_VARIABLE_PROPERTY_REVISION 0x0001 +#define VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY BIT(0) +/** + * struct var_check_property - Used to store variable properties in StMM + * + * @revision: magic revision number for variable property checking + * @property: properties mask for the variable used in StMM. + * Currently RO flag is supported + * @attributes: variable attributes used in StMM checking when properties + * for a variable are enabled + * @minsize: minimum allowed size for variable payload checked against + * smm_variable_access->datasize in StMM + * @maxsize: maximum allowed size for variable payload checked against + * smm_variable_access->datasize in StMM + * + * Defined in EDK2 as VAR_CHECK_VARIABLE_PROPERTY. + */ +struct var_check_property { + u16 revision; + u16 property; + u32 attributes; + efi_uintn_t minsize; + efi_uintn_t maxsize; +}; + +/** + * struct smm_variable_var_check_property - Used to communicate variable + * properties with StMM + * + * @guid: vendor GUID + * @name_size: size of EFI name + * @property: variable properties struct + * @name: variable name + * + * Defined in EDK2 as SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY. + */ +struct smm_variable_var_check_property { + efi_guid_t guid; + efi_uintn_t name_size; + struct var_check_property property; + u16 name[]; +}; + #endif /* _MM_COMMUNICATION_H_ */ diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 4324694d48..6017ffe9a6 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -27,13 +27,51 @@ config EFI_LOADER if EFI_LOADER +choice + prompt "Store for non-volatile UEFI variables" + default EFI_VARIABLE_FILE_STORE + help + Select where non-volatile UEFI variables shall be stored. + config EFI_VARIABLE_FILE_STORE bool "Store non-volatile UEFI variables as file" depends on FAT_WRITE - default y help - Select tis option if you want non-volatile UEFI variables to be stored - as file /ubootefi.var on the EFI system partition. + Select this option if you want non-volatile UEFI variables to be + stored as file /ubootefi.var on the EFI system partition. + +config EFI_MM_COMM_TEE + bool "UEFI variables storage service via OP-TEE" + depends on OPTEE + help + If OP-TEE is present and running StandAloneMM, dispatch all UEFI + variable related operations to that. The application will verify, + authenticate and store the variables on an RPMB. + +endchoice + +config EFI_VARIABLES_PRESEED + bool "Initial values for UEFI variables" + depends on EFI_VARIABLE_FILE_STORE + help + Include a file with the initial values for non-volatile UEFI variables + into the U-Boot binary. If this configuration option is set, changes + to authentication related variables (PK, KEK, db, dbx) are not + allowed. + +if EFI_VARIABLES_PRESEED + +config EFI_VAR_SEED_FILE + string "File with initial values of non-volatile UEFI variables" + default ubootefi.var + help + File with initial values of non-volatile UEFI variables. The file must + be in the same format as the storage in the EFI system partition. The + easiest way to create it is by setting the non-volatile variables in + U-Boot. If a relative file path is used, it is relative to the source + directory. + +endif config EFI_GET_TIME bool "GetTime() runtime service" @@ -174,13 +212,4 @@ config EFI_SECURE_BOOT it is signed with a trusted key. To do that, you need to install, at least, PK, KEK and db. -config EFI_MM_COMM_TEE - bool "UEFI variables storage service via OP-TEE" - depends on OPTEE - default n - help - If OP-TEE is present and running StandAloneMM, dispatch all UEFI variable - related operations to that. The application will verify, authenticate and - store the variables on an RPMB. - endif diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index f81ec8d277..441ac9432e 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -6,7 +6,7 @@ # This file only gets included with CONFIG_EFI_LOADER set, so all # object inclusion implicitly depends on it -asflags-y += -DHOST_ARCH="$(HOST_ARCH)" +asflags-y += -DHOST_ARCH="$(HOST_ARCH)" -I. ccflags-y += -DHOST_ARCH="$(HOST_ARCH)" CFLAGS_efi_boottime.o += \ @@ -42,6 +42,7 @@ obj-y += efi_variable_tee.o else obj-y += efi_variable.o obj-y += efi_var_file.o +obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o endif obj-y += efi_watchdog.o obj-$(CONFIG_LCD) += efi_gop.o @@ -53,3 +54,6 @@ obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o obj-y += efi_signature.o + +EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE)) +$(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE) diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c index 1e2be1135b..ee2e67bc8c 100644 --- a/lib/efi_loader/efi_var_common.c +++ b/lib/efi_loader/efi_var_common.c @@ -9,6 +9,33 @@ #include <efi_loader.h> #include <efi_variable.h> +enum efi_secure_mode { + EFI_MODE_SETUP, + EFI_MODE_USER, + EFI_MODE_AUDIT, + EFI_MODE_DEPLOYED, +}; + +struct efi_auth_var_name_type { + const u16 *name; + const efi_guid_t *guid; + const enum efi_auth_var_type type; +}; + +static const struct efi_auth_var_name_type name_type[] = { + {u"PK", &efi_global_variable_guid, EFI_AUTH_VAR_PK}, + {u"KEK", &efi_global_variable_guid, EFI_AUTH_VAR_KEK}, + {u"db", &efi_guid_image_security_database, EFI_AUTH_VAR_DB}, + {u"dbx", &efi_guid_image_security_database, EFI_AUTH_VAR_DBX}, + /* not used yet + {u"dbt", &efi_guid_image_security_database, EFI_AUTH_VAR_DBT}, + {u"dbr", &efi_guid_image_security_database, EFI_AUTH_VAR_DBR}, + */ +}; + +static bool efi_secure_boot; +static enum efi_secure_mode efi_secure_mode; + /** * efi_efi_get_variable() - retrieve value of a UEFI variable * @@ -138,3 +165,158 @@ efi_status_t EFIAPI efi_query_variable_info( return EFI_EXIT(ret); } + +/** + * efi_set_secure_state - modify secure boot state variables + * @secure_boot: value of SecureBoot + * @setup_mode: value of SetupMode + * @audit_mode: value of AuditMode + * @deployed_mode: value of DeployedMode + * + * Modify secure boot status related variables as indicated. + * + * Return: status code + */ +static efi_status_t efi_set_secure_state(u8 secure_boot, u8 setup_mode, + u8 audit_mode, u8 deployed_mode) +{ + efi_status_t ret; + const u32 attributes_ro = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_READ_ONLY; + const u32 attributes_rw = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; + + efi_secure_boot = secure_boot; + + ret = efi_set_variable_int(L"SecureBoot", &efi_global_variable_guid, + attributes_ro, sizeof(secure_boot), + &secure_boot, false); + if (ret != EFI_SUCCESS) + goto err; + + ret = efi_set_variable_int(L"SetupMode", &efi_global_variable_guid, + attributes_ro, sizeof(setup_mode), + &setup_mode, false); + if (ret != EFI_SUCCESS) + goto err; + + ret = efi_set_variable_int(L"AuditMode", &efi_global_variable_guid, + audit_mode || setup_mode ? + attributes_ro : attributes_rw, + sizeof(audit_mode), &audit_mode, false); + if (ret != EFI_SUCCESS) + goto err; + + ret = efi_set_variable_int(L"DeployedMode", + &efi_global_variable_guid, + audit_mode || deployed_mode || setup_mode ? + attributes_ro : attributes_rw, + sizeof(deployed_mode), &deployed_mode, + false); +err: + return ret; +} + +/** + * efi_transfer_secure_state - handle a secure boot state transition + * @mode: new state + * + * Depending on @mode, secure boot related variables are updated. + * Those variables are *read-only* for users, efi_set_variable_int() + * is called here. + * + * Return: status code + */ +static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode) +{ + efi_status_t ret; + + EFI_PRINT("Switching secure state from %d to %d\n", efi_secure_mode, + mode); + + if (mode == EFI_MODE_DEPLOYED) { + ret = efi_set_secure_state(1, 0, 0, 1); + if (ret != EFI_SUCCESS) + goto err; + } else if (mode == EFI_MODE_AUDIT) { + ret = efi_set_variable_int(L"PK", &efi_global_variable_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL, false); + if (ret != EFI_SUCCESS) + goto err; + + ret = efi_set_secure_state(0, 1, 1, 0); + if (ret != EFI_SUCCESS) + goto err; + } else if (mode == EFI_MODE_USER) { + ret = efi_set_secure_state(1, 0, 0, 0); + if (ret != EFI_SUCCESS) + goto err; + } else if (mode == EFI_MODE_SETUP) { + ret = efi_set_secure_state(0, 1, 0, 0); + if (ret != EFI_SUCCESS) + goto err; + } else { + return EFI_INVALID_PARAMETER; + } + + efi_secure_mode = mode; + + return EFI_SUCCESS; + +err: + /* TODO: What action should be taken here? */ + printf("ERROR: Secure state transition failed\n"); + return ret; +} + +efi_status_t efi_init_secure_state(void) +{ + enum efi_secure_mode mode = EFI_MODE_SETUP; + u8 efi_vendor_keys = 0; + efi_uintn_t size = 0; + efi_status_t ret; + + ret = efi_get_variable_int(L"PK", &efi_global_variable_guid, + NULL, &size, NULL, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) { + if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) + mode = EFI_MODE_USER; + } + + ret = efi_transfer_secure_state(mode); + if (ret != EFI_SUCCESS) + return ret; + + /* As we do not provide vendor keys this variable is always 0. */ + ret = efi_set_variable_int(L"VendorKeys", + &efi_global_variable_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_READ_ONLY, + sizeof(efi_vendor_keys), + &efi_vendor_keys, false); + return ret; +} + +/** + * efi_secure_boot_enabled - return if secure boot is enabled or not + * + * Return: true if enabled, false if disabled + */ +bool efi_secure_boot_enabled(void) +{ + return efi_secure_boot; +} + +enum efi_auth_var_type efi_auth_var_get_type(u16 *name, const efi_guid_t *guid) +{ + for (size_t i = 0; i < ARRAY_SIZE(name_type); ++i) { + if (!u16_strcmp(name, name_type[i].name) && + !guidcmp(guid, name_type[i].guid)) + return name_type[i].type; + } + return EFI_AUTH_VAR_NONE; +} diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c index 880c279aef..6f9d76f2a2 100644 --- a/lib/efi_loader/efi_var_file.c +++ b/lib/efi_loader/efi_var_file.c @@ -159,13 +159,7 @@ error: #endif } -/** - * efi_var_restore() - restore EFI variables from buffer - * - * @buf: buffer - * Return: status code - */ -static efi_status_t __maybe_unused efi_var_restore(struct efi_var_file *buf) +efi_status_t efi_var_restore(struct efi_var_file *buf) { struct efi_var_entry *var, *last_var; efi_status_t ret; diff --git a/lib/efi_loader/efi_var_seed.S b/lib/efi_loader/efi_var_seed.S new file mode 100644 index 0000000000..e0a40cf46c --- /dev/null +++ b/lib/efi_loader/efi_var_seed.S @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Predefined UEFI variables + * + * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> + */ + +#include <config.h> + +.section .rodata.efi_seed.init,"a" +.balign 16 +.global __efi_var_file_begin +__efi_var_file_begin: +.incbin CONFIG_EFI_VAR_SEED_FILE +.global __efi_var_file_end +__efi_var_file_end: +.balign 16 diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index eab5f005da..39a8482903 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -5,12 +5,15 @@ * Copyright (c) 2017 Rob Clark */ +#define LOG_CATEGORY LOGC_EFI + #include <common.h> #include <efi_loader.h> #include <efi_variable.h> #include <env.h> #include <env_internal.h> #include <hexdump.h> +#include <log.h> #include <malloc.h> #include <rtc.h> #include <search.h> @@ -18,166 +21,7 @@ #include <crypto/pkcs7_parser.h> #include <linux/compat.h> #include <u-boot/crc.h> - -enum efi_secure_mode { - EFI_MODE_SETUP, - EFI_MODE_USER, - EFI_MODE_AUDIT, - EFI_MODE_DEPLOYED, -}; - -static bool efi_secure_boot; -static enum efi_secure_mode efi_secure_mode; -static u8 efi_vendor_keys; - -/** - * efi_set_secure_state - modify secure boot state variables - * @secure_boot: value of SecureBoot - * @setup_mode: value of SetupMode - * @audit_mode: value of AuditMode - * @deployed_mode: value of DeployedMode - * - * Modify secure boot status related variables as indicated. - * - * Return: status code - */ -static efi_status_t efi_set_secure_state(u8 secure_boot, u8 setup_mode, - u8 audit_mode, u8 deployed_mode) -{ - efi_status_t ret; - const u32 attributes_ro = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_READ_ONLY; - const u32 attributes_rw = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS; - - efi_secure_boot = secure_boot; - - ret = efi_set_variable_int(L"SecureBoot", &efi_global_variable_guid, - attributes_ro, sizeof(secure_boot), - &secure_boot, false); - if (ret != EFI_SUCCESS) - goto err; - - ret = efi_set_variable_int(L"SetupMode", &efi_global_variable_guid, - attributes_ro, sizeof(setup_mode), - &setup_mode, false); - if (ret != EFI_SUCCESS) - goto err; - - ret = efi_set_variable_int(L"AuditMode", &efi_global_variable_guid, - audit_mode || setup_mode ? - attributes_ro : attributes_rw, - sizeof(audit_mode), &audit_mode, false); - if (ret != EFI_SUCCESS) - goto err; - - ret = efi_set_variable_int(L"DeployedMode", - &efi_global_variable_guid, - audit_mode || deployed_mode || setup_mode ? - attributes_ro : attributes_rw, - sizeof(deployed_mode), &deployed_mode, - false); -err: - return ret; -} - -/** - * efi_transfer_secure_state - handle a secure boot state transition - * @mode: new state - * - * Depending on @mode, secure boot related variables are updated. - * Those variables are *read-only* for users, efi_set_variable_int() - * is called here. - * - * Return: status code - */ -static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode) -{ - efi_status_t ret; - - EFI_PRINT("Switching secure state from %d to %d\n", efi_secure_mode, - mode); - - if (mode == EFI_MODE_DEPLOYED) { - ret = efi_set_secure_state(1, 0, 0, 1); - if (ret != EFI_SUCCESS) - goto err; - } else if (mode == EFI_MODE_AUDIT) { - ret = efi_set_variable_int(L"PK", &efi_global_variable_guid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - 0, NULL, false); - if (ret != EFI_SUCCESS) - goto err; - - ret = efi_set_secure_state(0, 1, 1, 0); - if (ret != EFI_SUCCESS) - goto err; - } else if (mode == EFI_MODE_USER) { - ret = efi_set_secure_state(1, 0, 0, 0); - if (ret != EFI_SUCCESS) - goto err; - } else if (mode == EFI_MODE_SETUP) { - ret = efi_set_secure_state(0, 1, 0, 0); - if (ret != EFI_SUCCESS) - goto err; - } else { - return EFI_INVALID_PARAMETER; - } - - efi_secure_mode = mode; - - return EFI_SUCCESS; - -err: - /* TODO: What action should be taken here? */ - printf("ERROR: Secure state transition failed\n"); - return ret; -} - -/** - * efi_init_secure_state - initialize secure boot state - * - * Return: status code - */ -static efi_status_t efi_init_secure_state(void) -{ - enum efi_secure_mode mode = EFI_MODE_SETUP; - efi_uintn_t size = 0; - efi_status_t ret; - - ret = efi_get_variable_int(L"PK", &efi_global_variable_guid, - NULL, &size, NULL, NULL); - if (ret == EFI_BUFFER_TOO_SMALL) { - if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) - mode = EFI_MODE_USER; - } - - ret = efi_transfer_secure_state(mode); - if (ret != EFI_SUCCESS) - return ret; - - /* As we do not provide vendor keys this variable is always 0. */ - ret = efi_set_variable_int(L"VendorKeys", - &efi_global_variable_guid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_READ_ONLY, - sizeof(efi_vendor_keys), - &efi_vendor_keys, false); - return ret; -} - -/** - * efi_secure_boot_enabled - return if secure boot is enabled or not - * - * Return: true if enabled, false if disabled - */ -bool efi_secure_boot_enabled(void) -{ - return efi_secure_boot; -} +#include <asm/sections.h> #ifdef CONFIG_EFI_SECURE_BOOT static u8 pkcs7_hdr[] = { @@ -292,6 +136,7 @@ static efi_status_t efi_variable_authenticate(u16 *variable, struct efi_time timestamp; struct rtc_time tm; u64 new_time; + enum efi_auth_var_type var_type; efi_status_t ret; var_sig = NULL; @@ -368,18 +213,20 @@ static efi_status_t efi_variable_authenticate(u16 *variable, } /* signature database used for authentication */ - if (u16_strcmp(variable, L"PK") == 0 || - u16_strcmp(variable, L"KEK") == 0) { + var_type = efi_auth_var_get_type(variable, vendor); + switch (var_type) { + case EFI_AUTH_VAR_PK: + case EFI_AUTH_VAR_KEK: /* with PK */ truststore = efi_sigstore_parse_sigdb(L"PK"); if (!truststore) goto err; - } else if (u16_strcmp(variable, L"db") == 0 || - u16_strcmp(variable, L"dbx") == 0) { + break; + case EFI_AUTH_VAR_DB: + case EFI_AUTH_VAR_DBX: /* with PK and KEK */ truststore = efi_sigstore_parse_sigdb(L"KEK"); truststore2 = efi_sigstore_parse_sigdb(L"PK"); - if (!truststore) { if (!truststore2) goto err; @@ -387,7 +234,8 @@ static efi_status_t efi_variable_authenticate(u16 *variable, truststore = truststore2; truststore2 = NULL; } - } else { + break; + default: /* TODO: support private authenticated variables */ goto err; } @@ -506,6 +354,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, efi_uintn_t ret; bool append, delete; u64 time = 0; + enum efi_auth_var_type var_type; if (!variable_name || !*variable_name || !vendor || ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) && @@ -519,10 +368,16 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, delete = !append && (!data_size || !attributes); /* check attributes */ + var_type = efi_auth_var_get_type(variable_name, vendor); if (var) { if (ro_check && (var->attr & EFI_VARIABLE_READ_ONLY)) return EFI_WRITE_PROTECTED; + if (IS_ENABLED(CONFIG_EFI_VARIABLES_PRESEED)) { + if (var_type != EFI_AUTH_VAR_NONE) + return EFI_WRITE_PROTECTED; + } + /* attributes won't be changed */ if (!delete && ((ro_check && var->attr != attributes) || @@ -540,12 +395,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, return EFI_NOT_FOUND; } - if (((!u16_strcmp(variable_name, L"PK") || - !u16_strcmp(variable_name, L"KEK")) && - !guidcmp(vendor, &efi_global_variable_guid)) || - ((!u16_strcmp(variable_name, L"db") || - !u16_strcmp(variable_name, L"dbx")) && - !guidcmp(vendor, &efi_guid_image_security_database))) { + if (var_type != EFI_AUTH_VAR_NONE) { /* authentication is mandatory */ if (!(attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) { @@ -604,7 +454,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, if (ret != EFI_SUCCESS) return ret; - if (!u16_strcmp(variable_name, L"PK")) + if (var_type == EFI_AUTH_VAR_PK) ret = efi_init_secure_state(); else ret = EFI_SUCCESS; @@ -747,5 +597,12 @@ efi_status_t efi_init_variables(void) if (ret != EFI_SUCCESS) return ret; + if (IS_ENABLED(CONFIG_EFI_VARIABLES_PRESEED)) { + ret = efi_var_restore((struct efi_var_file *) + __efi_var_file_begin); + if (ret != EFI_SUCCESS) + log_err("Invalid EFI variable seed\n"); + } + return efi_var_from_file(); } diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c index ff90aa8e81..c042348938 100644 --- a/lib/efi_loader/efi_variable_tee.c +++ b/lib/efi_loader/efi_variable_tee.c @@ -244,10 +244,92 @@ out: return ret; } +/* + * StMM can store internal attributes and properties for variables, i.e enabling + * R/O variables + */ +static efi_status_t set_property_int(u16 *variable_name, efi_uintn_t name_size, + const efi_guid_t *vendor, + struct var_check_property *var_property) +{ + struct smm_variable_var_check_property *smm_property; + efi_uintn_t payload_size; + u8 *comm_buf = NULL; + efi_status_t ret; + + payload_size = sizeof(*smm_property) + name_size; + if (payload_size > max_payload_size) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + comm_buf = setup_mm_hdr((void **)&smm_property, payload_size, + SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET, + &ret); + if (!comm_buf) + goto out; + + guidcpy(&smm_property->guid, vendor); + smm_property->name_size = name_size; + memcpy(&smm_property->property, var_property, + sizeof(smm_property->property)); + memcpy(smm_property->name, variable_name, name_size); + + ret = mm_communicate(comm_buf, payload_size); + +out: + free(comm_buf); + return ret; +} + +static efi_status_t get_property_int(u16 *variable_name, efi_uintn_t name_size, + const efi_guid_t *vendor, + struct var_check_property *var_property) +{ + struct smm_variable_var_check_property *smm_property; + efi_uintn_t payload_size; + u8 *comm_buf = NULL; + efi_status_t ret; + + memset(var_property, 0, sizeof(*var_property)); + payload_size = sizeof(*smm_property) + name_size; + if (payload_size > max_payload_size) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + comm_buf = setup_mm_hdr((void **)&smm_property, payload_size, + SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET, + &ret); + if (!comm_buf) + goto out; + + guidcpy(&smm_property->guid, vendor); + smm_property->name_size = name_size; + memcpy(smm_property->name, variable_name, name_size); + + ret = mm_communicate(comm_buf, payload_size); + /* + * Currently only R/O property is supported in StMM. + * Variables that are not set to R/O will not set the property in StMM + * and the call will return EFI_NOT_FOUND. We are setting the + * properties to 0x0 so checking against that is enough for the + * EFI_NOT_FOUND case. + */ + if (ret == EFI_NOT_FOUND) + ret = EFI_SUCCESS; + if (ret != EFI_SUCCESS) + goto out; + memcpy(var_property, &smm_property->property, sizeof(*var_property)); + +out: + free(comm_buf); + return ret; +} + efi_status_t efi_get_variable_int(u16 *variable_name, const efi_guid_t *vendor, u32 *attributes, efi_uintn_t *data_size, void *data, u64 *timep) { + struct var_check_property var_property; struct smm_variable_access *var_acc; efi_uintn_t payload_size; efi_uintn_t name_size; @@ -299,8 +381,16 @@ efi_status_t efi_get_variable_int(u16 *variable_name, const efi_guid_t *vendor, if (ret != EFI_SUCCESS) goto out; - if (attributes) + ret = get_property_int(variable_name, name_size, vendor, &var_property); + if (ret != EFI_SUCCESS) + goto out; + + if (attributes) { *attributes = var_acc->attr; + if (var_property.property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) + *attributes |= EFI_VARIABLE_READ_ONLY; + } + if (data) memcpy(data, (u8 *)var_acc->name + var_acc->name_size, var_acc->data_size); @@ -387,11 +477,13 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, u32 attributes, efi_uintn_t data_size, const void *data, bool ro_check) { + efi_status_t ret, alt_ret = EFI_SUCCESS; + struct var_check_property var_property; struct smm_variable_access *var_acc; efi_uintn_t payload_size; efi_uintn_t name_size; u8 *comm_buf = NULL; - efi_status_t ret; + bool ro; if (!variable_name || variable_name[0] == 0 || !vendor) { ret = EFI_INVALID_PARAMETER; @@ -401,7 +493,6 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, ret = EFI_INVALID_PARAMETER; goto out; } - /* Check payload size */ name_size = u16_strsize(variable_name); payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + data_size; @@ -410,12 +501,41 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, goto out; } - /* Get communication buffer and initialize header */ + /* + * Allocate the buffer early, before switching to RW (if needed) + * so we won't need to account for any failures in reading/setting + * the properties, if the allocation fails + */ comm_buf = setup_mm_hdr((void **)&var_acc, payload_size, SMM_VARIABLE_FUNCTION_SET_VARIABLE, &ret); if (!comm_buf) goto out; + ro = !!(attributes & EFI_VARIABLE_READ_ONLY); + attributes &= EFI_VARIABLE_MASK; + + /* + * The API has the ability to override RO flags. If no RO check was + * requested switch the variable to RW for the duration of this call + */ + ret = get_property_int(variable_name, name_size, vendor, + &var_property); + if (ret != EFI_SUCCESS) + goto out; + + if (var_property.property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) { + /* Bypass r/o check */ + if (!ro_check) { + var_property.property &= ~VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY; + ret = set_property_int(variable_name, name_size, vendor, &var_property); + if (ret != EFI_SUCCESS) + goto out; + } else { + ret = EFI_WRITE_PROTECTED; + goto out; + } + } + /* Fill in contents */ guidcpy(&var_acc->guid, vendor); var_acc->data_size = data_size; @@ -426,10 +546,26 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, /* Communicate */ ret = mm_communicate(comm_buf, payload_size); + if (ret != EFI_SUCCESS) + alt_ret = ret; + + if (ro && !(var_property.property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY)) { + var_property.revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION; + var_property.property |= VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY; + var_property.attributes = attributes; + var_property.minsize = 1; + var_property.maxsize = var_acc->data_size; + ret = set_property_int(variable_name, name_size, vendor, &var_property); + } + + if (alt_ret != EFI_SUCCESS) + goto out; + if (!u16_strcmp(variable_name, L"PK")) + alt_ret = efi_init_secure_state(); out: free(comm_buf); - return ret; + return alt_ret == EFI_SUCCESS ? ret : alt_ret; } efi_status_t efi_query_variable_info_int(u32 attributes, @@ -586,5 +722,9 @@ efi_status_t efi_init_variables(void) MM_VARIABLE_COMMUNICATE_SIZE + max_payload_size; + ret = efi_init_secure_state(); + if (ret != EFI_SUCCESS) + return ret; + return EFI_SUCCESS; } diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py index 9465c28fbc..7aa422e764 100644 --- a/test/py/tests/test_efi_loader.py +++ b/test/py/tests/test_efi_loader.py @@ -68,8 +68,8 @@ def test_efi_pre_commands(u_boot_console): u_boot_console.run_command('pci enum') @pytest.mark.buildconfigspec('cmd_dhcp') -def test_efi_dhcp(u_boot_console): - """Test the dhcp command. +def test_efi_setup_dhcp(u_boot_console): + """Set up the network using DHCP. The boardenv_* file may be used to enable/disable this test; see the comment at the beginning of this file. @@ -77,7 +77,10 @@ def test_efi_dhcp(u_boot_console): test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False) if not test_dhcp: - pytest.skip('No DHCP server available') + env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None) + if not env_vars: + pytest.skip('No DHCP server available') + return None u_boot_console.run_command('setenv autoload no') output = u_boot_console.run_command('dhcp') @@ -88,7 +91,7 @@ def test_efi_dhcp(u_boot_console): @pytest.mark.buildconfigspec('net') def test_efi_setup_static(u_boot_console): - """Set up a static IP configuration. + """Set up the network using a static IP configuration. The configuration is provided by the boardenv_* file; see the comment at the beginning of this file. @@ -96,7 +99,10 @@ def test_efi_setup_static(u_boot_console): env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None) if not env_vars: - pytest.skip('No static network configuration is defined') + test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False) + if not test_dhcp: + pytest.skip('No static network configuration is defined') + return None for (var, val) in env_vars: u_boot_console.run_command('setenv %s %s' % (var, val)) |