From c0c21d67f0654f9d3641b9dd3bdfd635110c2bc1 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 20 Dec 2020 11:05:38 +0100 Subject: efi_loader: make variable store size customizable Currently the size of the buffer to keep UEFI variables in memory is fixed at 16384 bytes. This size has proven to be too small for some use cases. Make the size of the memory buffer for UEFI variables customizable. Reported-by: Paulo Alcantara (SUSE) Signed-off-by: Heinrich Schuchardt Acked-by: Ilias Apalodimas --- include/efi_variable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/efi_variable.h b/include/efi_variable.h index 4704a3c16e6..bf5076233e4 100644 --- a/include/efi_variable.h +++ b/include/efi_variable.h @@ -91,7 +91,7 @@ efi_status_t efi_query_variable_info_int(u32 attributes, #define EFI_VAR_FILE_NAME "ubootefi.var" -#define EFI_VAR_BUF_SIZE 0x4000 +#define EFI_VAR_BUF_SIZE CONFIG_EFI_VAR_BUF_SIZE /* * This constant identifies the file format for storing UEFI variables in -- cgit v1.2.3 From d0be67657d64523b4499d385390c08c2bafab1bc Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 25 Dec 2020 14:30:04 +0100 Subject: fs: fat: eliminate DIRENTSPERBLOCK() macro The FAT filesystem implementation uses several marcros referring to a magic variable name mydata which renders the code less readable. Eliminate one of them which is only used for a debug() statement. Use log_debug() instead of debug(). Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- include/fat.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/fat.h b/include/fat.h index 3c29a4484d4..8cae283030f 100644 --- a/include/fat.h +++ b/include/fat.h @@ -22,7 +22,6 @@ struct disk_partition; #define MAX_CLUSTSIZE CONFIG_FS_FAT_MAX_CLUSTSIZE -#define DIRENTSPERBLOCK (mydata->sect_size / sizeof(dir_entry)) #define DIRENTSPERCLUST ((mydata->clust_size * mydata->sect_size) / \ sizeof(dir_entry)) -- cgit v1.2.3 From c0029e4e25c10d627f4bff62cdb4074bb2c7eaf7 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 31 Dec 2020 00:38:13 +0100 Subject: fs/fat: implement fsuuid command The FAT file system does not have a UUID but a 4 byte volume ID. Let the fsuuid command show it in XXXX-XXXX format. Signed-off-by: Heinrich Schuchardt --- include/fat.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/fat.h b/include/fat.h index 8cae283030f..b9f273f381f 100644 --- a/include/fat.h +++ b/include/fat.h @@ -212,4 +212,16 @@ int fat_unlink(const char *filename); int fat_mkdir(const char *dirname); void fat_close(void); void *fat_next_cluster(fat_itr *itr, unsigned int *nbytes); + +/** + * fat_uuid() - get FAT volume ID + * + * The FAT volume ID returned in @uuid_str as hexadecimal number in XXXX-XXXX + * format. + * + * @uuid_str: caller allocated buffer of at least 10 bytes for the volume ID + * Return: 0 on success + */ +int fat_uuid(char *uuid_str); + #endif /* _FAT_H_ */ -- cgit v1.2.3 From 0ce3fb55e0be286f1f7686aeb452ee77100a2493 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 28 Dec 2020 22:42:51 +0100 Subject: efi_loader: describe struct efi_loaded_image_obj Add the missing description of some fields of struct efi_loaded_image_obj. Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index 365f3d01dc7..280225a7c15 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -304,8 +304,10 @@ enum efi_image_auth_status { * @exit_status: exit status passed to Exit() * @exit_data_size: exit data size passed to Exit() * @exit_data: exit data passed to Exit() - * @exit_jmp: long jump buffer for returning form started image + * @exit_jmp: long jump buffer for returning from started image * @entry: entry address of the relocated image + * @image_type: indicates if the image is an applicition or a driver + * @auth_status: indicates if the image is authenticated */ struct efi_loaded_image_obj { struct efi_object header; -- cgit v1.2.3 From f8212f09702f802ffab42769133e3114bd6e5e77 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 28 Dec 2020 23:24:40 +0100 Subject: efi_loader: use after free in efi_exit() Do not use data from the loaded image object after deleting it. Fixes: 126a43f15b36 ("efi_loader: unload applications upon Exit()") Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index 280225a7c15..62a6c3de5a0 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -311,10 +311,10 @@ enum efi_image_auth_status { */ struct efi_loaded_image_obj { struct efi_object header; - efi_status_t exit_status; + efi_status_t *exit_status; efi_uintn_t *exit_data_size; u16 **exit_data; - struct jmp_buf_data exit_jmp; + struct jmp_buf_data *exit_jmp; EFIAPI efi_status_t (*entry)(efi_handle_t image_handle, struct efi_system_table *st); u16 image_type; -- cgit v1.2.3 From fe179d7fb5c10d8a4e299af06c766f47f2c8d51a Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Thu, 31 Dec 2020 12:26:46 +0200 Subject: efi_loader: Add size checks to efi_create_indexed_name() Although the function description states the caller must provide a sufficient buffer, it's better to have in function checks that the destination buffer can hold the intended value. So let's add an extra argument with the buffer size and check that before doing any copying. Signed-off-by: Ilias Apalodimas Reviewed-by: Heinrich Schuchardt --- include/efi_loader.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index 62a6c3de5a0..790d4bf64c9 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -824,7 +824,8 @@ bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, void efi_memcpy_runtime(void *dest, const void *src, size_t n); /* commonly used helper function */ -u16 *efi_create_indexed_name(u16 *buffer, const char *name, unsigned int index); +u16 *efi_create_indexed_name(u16 *buffer, size_t buffer_size, const char *name, + unsigned int index); extern const struct efi_firmware_management_protocol efi_fmp_fit; extern const struct efi_firmware_management_protocol efi_fmp_raw; -- cgit v1.2.3 From ab201a116f1e825b1728a0133718427885381efd Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Wed, 30 Dec 2020 19:27:04 +0530 Subject: fsp: Move and rename fsp_types.h file The fsp_types.h header file contains macros for building signatures of different widths. These signature macros are architecture agnostic, and can be used in all places which use signatures in a data structure. Move and rename the fsp_types.h under the common include header. Signed-off-by: Sughosh Ganu Reviewed-by: Simon Glass Reviewed-by: Bin Meng --- include/signatures.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 include/signatures.h (limited to 'include') diff --git a/include/signatures.h b/include/signatures.h new file mode 100644 index 00000000000..4042db1e00b --- /dev/null +++ b/include/signatures.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + */ + +#ifndef __SIGNATURES_H__ +#define __SIGNATURES_H__ + +/** + * Returns a 16-bit signature built from 2 ASCII characters. + * + * This macro returns a 16-bit value built from the two ASCII characters + * specified by A and B. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * + * @return: A 16-bit value built from the two ASCII characters specified by + * A and B. + */ +#define SIGNATURE_16(A, B) ((A) | (B << 8)) + +/** + * Returns a 32-bit signature built from 4 ASCII characters. + * + * This macro returns a 32-bit value built from the four ASCII characters + * specified by A, B, C, and D. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * @C: The third ASCII character. + * @D: The fourth ASCII character. + * + * @return: A 32-bit value built from the two ASCII characters specified by + * A, B, C and D. + */ +#define SIGNATURE_32(A, B, C, D) \ + (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) + +/** + * Returns a 64-bit signature built from 8 ASCII characters. + * + * This macro returns a 64-bit value built from the eight ASCII characters + * specified by A, B, C, D, E, F, G,and H. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * @C: The third ASCII character. + * @D: The fourth ASCII character. + * @E: The fifth ASCII character. + * @F: The sixth ASCII character. + * @G: The seventh ASCII character. + * @H: The eighth ASCII character. + * + * @return: A 64-bit value built from the two ASCII characters specified by + * A, B, C, D, E, F, G and H. + */ +#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ + (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32)) + +#endif /* __SIGNATURES_H__ */ -- cgit v1.2.3 From 201b8068f35385c1c7794f24d0a3ac427210f241 Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Wed, 30 Dec 2020 19:27:07 +0530 Subject: efi_loader: Make the pkcs7 header parsing function an extern The pkcs7 header parsing functionality is pretty generic, and can be used by other features like capsule authentication. Make the function an extern, also changing it's name to efi_parse_pkcs7_header Signed-off-by: Sughosh Ganu --- include/efi_loader.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index 790d4bf64c9..f1dfb1d33fd 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -820,6 +820,10 @@ bool efi_secure_boot_enabled(void); bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, WIN_CERTIFICATE **auth, size_t *auth_len); +struct pkcs7_message *efi_parse_pkcs7_header(const void *buf, + size_t buflen, + u8 **tmpbuf); + /* runtime implementation of memcpy() */ void efi_memcpy_runtime(void *dest, const void *src, size_t n); -- cgit v1.2.3 From b4f20a5d83f0b8a5c30128966eabe68748631e66 Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Wed, 30 Dec 2020 19:27:08 +0530 Subject: efi_loader: Re-factor code to build the signature store from efi signature list The efi_sigstore_parse_sigdb function reads the uefi authenticated variable, stored in the signature database format and builds the signature store structure. Factor out the code for building the signature store. This can then be used by the capsule authentication routine to build the signature store even when the signature database is not stored as an uefi authenticated variable Signed-off-by: Sughosh Ganu --- include/efi_loader.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index f1dfb1d33fd..7fd65eeb8db 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -813,6 +813,8 @@ efi_status_t efi_image_region_add(struct efi_image_regions *regs, int nocheck); void efi_sigstore_free(struct efi_signature_store *sigstore); +struct efi_signature_store *efi_build_signature_store(void *sig_list, + efi_uintn_t size); struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name); bool efi_secure_boot_enabled(void); -- cgit v1.2.3 From 04be98bd6bcfccf3ab028fda0ca962dd00f61260 Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Wed, 30 Dec 2020 19:27:09 +0530 Subject: efi: capsule: Add support for uefi capsule authentication Add support for authenticating uefi capsules. Most of the signature verification functionality is shared with the uefi secure boot feature. The root certificate containing the public key used for the signature verification is stored as part of the device tree blob. The root certificate is stored as an efi signature list(esl) file -- this file contains the x509 certificate which is the root certificate. Signed-off-by: Sughosh Ganu --- include/efi_api.h | 18 ++++++++++++++++++ include/efi_loader.h | 6 ++++++ 2 files changed, 24 insertions(+) (limited to 'include') diff --git a/include/efi_api.h b/include/efi_api.h index e82d4ca9ff4..ecb43a06070 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1812,6 +1812,24 @@ struct efi_variable_authentication_2 { struct win_certificate_uefi_guid auth_info; } __attribute__((__packed__)); +/** + * efi_firmware_image_authentication - Capsule authentication method + * descriptor + * + * This structure describes an authentication information for + * a capsule with IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED set + * and should be included as part of the capsule. + * Only EFI_CERT_TYPE_PKCS7_GUID is accepted. + * + * @monotonic_count: Count to prevent replay + * @auth_info: Authentication info + */ +struct efi_firmware_image_authentication { + uint64_t monotonic_count; + struct win_certificate_uefi_guid auth_info; +} __attribute__((__packed__)); + + /** * efi_signature_data - A format of signature * diff --git a/include/efi_loader.h b/include/efi_loader.h index 7fd65eeb8db..4719fa93f06 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -819,6 +819,8 @@ struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name); bool efi_secure_boot_enabled(void); +bool efi_capsule_auth_enabled(void); + bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, WIN_CERTIFICATE **auth, size_t *auth_len); @@ -847,6 +849,10 @@ efi_status_t EFIAPI efi_query_capsule_caps( u64 *maximum_capsule_size, u32 *reset_type); +efi_status_t efi_capsule_authenticate(const void *capsule, + efi_uintn_t capsule_size, + void **image, efi_uintn_t *image_size); + #define EFI_CAPSULE_DIR L"\\EFI\\UpdateCapsule\\" /* Hook at initialization */ -- cgit v1.2.3