All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] tpm: Support boot measurements
@ 2023-01-09 21:55 Eddie James
  2023-01-09 21:55 ` [PATCH v2 1/5] tpm: Fix spelling for tpmu_ha union Eddie James
                   ` (5 more replies)
  0 siblings, 6 replies; 18+ messages in thread
From: Eddie James @ 2023-01-09 21:55 UTC (permalink / raw)
  To: u-boot; +Cc: ilias.apalodimas, sjg, xypron.glpk, eajames

This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm 
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions.
 - Add test case
 - Drop #ifdefs for bootm
 - Add devicetree measurement config option
 - Update sandbox TPM driver

Eddie James (5):
  tpm: Fix spelling for tpmu_ha union
  tpm: Support boot measurements
  bootm: Support boot measurement
  tpm: sandbox: Update for needed TPM2 capabilities
  test: Add sandbox TPM boot measurement

 arch/sandbox/dts/test.dts      |  12 +
 boot/Kconfig                   |  23 ++
 boot/bootm.c                   |  64 +++
 cmd/bootm.c                    |   2 +
 configs/sandbox_defconfig      |   1 +
 drivers/tpm/tpm2_tis_sandbox.c | 100 +++--
 include/bootm.h                |   2 +
 include/efi_tcg2.h             |  44 --
 include/image.h                |   1 +
 include/test/suites.h          |   1 +
 include/tpm-v2.h               | 215 +++++++++-
 lib/efi_loader/efi_tcg2.c      | 362 +----------------
 lib/tpm-v2.c                   | 708 +++++++++++++++++++++++++++++++++
 test/boot/Makefile             |   1 +
 test/boot/measurement.c        |  66 +++
 test/cmd_ut.c                  |   2 +
 16 files changed, 1187 insertions(+), 417 deletions(-)
 create mode 100644 test/boot/measurement.c

-- 
2.31.1


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

* [PATCH v2 1/5] tpm: Fix spelling for tpmu_ha union
  2023-01-09 21:55 [PATCH v2 0/5] tpm: Support boot measurements Eddie James
@ 2023-01-09 21:55 ` Eddie James
  2023-01-09 21:55 ` [PATCH v2 2/5] tpm: Support boot measurements Eddie James
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Eddie James @ 2023-01-09 21:55 UTC (permalink / raw)
  To: u-boot; +Cc: ilias.apalodimas, sjg, xypron.glpk, eajames

tmpu -> tpmu

Signed-off-by: Eddie James <eajames@linux.ibm.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 737e57551d..85feda3e06 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -167,7 +167,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
 	u8 sha1[TPM2_SHA1_DIGEST_SIZE];
 	u8 sha256[TPM2_SHA256_DIGEST_SIZE];
 	u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -183,7 +183,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
 	u16 hash_alg;
-	union tmpu_ha digest;
+	union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.31.1


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

* [PATCH v2 2/5] tpm: Support boot measurements
  2023-01-09 21:55 [PATCH v2 0/5] tpm: Support boot measurements Eddie James
  2023-01-09 21:55 ` [PATCH v2 1/5] tpm: Fix spelling for tpmu_ha union Eddie James
@ 2023-01-09 21:55 ` Eddie James
  2023-01-09 21:55 ` [PATCH v2 3/5] bootm: Support boot measurement Eddie James
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Eddie James @ 2023-01-09 21:55 UTC (permalink / raw)
  To: u-boot; +Cc: ilias.apalodimas, sjg, xypron.glpk, eajames

Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
---
 include/efi_tcg2.h        |  44 ---
 include/tpm-v2.h          | 211 ++++++++++++
 lib/efi_loader/efi_tcg2.c | 362 +------------------
 lib/tpm-v2.c              | 708 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 938 insertions(+), 387 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index 874306dc11..23016773f4 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
 	offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id:	algorithm defined in enum tpm2_algorithms
- *  @digest_size:	size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-	u16      algorithm_id;
-	u16      digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature:			signature, set to Spec ID Event03
- * @platform_class:		class defined in TCG ACPI Specification
- *				Client  Common Header.
- * @spec_version_minor:		minor version
- * @spec_version_major:		major version
- * @spec_version_errata:	major version
- * @uintn_size:			size of the efi_uintn_t fields used in various
- *				data structures used in this specification.
- *				0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:	hashing algorithms used in this event log
- * @digest_sizes:		array of number_of_algorithms pairs
- *				1st member defines the algorithm id
- *				2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-	u8 signature[16];
-	u32 platform_class;
-	u8 spec_version_minor;
-	u8 spec_version_major;
-	u8 spec_errata;
-	u8 uintn_size;
-	u32 number_of_algorithms;
-	struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-} __packed;
-
 /**
  * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get Event Log
  * @version:		version number for this structure
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 85feda3e06..e3db3419dd 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -214,6 +214,50 @@ struct tcg_pcr_event2 {
 	u8 event[];
 } __packed;
 
+/**
+ *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
+ *
+ *  @algorithm_id:	algorithm defined in enum tpm2_algorithms
+ *  @digest_size:	size of the algorithm
+ */
+struct tcg_efi_spec_id_event_algorithm_size {
+	u16      algorithm_id;
+	u16      digest_size;
+} __packed;
+
+#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
+
+/**
+ * struct TCG_EfiSpecIDEventStruct - content of the event log header
+ *
+ * @signature:			signature, set to Spec ID Event03
+ * @platform_class:		class defined in TCG ACPI Specification
+ *				Client  Common Header.
+ * @spec_version_minor:		minor version
+ * @spec_version_major:		major version
+ * @spec_version_errata:	major version
+ * @uintn_size:			size of the efi_uintn_t fields used in various
+ *				data structures used in this specification.
+ *				0x01 indicates u32  and 0x02  indicates u64
+ * @number_of_algorithms:	hashing algorithms used in this event log
+ * @digest_sizes:		array of number_of_algorithms pairs
+ *				1st member defines the algorithm id
+ *				2nd member defines the algorithm size
+ */
+struct tcg_efi_spec_id_event {
+	u8 signature[16];
+	u32 platform_class;
+	u8 spec_version_minor;
+	u8 spec_version_major;
+	u8 spec_errata;
+	u8 uintn_size;
+	u32 number_of_algorithms;
+	struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
+} __packed;
+
 /**
  * TPM2 Structure Tags for command/response buffers.
  *
@@ -340,6 +384,24 @@ enum tpm2_algorithms {
 	TPM2_ALG_SM3_256	= 0x12,
 };
 
+static inline u16 tpm2_algorithm_to_len(enum tpm2_algorithms a)
+{
+	switch (a) {
+	case TPM2_ALG_SHA1:
+		return TPM2_SHA1_DIGEST_SIZE;
+	case TPM2_ALG_SHA256:
+		return TPM2_SHA256_DIGEST_SIZE;
+	case TPM2_ALG_SHA384:
+		return TPM2_SHA384_DIGEST_SIZE;
+	case TPM2_ALG_SHA512:
+		return TPM2_SHA512_DIGEST_SIZE;
+	default:
+		return 0;
+	}
+}
+
+#define tpm2_algorithm_to_mask(a)	(1 << (a))
+
 /* NV index attributes */
 enum tpm_index_attrs {
 	TPMA_NV_PPWRITE		= 1UL << 0,
@@ -419,6 +481,142 @@ enum {
 	HR_NV_INDEX		= TPM_HT_NV_INDEX << HR_SHIFT,
 };
 
+/**
+ * struct tcg2_event_log - Container for managing the platform event log
+ *
+ * @log:		Address of the log
+ * @log_position:	Current entry position
+ * @log_size:		Log space available
+ */
+struct tcg2_event_log {
+	u8 *log;
+	u32 log_position;
+	u32 log_size;
+};
+
+/**
+ * Create a list of digests of the supported PCR banks for a given input data
+ *
+ * @dev		TPM device
+ * @input	Data
+ * @length	Length of the data to calculate the digest
+ * @digest_list	List of digests to fill in
+ *
+ * Return: zero on success, negative errno otherwise
+ */
+int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length,
+		       struct tpml_digest_values *digest_list);
+
+/**
+ * Get the event size of the specified digests
+ *
+ * @digest_list	List of digests for the event
+ *
+ * Return: Size in bytes of the event
+ */
+u32 tcg2_event_get_size(struct tpml_digest_values *digest_list);
+
+/**
+ * tcg2_log_append - Append an event to an event log
+ *
+ * @pcr_index	Index of the PCR
+ * @event_type	Type of event
+ * @digest_list List of digests to add
+ * @size	Size of event
+ * @event	Event data
+ * @log		Log buffer to append the event to
+ */
+void tcg2_log_append(u32 pcr_index, u32 event_type,
+		     struct tpml_digest_values *digest_list, u32 size,
+		     const u8 *event, u8 *log);
+
+/**
+ * Extend the PCR with specified digests
+ *
+ * @dev		TPM device
+ * @pcr_index	Index of the PCR
+ * @digest_list	List of digests to extend
+ *
+ * Return: zero on success, negative errno otherwise
+ */
+int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
+		    struct tpml_digest_values *digest_list);
+
+/**
+ * Measure data into the TPM PCRs and the platform event log.
+ *
+ * @dev		TPM device
+ * @log		Platform event log
+ * @pcr_index	Index of the PCR
+ * @size	Size of the data
+ * @data	Pointer to the data
+ * @event_type	Event log type
+ * @event_size	Size of the event
+ * @event	Pointer to the event
+ *
+ * Return: zero on success, negative errno otherwise
+ */
+int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog,
+		      u32 pcr_index, u32 size, const u8 *data, u32 event_type,
+		      u32 event_size, const u8 *event);
+
+/**
+ * Measure an event into the platform event log.
+ *
+ * @dev		TPM device
+ * @log		Platform event log
+ * @pcr_index	Index of the PCR
+ * @event_type	Event log type
+ * @size	Size of the event
+ * @event	Pointer to the event
+ *
+ * Return: zero on success, negative errno otherwise
+ */
+int tcg2_measure_event(struct udevice *dev, struct tcg2_event_log *elog,
+		       u32 pcr_index, u32 event_type, u32 size,
+		       const u8 *event);
+
+/**
+ * Begin measurements.
+ *
+ * Return: zero on success, negative errno otherwise
+ */
+int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog);
+
+/**
+ * Stop measurements and record separator events.
+ */
+void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog,
+			   bool error);
+
+/**
+ * Get the platform event log address and size.
+ *
+ * @dev		TPM device
+ * @addr	Address of the log
+ * @size	Size of the log
+ *
+ * Return: zero on success, negative errno otherwise
+ */
+int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size);
+
+/**
+ * Get the first TPM2 device found.
+ *
+ * @dev		TPM device
+ *
+ * Return: zero on success, negative errno otherwise
+ */
+int tcg2_platform_get_tpm2(struct udevice **dev);
+
+/**
+ * Platform-specific function for handling TPM startup errors
+ *
+ * @dev		TPM device
+ * @rc		The TPM response code
+ */
+void tcg2_platform_startup_error(struct udevice *dev, int rc);
+
 /**
  * Issue a TPM2_Startup command.
  *
@@ -538,6 +736,19 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
 u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 property,
 			void *buf, size_t prop_count);
 
+/**
+ * tpm2_get_pcr_info() - get the supported, active PCRs and number of banks
+ *
+ * @dev:		TPM device
+ * @supported_pcr:	bitmask with the algorithms supported
+ * @active_pcr:		bitmask with the active algorithms
+ * @pcr_banks:		number of PCR banks
+ *
+ * @return 0 on success, code of operation or negative errno on failure
+ */
+int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
+		      u32 *pcr_banks);
+
 /**
  * Issue a TPM2_DictionaryAttackLockReset command.
  *
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index a525ebf75b..c0ac32a58e 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -162,52 +162,6 @@ static bool is_tcg2_protocol_installed(void)
 	return ret == EFI_SUCCESS;
 }
 
-static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
-{
-	u32 len;
-	size_t i;
-
-	len = offsetof(struct tcg_pcr_event2, digests);
-	len += offsetof(struct tpml_digest_values, digests);
-	for (i = 0; i < digest_list->count; i++) {
-		u16 hash_alg = digest_list->digests[i].hash_alg;
-
-		len += offsetof(struct tpmt_ha, digest);
-		len += alg_to_len(hash_alg);
-	}
-	len += sizeof(u32); /* tcg_pcr_event2 event_size*/
-
-	return len;
-}
-
-/* tcg2_pcr_extend - Extend PCRs for a TPM2 device for a given tpml_digest_values
- *
- * @dev:		device
- * @digest_list:	list of digest algorithms to extend
- *
- * @Return: status code
- */
-static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
-				    struct tpml_digest_values *digest_list)
-{
-	u32 rc;
-	size_t i;
-
-	for (i = 0; i < digest_list->count; i++) {
-		u32 alg = digest_list->digests[i].hash_alg;
-
-		rc = tpm2_pcr_extend(dev, pcr_index, alg,
-				     (u8 *)&digest_list->digests[i].digest,
-				     alg_to_len(alg));
-		if (rc) {
-			EFI_PRINT("Failed to extend PCR\n");
-			return EFI_DEVICE_ERROR;
-		}
-	}
-
-	return EFI_SUCCESS;
-}
-
 /* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values
  *
  * @dev:		device
@@ -246,61 +200,6 @@ static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index,
 	return EFI_SUCCESS;
 }
 
-/* put_event - Append an agile event to an eventlog
- *
- * @pcr_index:		PCR index
- * @event_type:		type of event added
- * @digest_list:	list of digest algorithms to add
- * @size:		size of event
- * @event:		event to add
- * @log:		log buffer to append the event
- *
- */
-static void put_event(u32 pcr_index, u32 event_type,
-		      struct tpml_digest_values *digest_list, u32 size,
-		      u8 event[], void *log)
-{
-	size_t pos;
-	size_t i;
-	u32 event_size;
-
-	/*
-	 * size refers to the length of event[] only, we need to check against
-	 * the final tcg_pcr_event2 size
-	 */
-	event_size = size + tcg_event_final_size(digest_list);
-
-	put_unaligned_le32(pcr_index, log);
-	pos = offsetof(struct tcg_pcr_event2, event_type);
-	put_unaligned_le32(event_type, (void *)((uintptr_t)log + pos));
-	pos = offsetof(struct tcg_pcr_event2, digests); /* count */
-	put_unaligned_le32(digest_list->count, (void *)((uintptr_t)log + pos));
-
-	pos += offsetof(struct tpml_digest_values, digests);
-	for (i = 0; i < digest_list->count; i++) {
-		u16 hash_alg = digest_list->digests[i].hash_alg;
-		u8 *digest = (u8 *)&digest_list->digests[i].digest;
-
-		put_unaligned_le16(hash_alg, (void *)((uintptr_t)log + pos));
-		pos += offsetof(struct tpmt_ha, digest);
-		memcpy((void *)((uintptr_t)log + pos), digest, alg_to_len(hash_alg));
-		pos += alg_to_len(hash_alg);
-	}
-
-	put_unaligned_le32(size, (void *)((uintptr_t)log + pos));
-	pos += sizeof(u32); /* tcg_pcr_event2 event_size*/
-	memcpy((void *)((uintptr_t)log + pos), event, size);
-	pos += size;
-
-	/*
-	 * make sure the calculated buffer is what we checked against
-	 * This check should never fail.  It checks the code above is
-	 * calculating the right length for the event we are adding
-	 */
-	if (pos != event_size)
-		log_err("Appending to the EventLog failed\n");
-}
-
 /* tcg2_agile_log_append - Append an agile event to an eventlog
  *
  * @pcr_index:		PCR index
@@ -317,7 +216,7 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
 					  u32 size, u8 event[])
 {
 	void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos);
-	u32 event_size = size + tcg_event_final_size(digest_list);
+	u32 event_size = size + tcg2_event_get_size(digest_list);
 	struct efi_tcg2_final_events_table *final_event;
 	efi_status_t ret = EFI_SUCCESS;
 
@@ -328,7 +227,7 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
 			event_log.truncated = true;
 			return EFI_VOLUME_FULL;
 		}
-		put_event(pcr_index, event_type, digest_list, size, event, log);
+		tcg2_log_append(pcr_index, event_type, digest_list, size, event, log);
 		event_log.pos += event_size;
 		event_log.last_event_size = event_size;
 	}
@@ -341,7 +240,7 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
 		return EFI_VOLUME_FULL;
 
 	log = (void *)((uintptr_t)event_log.final_buffer + event_log.final_pos);
-	put_event(pcr_index, event_type, digest_list, size, event, log);
+	tcg2_log_append(pcr_index, event_type, digest_list, size, event, log);
 
 	final_event = event_log.final_buffer;
 	final_event->number_of_events++;
@@ -350,27 +249,6 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
 	return ret;
 }
 
-/**
- * platform_get_tpm_device() - retrieve TPM device
- *
- * This function retrieves the udevice implementing a TPM
- *
- * This function may be overridden if special initialization is needed.
- *
- * @dev:	udevice
- * Return:	status code
- */
-__weak efi_status_t platform_get_tpm2_device(struct udevice **dev)
-{
-	for_each_tpm_device(*dev) {
-		/* Only support TPMv2 devices */
-		if (tpm_get_version(*dev) == TPM_V2)
-			return EFI_SUCCESS;
-	}
-
-	return EFI_NOT_FOUND;
-}
-
 /**
  * platform_get_eventlog() - retrieve the eventlog address and size
  *
@@ -485,144 +363,6 @@ static int tpm2_get_manufacturer_id(struct udevice *dev, u32 *manufacturer_id)
 	return 0;
 }
 
-/**
- * tpm2_get_num_pcr() - get the number of PCRs
- *
- * @dev:		TPM device
- * @manufacturer_id:	output buffer for the number
- *
- * Return: 0 on success, -1 on error
- */
-static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr)
-{
-	u8 response[TPM2_RESPONSE_BUFFER_SIZE];
-	u32 ret;
-
-	memset(response, 0, sizeof(response));
-	ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
-				  TPM2_PT_PCR_COUNT, response, 1);
-	if (ret)
-		return -1;
-
-	*num_pcr = get_unaligned_be32(response + properties_offset);
-	if (*num_pcr > TPM2_MAX_PCRS)
-		return -1;
-
-	return 0;
-}
-
-/**
- * is_active_pcr() - Check if a supported algorithm is active
- *
- * @dev:		TPM device
- * @selection:		struct of PCR information
- *
- * Return: true if PCR is active
- */
-static bool is_active_pcr(struct tpms_pcr_selection *selection)
-{
-	int i;
-	/*
-	 * check the pcr_select. If at least one of the PCRs supports the
-	 * algorithm add it on the active ones
-	 */
-	for (i = 0; i < selection->size_of_select; i++) {
-		if (selection->pcr_select[i])
-			return true;
-	}
-
-	return false;
-}
-
-/**
- * tpm2_get_pcr_info() - get the supported, active PCRs and number of banks
- *
- * @dev:		TPM device
- * @supported_pcr:	bitmask with the algorithms supported
- * @active_pcr:		bitmask with the active algorithms
- * @pcr_banks:		number of PCR banks
- *
- * Return: 0 on success, -1 on error
- */
-static int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr,
-			     u32 *active_pcr, u32 *pcr_banks)
-{
-	u8 response[TPM2_RESPONSE_BUFFER_SIZE];
-	struct tpml_pcr_selection pcrs;
-	u32 ret, num_pcr;
-	size_t i;
-	int tpm_ret;
-
-	*supported_pcr = 0;
-	*active_pcr = 0;
-	*pcr_banks = 0;
-	memset(response, 0, sizeof(response));
-	ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1);
-	if (ret)
-		goto out;
-
-	pcrs.count = get_unaligned_be32(response);
-	/*
-	 * We only support 5 algorithms for now so check against that
-	 * instead of TPM2_NUM_PCR_BANKS
-	 */
-	if (pcrs.count > MAX_HASH_COUNT || pcrs.count < 1)
-		goto out;
-
-	tpm_ret = tpm2_get_num_pcr(dev, &num_pcr);
-	if (tpm_ret)
-		goto out;
-
-	for (i = 0; i < pcrs.count; i++) {
-		/*
-		 * Definition of TPMS_PCR_SELECTION Structure
-		 * hash: u16
-		 * size_of_select: u8
-		 * pcr_select: u8 array
-		 *
-		 * The offsets depend on the number of the device PCRs
-		 * so we have to calculate them based on that
-		 */
-		u32 hash_offset = offsetof(struct tpml_pcr_selection, selection) +
-			i * offsetof(struct tpms_pcr_selection, pcr_select) +
-			i * ((num_pcr + 7) / 8);
-		u32 size_select_offset =
-			hash_offset + offsetof(struct tpms_pcr_selection,
-					       size_of_select);
-		u32 pcr_select_offset =
-			hash_offset + offsetof(struct tpms_pcr_selection,
-					       pcr_select);
-
-		pcrs.selection[i].hash =
-			get_unaligned_be16(response + hash_offset);
-		pcrs.selection[i].size_of_select =
-			__get_unaligned_be(response + size_select_offset);
-		if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX)
-			goto out;
-		/* copy the array of pcr_select */
-		memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset,
-		       pcrs.selection[i].size_of_select);
-	}
-
-	for (i = 0; i < pcrs.count; i++) {
-		u32 hash_mask = alg_to_mask(pcrs.selection[i].hash);
-
-		if (hash_mask) {
-			*supported_pcr |= hash_mask;
-			if (is_active_pcr(&pcrs.selection[i]))
-				*active_pcr |= hash_mask;
-		} else {
-			EFI_PRINT("Unknown algorithm %x\n", pcrs.selection[i].hash);
-		}
-	}
-
-	*pcr_banks = pcrs.count;
-
-	return 0;
-out:
-	return -1;
-}
-
 /**
  * __get_active_pcr_banks() - returns the currently active PCR banks
  *
@@ -638,7 +378,7 @@ static efi_status_t __get_active_pcr_banks(u32 *active_pcr_banks)
 	efi_status_t ret;
 	int err;
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
@@ -654,70 +394,6 @@ out:
 	return ret;
 }
 
-/* tcg2_create_digest - create a list of digests of the supported PCR banks
- *			for a given memory range
- *
- * @input:		input memory
- * @length:		length of buffer to calculate the digest
- * @digest_list:	list of digests to fill in
- *
- * Return:		status code
- */
-static efi_status_t tcg2_create_digest(const u8 *input, u32 length,
-				       struct tpml_digest_values *digest_list)
-{
-	sha1_context ctx;
-	sha256_context ctx_256;
-	sha512_context ctx_512;
-	u8 final[TPM2_SHA512_DIGEST_SIZE];
-	efi_status_t ret;
-	u32 active;
-	size_t i;
-
-	ret = __get_active_pcr_banks(&active);
-	if (ret != EFI_SUCCESS)
-		return ret;
-
-	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:
-			sha1_starts(&ctx);
-			sha1_update(&ctx, input, length);
-			sha1_finish(&ctx, final);
-			break;
-		case TPM2_ALG_SHA256:
-			sha256_starts(&ctx_256);
-			sha256_update(&ctx_256, input, length);
-			sha256_finish(&ctx_256, final);
-			break;
-		case TPM2_ALG_SHA384:
-			sha384_starts(&ctx_512);
-			sha384_update(&ctx_512, input, length);
-			sha384_finish(&ctx_512, final);
-			break;
-		case TPM2_ALG_SHA512:
-			sha512_starts(&ctx_512);
-			sha512_update(&ctx_512, input, length);
-			sha512_finish(&ctx_512, final);
-			break;
-		default:
-			EFI_PRINT("Unsupported algorithm %x\n", hash_alg);
-			return EFI_INVALID_PARAMETER;
-		}
-		digest_list->digests[digest_list->count].hash_alg = hash_alg;
-		memcpy(&digest_list->digests[digest_list->count].digest, final,
-		       (u32)alg_to_len(hash_alg));
-		digest_list->count++;
-	}
-
-	return EFI_SUCCESS;
-}
-
 /**
  * efi_tcg2_get_capability() - protocol capability information and state information
  *
@@ -759,7 +435,7 @@ efi_tcg2_get_capability(struct efi_tcg2_protocol *this,
 	capability->protocol_version.major = 1;
 	capability->protocol_version.minor = 1;
 
-	efi_ret = platform_get_tpm2_device(&dev);
+	efi_ret = tcg2_platform_get_tpm2(&dev);
 	if (efi_ret != EFI_SUCCESS) {
 		capability->supported_event_logs = 0;
 		capability->hash_algorithm_bitmap = 0;
@@ -855,7 +531,7 @@ efi_tcg2_get_eventlog(struct efi_tcg2_protocol *this,
 		goto out;
 	}
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS) {
 		event_log_location = NULL;
 		event_log_last_entry = NULL;
@@ -975,7 +651,7 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
 	if (!is_tcg2_protocol_installed())
 		return EFI_SUCCESS;
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		return EFI_SECURITY_VIOLATION;
 
@@ -1084,7 +760,7 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags,
 		goto out;
 	}
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
@@ -1119,7 +795,7 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags,
 		ret = tcg2_hash_pe_image((void *)(uintptr_t)data_to_hash,
 					 data_to_hash_len, &digest_list);
 	} else {
-		ret = tcg2_create_digest((u8 *)(uintptr_t)data_to_hash,
+		ret = tcg2_create_digest(dev, (u8 *)(uintptr_t)data_to_hash,
 					 data_to_hash_len, &digest_list);
 	}
 
@@ -1182,7 +858,7 @@ efi_tcg2_submit_command(struct efi_tcg2_protocol *this,
 		goto out;
 	}
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
@@ -1438,7 +1114,7 @@ static efi_status_t tcg2_parse_event(struct udevice *dev, void *buffer,
 	u32 count, size, event_size;
 	size_t pos;
 
-	event_size = tcg_event_final_size(digest_list);
+	event_size = tcg2_event_get_size(digest_list);
 	if (*offset >= log_size || *offset + event_size > log_size) {
 		log_err("Event exceeds log size\n");
 		return EFI_COMPROMISED_DATA;
@@ -1739,7 +1415,7 @@ tcg2_measure_event(struct udevice *dev, u32 pcr_index, u32 event_type,
 	struct tpml_digest_values digest_list;
 	efi_status_t ret;
 
-	ret = tcg2_create_digest(event, size, &digest_list);
+	ret = tcg2_create_digest(dev, event, size, &digest_list);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
@@ -1789,7 +1465,7 @@ static efi_status_t efi_init_event_log(void)
 	size_t spec_event_size;
 	efi_status_t ret;
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		return ret;
 
@@ -2194,7 +1870,7 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha
 	if (tcg2_efi_app_invoked)
 		return EFI_SUCCESS;
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		return EFI_SECURITY_VIOLATION;
 
@@ -2244,7 +1920,7 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void)
 	if (!is_tcg2_protocol_installed())
 		return EFI_SUCCESS;
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		return ret;
 
@@ -2275,7 +1951,7 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
 		goto out;
 	}
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
@@ -2307,7 +1983,7 @@ efi_status_t efi_tcg2_notify_exit_boot_services_failed(void)
 	if (!is_tcg2_protocol_installed())
 		return EFI_SUCCESS;
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		goto out;
 
@@ -2389,7 +2065,7 @@ efi_status_t efi_tcg2_do_initial_measurement(void)
 	if (!is_tcg2_protocol_installed())
 		return EFI_SUCCESS;
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS)
 		return EFI_SECURITY_VIOLATION;
 
@@ -2415,7 +2091,7 @@ efi_status_t efi_tcg2_register(void)
 	struct efi_event *event;
 	u32 err;
 
-	ret = platform_get_tpm2_device(&dev);
+	ret = tcg2_platform_get_tpm2(&dev);
 	if (ret != EFI_SUCCESS) {
 		log_warning("Unable to find TPMv2 device\n");
 		return EFI_SUCCESS;
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 697b982e07..00e1b04d74 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -4,13 +4,597 @@
  * Author: Miquel Raynal <miquel.raynal@bootlin.com>
  */
 
+#include <asm/types.h>
+#include <asm/io.h>
 #include <common.h>
 #include <dm.h>
+#include <dm/of_access.h>
 #include <tpm-common.h>
 #include <tpm-v2.h>
 #include <linux/bitops.h>
+#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/generic.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <u-boot/sha1.h>
+#include <u-boot/sha256.h>
+#include <u-boot/sha512.h>
+#include <version_string.h>
 #include "tpm-utils.h"
 
+static const enum tpm2_algorithms tcg2algos[] = {
+	TPM2_ALG_SHA1,
+	TPM2_ALG_SHA256,
+	TPM2_ALG_SHA384,
+	TPM2_ALG_SHA512,
+};
+
+static int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks)
+{
+	u32 supported = 0;
+	u32 pcr_banks = 0;
+	u32 active = 0;
+	int rc;
+
+	rc = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks);
+	if (rc)
+		return rc;
+
+	*active_pcr_banks = active;
+
+	return 0;
+}
+
+u32 tcg2_event_get_size(struct tpml_digest_values *digest_list)
+{
+	u32 len;
+	size_t i;
+
+	len = offsetof(struct tcg_pcr_event2, digests);
+	len += offsetof(struct tpml_digest_values, digests);
+	for (i = 0; i < digest_list->count; ++i) {
+		u16 l = tpm2_algorithm_to_len(digest_list->digests[i].hash_alg);
+
+		if (!l)
+			continue;
+
+		len += l + offsetof(struct tpmt_ha, digest);
+	}
+	len += sizeof(u32);
+
+	return len;
+}
+
+int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length,
+		       struct tpml_digest_values *digest_list)
+{
+	u8 final[sizeof(union tpmu_ha)];
+	sha256_context ctx_256;
+	sha512_context ctx_512;
+	sha1_context ctx;
+	u32 active;
+	size_t i;
+	u32 len;
+	int rc;
+
+	rc = tcg2_get_active_pcr_banks(dev, &active);
+	if (rc)
+		return rc;
+
+	digest_list->count = 0;
+	for (i = 0; i < ARRAY_SIZE(tcg2algos); ++i) {
+		u32 mask = tpm2_algorithm_to_mask(tcg2algos[i]);
+
+		if (!(active & mask))
+			continue;
+
+		switch (tcg2algos[i]) {
+		case TPM2_ALG_SHA1:
+			sha1_starts(&ctx);
+			sha1_update(&ctx, input, length);
+			sha1_finish(&ctx, final);
+			len = TPM2_SHA1_DIGEST_SIZE;
+			break;
+		case TPM2_ALG_SHA256:
+			sha256_starts(&ctx_256);
+			sha256_update(&ctx_256, input, length);
+			sha256_finish(&ctx_256, final);
+			len = TPM2_SHA256_DIGEST_SIZE;
+			break;
+		case TPM2_ALG_SHA384:
+			sha384_starts(&ctx_512);
+			sha384_update(&ctx_512, input, length);
+			sha384_finish(&ctx_512, final);
+			len = TPM2_SHA384_DIGEST_SIZE;
+			break;
+		case TPM2_ALG_SHA512:
+			sha512_starts(&ctx_512);
+			sha512_update(&ctx_512, input, length);
+			sha512_finish(&ctx_512, final);
+			len = TPM2_SHA512_DIGEST_SIZE;
+			break;
+		default:
+			printf("%s: unsupported algorithm %x\n", __func__,
+			       tcg2algos[i]);
+			continue;
+		}
+
+		digest_list->digests[digest_list->count].hash_alg =
+			tcg2algos[i];
+		memcpy(&digest_list->digests[digest_list->count].digest, final,
+		       len);
+		digest_list->count++;
+	}
+
+	return 0;
+}
+
+void tcg2_log_append(u32 pcr_index, u32 event_type,
+		     struct tpml_digest_values *digest_list, u32 size,
+		     const u8 *event, u8 *log)
+{
+	size_t len;
+	size_t pos;
+	u32 i;
+
+	pos = offsetof(struct tcg_pcr_event2, pcr_index);
+	put_unaligned_le32(pcr_index, log);
+	pos = offsetof(struct tcg_pcr_event2, event_type);
+	put_unaligned_le32(event_type, log + pos);
+	pos = offsetof(struct tcg_pcr_event2, digests) +
+		offsetof(struct tpml_digest_values, count);
+	put_unaligned_le32(digest_list->count, log + pos);
+
+	pos = offsetof(struct tcg_pcr_event2, digests) +
+		offsetof(struct tpml_digest_values, digests);
+	for (i = 0; i < digest_list->count; ++i) {
+		u16 hash_alg = digest_list->digests[i].hash_alg;
+
+		len = tpm2_algorithm_to_len(hash_alg);
+		if (!len)
+			continue;
+
+		pos += offsetof(struct tpmt_ha, hash_alg);
+		put_unaligned_le16(hash_alg, log + pos);
+		pos += offsetof(struct tpmt_ha, digest);
+		memcpy(log + pos, (u8 *)&digest_list->digests[i].digest, len);
+		pos += len;
+	}
+
+	put_unaligned_le32(size, log + pos);
+	pos += sizeof(u32);
+	memcpy(log + pos, event, size);
+}
+
+static int tcg2_log_append_check(struct tcg2_event_log *elog, u32 pcr_index,
+				 u32 event_type,
+				 struct tpml_digest_values *digest_list,
+				 u32 size, const u8 *event)
+{
+	u32 event_size;
+	u8 *log;
+
+	event_size = size + tcg2_event_get_size(digest_list);
+	if (elog->log_position + event_size > elog->log_size) {
+		printf("%s: log too large: %u + %u > %u\n", __func__,
+		       elog->log_position, event_size, elog->log_size);
+		return -ENOBUFS;
+	}
+
+	log = elog->log + elog->log_position;
+	elog->log_position += event_size;
+
+	tcg2_log_append(pcr_index, event_type, digest_list, size, event, log);
+
+	return 0;
+}
+
+static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog)
+{
+	struct tcg_efi_spec_id_event *ev;
+	struct tcg_pcr_event *log;
+	u32 event_size;
+	u32 count = 0;
+	u32 log_size;
+	u32 active;
+	u32 mask;
+	size_t i;
+	u16 len;
+	int rc;
+
+	rc = tcg2_get_active_pcr_banks(dev, &active);
+	if (rc)
+		return rc;
+
+	event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes);
+	for (i = 0; i < ARRAY_SIZE(tcg2algos); ++i) {
+		mask = tpm2_algorithm_to_mask(tcg2algos[i]);
+
+		if (!(active & mask))
+			continue;
+
+		switch (tcg2algos[i]) {
+		case TPM2_ALG_SHA1:
+		case TPM2_ALG_SHA256:
+		case TPM2_ALG_SHA384:
+		case TPM2_ALG_SHA512:
+			count++;
+			break;
+		default:
+			continue;
+		}
+	}
+
+	event_size += 1 +
+		(sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count);
+	log_size = offsetof(struct tcg_pcr_event, event) + event_size;
+
+	if (log_size > elog->log_size) {
+		printf("%s: log too large: %u > %u\n", __func__, log_size,
+		       elog->log_size);
+		return -ENOBUFS;
+	}
+
+	log = (struct tcg_pcr_event *)elog->log;
+	put_unaligned_le32(0, &log->pcr_index);
+	put_unaligned_le32(EV_NO_ACTION, &log->event_type);
+	memset(&log->digest, 0, sizeof(log->digest));
+	put_unaligned_le32(event_size, &log->event_size);
+
+	ev = (struct tcg_efi_spec_id_event *)log->event;
+	strlcpy((char *)ev->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03,
+		sizeof(ev->signature));
+	put_unaligned_le32(0, &ev->platform_class);
+	ev->spec_version_minor = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2;
+	ev->spec_version_major = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2;
+	ev->spec_errata = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2;
+	ev->uintn_size = sizeof(size_t) / sizeof(u32);
+	put_unaligned_le32(count, &ev->number_of_algorithms);
+
+	count = 0;
+	for (i = 0; i < ARRAY_SIZE(tcg2algos); ++i) {
+		mask = tpm2_algorithm_to_mask(tcg2algos[i]);
+
+		if (!(active & mask))
+			continue;
+
+		len = tpm2_algorithm_to_len(tcg2algos[i]);
+		if (!len)
+			continue;
+
+		put_unaligned_le16(tcg2algos[i],
+				   &ev->digest_sizes[count].algorithm_id);
+		put_unaligned_le16(len, &ev->digest_sizes[count].digest_size);
+		count++;
+	}
+
+	*((u8 *)ev + (event_size - 1)) = 0;
+	elog->log_position = log_size;
+
+	return 0;
+}
+
+static void tcg2_log_find_end(struct tcg2_event_log *elog)
+{
+	const u32 offset = offsetof(struct tcg_pcr_event2, digests) +
+		offsetof(struct tpml_digest_values, digests);
+	u32 event_size;
+	u32 count;
+	u16 algo;
+	u32 pos;
+	u16 len;
+	u8 *log;
+	u32 i;
+
+	while (elog->log_position + offset < elog->log_size) {
+		log = elog->log + elog->log_position;
+
+		pos = offsetof(struct tcg_pcr_event2, event_type);
+		if (!get_unaligned_le32(log + pos))
+			return;
+
+		pos = offsetof(struct tcg_pcr_event2, digests) +
+			offsetof(struct tpml_digest_values, count);
+		count = get_unaligned_le32(log + pos);
+		if (count > ARRAY_SIZE(tcg2algos))
+			return;
+
+		pos = offsetof(struct tcg_pcr_event2, digests) +
+			offsetof(struct tpml_digest_values, digests);
+		for (i = 0; i < count; ++i) {
+			pos += offsetof(struct tpmt_ha, hash_alg);
+			if (elog->log_position + pos + sizeof(u16) >=
+			    elog->log_size)
+				return;
+
+			algo = get_unaligned_le16(log + pos);
+			pos += offsetof(struct tpmt_ha, digest);
+			switch (algo) {
+			case TPM2_ALG_SHA1:
+			case TPM2_ALG_SHA256:
+			case TPM2_ALG_SHA384:
+			case TPM2_ALG_SHA512:
+				len = tpm2_algorithm_to_len(algo);
+				break;
+			default:
+				return;
+			}
+
+			pos += len;
+		}
+
+		if (elog->log_position + pos + sizeof(u32) >= elog->log_size)
+			return;
+
+		event_size = get_unaligned_le32(log + pos);
+		pos += event_size + sizeof(u32);
+		if (elog->log_position + pos >= elog->log_size)
+			return;
+
+		elog->log_position += pos;
+	}
+}
+
+static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog)
+{
+	struct tcg_efi_spec_id_event *event;
+	struct tcg_pcr_event *log;
+	u32 calc_size;
+	u32 active;
+	u32 count;
+	u32 evsz;
+	u32 mask;
+	u16 algo;
+	u16 len;
+	int rc;
+	u32 i;
+
+	if (elog->log_size <= offsetof(struct tcg_pcr_event, event))
+		return 0;
+
+	log = (struct tcg_pcr_event *)elog->log;
+	if (get_unaligned_le32(&log->pcr_index) != 0 ||
+	    get_unaligned_le32(&log->event_type) != EV_NO_ACTION)
+		return 0;
+
+	for (i = 0; i < sizeof(log->digest); i++) {
+		if (log->digest[i])
+			return 0;
+	}
+
+	evsz = get_unaligned_le32(&log->event_size);
+	if (evsz < offsetof(struct tcg_efi_spec_id_event, digest_sizes) ||
+	    evsz + offsetof(struct tcg_pcr_event, event) > elog->log_size)
+		return 0;
+
+	event = (struct tcg_efi_spec_id_event *)log->event;
+	if (memcmp(event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03,
+		   sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03)))
+		return 0;
+
+	if (event->spec_version_minor != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 ||
+	    event->spec_version_major != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2)
+		return 0;
+
+	count = get_unaligned_le32(&event->number_of_algorithms);
+	if (count > ARRAY_SIZE(tcg2algos))
+		return 0;
+
+	calc_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes) +
+		(sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count) +
+		1;
+	if (evsz != calc_size)
+		return 0;
+
+	rc = tcg2_get_active_pcr_banks(dev, &active);
+	if (rc)
+		return rc;
+
+	for (i = 0; i < count; ++i) {
+		algo = get_unaligned_le16(&event->digest_sizes[i].algorithm_id);
+		mask = tpm2_algorithm_to_mask(algo);
+
+		if (!(active & mask))
+			return 0;
+
+		switch (algo) {
+		case TPM2_ALG_SHA1:
+		case TPM2_ALG_SHA256:
+		case TPM2_ALG_SHA384:
+		case TPM2_ALG_SHA512:
+			len = get_unaligned_le16(&event->digest_sizes[i].digest_size);
+			if (tpm2_algorithm_to_len(algo) != len)
+				return 0;
+			break;
+		default:
+			return 0;
+		}
+	}
+
+	elog->log_position = offsetof(struct tcg_pcr_event, event) + evsz;
+
+	tcg2_log_find_end(elog);
+
+	return 1;
+}
+
+int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
+		    struct tpml_digest_values *digest_list)
+{
+	u32 rc;
+	size_t i;
+
+	for (i = 0; i < digest_list->count; i++) {
+		u32 alg = digest_list->digests[i].hash_alg;
+
+		rc = tpm2_pcr_extend(dev, pcr_index, alg,
+				     (u8 *)&digest_list->digests[i].digest,
+				     tpm2_algorithm_to_len(alg));
+		if (rc) {
+			printf("%s: error pcr:%u alg:%08x\n", __func__,
+			       pcr_index, alg);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog,
+		      u32 pcr_index, u32 size, const u8 *data, u32 event_type,
+		      u32 event_size, const u8 *event)
+{
+	struct tpml_digest_values digest_list;
+	int rc;
+
+	rc = tcg2_create_digest(dev, data, size, &digest_list);
+	if (rc)
+		return rc;
+
+	rc = tcg2_pcr_extend(dev, pcr_index, &digest_list);
+	if (rc)
+		return rc;
+
+	return tcg2_log_append_check(elog, pcr_index, event_type, &digest_list,
+				     event_size, event);
+}
+
+int tcg2_measure_event(struct udevice *dev, struct tcg2_event_log *elog,
+		       u32 pcr_index, u32 event_type, u32 size,
+		       const u8 *event)
+{
+	struct tpml_digest_values digest_list;
+	int rc;
+
+	rc = tcg2_create_digest(dev, event, size, &digest_list);
+	if (rc)
+		return rc;
+
+	rc = tcg2_pcr_extend(dev, pcr_index, &digest_list);
+	if (rc)
+		return rc;
+
+	return tcg2_log_append_check(elog, pcr_index, event_type, &digest_list,
+				     size, event);
+}
+
+int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog)
+{
+	int rc;
+
+	rc = tcg2_platform_get_tpm2(dev);
+	if (rc)
+		return rc;
+
+	rc = tpm_init(*dev);
+	if (rc)
+		return rc;
+
+	rc = tpm2_startup(*dev, TPM2_SU_CLEAR);
+	if (rc) {
+		tcg2_platform_startup_error(*dev, rc);
+		return rc;
+	}
+
+	rc = tpm2_self_test(*dev, TPMI_YES);
+	if (rc)
+		printf("%s: self test error, continuing.\n", __func__);
+
+	rc = tcg2_platform_get_log(*dev, (void **)&elog->log, &elog->log_size);
+	if (rc) {
+		tcg2_measurement_term(*dev, elog, true);
+		return rc;
+	}
+
+	elog->log_position = 0;
+	rc = tcg2_log_parse(*dev, elog);
+	if (rc < 0) {
+		tcg2_measurement_term(*dev, elog, true);
+		return rc;
+	}
+
+	if (!rc) {
+		rc = tcg2_log_init(*dev, elog);
+		if (rc) {
+			tcg2_measurement_term(*dev, elog, true);
+			return rc;
+		}
+	}
+
+	rc = tcg2_measure_event(*dev, elog, 0, EV_S_CRTM_VERSION,
+				strlen(version_string) + 1,
+				(u8 *)version_string);
+	if (rc) {
+		tcg2_measurement_term(*dev, elog, true);
+		return rc;
+	}
+
+	return 0;
+}
+
+void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog,
+			   bool error)
+{
+	u32 event = error ? 0x1 : 0xffffffff;
+	int i;
+
+	for (i = 0; i < 8; ++i)
+		tcg2_measure_event(dev, elog, i, EV_SEPARATOR, sizeof(event),
+				   (const u8 *)&event);
+
+	if (elog->log)
+		unmap_physmem(elog->log, MAP_NOCACHE);
+}
+
+__weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size)
+{
+	const __be32 *addr_prop;
+	const __be32 *size_prop;
+	int asize;
+	int ssize;
+
+	*addr = NULL;
+	*size = 0;
+
+	addr_prop = dev_read_prop(dev, "linux,sml-base", &asize);
+	size_prop = dev_read_prop(dev, "linux,sml-size", &ssize);
+	if (addr_prop && size_prop) {
+		u64 a = of_read_number(addr_prop, asize / sizeof(__be32));
+		u64 s = of_read_number(size_prop, ssize / sizeof(__be32));
+
+		*addr = map_physmem(a, s, MAP_NOCACHE);
+		*size = (u32)s;
+	} else {
+		struct ofnode_phandle_args args;
+		phys_addr_t a;
+		phys_size_t s;
+
+		if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0,
+					       0, &args))
+			return -ENODEV;
+
+		a = ofnode_get_addr_size(args.node, "reg", &s);
+		if (a == FDT_ADDR_T_NONE)
+			return -ENOMEM;
+
+		*addr = map_physmem(a, s, MAP_NOCACHE);
+		*size = (u32)s;
+	}
+
+	return 0;
+}
+
+__weak int tcg2_platform_get_tpm2(struct udevice **dev)
+{
+	for_each_tpm_device(*dev) {
+		if (tpm_get_version(*dev) == TPM_V2)
+			return 0;
+	}
+
+	return -ENODEV;
+}
+
+__weak void tcg2_platform_startup_error(struct udevice *dev, int rc) {}
+
 u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode)
 {
 	const u8 command_v2[12] = {
@@ -342,6 +926,130 @@ u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 property,
 	return 0;
 }
 
+static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr)
+{
+	u8 response[(sizeof(struct tpms_capability_data) -
+		offsetof(struct tpms_capability_data, data))];
+	u32 properties_offset =
+		offsetof(struct tpml_tagged_tpm_property, tpm_property) +
+		offsetof(struct tpms_tagged_property, value);
+	u32 ret;
+
+	memset(response, 0, sizeof(response));
+	ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
+				  TPM2_PT_PCR_COUNT, response, 1);
+	if (ret)
+		return ret;
+
+	*num_pcr = get_unaligned_be32(response + properties_offset);
+	if (*num_pcr > TPM2_MAX_PCRS) {
+		printf("%s: too many pcrs: %u\n", __func__, *num_pcr);
+		return -E2BIG;
+	}
+
+	return 0;
+}
+
+static bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection)
+{
+	int i;
+
+	/*
+	 * check the pcr_select. If at least one of the PCRs supports the
+	 * algorithm add it on the active ones
+	 */
+	for (i = 0; i < selection->size_of_select; i++) {
+		if (selection->pcr_select[i])
+			return true;
+	}
+
+	return false;
+}
+
+int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
+		      u32 *pcr_banks)
+{
+	u8 response[(sizeof(struct tpms_capability_data) -
+		offsetof(struct tpms_capability_data, data))];
+	struct tpml_pcr_selection pcrs;
+	u32 num_pcr;
+	size_t i;
+	u32 ret;
+
+	*supported_pcr = 0;
+	*active_pcr = 0;
+	*pcr_banks = 0;
+	memset(response, 0, sizeof(response));
+	ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1);
+	if (ret)
+		return ret;
+
+	pcrs.count = get_unaligned_be32(response);
+	/*
+	 * We only support 5 algorithms for now so check against that
+	 * instead of TPM2_NUM_PCR_BANKS
+	 */
+	if (pcrs.count > ARRAY_SIZE(tcg2algos) || pcrs.count < 1) {
+		printf("%s: too many pcrs: %u\n", __func__, pcrs.count);
+		return -EMSGSIZE;
+	}
+
+	ret = tpm2_get_num_pcr(dev, &num_pcr);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < pcrs.count; i++) {
+		/*
+		 * Definition of TPMS_PCR_SELECTION Structure
+		 * hash: u16
+		 * size_of_select: u8
+		 * pcr_select: u8 array
+		 *
+		 * The offsets depend on the number of the device PCRs
+		 * so we have to calculate them based on that
+		 */
+		u32 hash_offset = offsetof(struct tpml_pcr_selection, selection) +
+			i * offsetof(struct tpms_pcr_selection, pcr_select) +
+			i * ((num_pcr + 7) / 8);
+		u32 size_select_offset =
+			hash_offset + offsetof(struct tpms_pcr_selection,
+					       size_of_select);
+		u32 pcr_select_offset =
+			hash_offset + offsetof(struct tpms_pcr_selection,
+					       pcr_select);
+
+		pcrs.selection[i].hash =
+			get_unaligned_be16(response + hash_offset);
+		pcrs.selection[i].size_of_select =
+			__get_unaligned_be(response + size_select_offset);
+		if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX) {
+			printf("%s: pcrs selection too large: %u\n", __func__,
+			       pcrs.selection[i].size_of_select);
+			return -ENOBUFS;
+		}
+		/* copy the array of pcr_select */
+		memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset,
+		       pcrs.selection[i].size_of_select);
+	}
+
+	for (i = 0; i < pcrs.count; i++) {
+		u32 hash_mask = tpm2_algorithm_to_mask(pcrs.selection[i].hash);
+
+		if (hash_mask) {
+			*supported_pcr |= hash_mask;
+			if (tpm2_is_active_pcr(&pcrs.selection[i]))
+				*active_pcr |= hash_mask;
+		} else {
+			printf("%s: unknown algorithm %x\n", __func__,
+			       pcrs.selection[i].hash);
+		}
+	}
+
+	*pcr_banks = pcrs.count;
+
+	return 0;
+}
+
 u32 tpm2_dam_reset(struct udevice *dev, const char *pw, const ssize_t pw_sz)
 {
 	u8 command_v2[COMMAND_BUFFER_SIZE] = {
-- 
2.31.1


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

* [PATCH v2 3/5] bootm: Support boot measurement
  2023-01-09 21:55 [PATCH v2 0/5] tpm: Support boot measurements Eddie James
  2023-01-09 21:55 ` [PATCH v2 1/5] tpm: Fix spelling for tpmu_ha union Eddie James
  2023-01-09 21:55 ` [PATCH v2 2/5] tpm: Support boot measurements Eddie James
@ 2023-01-09 21:55 ` Eddie James
  2023-01-09 21:55 ` [PATCH v2 4/5] tpm: sandbox: Update for needed TPM2 capabilities Eddie James
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Eddie James @ 2023-01-09 21:55 UTC (permalink / raw)
  To: u-boot; +Cc: ilias.apalodimas, sjg, xypron.glpk, eajames

Add a configuration option to measure the boot through the bootm
function.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
---
 boot/Kconfig    | 23 ++++++++++++++++++
 boot/bootm.c    | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
 cmd/bootm.c     |  2 ++
 include/bootm.h |  2 ++
 include/image.h |  1 +
 5 files changed, 92 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index 30bc182fcd..e90d61412e 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -587,6 +587,29 @@ config LEGACY_IMAGE_FORMAT
 	  loaded. If a board needs the legacy image format support in this
 	  case, enable it here.
 
+config MEASURED_BOOT
+	bool "Measure boot images and configuration to TPM and event log"
+	depends on HASH && TPM_V2
+	help
+	  This option enables measurement of the boot process. Measurement
+	  involves creating cryptographic hashes of the binary images that
+	  are booting and storing them in the TPM. In addition, a log of
+	  these hashes is stored in memory for the OS to verify the booted
+	  images and configuration. Enable this if the OS has configured
+	  some memory area for the event log and you intend to use some
+	  attestation tools on your system.
+
+if MEASURED_BOOT
+	config MEASURE_DEVICETREE
+	bool "Measure the devicetree image"
+	default y if MEASURED_BOOT
+	help
+	  On some platforms, the devicetree is not static as it may contain
+	  random MAC addresses or other such data that changes each boot.
+	  Therefore, it should not be measured into the TPM. In that case,
+	  disable the measurement here.
+endif # MEASURED_BOOT
+
 config SUPPORT_RAW_INITRD
 	bool "Enable raw initrd images"
 	help
diff --git a/boot/bootm.c b/boot/bootm.c
index 15fce8ad95..932961ceb7 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -22,6 +22,7 @@
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <linux/sizes.h>
+#include <tpm-v2.h>
 #if defined(CONFIG_CMD_USB)
 #include <usb.h>
 #endif
@@ -659,6 +660,66 @@ int bootm_process_cmdline_env(int flags)
 	return 0;
 }
 
+int bootm_measure(struct bootm_headers *images)
+{
+	int ret = 0;
+
+	if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
+		struct tcg2_event_log elog;
+		struct udevice *dev;
+		void *initrd_buf;
+		void *image_buf;
+		const char *s;
+		u32 rd_len;
+
+		ret = tcg2_measurement_init(&dev, &elog);
+		if (ret)
+			return ret;
+
+		image_buf = map_sysmem(images->os.image_start,
+				       images->os.image_len);
+		ret = tcg2_measure_data(dev, &elog, 8, images->os.image_len,
+					image_buf, EV_COMPACT_HASH,
+					strlen("linux") + 1, (u8 *)"linux");
+		if (ret)
+			goto unmap_image;
+
+		rd_len = images->rd_end - images->rd_start;
+		initrd_buf = map_sysmem(images->rd_start, rd_len);
+		ret = tcg2_measure_data(dev, &elog, 8, rd_len, initrd_buf,
+					EV_COMPACT_HASH, strlen("initrd") + 1,
+					(u8 *)"initrd");
+		if (ret)
+			goto unmap_initrd;
+
+		if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
+			ret = tcg2_measure_data(dev, &elog, 9, images->ft_len,
+						(u8 *)images->ft_addr,
+						EV_TABLE_OF_DEVICES,
+						strlen("dts") + 1,
+						(u8 *)"dts");
+			if (ret)
+				goto unmap_initrd;
+		}
+
+		s = env_get("bootargs");
+		if (!s)
+			s = "";
+		ret = tcg2_measure_data(dev, &elog, 1, strlen(s) + 1, (u8 *)s,
+					EV_PLATFORM_CONFIG_FLAGS,
+					strlen(s) + 1, (u8 *)s);
+
+unmap_initrd:
+		unmap_sysmem(initrd_buf);
+
+unmap_image:
+		unmap_sysmem(image_buf);
+		tcg2_measurement_term(dev, &elog, ret != 0);
+	}
+
+	return ret;
+}
+
 /**
  * Execute selected states of the bootm command.
  *
@@ -710,6 +771,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
 	if (!ret && (states & BOOTM_STATE_FINDOTHER))
 		ret = bootm_find_other(cmdtp, flag, argc, argv);
 
+	if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && (states & BOOTM_STATE_MEASURE))
+		bootm_measure(images);
+
 	/* Load the OS */
 	if (!ret && (states & BOOTM_STATE_LOADOS)) {
 		iflag = bootm_disable_interrupts();
diff --git a/cmd/bootm.c b/cmd/bootm.c
index 37c2af96e0..0c4a713e02 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -161,6 +161,8 @@ int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 		BOOTM_STATE_OS_GO;
 	if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH))
 		states |= BOOTM_STATE_RAMDISK;
+	if (IS_ENABLED(CONFIG_MEASURED_BOOT))
+		states |= BOOTM_STATE_MEASURE;
 	if (IS_ENABLED(CONFIG_PPC) || IS_ENABLED(CONFIG_MIPS))
 		states |= BOOTM_STATE_OS_CMDLINE;
 	ret = do_bootm_states(cmdtp, flag, argc, argv, states, &images, 1);
diff --git a/include/bootm.h b/include/bootm.h
index 044a4797ed..06d8b1acd8 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -55,6 +55,8 @@ ulong bootm_disable_interrupts(void);
 int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
 		      ulong size);
 
+int bootm_measure(struct bootm_headers *images);
+
 int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
 		    char *const argv[], int states, struct bootm_headers *images,
 		    int boot_progress);
diff --git a/include/image.h b/include/image.h
index bed75ce1b3..bd74e74a75 100644
--- a/include/image.h
+++ b/include/image.h
@@ -407,6 +407,7 @@ struct bootm_headers {
 #define BOOTM_STATE_OS_FAKE_GO	0x00000200	/* 'Almost' run the OS */
 #define BOOTM_STATE_OS_GO	0x00000400
 #define BOOTM_STATE_PRE_LOAD	0x00000800
+#define BOOTM_STATE_MEASURE	0x00001000
 	int		state;
 
 #if defined(CONFIG_LMB) && !defined(USE_HOSTCC)
-- 
2.31.1


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

* [PATCH v2 4/5] tpm: sandbox: Update for needed TPM2 capabilities
  2023-01-09 21:55 [PATCH v2 0/5] tpm: Support boot measurements Eddie James
                   ` (2 preceding siblings ...)
  2023-01-09 21:55 ` [PATCH v2 3/5] bootm: Support boot measurement Eddie James
@ 2023-01-09 21:55 ` Eddie James
  2023-01-11  0:15   ` Simon Glass
  2023-01-09 21:55 ` [PATCH v2 5/5] test: Add sandbox TPM boot measurement Eddie James
  2023-01-09 23:35 ` [PATCH v2 0/5] tpm: Support boot measurements Heinrich Schuchardt
  5 siblings, 1 reply; 18+ messages in thread
From: Eddie James @ 2023-01-09 21:55 UTC (permalink / raw)
  To: u-boot; +Cc: ilias.apalodimas, sjg, xypron.glpk, eajames

The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
---
 drivers/tpm/tpm2_tis_sandbox.c | 100 ++++++++++++++++++++++++---------
 1 file changed, 72 insertions(+), 28 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index dd94bdc31f..ea7fb5e3cb 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
 	TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-	TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x0000020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
 	TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX	((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
 	int i, j;
 
 	/* TPM2_GetProperty */
-	u32 capability, property, property_count;
+	u32 capability, property, property_count, val;
 
 	/* TPM2_PCR_Read/Extend variables */
 	int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
 	case TPM2_CC_GET_CAPABILITY:
 		capability = get_unaligned_be32(sent);
 		sent += sizeof(capability);
-		if (capability != TPM_CAP_TPM_PROPERTIES) {
-			printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-			return TPM2_RC_HANDLE;
-		}
-
 		property = get_unaligned_be32(sent);
 		sent += sizeof(property);
-		property -= TPM2_PROPERTIES_OFFSET;
-
 		property_count = get_unaligned_be32(sent);
 		sent += sizeof(property_count);
-		if (!property_count ||
-		    property + property_count > TPM2_PROPERTY_NB) {
+
+		switch (capability) {
+		case TPM2_CAP_PCRS:
+			break;
+		case TPM2_CAP_TPM_PROPERTIES:
+			if (!property_count) {
+				rc = TPM2_RC_HANDLE;
+				return sandbox_tpm2_fill_buf(recv, recv_len,
+							     tag, rc);
+			}
+
+			if (property > TPM2_PROPERTIES_OFFSET &&
+			    ((property - TPM2_PROPERTIES_OFFSET) +
+			     property_count > TPM2_PROPERTY_NB)) {
+				rc = TPM2_RC_HANDLE;
+				return sandbox_tpm2_fill_buf(recv, recv_len,
+							     tag, rc);
+			}
+			break;
+		default:
+			printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+			       "TPM2_CAP_TPM_PROPERTIES\n");
 			rc = TPM2_RC_HANDLE;
 			return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
 		}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
 		put_unaligned_be32(capability, recv);
 		recv += sizeof(capability);
 
-		/* Give the number of properties that follow */
-		put_unaligned_be32(property_count, recv);
-		recv += sizeof(property_count);
-
-		/* Fill with the properties */
-		for (i = 0; i < property_count; i++) {
-			put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-					   i, recv);
-			recv += sizeof(property);
-			put_unaligned_be32(tpm->properties[property + i],
-					   recv);
-			recv += sizeof(property);
+		switch (capability) {
+		case TPM2_CAP_PCRS:
+			/* Give the number of algorithms supported - just SHA256 */
+			put_unaligned_be32(1, recv);
+			recv += sizeof(u32);
+
+			/* Give SHA256 algorithm */
+			put_unaligned_be16(TPM2_ALG_SHA256, recv);
+			recv += sizeof(u16);
+
+			/* Select the PCRs supported */
+			*recv = SANDBOX_TPM_PCR_SELECT_MAX;
+			recv++;
+
+			/* Activate all the PCR bits */
+			for (i = 0; i < SANDBOX_TPM_PCR_SELECT_MAX; ++i) {
+				*recv = 0xff;
+				recv++;
+			}
+			break;
+		case TPM2_CAP_TPM_PROPERTIES:
+			/* Give the number of properties that follow */
+			put_unaligned_be32(property_count, recv);
+			recv += sizeof(property_count);
+
+			/* Fill with the properties */
+			for (i = 0; i < property_count; i++) {
+				put_unaligned_be32(property + i, recv);
+				recv += sizeof(property);
+				if (property > TPM2_PROPERTIES_OFFSET) {
+					val = tpm->properties[(property -
+						TPM2_PROPERTIES_OFFSET) + i];
+				} else {
+					switch (property) {
+					case TPM2_PT_PCR_COUNT:
+						val = SANDBOX_TPM_PCR_NB;
+						break;
+					default:
+						val = 0xffffffff;
+						break;
+					}
+				}
+
+				put_unaligned_be32(val, recv);
+				recv += sizeof(property);
+			}
+			break;
 		}
 
 		/* Add trailing \0 */
-- 
2.31.1


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

* [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-09 21:55 [PATCH v2 0/5] tpm: Support boot measurements Eddie James
                   ` (3 preceding siblings ...)
  2023-01-09 21:55 ` [PATCH v2 4/5] tpm: sandbox: Update for needed TPM2 capabilities Eddie James
@ 2023-01-09 21:55 ` Eddie James
  2023-01-09 23:13   ` Heinrich Schuchardt
  2023-01-10 22:32   ` Heinrich Schuchardt
  2023-01-09 23:35 ` [PATCH v2 0/5] tpm: Support boot measurements Heinrich Schuchardt
  5 siblings, 2 replies; 18+ messages in thread
From: Eddie James @ 2023-01-09 21:55 UTC (permalink / raw)
  To: u-boot; +Cc: ilias.apalodimas, sjg, xypron.glpk, eajames

Use the sandbox TPM driver to measure some boot images in a unit
test case.

$ ./u-boot -T -c "ut measurement"
Running 1 measurement tests
Test: measure: measurement.c
Failures: 0

Signed-off-by: Eddie James <eajames@linux.ibm.com>
---
 arch/sandbox/dts/test.dts | 12 +++++++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h     |  1 +
 test/boot/Makefile        |  1 +
 test/boot/measurement.c   | 66 +++++++++++++++++++++++++++++++++++++++
 test/cmd_ut.c             |  2 ++
 6 files changed, 83 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dffe10adbf..ad90bf0541 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -66,6 +66,17 @@
 		osd0 = "/osd";
 	};
 
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		event_log: tcg_event_log@d0e000 {
+			no-map;
+			reg = <0x00d0e000 0x2000>;
+		};
+	};
+
 	binman: binman {
 	};
 
@@ -1332,6 +1343,7 @@
 
 	tpm2 {
 		compatible = "sandbox,tpm2";
+		memory-region = <&event_log>;
 	};
 
 	uart0: serial {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index de799b5cea..5ac115f2d8 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index a01000e127..f9284871b0 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -43,6 +43,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index d724629d3b..24cc20bdff 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 ifdef CONFIG_OF_LIVE
 obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 0000000000..2155208894
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James <eajames@linux.ibm.com>
+ */
+
+#include <common.h>
+#include <bootm.h>
+#include <malloc.h>
+#include <test/suites.h>
+#include <test/test.h>
+#include <test/ut.h>
+#include <asm/io.h>
+
+#define MEASUREMENT_TEST(_name, _flags)	\
+	UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+	struct bootm_headers images;
+	const size_t size = 1024;
+	u8 *kernel;
+	u8 *initrd;
+	size_t i;
+
+	kernel = malloc(size);
+	initrd = malloc(size);
+
+	images.os.image_start = map_to_sysmem(kernel);
+	images.os.image_len = size;
+
+	images.rd_start = map_to_sysmem(initrd);
+	images.rd_end = images.rd_start + size;
+
+	images.ft_addr = malloc(size);
+	images.ft_len = size;
+
+	env_set("bootargs", "measurement testing");
+
+	for (i = 0; i < size; ++i) {
+		kernel[i] = (u8)(0xf0 | (i & 0xf));
+		initrd[i] = (u8)((i & 0xf0) | 0xf);
+		((u8 *)images.ft_addr)[i] = (u8)(i & 0xff);
+	}
+
+	ut_assertok(bootm_measure(&images));
+
+	free(images.ft_addr);
+	free(initrd);
+	free(kernel);
+
+	return 0;
+}
+MEASUREMENT_TEST(measure, 0);
+
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc,
+		      char *const argv[])
+{
+	struct unit_test *tests = UNIT_TEST_SUITE_START(measurement_test);
+	const int n_ents = UNIT_TEST_SUITE_COUNT(measurement_test);
+
+	return cmd_ut_category("measurement", "measurement_test_", tests,
+			       n_ents, argc, argv);
+}
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 2736582f11..819031c0f8 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -100,6 +100,8 @@ static struct cmd_tbl cmd_ut_sub[] = {
 			 "", ""),
 	U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1, do_ut_bloblist,
 			 "", ""),
+	U_BOOT_CMD_MKENT(measurement, CONFIG_SYS_MAXARGS, 1, do_ut_measurement,
+			 "", ""),
 	U_BOOT_CMD_MKENT(bootm, CONFIG_SYS_MAXARGS, 1, do_ut_bootm, "", ""),
 #endif
 	U_BOOT_CMD_MKENT(str, CONFIG_SYS_MAXARGS, 1, do_ut_str, "", ""),
-- 
2.31.1


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

* Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-09 21:55 ` [PATCH v2 5/5] test: Add sandbox TPM boot measurement Eddie James
@ 2023-01-09 23:13   ` Heinrich Schuchardt
  2023-01-09 23:26     ` Heinrich Schuchardt
  2023-01-10 22:32   ` Heinrich Schuchardt
  1 sibling, 1 reply; 18+ messages in thread
From: Heinrich Schuchardt @ 2023-01-09 23:13 UTC (permalink / raw)
  To: Eddie James; +Cc: ilias.apalodimas, sjg, u-boot

On 1/9/23 22:55, Eddie James wrote:
> Use the sandbox TPM driver to measure some boot images in a unit
> test case.
>
> $ ./u-boot -T -c "ut measurement"
> Running 1 measurement tests
> Test: measure: measurement.c
> Failures: 0
>
> Signed-off-by: Eddie James <eajames@linux.ibm.com>
> ---
>   arch/sandbox/dts/test.dts | 12 +++++++
>   configs/sandbox_defconfig |  1 +
>   include/test/suites.h     |  1 +
>   test/boot/Makefile        |  1 +
>   test/boot/measurement.c   | 66 +++++++++++++++++++++++++++++++++++++++
>   test/cmd_ut.c             |  2 ++
>   6 files changed, 83 insertions(+)
>   create mode 100644 test/boot/measurement.c
>
> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> index dffe10adbf..ad90bf0541 100644
> --- a/arch/sandbox/dts/test.dts
> +++ b/arch/sandbox/dts/test.dts
> @@ -66,6 +66,17 @@
>   		osd0 = "/osd";
>   	};
>
> +	reserved-memory {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		event_log: tcg_event_log@d0e000 {
> +			no-map;
> +			reg = <0x00d0e000 0x2000>;

This would limit the file loaded at $loadaddr = 0x0 to 13 MiB. Please,
choose a much higher address. Or change $loadaddr, e.g. use loadaddr =
kernel_addr_r = 0x1000000. I would prefer raising loadaddr.

Best regards

Heinrich

> +		};
> +	};
> +
>   	binman: binman {
>   	};
>
> @@ -1332,6 +1343,7 @@
>
>   	tpm2 {
>   		compatible = "sandbox,tpm2";
> +		memory-region = <&event_log>;
>   	};
>
>   	uart0: serial {
> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
> index de799b5cea..5ac115f2d8 100644
> --- a/configs/sandbox_defconfig
> +++ b/configs/sandbox_defconfig
> @@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
>   CONFIG_UNIT_TEST=y
>   CONFIG_UT_TIME=y
>   CONFIG_UT_DM=y
> +CONFIG_MEASURED_BOOT=y
> diff --git a/include/test/suites.h b/include/test/suites.h
> index a01000e127..f9284871b0 100644
> --- a/include/test/suites.h
> +++ b/include/test/suites.h
> @@ -43,6 +43,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>   int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>   int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>   int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
> +int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
>   int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>   int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>   int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
> diff --git a/test/boot/Makefile b/test/boot/Makefile
> index d724629d3b..24cc20bdff 100644
> --- a/test/boot/Makefile
> +++ b/test/boot/Makefile
> @@ -4,6 +4,7 @@
>
>   obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
>   obj-$(CONFIG_FIT) += image.o
> +obj-$(CONFIG_MEASURED_BOOT) += measurement.o
>
>   ifdef CONFIG_OF_LIVE
>   obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o
> diff --git a/test/boot/measurement.c b/test/boot/measurement.c
> new file mode 100644
> index 0000000000..2155208894
> --- /dev/null
> +++ b/test/boot/measurement.c
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Test for measured boot functions
> + *
> + * Copyright 2023 IBM Corp.
> + * Written by Eddie James <eajames@linux.ibm.com>
> + */
> +
> +#include <common.h>
> +#include <bootm.h>
> +#include <malloc.h>
> +#include <test/suites.h>
> +#include <test/test.h>
> +#include <test/ut.h>
> +#include <asm/io.h>
> +
> +#define MEASUREMENT_TEST(_name, _flags)	\
> +	UNIT_TEST(_name, _flags, measurement_test)
> +
> +static int measure(struct unit_test_state *uts)
> +{
> +	struct bootm_headers images;
> +	const size_t size = 1024;
> +	u8 *kernel;
> +	u8 *initrd;
> +	size_t i;
> +
> +	kernel = malloc(size);
> +	initrd = malloc(size);
> +
> +	images.os.image_start = map_to_sysmem(kernel);
> +	images.os.image_len = size;
> +
> +	images.rd_start = map_to_sysmem(initrd);
> +	images.rd_end = images.rd_start + size;
> +
> +	images.ft_addr = malloc(size);
> +	images.ft_len = size;
> +
> +	env_set("bootargs", "measurement testing");
> +
> +	for (i = 0; i < size; ++i) {
> +		kernel[i] = (u8)(0xf0 | (i & 0xf));
> +		initrd[i] = (u8)((i & 0xf0) | 0xf);
> +		((u8 *)images.ft_addr)[i] = (u8)(i & 0xff);
> +	}
> +
> +	ut_assertok(bootm_measure(&images));
> +
> +	free(images.ft_addr);
> +	free(initrd);
> +	free(kernel);
> +
> +	return 0;
> +}
> +MEASUREMENT_TEST(measure, 0);
> +
> +int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc,
> +		      char *const argv[])
> +{
> +	struct unit_test *tests = UNIT_TEST_SUITE_START(measurement_test);
> +	const int n_ents = UNIT_TEST_SUITE_COUNT(measurement_test);
> +
> +	return cmd_ut_category("measurement", "measurement_test_", tests,
> +			       n_ents, argc, argv);
> +}
> diff --git a/test/cmd_ut.c b/test/cmd_ut.c
> index 2736582f11..819031c0f8 100644
> --- a/test/cmd_ut.c
> +++ b/test/cmd_ut.c
> @@ -100,6 +100,8 @@ static struct cmd_tbl cmd_ut_sub[] = {
>   			 "", ""),
>   	U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1, do_ut_bloblist,
>   			 "", ""),
> +	U_BOOT_CMD_MKENT(measurement, CONFIG_SYS_MAXARGS, 1, do_ut_measurement,
> +			 "", ""),
>   	U_BOOT_CMD_MKENT(bootm, CONFIG_SYS_MAXARGS, 1, do_ut_bootm, "", ""),
>   #endif
>   	U_BOOT_CMD_MKENT(str, CONFIG_SYS_MAXARGS, 1, do_ut_str, "", ""),


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

* Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-09 23:13   ` Heinrich Schuchardt
@ 2023-01-09 23:26     ` Heinrich Schuchardt
  2023-01-10 16:38       ` Eddie James
  0 siblings, 1 reply; 18+ messages in thread
From: Heinrich Schuchardt @ 2023-01-09 23:26 UTC (permalink / raw)
  To: Eddie James; +Cc: ilias.apalodimas, sjg, u-boot

On 1/10/23 00:13, Heinrich Schuchardt wrote:
> On 1/9/23 22:55, Eddie James wrote:
>> Use the sandbox TPM driver to measure some boot images in a unit
>> test case.
>>
>> $ ./u-boot -T -c "ut measurement"
>> Running 1 measurement tests
>> Test: measure: measurement.c
>> Failures: 0
>>
>> Signed-off-by: Eddie James <eajames@linux.ibm.com>
>> ---
>>   arch/sandbox/dts/test.dts | 12 +++++++
>>   configs/sandbox_defconfig |  1 +
>>   include/test/suites.h     |  1 +
>>   test/boot/Makefile        |  1 +
>>   test/boot/measurement.c   | 66 +++++++++++++++++++++++++++++++++++++++
>>   test/cmd_ut.c             |  2 ++
>>   6 files changed, 83 insertions(+)
>>   create mode 100644 test/boot/measurement.c
>>
>> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
>> index dffe10adbf..ad90bf0541 100644
>> --- a/arch/sandbox/dts/test.dts
>> +++ b/arch/sandbox/dts/test.dts
>> @@ -66,6 +66,17 @@
>>           osd0 = "/osd";
>>       };
>>
>> +    reserved-memory {
>> +        #address-cells = <1>;
>> +        #size-cells = <1>;
>> +        ranges;
>> +
>> +        event_log: tcg_event_log@d0e000 {
>> +            no-map;
>> +            reg = <0x00d0e000 0x2000>;

How should this work if you don't define linux,sml-base and linux,sml-size?

Best regards

Heinrich

>
> This would limit the file loaded at $loadaddr = 0x0 to 13 MiB. Please,
> choose a much higher address. Or change $loadaddr, e.g. use loadaddr =
> kernel_addr_r = 0x1000000. I would prefer raising loadaddr.
>
> Best regards
>
> Heinrich
>
>> +        };
>> +    };
>> +
>>       binman: binman {
>>       };
>>
>> @@ -1332,6 +1343,7 @@
>>
>>       tpm2 {
>>           compatible = "sandbox,tpm2";
>> +        memory-region = <&event_log>;
>>       };
>>
>>       uart0: serial {
>> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
>> index de799b5cea..5ac115f2d8 100644
>> --- a/configs/sandbox_defconfig
>> +++ b/configs/sandbox_defconfig
>> @@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
>>   CONFIG_UNIT_TEST=y
>>   CONFIG_UT_TIME=y
>>   CONFIG_UT_DM=y
>> +CONFIG_MEASURED_BOOT=y
>> diff --git a/include/test/suites.h b/include/test/suites.h
>> index a01000e127..f9284871b0 100644
>> --- a/include/test/suites.h
>> +++ b/include/test/suites.h
>> @@ -43,6 +43,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int
>> argc, char *const argv[]);
>>   int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const
>> argv[]);
>>   int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char
>> *const argv[]);
>>   int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char *
>> const argv[]);
>> +int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char
>> * const argv[]);
>>   int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const
>> argv[]);
>>   int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char
>> *const argv[]);
>>   int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
>> diff --git a/test/boot/Makefile b/test/boot/Makefile
>> index d724629d3b..24cc20bdff 100644
>> --- a/test/boot/Makefile
>> +++ b/test/boot/Makefile
>> @@ -4,6 +4,7 @@
>>
>>   obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o
>> bootmeth.o
>>   obj-$(CONFIG_FIT) += image.o
>> +obj-$(CONFIG_MEASURED_BOOT) += measurement.o
>>
>>   ifdef CONFIG_OF_LIVE
>>   obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o
>> diff --git a/test/boot/measurement.c b/test/boot/measurement.c
>> new file mode 100644
>> index 0000000000..2155208894
>> --- /dev/null
>> +++ b/test/boot/measurement.c
>> @@ -0,0 +1,66 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Test for measured boot functions
>> + *
>> + * Copyright 2023 IBM Corp.
>> + * Written by Eddie James <eajames@linux.ibm.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <bootm.h>
>> +#include <malloc.h>
>> +#include <test/suites.h>
>> +#include <test/test.h>
>> +#include <test/ut.h>
>> +#include <asm/io.h>
>> +
>> +#define MEASUREMENT_TEST(_name, _flags)    \
>> +    UNIT_TEST(_name, _flags, measurement_test)
>> +
>> +static int measure(struct unit_test_state *uts)
>> +{
>> +    struct bootm_headers images;
>> +    const size_t size = 1024;
>> +    u8 *kernel;
>> +    u8 *initrd;
>> +    size_t i;
>> +
>> +    kernel = malloc(size);
>> +    initrd = malloc(size);
>> +
>> +    images.os.image_start = map_to_sysmem(kernel);
>> +    images.os.image_len = size;
>> +
>> +    images.rd_start = map_to_sysmem(initrd);
>> +    images.rd_end = images.rd_start + size;
>> +
>> +    images.ft_addr = malloc(size);
>> +    images.ft_len = size;
>> +
>> +    env_set("bootargs", "measurement testing");
>> +
>> +    for (i = 0; i < size; ++i) {
>> +        kernel[i] = (u8)(0xf0 | (i & 0xf));
>> +        initrd[i] = (u8)((i & 0xf0) | 0xf);
>> +        ((u8 *)images.ft_addr)[i] = (u8)(i & 0xff);
>> +    }
>> +
>> +    ut_assertok(bootm_measure(&images));
>> +
>> +    free(images.ft_addr);
>> +    free(initrd);
>> +    free(kernel);
>> +
>> +    return 0;
>> +}
>> +MEASUREMENT_TEST(measure, 0);
>> +
>> +int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc,
>> +              char *const argv[])
>> +{
>> +    struct unit_test *tests = UNIT_TEST_SUITE_START(measurement_test);
>> +    const int n_ents = UNIT_TEST_SUITE_COUNT(measurement_test);
>> +
>> +    return cmd_ut_category("measurement", "measurement_test_", tests,
>> +                   n_ents, argc, argv);
>> +}
>> diff --git a/test/cmd_ut.c b/test/cmd_ut.c
>> index 2736582f11..819031c0f8 100644
>> --- a/test/cmd_ut.c
>> +++ b/test/cmd_ut.c
>> @@ -100,6 +100,8 @@ static struct cmd_tbl cmd_ut_sub[] = {
>>                "", ""),
>>       U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1, do_ut_bloblist,
>>                "", ""),
>> +    U_BOOT_CMD_MKENT(measurement, CONFIG_SYS_MAXARGS, 1,
>> do_ut_measurement,
>> +             "", ""),
>>       U_BOOT_CMD_MKENT(bootm, CONFIG_SYS_MAXARGS, 1, do_ut_bootm, "",
>> ""),
>>   #endif
>>       U_BOOT_CMD_MKENT(str, CONFIG_SYS_MAXARGS, 1, do_ut_str, "", ""),
>



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

* Re: [PATCH v2 0/5] tpm: Support boot measurements
  2023-01-09 21:55 [PATCH v2 0/5] tpm: Support boot measurements Eddie James
                   ` (4 preceding siblings ...)
  2023-01-09 21:55 ` [PATCH v2 5/5] test: Add sandbox TPM boot measurement Eddie James
@ 2023-01-09 23:35 ` Heinrich Schuchardt
  2023-01-10 21:42   ` Eddie James
  5 siblings, 1 reply; 18+ messages in thread
From: Heinrich Schuchardt @ 2023-01-09 23:35 UTC (permalink / raw)
  To: Eddie James; +Cc: ilias.apalodimas, sjg, u-boot

On 1/9/23 22:55, Eddie James wrote:
> This series adds support for measuring the boot images more generically
> than the existing EFI support. Several EFI functions have been moved to
> the TPM layer. The series includes optional measurement from the bootm
> command.
> A new test case has been added for the bootm measurement to test the new
> path, and the sandbox TPM2 driver has been updated to support this use
> case.
>
> Changes since v1:
>   - Refactor TPM layer functions to allow EFI system to use them, and
>     remove duplicate EFI functions.
>   - Add test case
>   - Drop #ifdefs for bootm
>   - Add devicetree measurement config option
>   - Update sandbox TPM driver

This looks like a useful feature to me. Some questions remain:

How about the booti and bootz commands. Are they covered by the change?

What are the consequences of your changes for UEFI FIT images (cf.
CONFIG_BOOTM_EFI)?

>
> Eddie James (5):
>    tpm: Fix spelling for tpmu_ha union
>    tpm: Support boot measurements
>    bootm: Support boot measurement
>    tpm: sandbox: Update for needed TPM2 capabilities
>    test: Add sandbox TPM boot measurement

I am missing the documentation changes. These should describe which
changes in the device-tree and in the configuration are needed to enable
measurements. This should be in doc/usage/

@Ilias:
Could you contribute the UEFI part for the document, please.

Best regards

Heinrich

>
>   arch/sandbox/dts/test.dts      |  12 +
>   boot/Kconfig                   |  23 ++
>   boot/bootm.c                   |  64 +++
>   cmd/bootm.c                    |   2 +
>   configs/sandbox_defconfig      |   1 +
>   drivers/tpm/tpm2_tis_sandbox.c | 100 +++--
>   include/bootm.h                |   2 +
>   include/efi_tcg2.h             |  44 --
>   include/image.h                |   1 +
>   include/test/suites.h          |   1 +
>   include/tpm-v2.h               | 215 +++++++++-
>   lib/efi_loader/efi_tcg2.c      | 362 +----------------
>   lib/tpm-v2.c                   | 708 +++++++++++++++++++++++++++++++++
>   test/boot/Makefile             |   1 +
>   test/boot/measurement.c        |  66 +++
>   test/cmd_ut.c                  |   2 +
>   16 files changed, 1187 insertions(+), 417 deletions(-)
>   create mode 100644 test/boot/measurement.c
>


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

* Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-09 23:26     ` Heinrich Schuchardt
@ 2023-01-10 16:38       ` Eddie James
  2023-01-10 22:02         ` Heinrich Schuchardt
  0 siblings, 1 reply; 18+ messages in thread
From: Eddie James @ 2023-01-10 16:38 UTC (permalink / raw)
  To: Heinrich Schuchardt; +Cc: ilias.apalodimas, sjg, u-boot


On 1/9/23 17:26, Heinrich Schuchardt wrote:
> On 1/10/23 00:13, Heinrich Schuchardt wrote:
>> On 1/9/23 22:55, Eddie James wrote:
>>> Use the sandbox TPM driver to measure some boot images in a unit
>>> test case.
>>>
>>> $ ./u-boot -T -c "ut measurement"
>>> Running 1 measurement tests
>>> Test: measure: measurement.c
>>> Failures: 0
>>>
>>> Signed-off-by: Eddie James <eajames@linux.ibm.com>
>>> ---
>>>   arch/sandbox/dts/test.dts | 12 +++++++
>>>   configs/sandbox_defconfig |  1 +
>>>   include/test/suites.h     |  1 +
>>>   test/boot/Makefile        |  1 +
>>>   test/boot/measurement.c   | 66 
>>> +++++++++++++++++++++++++++++++++++++++
>>>   test/cmd_ut.c             |  2 ++
>>>   6 files changed, 83 insertions(+)
>>>   create mode 100644 test/boot/measurement.c
>>>
>>> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
>>> index dffe10adbf..ad90bf0541 100644
>>> --- a/arch/sandbox/dts/test.dts
>>> +++ b/arch/sandbox/dts/test.dts
>>> @@ -66,6 +66,17 @@
>>>           osd0 = "/osd";
>>>       };
>>>
>>> +    reserved-memory {
>>> +        #address-cells = <1>;
>>> +        #size-cells = <1>;
>>> +        ranges;
>>> +
>>> +        event_log: tcg_event_log@d0e000 {
>>> +            no-map;
>>> +            reg = <0x00d0e000 0x2000>;
>
> How should this work if you don't define linux,sml-base and 
> linux,sml-size?


I have sent a patch to the linux list for using a reserved memory 
region, as I have also added in the u-boot TPM layer for the event log.

https://patchwork.kernel.org/project/linux-integrity/patch/20230103162010.381214-1-eajames@linux.ibm.com/


Thanks,

Eddie


>
> Best regards
>
> Heinrich
>
>>
>> This would limit the file loaded at $loadaddr = 0x0 to 13 MiB. Please,
>> choose a much higher address. Or change $loadaddr, e.g. use loadaddr =
>> kernel_addr_r = 0x1000000. I would prefer raising loadaddr.
>>
>> Best regards
>>
>> Heinrich
>>
>>> +        };
>>> +    };
>>> +
>>>       binman: binman {
>>>       };
>>>
>>> @@ -1332,6 +1343,7 @@
>>>
>>>       tpm2 {
>>>           compatible = "sandbox,tpm2";
>>> +        memory-region = <&event_log>;
>>>       };
>>>
>>>       uart0: serial {
>>> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
>>> index de799b5cea..5ac115f2d8 100644
>>> --- a/configs/sandbox_defconfig
>>> +++ b/configs/sandbox_defconfig
>>> @@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
>>>   CONFIG_UNIT_TEST=y
>>>   CONFIG_UT_TIME=y
>>>   CONFIG_UT_DM=y
>>> +CONFIG_MEASURED_BOOT=y
>>> diff --git a/include/test/suites.h b/include/test/suites.h
>>> index a01000e127..f9284871b0 100644
>>> --- a/include/test/suites.h
>>> +++ b/include/test/suites.h
>>> @@ -43,6 +43,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int
>>> argc, char *const argv[]);
>>>   int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const
>>> argv[]);
>>>   int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char
>>> *const argv[]);
>>>   int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char *
>>> const argv[]);
>>> +int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char
>>> * const argv[]);
>>>   int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const
>>> argv[]);
>>>   int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char
>>> *const argv[]);
>>>   int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
>>> diff --git a/test/boot/Makefile b/test/boot/Makefile
>>> index d724629d3b..24cc20bdff 100644
>>> --- a/test/boot/Makefile
>>> +++ b/test/boot/Makefile
>>> @@ -4,6 +4,7 @@
>>>
>>>   obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o
>>> bootmeth.o
>>>   obj-$(CONFIG_FIT) += image.o
>>> +obj-$(CONFIG_MEASURED_BOOT) += measurement.o
>>>
>>>   ifdef CONFIG_OF_LIVE
>>>   obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o
>>> diff --git a/test/boot/measurement.c b/test/boot/measurement.c
>>> new file mode 100644
>>> index 0000000000..2155208894
>>> --- /dev/null
>>> +++ b/test/boot/measurement.c
>>> @@ -0,0 +1,66 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Test for measured boot functions
>>> + *
>>> + * Copyright 2023 IBM Corp.
>>> + * Written by Eddie James <eajames@linux.ibm.com>
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <bootm.h>
>>> +#include <malloc.h>
>>> +#include <test/suites.h>
>>> +#include <test/test.h>
>>> +#include <test/ut.h>
>>> +#include <asm/io.h>
>>> +
>>> +#define MEASUREMENT_TEST(_name, _flags)    \
>>> +    UNIT_TEST(_name, _flags, measurement_test)
>>> +
>>> +static int measure(struct unit_test_state *uts)
>>> +{
>>> +    struct bootm_headers images;
>>> +    const size_t size = 1024;
>>> +    u8 *kernel;
>>> +    u8 *initrd;
>>> +    size_t i;
>>> +
>>> +    kernel = malloc(size);
>>> +    initrd = malloc(size);
>>> +
>>> +    images.os.image_start = map_to_sysmem(kernel);
>>> +    images.os.image_len = size;
>>> +
>>> +    images.rd_start = map_to_sysmem(initrd);
>>> +    images.rd_end = images.rd_start + size;
>>> +
>>> +    images.ft_addr = malloc(size);
>>> +    images.ft_len = size;
>>> +
>>> +    env_set("bootargs", "measurement testing");
>>> +
>>> +    for (i = 0; i < size; ++i) {
>>> +        kernel[i] = (u8)(0xf0 | (i & 0xf));
>>> +        initrd[i] = (u8)((i & 0xf0) | 0xf);
>>> +        ((u8 *)images.ft_addr)[i] = (u8)(i & 0xff);
>>> +    }
>>> +
>>> +    ut_assertok(bootm_measure(&images));
>>> +
>>> +    free(images.ft_addr);
>>> +    free(initrd);
>>> +    free(kernel);
>>> +
>>> +    return 0;
>>> +}
>>> +MEASUREMENT_TEST(measure, 0);
>>> +
>>> +int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc,
>>> +              char *const argv[])
>>> +{
>>> +    struct unit_test *tests = UNIT_TEST_SUITE_START(measurement_test);
>>> +    const int n_ents = UNIT_TEST_SUITE_COUNT(measurement_test);
>>> +
>>> +    return cmd_ut_category("measurement", "measurement_test_", tests,
>>> +                   n_ents, argc, argv);
>>> +}
>>> diff --git a/test/cmd_ut.c b/test/cmd_ut.c
>>> index 2736582f11..819031c0f8 100644
>>> --- a/test/cmd_ut.c
>>> +++ b/test/cmd_ut.c
>>> @@ -100,6 +100,8 @@ static struct cmd_tbl cmd_ut_sub[] = {
>>>                "", ""),
>>>       U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1, do_ut_bloblist,
>>>                "", ""),
>>> +    U_BOOT_CMD_MKENT(measurement, CONFIG_SYS_MAXARGS, 1,
>>> do_ut_measurement,
>>> +             "", ""),
>>>       U_BOOT_CMD_MKENT(bootm, CONFIG_SYS_MAXARGS, 1, do_ut_bootm, "",
>>> ""),
>>>   #endif
>>>       U_BOOT_CMD_MKENT(str, CONFIG_SYS_MAXARGS, 1, do_ut_str, "", ""),
>>
>
>

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

* Re: [PATCH v2 0/5] tpm: Support boot measurements
  2023-01-09 23:35 ` [PATCH v2 0/5] tpm: Support boot measurements Heinrich Schuchardt
@ 2023-01-10 21:42   ` Eddie James
  2023-01-10 22:08     ` Heinrich Schuchardt
  0 siblings, 1 reply; 18+ messages in thread
From: Eddie James @ 2023-01-10 21:42 UTC (permalink / raw)
  To: Heinrich Schuchardt; +Cc: ilias.apalodimas, sjg, u-boot


On 1/9/23 17:35, Heinrich Schuchardt wrote:
> On 1/9/23 22:55, Eddie James wrote:
>> This series adds support for measuring the boot images more generically
>> than the existing EFI support. Several EFI functions have been moved to
>> the TPM layer. The series includes optional measurement from the bootm
>> command.
>> A new test case has been added for the bootm measurement to test the new
>> path, and the sandbox TPM2 driver has been updated to support this use
>> case.
>>
>> Changes since v1:
>>   - Refactor TPM layer functions to allow EFI system to use them, and
>>     remove duplicate EFI functions.
>>   - Add test case
>>   - Drop #ifdefs for bootm
>>   - Add devicetree measurement config option
>>   - Update sandbox TPM driver
>
> This looks like a useful feature to me. Some questions remain:
>
> How about the booti and bootz commands. Are they covered by the change?


No, not yet.


>
> What are the consequences of your changes for UEFI FIT images (cf.
> CONFIG_BOOTM_EFI)?


I suppose the image would be measured twice, but only if the user 
selected both of the relevant config options.


>
>>
>> Eddie James (5):
>>    tpm: Fix spelling for tpmu_ha union
>>    tpm: Support boot measurements
>>    bootm: Support boot measurement
>>    tpm: sandbox: Update for needed TPM2 capabilities
>>    test: Add sandbox TPM boot measurement
>
> I am missing the documentation changes. These should describe which
> changes in the device-tree and in the configuration are needed to enable
> measurements. This should be in doc/usage/


Sure.

Thanks,

Eddie


>
> @Ilias:
> Could you contribute the UEFI part for the document, please.
>
> Best regards
>
> Heinrich
>
>>
>>   arch/sandbox/dts/test.dts      |  12 +
>>   boot/Kconfig                   |  23 ++
>>   boot/bootm.c                   |  64 +++
>>   cmd/bootm.c                    |   2 +
>>   configs/sandbox_defconfig      |   1 +
>>   drivers/tpm/tpm2_tis_sandbox.c | 100 +++--
>>   include/bootm.h                |   2 +
>>   include/efi_tcg2.h             |  44 --
>>   include/image.h                |   1 +
>>   include/test/suites.h          |   1 +
>>   include/tpm-v2.h               | 215 +++++++++-
>>   lib/efi_loader/efi_tcg2.c      | 362 +----------------
>>   lib/tpm-v2.c                   | 708 +++++++++++++++++++++++++++++++++
>>   test/boot/Makefile             |   1 +
>>   test/boot/measurement.c        |  66 +++
>>   test/cmd_ut.c                  |   2 +
>>   16 files changed, 1187 insertions(+), 417 deletions(-)
>>   create mode 100644 test/boot/measurement.c
>>
>

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

* Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-10 16:38       ` Eddie James
@ 2023-01-10 22:02         ` Heinrich Schuchardt
  2023-01-10 22:11           ` Eddie James
  0 siblings, 1 reply; 18+ messages in thread
From: Heinrich Schuchardt @ 2023-01-10 22:02 UTC (permalink / raw)
  To: Eddie James; +Cc: ilias.apalodimas, sjg, u-boot

On 1/10/23 17:38, Eddie James wrote:
>
> On 1/9/23 17:26, Heinrich Schuchardt wrote:
>> On 1/10/23 00:13, Heinrich Schuchardt wrote:
>>> On 1/9/23 22:55, Eddie James wrote:
>>>> Use the sandbox TPM driver to measure some boot images in a unit
>>>> test case.
>>>>
>>>> $ ./u-boot -T -c "ut measurement"
>>>> Running 1 measurement tests
>>>> Test: measure: measurement.c
>>>> Failures: 0
>>>>
>>>> Signed-off-by: Eddie James <eajames@linux.ibm.com>
>>>> ---
>>>>   arch/sandbox/dts/test.dts | 12 +++++++
>>>>   configs/sandbox_defconfig |  1 +
>>>>   include/test/suites.h     |  1 +
>>>>   test/boot/Makefile        |  1 +
>>>>   test/boot/measurement.c   | 66
>>>> +++++++++++++++++++++++++++++++++++++++
>>>>   test/cmd_ut.c             |  2 ++
>>>>   6 files changed, 83 insertions(+)
>>>>   create mode 100644 test/boot/measurement.c
>>>>
>>>> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
>>>> index dffe10adbf..ad90bf0541 100644
>>>> --- a/arch/sandbox/dts/test.dts
>>>> +++ b/arch/sandbox/dts/test.dts
>>>> @@ -66,6 +66,17 @@
>>>>           osd0 = "/osd";
>>>>       };
>>>>
>>>> +    reserved-memory {
>>>> +        #address-cells = <1>;
>>>> +        #size-cells = <1>;
>>>> +        ranges;
>>>> +
>>>> +        event_log: tcg_event_log@d0e000 {
>>>> +            no-map;
>>>> +            reg = <0x00d0e000 0x2000>;
>>
>> How should this work if you don't define linux,sml-base and
>> linux,sml-size?
>
>
> I have sent a patch to the linux list for using a reserved memory
> region, as I have also added in the u-boot TPM layer for the event log.
>
> https://patchwork.kernel.org/project/linux-integrity/patch/20230103162010.381214-1-eajames@linux.ibm.com/

Thank you for the clarification.

The kernel patch seems to need rework:
https://lore.kernel.org/all/202301040834.YsMHDMpw-lkp@intel.com/

Shouldn't the sandbox device-tree support these properties? This will
allow us to write a test application that the sandbox can run via
booti/bootz (depending on bitness) and bootm. This test application can
retrieve the event log and print it via Linux system calls.

Best regards

Heinrich

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

* Re: [PATCH v2 0/5] tpm: Support boot measurements
  2023-01-10 21:42   ` Eddie James
@ 2023-01-10 22:08     ` Heinrich Schuchardt
  0 siblings, 0 replies; 18+ messages in thread
From: Heinrich Schuchardt @ 2023-01-10 22:08 UTC (permalink / raw)
  To: Eddie James; +Cc: ilias.apalodimas, sjg, u-boot

On 1/10/23 22:42, Eddie James wrote:
>
> On 1/9/23 17:35, Heinrich Schuchardt wrote:
>> On 1/9/23 22:55, Eddie James wrote:
>>> This series adds support for measuring the boot images more generically
>>> than the existing EFI support. Several EFI functions have been moved to
>>> the TPM layer. The series includes optional measurement from the bootm
>>> command.
>>> A new test case has been added for the bootm measurement to test the new
>>> path, and the sandbox TPM2 driver has been updated to support this use
>>> case.
>>>
>>> Changes since v1:
>>>   - Refactor TPM layer functions to allow EFI system to use them, and
>>>     remove duplicate EFI functions.
>>>   - Add test case
>>>   - Drop #ifdefs for bootm
>>>   - Add devicetree measurement config option
>>>   - Update sandbox TPM driver
>>
>> This looks like a useful feature to me. Some questions remain:
>>
>> How about the booti and bootz commands. Are they covered by the change?
>
>
> No, not yet.

Please, add the measurements in common code for all boot commands
(except bootefi).

>
>
>>
>> What are the consequences of your changes for UEFI FIT images (cf.
>> CONFIG_BOOTM_EFI)?
>
>
> I suppose the image would be measured twice, but only if the user
> selected both of the relevant config options.

We should have a test case for this.

Best regards

Heinrich

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

* Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-10 22:02         ` Heinrich Schuchardt
@ 2023-01-10 22:11           ` Eddie James
  0 siblings, 0 replies; 18+ messages in thread
From: Eddie James @ 2023-01-10 22:11 UTC (permalink / raw)
  To: Heinrich Schuchardt; +Cc: ilias.apalodimas, sjg, u-boot


On 1/10/23 16:02, Heinrich Schuchardt wrote:
> On 1/10/23 17:38, Eddie James wrote:
>>
>> On 1/9/23 17:26, Heinrich Schuchardt wrote:
>>> On 1/10/23 00:13, Heinrich Schuchardt wrote:
>>>> On 1/9/23 22:55, Eddie James wrote:
>>>>> Use the sandbox TPM driver to measure some boot images in a unit
>>>>> test case.
>>>>>
>>>>> $ ./u-boot -T -c "ut measurement"
>>>>> Running 1 measurement tests
>>>>> Test: measure: measurement.c
>>>>> Failures: 0
>>>>>
>>>>> Signed-off-by: Eddie James <eajames@linux.ibm.com>
>>>>> ---
>>>>>   arch/sandbox/dts/test.dts | 12 +++++++
>>>>>   configs/sandbox_defconfig |  1 +
>>>>>   include/test/suites.h     |  1 +
>>>>>   test/boot/Makefile        |  1 +
>>>>>   test/boot/measurement.c   | 66
>>>>> +++++++++++++++++++++++++++++++++++++++
>>>>>   test/cmd_ut.c             |  2 ++
>>>>>   6 files changed, 83 insertions(+)
>>>>>   create mode 100644 test/boot/measurement.c
>>>>>
>>>>> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
>>>>> index dffe10adbf..ad90bf0541 100644
>>>>> --- a/arch/sandbox/dts/test.dts
>>>>> +++ b/arch/sandbox/dts/test.dts
>>>>> @@ -66,6 +66,17 @@
>>>>>           osd0 = "/osd";
>>>>>       };
>>>>>
>>>>> +    reserved-memory {
>>>>> +        #address-cells = <1>;
>>>>> +        #size-cells = <1>;
>>>>> +        ranges;
>>>>> +
>>>>> +        event_log: tcg_event_log@d0e000 {
>>>>> +            no-map;
>>>>> +            reg = <0x00d0e000 0x2000>;
>>>
>>> How should this work if you don't define linux,sml-base and
>>> linux,sml-size?
>>
>>
>> I have sent a patch to the linux list for using a reserved memory
>> region, as I have also added in the u-boot TPM layer for the event log.
>>
>> https://patchwork.kernel.org/project/linux-integrity/patch/20230103162010.381214-1-eajames@linux.ibm.com/ 
>>
>
> Thank you for the clarification.
>
> The kernel patch seems to need rework:
> https://lore.kernel.org/all/202301040834.YsMHDMpw-lkp@intel.com/


Yes I'll address that.


>
> Shouldn't the sandbox device-tree support these properties? This will
> allow us to write a test application that the sandbox can run via
> booti/bootz (depending on bitness) and bootm. This test application can
> retrieve the event log and print it via Linux system calls.


OK, I can add it to the main sandbox device-tree as well then. It is 
added to the sandbox test device-tree, used by the unit test case I added.


Thanks,

Eddie


>
> Best regards
>
> Heinrich

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

* Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-09 21:55 ` [PATCH v2 5/5] test: Add sandbox TPM boot measurement Eddie James
  2023-01-09 23:13   ` Heinrich Schuchardt
@ 2023-01-10 22:32   ` Heinrich Schuchardt
  2023-01-10 22:37     ` Heinrich Schuchardt
  1 sibling, 1 reply; 18+ messages in thread
From: Heinrich Schuchardt @ 2023-01-10 22:32 UTC (permalink / raw)
  To: Eddie James; +Cc: ilias.apalodimas, sjg, u-boot

On 1/9/23 22:55, Eddie James wrote:
> Use the sandbox TPM driver to measure some boot images in a unit
> test case.
>
> $ ./u-boot -T -c "ut measurement"
> Running 1 measurement tests
> Test: measure: measurement.c
> Failures: 0
>
> Signed-off-by: Eddie James <eajames@linux.ibm.com>
> ---
>   arch/sandbox/dts/test.dts | 12 +++++++
>   configs/sandbox_defconfig |  1 +
>   include/test/suites.h     |  1 +
>   test/boot/Makefile        |  1 +
>   test/boot/measurement.c   | 66 +++++++++++++++++++++++++++++++++++++++
>   test/cmd_ut.c             |  2 ++
>   6 files changed, 83 insertions(+)
>   create mode 100644 test/boot/measurement.c
>
> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> index dffe10adbf..ad90bf0541 100644
> --- a/arch/sandbox/dts/test.dts
> +++ b/arch/sandbox/dts/test.dts
> @@ -66,6 +66,17 @@
>   		osd0 = "/osd";
>   	};
>
> +	reserved-memory {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		event_log: tcg_event_log@d0e000 {
> +			no-map;

Isn't no-map misplaced? Shouldn't it be a reserved-memory property?

If the memory region is not mapped, Linux can never access it as
described in
Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml.

Please, document all changes to the device-tree semantics via patches
for the Linux kernels documentation and provide a full example.

Best regards

Heinrich

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

* Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-10 22:32   ` Heinrich Schuchardt
@ 2023-01-10 22:37     ` Heinrich Schuchardt
  2023-01-11 14:14       ` Eddie James
  0 siblings, 1 reply; 18+ messages in thread
From: Heinrich Schuchardt @ 2023-01-10 22:37 UTC (permalink / raw)
  To: Eddie James; +Cc: ilias.apalodimas, sjg, u-boot

On 1/10/23 23:32, Heinrich Schuchardt wrote:
> On 1/9/23 22:55, Eddie James wrote:
>> Use the sandbox TPM driver to measure some boot images in a unit
>> test case.
>>
>> $ ./u-boot -T -c "ut measurement"
>> Running 1 measurement tests
>> Test: measure: measurement.c
>> Failures: 0
>>
>> Signed-off-by: Eddie James <eajames@linux.ibm.com>
>> ---
>>   arch/sandbox/dts/test.dts | 12 +++++++
>>   configs/sandbox_defconfig |  1 +
>>   include/test/suites.h     |  1 +
>>   test/boot/Makefile        |  1 +
>>   test/boot/measurement.c   | 66 +++++++++++++++++++++++++++++++++++++++
>>   test/cmd_ut.c             |  2 ++
>>   6 files changed, 83 insertions(+)
>>   create mode 100644 test/boot/measurement.c
>>
>> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
>> index dffe10adbf..ad90bf0541 100644
>> --- a/arch/sandbox/dts/test.dts
>> +++ b/arch/sandbox/dts/test.dts
>> @@ -66,6 +66,17 @@
>>           osd0 = "/osd";
>>       };
>>
>> +    reserved-memory {
>> +        #address-cells = <1>;
>> +        #size-cells = <1>;
>> +        ranges;
>> +
>> +        event_log: tcg_event_log@d0e000 {
>> +            no-map;
>
> Isn't no-map misplaced? Shouldn't it be a reserved-memory property?

The placement is correct. But I still wonder why we should have this
area as no-map.

>
> If the memory region is not mapped, Linux can never access it as
> described in
> Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml.
>
> Please, document all changes to the device-tree semantics via patches
> for the Linux kernels documentation and provide a full example.
>
> Best regards
>
> Heinrich


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

* Re: [PATCH v2 4/5] tpm: sandbox: Update for needed TPM2 capabilities
  2023-01-09 21:55 ` [PATCH v2 4/5] tpm: sandbox: Update for needed TPM2 capabilities Eddie James
@ 2023-01-11  0:15   ` Simon Glass
  0 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2023-01-11  0:15 UTC (permalink / raw)
  To: Eddie James; +Cc: u-boot, ilias.apalodimas, xypron.glpk

On Mon, 9 Jan 2023 at 14:55, Eddie James <eajames@linux.ibm.com> wrote:
>
> The driver needs to support getting the PCRs in the capabilities
> command. Fix various other things and support the max number
> of PCRs for TPM2.
>
> Signed-off-by: Eddie James <eajames@linux.ibm.com>
> ---
>  drivers/tpm/tpm2_tis_sandbox.c | 100 ++++++++++++++++++++++++---------
>  1 file changed, 72 insertions(+), 28 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement
  2023-01-10 22:37     ` Heinrich Schuchardt
@ 2023-01-11 14:14       ` Eddie James
  0 siblings, 0 replies; 18+ messages in thread
From: Eddie James @ 2023-01-11 14:14 UTC (permalink / raw)
  To: Heinrich Schuchardt; +Cc: ilias.apalodimas, sjg, u-boot


On 1/10/23 16:37, Heinrich Schuchardt wrote:
> On 1/10/23 23:32, Heinrich Schuchardt wrote:
>> On 1/9/23 22:55, Eddie James wrote:
>>> Use the sandbox TPM driver to measure some boot images in a unit
>>> test case.
>>>
>>> $ ./u-boot -T -c "ut measurement"
>>> Running 1 measurement tests
>>> Test: measure: measurement.c
>>> Failures: 0
>>>
>>> Signed-off-by: Eddie James <eajames@linux.ibm.com>
>>> ---
>>>   arch/sandbox/dts/test.dts | 12 +++++++
>>>   configs/sandbox_defconfig |  1 +
>>>   include/test/suites.h     |  1 +
>>>   test/boot/Makefile        |  1 +
>>>   test/boot/measurement.c   | 66 
>>> +++++++++++++++++++++++++++++++++++++++
>>>   test/cmd_ut.c             |  2 ++
>>>   6 files changed, 83 insertions(+)
>>>   create mode 100644 test/boot/measurement.c
>>>
>>> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
>>> index dffe10adbf..ad90bf0541 100644
>>> --- a/arch/sandbox/dts/test.dts
>>> +++ b/arch/sandbox/dts/test.dts
>>> @@ -66,6 +66,17 @@
>>>           osd0 = "/osd";
>>>       };
>>>
>>> +    reserved-memory {
>>> +        #address-cells = <1>;
>>> +        #size-cells = <1>;
>>> +        ranges;
>>> +
>>> +        event_log: tcg_event_log@d0e000 {
>>> +            no-map;
>>
>> Isn't no-map misplaced? Shouldn't it be a reserved-memory property?
>
> The placement is correct. But I still wonder why we should have this
> area as no-map.
>
>>
>> If the memory region is not mapped, Linux can never access it as
>> described in
>> Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml.


I read the documentation as meaning that Linux won't map it as part of 
it's standard mappings. It's still available for a device driver (TPM 
driver in this case). I believe no-map is appropriate here since we 
don't want anything except the TPM driver to access that memory.


Thanks,

Eddie


>>
>> Please, document all changes to the device-tree semantics via patches
>> for the Linux kernels documentation and provide a full example.
>>
>> Best regards
>>
>> Heinrich
>

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

end of thread, other threads:[~2023-01-11 14:14 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-09 21:55 [PATCH v2 0/5] tpm: Support boot measurements Eddie James
2023-01-09 21:55 ` [PATCH v2 1/5] tpm: Fix spelling for tpmu_ha union Eddie James
2023-01-09 21:55 ` [PATCH v2 2/5] tpm: Support boot measurements Eddie James
2023-01-09 21:55 ` [PATCH v2 3/5] bootm: Support boot measurement Eddie James
2023-01-09 21:55 ` [PATCH v2 4/5] tpm: sandbox: Update for needed TPM2 capabilities Eddie James
2023-01-11  0:15   ` Simon Glass
2023-01-09 21:55 ` [PATCH v2 5/5] test: Add sandbox TPM boot measurement Eddie James
2023-01-09 23:13   ` Heinrich Schuchardt
2023-01-09 23:26     ` Heinrich Schuchardt
2023-01-10 16:38       ` Eddie James
2023-01-10 22:02         ` Heinrich Schuchardt
2023-01-10 22:11           ` Eddie James
2023-01-10 22:32   ` Heinrich Schuchardt
2023-01-10 22:37     ` Heinrich Schuchardt
2023-01-11 14:14       ` Eddie James
2023-01-09 23:35 ` [PATCH v2 0/5] tpm: Support boot measurements Heinrich Schuchardt
2023-01-10 21:42   ` Eddie James
2023-01-10 22:08     ` Heinrich Schuchardt

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.