[v2,04/14] libstb/stb.c: change tb_measure() to use flash_lookup_resource_name()

Message ID 1504164285-15095-5-git-send-email-cclaudio@linux.vnet.ibm.com
State Under Review
Headers show
Series
  • libstb: simplify the initialization of cvc drivers
Related show

Commit Message

Claudio Carvalho Aug. 31, 2017, 7:24 a.m.
Trustedboot measures only images stored in known PNOR partitions. With
the flash_lookup_resource_name(), the PNOR partition information don't
need to be duplicated in libstb for trustedboot.

Additionally, an image can be measured to a PCR only if a PCR number has
been mapped to the respective partition.

This adds the pcr_map() function and replaces stb_resource_lookup() by
both flash_lookup_resource_name() and pcr_map().

Signed-off-by: Claudio Carvalho <cclaudio@linux.vnet.ibm.com>
---
 libstb/stb.c | 76 +++++++++++++++++++++++++++++-------------------------------
 1 file changed, 37 insertions(+), 39 deletions(-)

Patch

diff --git a/libstb/stb.c b/libstb/stb.c
index 949f81c..ed34c6a 100644
--- a/libstb/stb.c
+++ b/libstb/stb.c
@@ -34,8 +34,6 @@  static bool trusted_mode = false;
 
 static struct rom_driver_ops *rom_driver = NULL;
 
-#define MAX_RESOURCE_NAME	15
-
 /*
  * This maps a PCR for each resource we can measure. The PCR number is
  * mapped according to the TCG PC Client Platform Firmware Profile
@@ -43,21 +41,23 @@  static struct rom_driver_ops *rom_driver = NULL;
  * Only resources included in this whitelist can be measured.
  */
 static struct {
-
-	/* PNOR partition id */
 	enum resource_id id;
-
-	/* PCR mapping for the resource id */
 	TPM_Pcr pcr;
-
-	/* Resource name */
-	const char name[MAX_RESOURCE_NAME+1];
-
-} resource_map[] = {
-	{ RESOURCE_ID_KERNEL, PCR_4, "BOOTKERNEL" },
-	{ RESOURCE_ID_CAPP,   PCR_2, "CAPP"},
+} resources[] = {
+	{ RESOURCE_ID_KERNEL, PCR_4 },
+	{ RESOURCE_ID_CAPP,   PCR_2 },
 };
 
+static TPM_Pcr map_pcr(enum resource_id id)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(resources); i++) {
+		if (resources[i].id == id)
+			return resources[i].pcr;
+	}
+	return -1;
+}
+
 struct event_hash {
 	const unsigned char *sha1;
 	const unsigned char *sha256;
@@ -76,15 +76,6 @@  static struct event_hash evFF = {
 		  "\xfd\x0e"
 };
 
-static int stb_resource_lookup(enum resource_id id)
-{
-	int i;
-	for (i = 0; i < ARRAY_SIZE(resource_map); i++)
-		if (resource_map[i].id == id)
-			return i;
-	return -1;
-}
-
 static void sb_enforce(void)
 {
 	/*
@@ -188,9 +179,10 @@  int stb_final(void)
 
 int tb_measure(enum resource_id id, void *buf, size_t len)
 {
-	int r;
 	uint8_t digest[SHA512_DIGEST_LENGTH];
 	const uint8_t *digestp;
+	const char *name;
+	TPM_Pcr pcr;
 
 	digestp = NULL;
 	if (!trusted_mode) {
@@ -198,17 +190,25 @@  int tb_measure(enum resource_id id, void *buf, size_t len)
 		      "trusted_mode=0\n", __func__, id);
 		return STB_TRUSTED_MODE_DISABLED;
 	}
-	r = stb_resource_lookup(id);
-	if (r == -1) {
+	name = flash_map_resource_name(id);
+	if (!name) {
 		/**
-		 * @fwts-label STBMeasureResourceNotMapped
-		 * @fwts-advice The resource is not registered in the resource_map[]
-		 * array, but it should be otherwise the resource cannot be
-		 * measured if trusted mode is on.
+		 * @fwts-label ResourceNotMeasuredUnknown
+		 * @fwts-advice This is a bug in the tb_measure() caller, which
+		 * is passing an unknown resource_id.
 		 */
-		prlog(PR_ERR, "STB: %s failed, resource %d not mapped\n",
-		      __func__, id);
-		return STB_ARG_ERROR;
+		prerror("STB: resource NOT MEASURED, resource_id=%d unknown\n", id);
+		return -1;
+	}
+	pcr = map_pcr(id);
+	if (pcr == -1) {
+		/**
+		 * @fwts-label ResourceNotMappedToPCR
+		 * @fwts-advice This is a bug. The resource cannot be measured
+		 * because it is not mapped to a PCR in the resources[] array.
+		 */
+		prerror("STB: %s NOT MEASURED, it's not mapped to a PCR\n", name);
+		return -1;
 	}
 	if (!buf) {
 		/**
@@ -218,7 +218,7 @@  int tb_measure(enum resource_id id, void *buf, size_t len)
 		 * bug in the framework.
 		 */
 		prlog(PR_ERR, "STB: %s failed: resource %s, buf null\n",
-		      __func__, resource_map[r].name);
+		      __func__, name);
 		return STB_ARG_ERROR;
 	}
 	memset(digest, 0, SHA512_DIGEST_LENGTH);
@@ -239,8 +239,7 @@  int tb_measure(enum resource_id id, void *buf, size_t len)
 			      (void*)((uint8_t*)buf + SECURE_BOOT_HEADERS_SIZE),
 			      len - SECURE_BOOT_HEADERS_SIZE, digest);
 
-		prlog(PR_INFO, "STB: %s sha512 hash re-calculated\n",
-		      resource_map[r].name);
+		prlog(PR_INFO, "STB: %s sha512 hash re-calculated\n", name);
 		if (memcmp(digestp, digest, TPM_ALG_SHA256_SIZE) != 0) {
 			prlog(PR_ALERT, "STB: HASH IN CONTAINER DOESN'T MATCH CONTENT!\n");
 			prlog(PR_ALERT, "STB: Container hash:\n");
@@ -253,8 +252,7 @@  int tb_measure(enum resource_id id, void *buf, size_t len)
 		}
 	} else {
 		rom_driver->sha512(buf, len, digest);
-		prlog(PR_INFO, "STB: %s sha512 hash calculated\n",
-		      resource_map[r].name);
+		prlog(PR_INFO, "STB: %s sha512 hash calculated\n", name);
 	}
 
 #ifdef STB_DEBUG
@@ -267,10 +265,10 @@  int tb_measure(enum resource_id id, void *buf, size_t len)
 	 * algorithm, the sha512 hash is truncated to match the size required
 	 * by each PCR bank.
 	 */
-	return tpm_extendl(resource_map[r].pcr,
+	return tpm_extendl(pcr,
 			   TPM_ALG_SHA256, digest, TPM_ALG_SHA256_SIZE,
 			   TPM_ALG_SHA1,   digest, TPM_ALG_SHA1_SIZE,
-			   EV_ACTION, resource_map[r].name);
+			   EV_ACTION, name);
 }
 
 int sb_verify(enum resource_id id, void *buf, size_t len)