All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ruchika Gupta <ruchika.gupta@linaro.org>
To: u-boot@lists.denx.de, ilias.apalodimas@linaro.org,
	xypron.glpk@gmx.de, agraf@csgraf.de
Cc: Ruchika Gupta <ruchika.gupta@linaro.org>
Subject: [PATCH 3/3] efi_loader: Extend PCR's for firmware measurements
Date: Thu, 18 Nov 2021 11:47:51 +0530	[thread overview]
Message-ID: <20211118061751.3334620-4-ruchika.gupta@linaro.org> (raw)
In-Reply-To: <20211118061751.3334620-1-ruchika.gupta@linaro.org>

Firmwares before U-Boot may be capable of doing tpm measurements
and passing them to U-Boot in the form of eventlog. However there
may be scenarios where the firmwares don't have TPM driver and
are not capable of extending the measurements in the PCRs. To
cater to such platforms, read the PCR0 to determine if the
previous firmwares have extended the PCR0. If not, then extend
the PCR's as the eventlog is parsed.

Signed-off-by: Ruchika Gupta <ruchika.gupta@linaro.org>
---
 lib/efi_loader/efi_tcg2.c | 86 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index c97766eae3..cbd0c7d224 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -178,6 +178,43 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
 	return EFI_SUCCESS;
 }
 
+/* tcg2_pcr_read - Read 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_read(struct udevice *dev, u32 pcr_index,
+				    struct tpml_digest_values *digest_list)
+{
+	struct tpm_chip_priv *priv;
+	unsigned int updates, pcr_select_min;
+	u32 rc;
+	size_t i;
+
+	priv = dev_get_uclass_priv(dev);
+	if (!priv)
+		return EFI_DEVICE_ERROR;
+
+	pcr_select_min = priv->pcr_select_min;
+
+	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;
+
+		rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min,
+				    hash_alg, digest, alg_to_len(hash_alg),
+				    &updates);
+		if (rc) {
+			EFI_PRINT("Failed to read PCR\n");
+			return EFI_DEVICE_ERROR;
+		}
+	}
+
+	return EFI_SUCCESS;
+}
+
 /* tcg2_agile_log_append - Append an agile event to out eventlog
  *
  * @pcr_index:		PCR index
@@ -1488,10 +1525,12 @@ static efi_status_t efi_init_event_log(struct udevice *dev)
 	struct tcg_pcr_event *event_header = NULL;
 	struct tpml_digest_values digest_list;
 	size_t spec_event_size;
+	bool extend_pcr = false;
 	efi_status_t ret;
 	u32 pcr, pos;
 	u64 base;
 	u32 sz;
+	int i;
 
 	ret = platform_get_tpm2_device(&dev);
 	if (ret != EFI_SUCCESS)
@@ -1541,6 +1580,26 @@ static efi_status_t efi_init_event_log(struct udevice *dev)
 			goto free_pool;
 		}
 
+		ret = tcg2_pcr_read(dev, 0, &digest_list);
+		if (ret) {
+			log_err("Error reading PCR 0\n");
+			goto free_pool;
+		}
+
+		/*
+		 * If PCR0 is 0, previous firmware didn't have the capability
+		 * to extend the PCR. In this scenario, extend the PCR as
+		 * the eventlog is parsed.
+		 */
+		for (i = 0; i < digest_list.count; i++) {
+			u8 buffer[TPM2_DIGEST_LEN] =  { 0 };
+			u16 hash_alg = digest_list.digests[i].hash_alg;
+
+			if (!memcmp((u8 *)&digest_list.digests[i].digest,
+				    buffer, alg_to_len(hash_alg)))
+				extend_pcr = true;
+		}
+
 		while (pos < sz) {
 			ret = tcg2_parse_event(dev, buffer, sz, &pos,
 					       &digest_list, &pcr);
@@ -1548,6 +1607,33 @@ static efi_status_t efi_init_event_log(struct udevice *dev)
 				log_err("Error parsing event\n");
 				goto free_pool;
 			}
+
+			if (pcr != 0) {
+				/*
+				 * Eventlog passed by firmware should extend
+				 * PCR0 only.
+				 */
+				log_err("Invalid PCR\n");
+				goto free_pool;
+			}
+
+			if (extend_pcr) {
+				ret = tcg2_pcr_extend(dev, pcr, &digest_list);
+				if (ret != EFI_SUCCESS) {
+					log_err("Error in extending PCR\n");
+					goto free_pool;
+				}
+
+				/* Clear the digest for next event */
+				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;
+
+					memset(digest, 0, alg_to_len(hash_alg));
+				}
+			}
 		}
 
 		memcpy(event_log.buffer, buffer, sz);
-- 
2.25.1


  parent reply	other threads:[~2021-11-18  6:18 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-18  6:17 [PATCH 1/3] efi_loader: Add check for event log passed from firmware Ruchika Gupta
2021-11-18  6:17 ` [PATCH] efi_loader: fix FinalEvents table if an EFI uses GetEventLog Ruchika Gupta
2021-11-18  6:23   ` Ruchika Gupta
2021-11-18  6:17 ` [PATCH 2/3] tpm: use more algorithms than sha256 on pcr_read Ruchika Gupta
2021-11-22 10:48   ` Ilias Apalodimas
2021-11-18  6:17 ` Ruchika Gupta [this message]
2021-11-22 11:41   ` [PATCH 3/3] efi_loader: Extend PCR's for firmware measurements Ilias Apalodimas
2021-11-20  8:55 ` Fwd: [PATCH 1/3] efi_loader: Add check for event log passed from firmware Heinrich Schuchardt
2021-11-22 11:32 ` Ilias Apalodimas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211118061751.3334620-4-ruchika.gupta@linaro.org \
    --to=ruchika.gupta@linaro.org \
    --cc=agraf@csgraf.de \
    --cc=ilias.apalodimas@linaro.org \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.