Commit 58c90902 authored by Lenny Szubowicz's avatar Lenny Szubowicz Committed by Ard Biesheuvel

efi: Support for MOK variable config table

Because of system-specific EFI firmware limitations, EFI volatile
variables may not be capable of holding the required contents of
the Machine Owner Key (MOK) certificate store when the certificate
list grows above some size. Therefore, an EFI boot loader may pass
the MOK certs via a EFI configuration table created specifically for
this purpose to avoid this firmware limitation.

An EFI configuration table is a much more primitive mechanism
compared to EFI variables and is well suited for one-way passage
of static information from a pre-OS environment to the kernel.

This patch adds initial kernel support to recognize, parse,
and validate the EFI MOK configuration table, where named
entries contain the same data that would otherwise be provided
in similarly named EFI variables.

Additionally, this patch creates a sysfs binary file for each
EFI MOK configuration table entry found. These files are read-only
to root and are provided for use by user space utilities such as
mokutil.

A subsequent patch will load MOK certs into the trusted platform
key ring using this infrastructure.
Signed-off-by: default avatarLenny Szubowicz <lszubowi@redhat.com>
Link: https://lore.kernel.org/r/20200905013107.10457-2-lszubowi@redhat.comSigned-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 5c4c30f4
...@@ -1077,6 +1077,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -1077,6 +1077,7 @@ void __init setup_arch(char **cmdline_p)
efi_fake_memmap(); efi_fake_memmap();
efi_find_mirror(); efi_find_mirror();
efi_esrt_init(); efi_esrt_init();
efi_mokvar_table_init();
/* /*
* The EFI specification says that boot service code won't be * The EFI specification says that boot service code won't be
......
...@@ -91,6 +91,9 @@ static const unsigned long * const efi_tables[] = { ...@@ -91,6 +91,9 @@ static const unsigned long * const efi_tables[] = {
&efi.tpm_log, &efi.tpm_log,
&efi.tpm_final_log, &efi.tpm_final_log,
&efi_rng_seed, &efi_rng_seed,
#ifdef CONFIG_LOAD_UEFI_KEYS
&efi.mokvar_table,
#endif
}; };
u64 efi_setup; /* efi setup_data physical address */ u64 efi_setup; /* efi setup_data physical address */
......
...@@ -28,6 +28,7 @@ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o ...@@ -28,6 +28,7 @@ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o
obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o
obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o
obj-$(CONFIG_LOAD_UEFI_KEYS) += mokvar-table.o
fake_map-y += fake_mem.o fake_map-y += fake_mem.o
fake_map-$(CONFIG_X86) += x86_fake_mem.o fake_map-$(CONFIG_X86) += x86_fake_mem.o
......
...@@ -236,6 +236,7 @@ void __init efi_init(void) ...@@ -236,6 +236,7 @@ void __init efi_init(void)
reserve_regions(); reserve_regions();
efi_esrt_init(); efi_esrt_init();
efi_mokvar_table_init();
memblock_reserve(data.phys_map & PAGE_MASK, memblock_reserve(data.phys_map & PAGE_MASK,
PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK))); PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));
......
...@@ -43,6 +43,9 @@ struct efi __read_mostly efi = { ...@@ -43,6 +43,9 @@ struct efi __read_mostly efi = {
.esrt = EFI_INVALID_TABLE_ADDR, .esrt = EFI_INVALID_TABLE_ADDR,
.tpm_log = EFI_INVALID_TABLE_ADDR, .tpm_log = EFI_INVALID_TABLE_ADDR,
.tpm_final_log = EFI_INVALID_TABLE_ADDR, .tpm_final_log = EFI_INVALID_TABLE_ADDR,
#ifdef CONFIG_LOAD_UEFI_KEYS
.mokvar_table = EFI_INVALID_TABLE_ADDR,
#endif
}; };
EXPORT_SYMBOL(efi); EXPORT_SYMBOL(efi);
...@@ -516,6 +519,9 @@ static const efi_config_table_type_t common_tables[] __initconst = { ...@@ -516,6 +519,9 @@ static const efi_config_table_type_t common_tables[] __initconst = {
{EFI_RT_PROPERTIES_TABLE_GUID, &rt_prop, "RTPROP" }, {EFI_RT_PROPERTIES_TABLE_GUID, &rt_prop, "RTPROP" },
#ifdef CONFIG_EFI_RCI2_TABLE #ifdef CONFIG_EFI_RCI2_TABLE
{DELLEMC_EFI_RCI2_TABLE_GUID, &rci2_table_phys }, {DELLEMC_EFI_RCI2_TABLE_GUID, &rci2_table_phys },
#endif
#ifdef CONFIG_LOAD_UEFI_KEYS
{LINUX_EFI_MOK_VARIABLE_TABLE_GUID, &efi.mokvar_table, "MOKvar" },
#endif #endif
{}, {},
}; };
......
This diff is collapsed.
...@@ -357,6 +357,7 @@ void efi_native_runtime_setup(void); ...@@ -357,6 +357,7 @@ void efi_native_runtime_setup(void);
#define LINUX_EFI_TPM_FINAL_LOG_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25) #define LINUX_EFI_TPM_FINAL_LOG_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
#define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2) #define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)
#define LINUX_EFI_INITRD_MEDIA_GUID EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68) #define LINUX_EFI_INITRD_MEDIA_GUID EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
#define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
/* OEM GUIDs */ /* OEM GUIDs */
#define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55) #define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55)
...@@ -546,6 +547,7 @@ extern struct efi { ...@@ -546,6 +547,7 @@ extern struct efi {
unsigned long esrt; /* ESRT table */ unsigned long esrt; /* ESRT table */
unsigned long tpm_log; /* TPM2 Event Log table */ unsigned long tpm_log; /* TPM2 Event Log table */
unsigned long tpm_final_log; /* TPM2 Final Events Log table */ unsigned long tpm_final_log; /* TPM2 Final Events Log table */
unsigned long mokvar_table; /* MOK variable config table */
efi_get_time_t *get_time; efi_get_time_t *get_time;
efi_set_time_t *set_time; efi_set_time_t *set_time;
...@@ -1252,4 +1254,36 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size); ...@@ -1252,4 +1254,36 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size);
char *efi_systab_show_arch(char *str); char *efi_systab_show_arch(char *str);
/*
* The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table can be provided
* to the kernel by an EFI boot loader. The table contains a packed
* sequence of these entries, one for each named MOK variable.
* The sequence is terminated by an entry with a completely NULL
* name and 0 data size.
*/
struct efi_mokvar_table_entry {
char name[256];
u64 data_size;
u8 data[];
} __attribute((packed));
#ifdef CONFIG_LOAD_UEFI_KEYS
extern void __init efi_mokvar_table_init(void);
extern struct efi_mokvar_table_entry *efi_mokvar_entry_next(
struct efi_mokvar_table_entry **mokvar_entry);
extern struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name);
#else
static inline void efi_mokvar_table_init(void) { }
static inline struct efi_mokvar_table_entry *efi_mokvar_entry_next(
struct efi_mokvar_table_entry **mokvar_entry)
{
return NULL;
}
static inline struct efi_mokvar_table_entry *efi_mokvar_entry_find(
const char *name)
{
return NULL;
}
#endif
#endif /* _LINUX_EFI_H */ #endif /* _LINUX_EFI_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment