All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] PE/COFF measurement support
@ 2021-04-28 12:19 Masahisa Kojima
  2021-04-28 12:19 ` [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled Masahisa Kojima
  2021-04-28 12:19 ` [PATCH v3 2/2] efi_loader: add PE/COFF image measurement Masahisa Kojima
  0 siblings, 2 replies; 9+ messages in thread
From: Masahisa Kojima @ 2021-04-28 12:19 UTC (permalink / raw)
  To: u-boot

This patch series add the PE/COFF measurement support.
Extending PCR and Event Log is tested with fTPM
running as a OP-TEE TA.
Unit test will be added in the separate series.

Masahisa Kojima (2):
  efi_loader: expose efi_image_parse() even if UEFI Secure Boot is
    disabled
  efi_loader: add PE/COFF image measurement

 include/efi_loader.h              |   6 +
 include/efi_tcg2.h                |   9 ++
 include/tpm-v2.h                  |  18 +++
 lib/efi_loader/Kconfig            |   6 +
 lib/efi_loader/Makefile           |   2 +-
 lib/efi_loader/efi_image_loader.c | 132 +++++++++++++++----
 lib/efi_loader/efi_signature.c    |  67 +---------
 lib/efi_loader/efi_tcg2.c         | 207 ++++++++++++++++++++++++++++--
 lib/efi_loader/efi_var_common.c   |   3 +
 9 files changed, 351 insertions(+), 99 deletions(-)

-- 
2.17.1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled
  2021-04-28 12:19 [PATCH v3 0/2] PE/COFF measurement support Masahisa Kojima
@ 2021-04-28 12:19 ` Masahisa Kojima
  2021-04-28 13:16   ` Heinrich Schuchardt
  2021-04-28 12:19 ` [PATCH v3 2/2] efi_loader: add PE/COFF image measurement Masahisa Kojima
  1 sibling, 1 reply; 9+ messages in thread
From: Masahisa Kojima @ 2021-04-28 12:19 UTC (permalink / raw)
  To: u-boot

This is preparation for PE/COFF measurement support.
PE/COFF image hash calculation is same in both
UEFI Secure Boot image verification and measurement in
measured boot. PE/COFF image parsing functions are
gathered into efi_image_loader.c, and exposed even if
UEFI Secure Boot is not enabled.

This commit also adds the EFI_SIGNATURE_SUPPORT option
to decide if efi_signature.c shall be compiled.

Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
---

Changes in v3:
- hide EFI_SIGNATURE_SUPPORT option

Changes in v2:
- Remove all #ifdef from efi_image_loader.c and efi_signature.c
- Add EFI_SIGNATURE_SUPPORT option
- Explicitly include <u-boot/hash-checksum.h>
- Gather PE/COFF parsing functions into efi_image_loader.c
- Move efi_guid_t efi_guid_image_security_database in efi_var_common.c


 lib/efi_loader/Kconfig            |  6 +++
 lib/efi_loader/Makefile           |  2 +-
 lib/efi_loader/efi_image_loader.c | 73 +++++++++++++++++++++++++++----
 lib/efi_loader/efi_signature.c    | 67 +---------------------------
 lib/efi_loader/efi_var_common.c   |  3 ++
 5 files changed, 76 insertions(+), 75 deletions(-)

diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 0b99d7c774..b76e77180e 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -174,6 +174,7 @@ config EFI_CAPSULE_AUTHENTICATE
 	select PKCS7_MESSAGE_PARSER
 	select PKCS7_VERIFY
 	select IMAGE_SIGN_INFO
+	select EFI_SIGNATURE_SUPPORT
 	default n
 	help
 	  Select this option if you want to enable capsule
@@ -336,6 +337,7 @@ config EFI_SECURE_BOOT
 	select X509_CERTIFICATE_PARSER
 	select PKCS7_MESSAGE_PARSER
 	select PKCS7_VERIFY
+	select EFI_SIGNATURE_SUPPORT
 	default n
 	help
 	  Select this option to enable EFI secure boot support.
@@ -343,6 +345,10 @@ 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_SIGNATURE_SUPPORT
+	bool
+	depends on EFI_SECURE_BOOT || EFI_CAPSULE_AUTHENTICATE
+
 config EFI_ESRT
 	bool "Enable the UEFI ESRT generation"
 	depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 8bd343e258..fd344cea29 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -63,7 +63,7 @@ obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o
 obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o
 obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o
 obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o
-obj-y += efi_signature.o
+obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += 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_image_loader.c b/lib/efi_loader/efi_image_loader.c
index f53ef367ec..b8a790bcb9 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -213,7 +213,68 @@ static void efi_set_code_and_data_type(
 	}
 }
 
-#ifdef CONFIG_EFI_SECURE_BOOT
+/**
+ * efi_image_region_add() - add an entry of region
+ * @regs:	Pointer to array of regions
+ * @start:	Start address of region (included)
+ * @end:	End address of region (excluded)
+ * @nocheck:	flag against overlapped regions
+ *
+ * Take one entry of region [@start, @end[ and insert it into the list.
+ *
+ * * If @nocheck is false, the list will be sorted ascending by address.
+ *   Overlapping entries will not be allowed.
+ *
+ * * If @nocheck is true, the list will be sorted ascending by sequence
+ *   of adding the entries. Overlapping is allowed.
+ *
+ * Return:	status code
+ */
+efi_status_t efi_image_region_add(struct efi_image_regions *regs,
+				  const void *start, const void *end,
+				  int nocheck)
+{
+	struct image_region *reg;
+	int i, j;
+
+	if (regs->num >= regs->max) {
+		EFI_PRINT("%s: no more room for regions\n", __func__);
+		return EFI_OUT_OF_RESOURCES;
+	}
+
+	if (end < start)
+		return EFI_INVALID_PARAMETER;
+
+	for (i = 0; i < regs->num; i++) {
+		reg = &regs->reg[i];
+		if (nocheck)
+			continue;
+
+		/* new data after registered region */
+		if (start >= reg->data + reg->size)
+			continue;
+
+		/* new data preceding registered region */
+		if (end <= reg->data) {
+			for (j = regs->num - 1; j >= i; j--)
+				memcpy(&regs->reg[j + 1], &regs->reg[j],
+				       sizeof(*reg));
+			break;
+		}
+
+		/* new data overlapping registered region */
+		EFI_PRINT("%s: new region already part of another\n", __func__);
+		return EFI_INVALID_PARAMETER;
+	}
+
+	reg = &regs->reg[i];
+	reg->data = start;
+	reg->size = end - start;
+	regs->num++;
+
+	return EFI_SUCCESS;
+}
+
 /**
  * cmp_pe_section() - compare virtual addresses of two PE image sections
  * @arg1:	pointer to pointer to first section header
@@ -504,6 +565,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
 
 	EFI_PRINT("%s: Enter, %d\n", __func__, ret);
 
+	if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
+		return true;
+
 	if (!efi_secure_boot_enabled())
 		return true;
 
@@ -668,13 +732,6 @@ err:
 	EFI_PRINT("%s: Exit, %d\n", __func__, ret);
 	return ret;
 }
-#else
-static bool efi_image_authenticate(void *efi, size_t efi_size)
-{
-	return true;
-}
-#endif /* CONFIG_EFI_SECURE_BOOT */
-
 
 /**
  * efi_check_pe() - check if a memory buffer contains a PE-COFF image
diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c
index c7ec275414..bdd09881fc 100644
--- a/lib/efi_loader/efi_signature.c
+++ b/lib/efi_loader/efi_signature.c
@@ -15,18 +15,16 @@
 #include <crypto/public_key.h>
 #include <linux/compat.h>
 #include <linux/oid_registry.h>
+#include <u-boot/hash-checksum.h>
 #include <u-boot/rsa.h>
 #include <u-boot/sha256.h>
 
-const efi_guid_t efi_guid_image_security_database =
-		EFI_IMAGE_SECURITY_DATABASE_GUID;
 const efi_guid_t efi_guid_sha256 = EFI_CERT_SHA256_GUID;
 const efi_guid_t efi_guid_cert_rsa2048 = EFI_CERT_RSA2048_GUID;
 const efi_guid_t efi_guid_cert_x509 = EFI_CERT_X509_GUID;
 const efi_guid_t efi_guid_cert_x509_sha256 = EFI_CERT_X509_SHA256_GUID;
 const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
 
-#if defined(CONFIG_EFI_SECURE_BOOT) || defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
 static u8 pkcs7_hdr[] = {
 	/* SEQUENCE */
 	0x30, 0x82, 0x05, 0xc7,
@@ -539,68 +537,6 @@ out:
 	return !revoked;
 }
 
-/**
- * efi_image_region_add() - add an entry of region
- * @regs:	Pointer to array of regions
- * @start:	Start address of region (included)
- * @end:	End address of region (excluded)
- * @nocheck:	flag against overlapped regions
- *
- * Take one entry of region [@start, @end[ and insert it into the list.
- *
- * * If @nocheck is false, the list will be sorted ascending by address.
- *   Overlapping entries will not be allowed.
- *
- * * If @nocheck is true, the list will be sorted ascending by sequence
- *   of adding the entries. Overlapping is allowed.
- *
- * Return:	status code
- */
-efi_status_t efi_image_region_add(struct efi_image_regions *regs,
-				  const void *start, const void *end,
-				  int nocheck)
-{
-	struct image_region *reg;
-	int i, j;
-
-	if (regs->num >= regs->max) {
-		EFI_PRINT("%s: no more room for regions\n", __func__);
-		return EFI_OUT_OF_RESOURCES;
-	}
-
-	if (end < start)
-		return EFI_INVALID_PARAMETER;
-
-	for (i = 0; i < regs->num; i++) {
-		reg = &regs->reg[i];
-		if (nocheck)
-			continue;
-
-		/* new data after registered region */
-		if (start >= reg->data + reg->size)
-			continue;
-
-		/* new data preceding registered region */
-		if (end <= reg->data) {
-			for (j = regs->num - 1; j >= i; j--)
-				memcpy(&regs->reg[j + 1], &regs->reg[j],
-				       sizeof(*reg));
-			break;
-		}
-
-		/* new data overlapping registered region */
-		EFI_PRINT("%s: new region already part of another\n", __func__);
-		return EFI_INVALID_PARAMETER;
-	}
-
-	reg = &regs->reg[i];
-	reg->data = start;
-	reg->size = end - start;
-	regs->num++;
-
-	return EFI_SUCCESS;
-}
-
 /**
  * efi_sigstore_free - free signature store
  * @sigstore:	Pointer to signature store structure
@@ -846,4 +782,3 @@ struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name)
 
 	return efi_build_signature_store(db, db_size);
 }
-#endif /* CONFIG_EFI_SECURE_BOOT || CONFIG_EFI_CAPSULE_AUTHENTICATE */
diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
index b11ed91a74..83479dd142 100644
--- a/lib/efi_loader/efi_var_common.c
+++ b/lib/efi_loader/efi_var_common.c
@@ -24,6 +24,9 @@ struct efi_auth_var_name_type {
 	const enum efi_auth_var_type type;
 };
 
+const efi_guid_t efi_guid_image_security_database =
+		EFI_IMAGE_SECURITY_DATABASE_GUID;
+
 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},
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/2] efi_loader: add PE/COFF image measurement
  2021-04-28 12:19 [PATCH v3 0/2] PE/COFF measurement support Masahisa Kojima
  2021-04-28 12:19 ` [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled Masahisa Kojima
@ 2021-04-28 12:19 ` Masahisa Kojima
  1 sibling, 0 replies; 9+ messages in thread
From: Masahisa Kojima @ 2021-04-28 12:19 UTC (permalink / raw)
  To: u-boot

"TCG PC Client Platform Firmware Profile Specification"
requires to measure every attempt to load and execute
a OS Loader(a UEFI application) into PCR[4].
This commit adds the PE/COFF image measurement, extends PCR,
and appends measurement into Event Log.

Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
---

(no changes since v2)

Changes in v2:
- Remove duplicate <efi.h> include
- Remove unnecessary __packed attribute
- Add all EV_EFI_* event definition
- Create common function to prepare 8-byte aligned image
- Add measurement for EV_EFI_BOOT_SERVICES_DRIVER and
  EV_EFI_RUNTIME_SERVICES_DRIVER
- Use efi_search_protocol() to get device_path
- Add function comment


 include/efi_loader.h              |   6 +
 include/efi_tcg2.h                |   9 ++
 include/tpm-v2.h                  |  18 +++
 lib/efi_loader/efi_image_loader.c |  59 +++++++--
 lib/efi_loader/efi_tcg2.c         | 207 ++++++++++++++++++++++++++++--
 5 files changed, 275 insertions(+), 24 deletions(-)

diff --git a/include/efi_loader.h b/include/efi_loader.h
index de1a496a97..9f2854a255 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -426,6 +426,10 @@ efi_status_t efi_disk_register(void);
 efi_status_t efi_rng_register(void);
 /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
 efi_status_t efi_tcg2_register(void);
+/* measure the pe-coff image, extend PCR and add Event Log */
+efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
+				   struct efi_loaded_image_obj *handle,
+				   struct efi_loaded_image *loaded_image_info);
 /* Create handles and protocols for the partitions of a block device */
 int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
 			       const char *if_typename, int diskid,
@@ -847,6 +851,8 @@ bool efi_secure_boot_enabled(void);
 
 bool efi_capsule_auth_enabled(void);
 
+void *efi_prepare_aligned_image(void *efi, u64 *efi_size, void **new_efi);
+
 bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp,
 		     WIN_CERTIFICATE **auth, size_t *auth_len);
 
diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index 40e241ce31..bcfb98168a 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -9,6 +9,7 @@
 #if !defined _EFI_TCG2_PROTOCOL_H_
 #define _EFI_TCG2_PROTOCOL_H_
 
+#include <efi_api.h>
 #include <tpm-v2.h>
 
 #define EFI_TCG2_PROTOCOL_GUID \
@@ -53,6 +54,14 @@ struct efi_tcg2_event {
 	u8 event[];
 } __packed;
 
+struct uefi_image_load_event {
+	efi_physical_addr_t image_location_in_memory;
+	u64 image_length_in_memory;
+	u64 image_link_time_address;
+	u64 length_of_device_path;
+	struct efi_device_path device_path[];
+};
+
 struct efi_tcg2_boot_service_capability {
 	u8 size;
 	struct efi_tcg2_version structure_version;
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index df67a196cf..6e812c017c 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -62,6 +62,24 @@ struct udevice;
 #define EV_CPU_MICROCODE	((u32)0x00000009)
 #define EV_TABLE_OF_DEVICES	((u32)0x0000000B)
 
+/*
+ * event types, cf.
+ * "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
+ * rev 1.04, June 3, 2019
+ */
+#define EV_EFI_EVENT_BASE			((u32)0x80000000)
+#define EV_EFI_VARIABLE_DRIVER_CONFIG		((u32)0x80000001)
+#define EV_EFI_VARIABLE_BOOT			((u32)0x80000002)
+#define EV_EFI_BOOT_SERVICES_APPLICATION	((u32)0x80000003)
+#define EV_EFI_BOOT_SERVICES_DRIVER		((u32)0x80000004)
+#define EV_EFI_RUNTIME_SERVICES_DRIVER		((u32)0x80000005)
+#define EV_EFI_GPT_EVENT			((u32)0x80000006)
+#define EV_EFI_ACTION				((u32)0x80000007)
+#define EV_EFI_PLATFORM_FIRMWARE_BLOB		((u32)0x80000008)
+#define EV_EFI_HANDOFF_TABLES			((u32)0x80000009)
+#define EV_EFI_HCRTM_EVENT			((u32)0x80000010)
+#define EV_EFI_VARIABLE_AUTHORITY		((u32)0x800000E0)
+
 /* TPMS_TAGGED_PROPERTY Structure */
 struct tpms_tagged_property {
 	u32 property;
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index b8a790bcb9..cc548e1b88 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -302,6 +302,40 @@ static int cmp_pe_section(const void *arg1, const void *arg2)
 		return 1;
 }
 
+/**
+ * efi_prepare_aligned_image() - prepare 8-byte aligned image
+ * @efi:		pointer to the EFI binary
+ * @efi_size:		size of @efi binary
+ * @new_efi:		pointer to the newly allocated image
+ *
+ * If @efi is not 8-byte aligned, this function newly allocates
+ * the image buffer and updates @efi_size.
+ *
+ * Return:	valid pointer to a image, return NULL if allocation fails.
+ */
+void *efi_prepare_aligned_image(void *efi, u64 *efi_size, void **new_efi)
+{
+	size_t new_efi_size;
+	void *p;
+
+	/*
+	 * Size must be 8-byte aligned and the trailing bytes must be
+	 * zero'ed. Otherwise hash value may be incorrect.
+	 */
+	if (!IS_ALIGNED(*efi_size, 8)) {
+		new_efi_size = ALIGN(*efi_size, 8);
+		p = calloc(new_efi_size, 1);
+		if (!p)
+			return NULL;
+		memcpy(p, efi, *efi_size);
+		*efi_size = new_efi_size;
+		*new_efi = p;
+		return p;
+	} else {
+		return efi;
+	}
+}
+
 /**
  * efi_image_parse() - parse a PE image
  * @efi:	Pointer to image
@@ -560,7 +594,7 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
 	struct efi_signature_store *db = NULL, *dbx = NULL;
 	void *new_efi = NULL;
 	u8 *auth, *wincerts_end;
-	size_t new_efi_size, auth_size;
+	size_t auth_size;
 	bool ret = false;
 
 	EFI_PRINT("%s: Enter, %d\n", __func__, ret);
@@ -571,19 +605,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
 	if (!efi_secure_boot_enabled())
 		return true;
 
-	/*
-	 * Size must be 8-byte aligned and the trailing bytes must be
-	 * zero'ed. Otherwise hash value may be incorrect.
-	 */
-	if (efi_size & 0x7) {
-		new_efi_size = (efi_size + 0x7) & ~0x7ULL;
-		new_efi = calloc(new_efi_size, 1);
-		if (!new_efi)
-			return false;
-		memcpy(new_efi, efi, efi_size);
-		efi = new_efi;
-		efi_size = new_efi_size;
-	}
+	efi = efi_prepare_aligned_image(efi, (u64 *)&efi_size, &new_efi);
+	if (!efi)
+		return false;
 
 	if (!efi_image_parse(efi, efi_size, &regs, &wincerts,
 			     &wincerts_len)) {
@@ -886,6 +910,13 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
 		goto err;
 	}
 
+#if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL)
+	/* Measure an PE/COFF image */
+	if (tcg2_measure_pe_image(efi, efi_size, handle,
+				  loaded_image_info))
+		log_err("PE image measurement failed\n");
+#endif
+
 	/* Copy PE headers */
 	memcpy(efi_reloc, efi,
 	       sizeof(*dos)
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 94e8f22bbb..7ad9cb2b89 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -13,8 +13,10 @@
 #include <efi_loader.h>
 #include <efi_tcg2.h>
 #include <log.h>
+#include <malloc.h>
 #include <version.h>
 #include <tpm-v2.h>
+#include <u-boot/rsa.h>
 #include <u-boot/sha1.h>
 #include <u-boot/sha256.h>
 #include <u-boot/sha512.h>
@@ -706,6 +708,183 @@ out:
 	return EFI_EXIT(ret);
 }
 
+/**
+ * tcg2_hash_pe_image() - calculate PE/COFF image hash
+ *
+ * @efi:		pointer to the EFI binary
+ * @efi_size:		size of @efi binary
+ * @digest_list:	list of digest algorithms to extend
+ *
+ * Return:	status code
+ */
+static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size,
+				       struct tpml_digest_values *digest_list)
+{
+	WIN_CERTIFICATE *wincerts = NULL;
+	size_t wincerts_len;
+	struct efi_image_regions *regs = NULL;
+	void *new_efi = NULL;
+	u8 hash[TPM2_SHA512_DIGEST_SIZE];
+	efi_status_t ret;
+	u32 active;
+	int i;
+
+	efi = efi_prepare_aligned_image(efi, &efi_size, &new_efi);
+	if (!efi)
+		return EFI_OUT_OF_RESOURCES;
+
+	if (!efi_image_parse(efi, efi_size, &regs, &wincerts,
+			     &wincerts_len)) {
+		log_err("Parsing PE executable image failed\n");
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	ret = __get_active_pcr_banks(&active);
+	if (ret != EFI_SUCCESS) {
+		ret = EFI_DEVICE_ERROR;
+		goto out;
+	}
+
+	digest_list->count = 0;
+	for (i = 0; i < MAX_HASH_COUNT; i++) {
+		u16 hash_alg = hash_algo_list[i].hash_alg;
+
+		if (!(active & alg_to_mask(hash_alg)))
+			continue;
+		switch (hash_alg) {
+		case TPM2_ALG_SHA1:
+			hash_calculate("sha1", regs->reg, regs->num, hash);
+			break;
+		case TPM2_ALG_SHA256:
+			hash_calculate("sha256", regs->reg, regs->num, hash);
+			break;
+		case TPM2_ALG_SHA384:
+			hash_calculate("sha384", regs->reg, regs->num, hash);
+			break;
+		case TPM2_ALG_SHA512:
+			hash_calculate("sha512", regs->reg, regs->num, hash);
+			break;
+		default:
+			EFI_PRINT("Unsupported algorithm %x\n", hash_alg);
+			return EFI_INVALID_PARAMETER;
+		}
+		digest_list->digests[i].hash_alg = hash_alg;
+		memcpy(&digest_list->digests[i].digest, hash, (u32)alg_to_len(hash_alg));
+		digest_list->count++;
+	}
+
+out:
+	free(new_efi);
+	free(regs);
+
+	return ret;
+}
+
+/**
+ * tcg2_measure_pe_image() - measure PE/COFF image
+ *
+ * @efi:		pointer to the EFI binary
+ * @efi_size:		size of @efi binary
+ * @handle:		loaded image handle
+ * @loaded_image:	loaded image protocol
+ *
+ * Return:	status code
+ */
+efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
+				   struct efi_loaded_image_obj *handle,
+				   struct efi_loaded_image *loaded_image)
+{
+	struct tpml_digest_values digest_list;
+	efi_status_t ret;
+	struct udevice *dev;
+	u32 pcr_index, event_type, event_size;
+	struct uefi_image_load_event *image_load_event;
+	struct efi_device_path *device_path;
+	u32 device_path_length;
+	IMAGE_DOS_HEADER *dos;
+	IMAGE_NT_HEADERS32 *nt;
+	struct efi_handler *handler;
+
+	ret = platform_get_tpm2_device(&dev);
+	if (ret != EFI_SUCCESS)
+		return ret;
+
+	switch (handle->image_type) {
+	case IMAGE_SUBSYSTEM_EFI_APPLICATION:
+		pcr_index = 4;
+		event_type = EV_EFI_BOOT_SERVICES_APPLICATION;
+		break;
+	case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+		pcr_index = 2;
+		event_type = EV_EFI_BOOT_SERVICES_DRIVER;
+		break;
+	case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+		pcr_index = 2;
+		event_type = EV_EFI_RUNTIME_SERVICES_DRIVER;
+		break;
+	default:
+		return EFI_UNSUPPORTED;
+	}
+
+	ret = tcg2_hash_pe_image(efi, efi_size, &digest_list);
+	if (ret != EFI_SUCCESS)
+		return ret;
+
+	ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
+	if (ret != EFI_SUCCESS)
+		return ret;
+
+	ret = EFI_CALL(efi_search_protocol(&handle->header,
+					   &efi_guid_loaded_image_device_path,
+					   &handler));
+	if (ret != EFI_SUCCESS)
+		return ret;
+
+	device_path = EFI_CALL(handler->protocol_interface);
+	device_path_length = efi_dp_size(device_path);
+	if (device_path_length > 0) {
+		/* add end node size */
+		device_path_length += sizeof(struct efi_device_path);
+	}
+	event_size = sizeof(struct uefi_image_load_event) + device_path_length;
+	image_load_event = (struct uefi_image_load_event *)malloc(event_size);
+	if (!image_load_event)
+		return EFI_OUT_OF_RESOURCES;
+
+	image_load_event->image_location_in_memory = (efi_physical_addr_t)efi;
+	image_load_event->image_length_in_memory = efi_size;
+	image_load_event->length_of_device_path = device_path_length;
+
+	dos = (IMAGE_DOS_HEADER *)efi;
+	nt = (IMAGE_NT_HEADERS32 *)(efi + dos->e_lfanew);
+	if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+		IMAGE_NT_HEADERS64 *nt64 = (IMAGE_NT_HEADERS64 *)nt;
+
+		image_load_event->image_link_time_address =
+				nt64->OptionalHeader.ImageBase;
+	} else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+		image_load_event->image_link_time_address =
+				nt->OptionalHeader.ImageBase;
+	} else {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (device_path_length > 0) {
+		memcpy(image_load_event->device_path, device_path,
+		       device_path_length);
+	}
+
+	ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
+				    event_size, (u8 *)image_load_event);
+
+out:
+	free(image_load_event);
+
+	return ret;
+}
+
 /**
  * efi_tcg2_hash_log_extend_event() - extend and optionally log events
  *
@@ -758,24 +937,32 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags,
 	/*
 	 * if PE_COFF_IMAGE is set we need to make sure the image is not
 	 * corrupted, verify it and hash the PE/COFF image in accordance with
-	 * the  procedure  specified  in  "Calculating  the  PE  Image  Hash"
-	 * section  of the "Windows Authenticode Portable Executable Signature
+	 * the procedure specified in "Calculating the PE Image Hash"
+	 * section of the "Windows Authenticode Portable Executable Signature
 	 * Format"
-	 * Not supported for now
 	 */
 	if (flags & PE_COFF_IMAGE) {
-		ret = EFI_UNSUPPORTED;
-		goto out;
-	}
+		IMAGE_NT_HEADERS32 *nt;
 
-	pcr_index = efi_tcg_event->header.pcr_index;
-	event_type = efi_tcg_event->header.event_type;
+		ret = efi_check_pe((void *)data_to_hash, data_to_hash_len,
+				   (void **)&nt);
+		if (ret != EFI_SUCCESS) {
+			log_err("Not a valid PE-COFF file\n");
+			goto out;
+		}
 
-	ret = tcg2_create_digest((u8 *)data_to_hash, data_to_hash_len,
-				 &digest_list);
+		ret = tcg2_hash_pe_image((void *)data_to_hash, data_to_hash_len,
+					 &digest_list);
+	} else {
+		ret = tcg2_create_digest((u8 *)data_to_hash, data_to_hash_len,
+					 &digest_list);
+	}
 	if (ret != EFI_SUCCESS)
 		goto out;
 
+	pcr_index = efi_tcg_event->header.pcr_index;
+	event_type = efi_tcg_event->header.event_type;
+
 	ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
 	if (ret != EFI_SUCCESS)
 		goto out;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled
  2021-04-28 12:19 ` [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled Masahisa Kojima
@ 2021-04-28 13:16   ` Heinrich Schuchardt
  2021-05-08 14:08     ` Heinrich Schuchardt
  0 siblings, 1 reply; 9+ messages in thread
From: Heinrich Schuchardt @ 2021-04-28 13:16 UTC (permalink / raw)
  To: u-boot

On 28.04.21 14:19, Masahisa Kojima wrote:
> This is preparation for PE/COFF measurement support.
> PE/COFF image hash calculation is same in both
> UEFI Secure Boot image verification and measurement in
> measured boot. PE/COFF image parsing functions are
> gathered into efi_image_loader.c, and exposed even if
> UEFI Secure Boot is not enabled.
>
> This commit also adds the EFI_SIGNATURE_SUPPORT option
> to decide if efi_signature.c shall be compiled.
>
> Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> ---
>
> Changes in v3:
> - hide EFI_SIGNATURE_SUPPORT option
>
> Changes in v2:
> - Remove all #ifdef from efi_image_loader.c and efi_signature.c
> - Add EFI_SIGNATURE_SUPPORT option
> - Explicitly include <u-boot/hash-checksum.h>
> - Gather PE/COFF parsing functions into efi_image_loader.c
> - Move efi_guid_t efi_guid_image_security_database in efi_var_common.c
>
>
>  lib/efi_loader/Kconfig            |  6 +++
>  lib/efi_loader/Makefile           |  2 +-
>  lib/efi_loader/efi_image_loader.c | 73 +++++++++++++++++++++++++++----
>  lib/efi_loader/efi_signature.c    | 67 +---------------------------
>  lib/efi_loader/efi_var_common.c   |  3 ++
>  5 files changed, 76 insertions(+), 75 deletions(-)
>
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 0b99d7c774..b76e77180e 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -174,6 +174,7 @@ config EFI_CAPSULE_AUTHENTICATE
>  	select PKCS7_MESSAGE_PARSER
>  	select PKCS7_VERIFY
>  	select IMAGE_SIGN_INFO
> +	select EFI_SIGNATURE_SUPPORT
>  	default n
>  	help
>  	  Select this option if you want to enable capsule
> @@ -336,6 +337,7 @@ config EFI_SECURE_BOOT
>  	select X509_CERTIFICATE_PARSER
>  	select PKCS7_MESSAGE_PARSER
>  	select PKCS7_VERIFY
> +	select EFI_SIGNATURE_SUPPORT
>  	default n
>  	help
>  	  Select this option to enable EFI secure boot support.
> @@ -343,6 +345,10 @@ 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_SIGNATURE_SUPPORT
> +	bool
> +	depends on EFI_SECURE_BOOT || EFI_CAPSULE_AUTHENTICATE
> +
>  config EFI_ESRT
>  	bool "Enable the UEFI ESRT generation"
>  	depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> index 8bd343e258..fd344cea29 100644
> --- a/lib/efi_loader/Makefile
> +++ b/lib/efi_loader/Makefile
> @@ -63,7 +63,7 @@ obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o
>  obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o
>  obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o
>  obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o
> -obj-y += efi_signature.o
> +obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += 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_image_loader.c b/lib/efi_loader/efi_image_loader.c
> index f53ef367ec..b8a790bcb9 100644
> --- a/lib/efi_loader/efi_image_loader.c
> +++ b/lib/efi_loader/efi_image_loader.c
> @@ -213,7 +213,68 @@ static void efi_set_code_and_data_type(
>  	}
>  }
>
> -#ifdef CONFIG_EFI_SECURE_BOOT
> +/**
> + * efi_image_region_add() - add an entry of region
> + * @regs:	Pointer to array of regions
> + * @start:	Start address of region (included)
> + * @end:	End address of region (excluded)
> + * @nocheck:	flag against overlapped regions
> + *
> + * Take one entry of region [@start, @end[ and insert it into the list.
> + *
> + * * If @nocheck is false, the list will be sorted ascending by address.
> + *   Overlapping entries will not be allowed.
> + *
> + * * If @nocheck is true, the list will be sorted ascending by sequence
> + *   of adding the entries. Overlapping is allowed.
> + *
> + * Return:	status code
> + */
> +efi_status_t efi_image_region_add(struct efi_image_regions *regs,
> +				  const void *start, const void *end,
> +				  int nocheck)
> +{
> +	struct image_region *reg;
> +	int i, j;
> +
> +	if (regs->num >= regs->max) {
> +		EFI_PRINT("%s: no more room for regions\n", __func__);
> +		return EFI_OUT_OF_RESOURCES;
> +	}
> +
> +	if (end < start)
> +		return EFI_INVALID_PARAMETER;
> +
> +	for (i = 0; i < regs->num; i++) {
> +		reg = &regs->reg[i];
> +		if (nocheck)
> +			continue;
> +
> +		/* new data after registered region */
> +		if (start >= reg->data + reg->size)
> +			continue;
> +
> +		/* new data preceding registered region */
> +		if (end <= reg->data) {
> +			for (j = regs->num - 1; j >= i; j--)
> +				memcpy(&regs->reg[j + 1], &regs->reg[j],
> +				       sizeof(*reg));
> +			break;
> +		}
> +
> +		/* new data overlapping registered region */
> +		EFI_PRINT("%s: new region already part of another\n", __func__);
> +		return EFI_INVALID_PARAMETER;
> +	}
> +
> +	reg = &regs->reg[i];
> +	reg->data = start;
> +	reg->size = end - start;
> +	regs->num++;
> +
> +	return EFI_SUCCESS;
> +}
> +
>  /**
>   * cmp_pe_section() - compare virtual addresses of two PE image sections
>   * @arg1:	pointer to pointer to first section header
> @@ -504,6 +565,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
>
>  	EFI_PRINT("%s: Enter, %d\n", __func__, ret);
>
> +	if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> +		return true;
> +

Why is this needed? Doesn't efi_secure_boot_enabled() return false in
this case?

Best regards

Heinrich

>  	if (!efi_secure_boot_enabled())
>  		return true;
>
> @@ -668,13 +732,6 @@ err:
>  	EFI_PRINT("%s: Exit, %d\n", __func__, ret);
>  	return ret;
>  }
> -#else
> -static bool efi_image_authenticate(void *efi, size_t efi_size)
> -{
> -	return true;
> -}
> -#endif /* CONFIG_EFI_SECURE_BOOT */
> -
>
>  /**
>   * efi_check_pe() - check if a memory buffer contains a PE-COFF image
> diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c
> index c7ec275414..bdd09881fc 100644
> --- a/lib/efi_loader/efi_signature.c
> +++ b/lib/efi_loader/efi_signature.c
> @@ -15,18 +15,16 @@
>  #include <crypto/public_key.h>
>  #include <linux/compat.h>
>  #include <linux/oid_registry.h>
> +#include <u-boot/hash-checksum.h>
>  #include <u-boot/rsa.h>
>  #include <u-boot/sha256.h>
>
> -const efi_guid_t efi_guid_image_security_database =
> -		EFI_IMAGE_SECURITY_DATABASE_GUID;
>  const efi_guid_t efi_guid_sha256 = EFI_CERT_SHA256_GUID;
>  const efi_guid_t efi_guid_cert_rsa2048 = EFI_CERT_RSA2048_GUID;
>  const efi_guid_t efi_guid_cert_x509 = EFI_CERT_X509_GUID;
>  const efi_guid_t efi_guid_cert_x509_sha256 = EFI_CERT_X509_SHA256_GUID;
>  const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
>
> -#if defined(CONFIG_EFI_SECURE_BOOT) || defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
>  static u8 pkcs7_hdr[] = {
>  	/* SEQUENCE */
>  	0x30, 0x82, 0x05, 0xc7,
> @@ -539,68 +537,6 @@ out:
>  	return !revoked;
>  }
>
> -/**
> - * efi_image_region_add() - add an entry of region
> - * @regs:	Pointer to array of regions
> - * @start:	Start address of region (included)
> - * @end:	End address of region (excluded)
> - * @nocheck:	flag against overlapped regions
> - *
> - * Take one entry of region [@start, @end[ and insert it into the list.
> - *
> - * * If @nocheck is false, the list will be sorted ascending by address.
> - *   Overlapping entries will not be allowed.
> - *
> - * * If @nocheck is true, the list will be sorted ascending by sequence
> - *   of adding the entries. Overlapping is allowed.
> - *
> - * Return:	status code
> - */
> -efi_status_t efi_image_region_add(struct efi_image_regions *regs,
> -				  const void *start, const void *end,
> -				  int nocheck)
> -{
> -	struct image_region *reg;
> -	int i, j;
> -
> -	if (regs->num >= regs->max) {
> -		EFI_PRINT("%s: no more room for regions\n", __func__);
> -		return EFI_OUT_OF_RESOURCES;
> -	}
> -
> -	if (end < start)
> -		return EFI_INVALID_PARAMETER;
> -
> -	for (i = 0; i < regs->num; i++) {
> -		reg = &regs->reg[i];
> -		if (nocheck)
> -			continue;
> -
> -		/* new data after registered region */
> -		if (start >= reg->data + reg->size)
> -			continue;
> -
> -		/* new data preceding registered region */
> -		if (end <= reg->data) {
> -			for (j = regs->num - 1; j >= i; j--)
> -				memcpy(&regs->reg[j + 1], &regs->reg[j],
> -				       sizeof(*reg));
> -			break;
> -		}
> -
> -		/* new data overlapping registered region */
> -		EFI_PRINT("%s: new region already part of another\n", __func__);
> -		return EFI_INVALID_PARAMETER;
> -	}
> -
> -	reg = &regs->reg[i];
> -	reg->data = start;
> -	reg->size = end - start;
> -	regs->num++;
> -
> -	return EFI_SUCCESS;
> -}
> -
>  /**
>   * efi_sigstore_free - free signature store
>   * @sigstore:	Pointer to signature store structure
> @@ -846,4 +782,3 @@ struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name)
>
>  	return efi_build_signature_store(db, db_size);
>  }
> -#endif /* CONFIG_EFI_SECURE_BOOT || CONFIG_EFI_CAPSULE_AUTHENTICATE */
> diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
> index b11ed91a74..83479dd142 100644
> --- a/lib/efi_loader/efi_var_common.c
> +++ b/lib/efi_loader/efi_var_common.c
> @@ -24,6 +24,9 @@ struct efi_auth_var_name_type {
>  	const enum efi_auth_var_type type;
>  };
>
> +const efi_guid_t efi_guid_image_security_database =
> +		EFI_IMAGE_SECURITY_DATABASE_GUID;
> +
>  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},
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled
  2021-04-28 13:16   ` Heinrich Schuchardt
@ 2021-05-08 14:08     ` Heinrich Schuchardt
  2021-05-10  0:49       ` Masahisa Kojima
  0 siblings, 1 reply; 9+ messages in thread
From: Heinrich Schuchardt @ 2021-05-08 14:08 UTC (permalink / raw)
  To: u-boot

On 4/28/21 3:16 PM, Heinrich Schuchardt wrote:
> On 28.04.21 14:19, Masahisa Kojima wrote:
<snip />
>>   /**
>>    * cmp_pe_section() - compare virtual addresses of two PE image sections
>>    * @arg1:	pointer to pointer to first section header
>> @@ -504,6 +565,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
>>
>>   	EFI_PRINT("%s: Enter, %d\n", __func__, ret);
>>
>> +	if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
>> +		return true;
>> +
>
> Why is this needed? Doesn't efi_secure_boot_enabled() return false in
> this case?

Hello Masahisa,

I did not see any reply yet. Was a mail lost?

Best regards

Heinrich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled
  2021-05-08 14:08     ` Heinrich Schuchardt
@ 2021-05-10  0:49       ` Masahisa Kojima
  2021-05-10  2:07         ` Takahiro Akashi
  0 siblings, 1 reply; 9+ messages in thread
From: Masahisa Kojima @ 2021-05-10  0:49 UTC (permalink / raw)
  To: u-boot

Hi Heinrich,

Sorry for the late reply.

On Sat, 8 May 2021 at 23:08, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> On 4/28/21 3:16 PM, Heinrich Schuchardt wrote:
> > On 28.04.21 14:19, Masahisa Kojima wrote:
> <snip />
> >>   /**
> >>    * cmp_pe_section() - compare virtual addresses of two PE image sections
> >>    * @arg1:  pointer to pointer to first section header
> >> @@ -504,6 +565,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
> >>
> >>      EFI_PRINT("%s: Enter, %d\n", __func__, ret);
> >>
> >> +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> >> +            return true;
> >> +
> >
> > Why is this needed? Doesn't efi_secure_boot_enabled() return false in
> > this case?

The original code is as follows.

#ifdef CONFIG_EFI_SECURE_BOOT
static bool efi_image_authenticate(void *efi, size_t efi_size) {

  < snip >

 }
#else
static bool efi_image_authenticate(void *efi, size_t efi_size)
{
       return true;
}
#endif /* CONFIG_EFI_SECURE_BOOT */

The purpose of this commit is removing #if compilation switch,
so I keep the original implementation, always return true
if CONFIG_EFI_SECURE_BOOT is disabled.

Thanks,
Masahisa

>
> Hello Masahisa,
>
> I did not see any reply yet. Was a mail lost?
>
> Best regards
>
> Heinrich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled
  2021-05-10  0:49       ` Masahisa Kojima
@ 2021-05-10  2:07         ` Takahiro Akashi
  2021-05-10 22:06           ` Masahisa Kojima
  0 siblings, 1 reply; 9+ messages in thread
From: Takahiro Akashi @ 2021-05-10  2:07 UTC (permalink / raw)
  To: u-boot

On Mon, May 10, 2021 at 09:49:03AM +0900, Masahisa Kojima wrote:
> Hi Heinrich,
> 
> Sorry for the late reply.
> 
> On Sat, 8 May 2021 at 23:08, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> >
> > On 4/28/21 3:16 PM, Heinrich Schuchardt wrote:
> > > On 28.04.21 14:19, Masahisa Kojima wrote:
> > <snip />
> > >>   /**
> > >>    * cmp_pe_section() - compare virtual addresses of two PE image sections
> > >>    * @arg1:  pointer to pointer to first section header
> > >> @@ -504,6 +565,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
> > >>
> > >>      EFI_PRINT("%s: Enter, %d\n", __func__, ret);
> > >>
> > >> +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > >> +            return true;
> > >> +
> > >
> > > Why is this needed? Doesn't efi_secure_boot_enabled() return false in
> > > this case?
> 
> The original code is as follows.

Heinrich's concern was, I guess, that

> > >> +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > >> +            return true;

and the succeeding check,

        if (!efi_secure_boot_enabled())
                        return true;

are somehow redundant.
But in the latter case, I'm afraid that a compiler cannot optimize out
the rest of the logic in efi_image_authenticate().

-Takahiro Akashi


> #ifdef CONFIG_EFI_SECURE_BOOT
> static bool efi_image_authenticate(void *efi, size_t efi_size) {
> 
>   < snip >
> 
>  }
> #else
> static bool efi_image_authenticate(void *efi, size_t efi_size)
> {
>        return true;
> }
> #endif /* CONFIG_EFI_SECURE_BOOT */
> 
> The purpose of this commit is removing #if compilation switch,
> so I keep the original implementation, always return true
> if CONFIG_EFI_SECURE_BOOT is disabled.
> 
> Thanks,
> Masahisa
> 
> >
> > Hello Masahisa,
> >
> > I did not see any reply yet. Was a mail lost?
> >
> > Best regards
> >
> > Heinrich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled
  2021-05-10  2:07         ` Takahiro Akashi
@ 2021-05-10 22:06           ` Masahisa Kojima
  2021-05-12  6:57             ` Masahisa Kojima
  0 siblings, 1 reply; 9+ messages in thread
From: Masahisa Kojima @ 2021-05-10 22:06 UTC (permalink / raw)
  To: u-boot

On Mon, 10 May 2021 at 11:07, Takahiro Akashi
<takahiro.akashi@linaro.org> wrote:
>
> On Mon, May 10, 2021 at 09:49:03AM +0900, Masahisa Kojima wrote:
> > Hi Heinrich,
> >
> > Sorry for the late reply.
> >
> > On Sat, 8 May 2021 at 23:08, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> > >
> > > On 4/28/21 3:16 PM, Heinrich Schuchardt wrote:
> > > > On 28.04.21 14:19, Masahisa Kojima wrote:
> > > <snip />
> > > >>   /**
> > > >>    * cmp_pe_section() - compare virtual addresses of two PE image sections
> > > >>    * @arg1:  pointer to pointer to first section header
> > > >> @@ -504,6 +565,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
> > > >>
> > > >>      EFI_PRINT("%s: Enter, %d\n", __func__, ret);
> > > >>
> > > >> +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > > >> +            return true;
> > > >> +
> > > >
> > > > Why is this needed? Doesn't efi_secure_boot_enabled() return false in
> > > > this case?
> >
> > The original code is as follows.
>
> Heinrich's concern was, I guess, that
>
> > > >> +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > > >> +            return true;
>
> and the succeeding check,
>
>         if (!efi_secure_boot_enabled())
>                         return true;
>
> are somehow redundant.
> But in the latter case, I'm afraid that a compiler cannot optimize out
> the rest of the logic in efi_image_authenticate().

Hi Heinrich, Takahiro,

Sorry for the late reply.
I now understand Takahiro's concern.
If I remove following check,

> +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> +            return true;

compiler optimization does not work and link error occurs.

lib/built-in.o: In function `efi_image_authenticate':
/home/ubuntu/SynQuacer/ledge/u-boot/lib/efi_loader/efi_image_loader.c:601:
undefined reference to `efi_sigstore_parse_sigdb'
/home/ubuntu/SynQuacer/ledge/u-boot/lib/efi_loader/efi_image_loader.c:607:
undefined reference to `efi_sigstore_parse_sigdb'
/home/ubuntu/SynQuacer/ledge/u-boot/lib/efi_loader/efi_image_loader.c:613:
undefined reference to `efi_signature_lookup_digest'

I would like to propose two resolution.

1) keep if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) condition
2) remove if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) condition and
    always include efi_signature.c as compilation target.

Please advise.

Thanks,
Masahisa


>
> -Takahiro Akashi
>
>
> > #ifdef CONFIG_EFI_SECURE_BOOT
> > static bool efi_image_authenticate(void *efi, size_t efi_size) {
> >
> >   < snip >
> >
> >  }
> > #else
> > static bool efi_image_authenticate(void *efi, size_t efi_size)
> > {
> >        return true;
> > }
> > #endif /* CONFIG_EFI_SECURE_BOOT */
> >
> > The purpose of this commit is removing #if compilation switch,
> > so I keep the original implementation, always return true
> > if CONFIG_EFI_SECURE_BOOT is disabled.
> >
> > Thanks,
> > Masahisa
> >
> > >
> > > Hello Masahisa,
> > >
> > > I did not see any reply yet. Was a mail lost?
> > >
> > > Best regards
> > >
> > > Heinrich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled
  2021-05-10 22:06           ` Masahisa Kojima
@ 2021-05-12  6:57             ` Masahisa Kojima
  0 siblings, 0 replies; 9+ messages in thread
From: Masahisa Kojima @ 2021-05-12  6:57 UTC (permalink / raw)
  To: u-boot

Hi Heinrich,

I'm about to send v4 patch series.

> 1) keep if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) condition

I chose this option, but I reverted #ifdef statement instead of using
"if (IS_ENABLED)" because I think it is better not to rely on compiler
optimization.

> 2) remove if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) condition and
>     always include efi_signature.c as compilation target.

In this option, CONFIG_PKCS7_VERIFY is required for EFI_TCG2_PROTOCOL
just for successful build.
To minimize dependency, I did not proceed with 2).

Please kindly review v4.

Thanks,
Masahisa

On Tue, 11 May 2021 at 07:06, Masahisa Kojima
<masahisa.kojima@linaro.org> wrote:
>
> On Mon, 10 May 2021 at 11:07, Takahiro Akashi
> <takahiro.akashi@linaro.org> wrote:
> >
> > On Mon, May 10, 2021 at 09:49:03AM +0900, Masahisa Kojima wrote:
> > > Hi Heinrich,
> > >
> > > Sorry for the late reply.
> > >
> > > On Sat, 8 May 2021 at 23:08, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> > > >
> > > > On 4/28/21 3:16 PM, Heinrich Schuchardt wrote:
> > > > > On 28.04.21 14:19, Masahisa Kojima wrote:
> > > > <snip />
> > > > >>   /**
> > > > >>    * cmp_pe_section() - compare virtual addresses of two PE image sections
> > > > >>    * @arg1:  pointer to pointer to first section header
> > > > >> @@ -504,6 +565,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
> > > > >>
> > > > >>      EFI_PRINT("%s: Enter, %d\n", __func__, ret);
> > > > >>
> > > > >> +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > > > >> +            return true;
> > > > >> +
> > > > >
> > > > > Why is this needed? Doesn't efi_secure_boot_enabled() return false in
> > > > > this case?
> > >
> > > The original code is as follows.
> >
> > Heinrich's concern was, I guess, that
> >
> > > > >> +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > > > >> +            return true;
> >
> > and the succeeding check,
> >
> >         if (!efi_secure_boot_enabled())
> >                         return true;
> >
> > are somehow redundant.
> > But in the latter case, I'm afraid that a compiler cannot optimize out
> > the rest of the logic in efi_image_authenticate().
>
> Hi Heinrich, Takahiro,
>
> Sorry for the late reply.
> I now understand Takahiro's concern.
> If I remove following check,
>
> > +    if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > +            return true;
>
> compiler optimization does not work and link error occurs.
>
> lib/built-in.o: In function `efi_image_authenticate':
> /home/ubuntu/SynQuacer/ledge/u-boot/lib/efi_loader/efi_image_loader.c:601:
> undefined reference to `efi_sigstore_parse_sigdb'
> /home/ubuntu/SynQuacer/ledge/u-boot/lib/efi_loader/efi_image_loader.c:607:
> undefined reference to `efi_sigstore_parse_sigdb'
> /home/ubuntu/SynQuacer/ledge/u-boot/lib/efi_loader/efi_image_loader.c:613:
> undefined reference to `efi_signature_lookup_digest'
>
> I would like to propose two resolution.
>
> 1) keep if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) condition
> 2) remove if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) condition and
>     always include efi_signature.c as compilation target.
>
> Please advise.
>
> Thanks,
> Masahisa
>
>
> >
> > -Takahiro Akashi
> >
> >
> > > #ifdef CONFIG_EFI_SECURE_BOOT
> > > static bool efi_image_authenticate(void *efi, size_t efi_size) {
> > >
> > >   < snip >
> > >
> > >  }
> > > #else
> > > static bool efi_image_authenticate(void *efi, size_t efi_size)
> > > {
> > >        return true;
> > > }
> > > #endif /* CONFIG_EFI_SECURE_BOOT */
> > >
> > > The purpose of this commit is removing #if compilation switch,
> > > so I keep the original implementation, always return true
> > > if CONFIG_EFI_SECURE_BOOT is disabled.
> > >
> > > Thanks,
> > > Masahisa
> > >
> > > >
> > > > Hello Masahisa,
> > > >
> > > > I did not see any reply yet. Was a mail lost?
> > > >
> > > > Best regards
> > > >
> > > > Heinrich

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-05-12  6:57 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-28 12:19 [PATCH v3 0/2] PE/COFF measurement support Masahisa Kojima
2021-04-28 12:19 ` [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled Masahisa Kojima
2021-04-28 13:16   ` Heinrich Schuchardt
2021-05-08 14:08     ` Heinrich Schuchardt
2021-05-10  0:49       ` Masahisa Kojima
2021-05-10  2:07         ` Takahiro Akashi
2021-05-10 22:06           ` Masahisa Kojima
2021-05-12  6:57             ` Masahisa Kojima
2021-04-28 12:19 ` [PATCH v3 2/2] efi_loader: add PE/COFF image measurement Masahisa Kojima

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.