[Skiboot] [PATCH 1/2] tpm_extendl: report number of tpms that failed and properly measured

Claudio Carvalho cclaudio at linux.vnet.ibm.com
Mon Oct 31 14:12:46 AEDT 2016


This changes tpm_extendl() to report to the caller the number of tpms
that successfully measured and failed to measure a given PCR. Thus, the
caller can properly print messages and whenever it is necessary.

Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
 libstb/status_codes.h |  3 +--
 libstb/stb.c          | 37 ++++++++++++++++++++++---------------
 libstb/tpm_chip.c     | 42 +++++++++++++++++++++++++++++++-----------
 libstb/tpm_chip.h     |  9 +++++++--
 4 files changed, 61 insertions(+), 30 deletions(-)

diff --git a/libstb/status_codes.h b/libstb/status_codes.h
index 64f9325..e67c17b 100644
--- a/libstb/status_codes.h
+++ b/libstb/status_codes.h
@@ -28,8 +28,7 @@
 
 /* trusted boot */
 #define STB_TRUSTED_MODE_DISABLED	 200
-#define STB_EVENTLOG_FAILED	-200
-#define STB_PCR_EXTEND_FAILED	-201
+#define STB_MEASURE_FAILED		-200
 
 /* TPM */
 #define STB_TPM_OVERFLOW	-300
diff --git a/libstb/stb.c b/libstb/stb.c
index be68a50..4991d93 100644
--- a/libstb/stb.c
+++ b/libstb/stb.c
@@ -163,7 +163,9 @@ void stb_init(void)
 int stb_final(void)
 {
 	uint32_t pcr;
-	int rc = 0;
+	int rc, measured, failed;
+
+	rc = 0;
 
 	if (trusted_mode) {
 #ifdef STB_DEBUG
@@ -184,11 +186,14 @@ int stb_final(void)
 					TPM_ALG_SHA256_SIZE, TPM_ALG_SHA1,
 					(uint8_t*) evFF.sha1,
 					TPM_ALG_SHA1_SIZE, EV_SEPARATOR,
-					"Skiboot Boot");
-			if (rc)
-				return rc;
-			prlog(PR_NOTICE, "STB: 0xFFFFFFFF measured "
-			      "to pcr%d\n", pcr);
+					"Skiboot Boot", &measured, &failed);
+			if (rc > 0)
+				prlog(PR_NOTICE, "STB: 0xFFFFFFFF (pcr%d) not "
+				      "measured. No tpm registered\n", pcr);
+			else
+				prlog(PR_NOTICE, "STB: 0xFFFFFFFF (pcr%d) "
+				      "measured on %d tpms and failed on "
+				      "%d tpms\n", pcr, measured, failed);
 		}
 		tpm_add_status_property();
 	}
@@ -204,11 +209,10 @@ int stb_final(void)
 
 int tb_measure(enum resource_id id, void *buf, size_t len)
 {
-	int rc, r;
+	int r, rc, measured, failed;
 	uint8_t digest[SHA512_DIGEST_LENGTH];
 	const uint8_t *digestp;
 
-	rc = 0;
 	digestp = NULL;
 	if (!trusted_mode) {
 		prlog(PR_NOTICE, "STB: %s skipped resource %d, "
@@ -275,7 +279,6 @@ int tb_measure(enum resource_id id, void *buf, size_t len)
 	}
 
 #ifdef STB_DEBUG
-	/* print the payload/image hash */
 	prlog(PR_NOTICE, "STB: %s hash:\n", resource_map[r].name);
 	stb_print_data(digest, TPM_ALG_SHA256_SIZE);
 #endif
@@ -287,12 +290,16 @@ int tb_measure(enum resource_id id, void *buf, size_t len)
 	rc = tpm_extendl(resource_map[r].pcr,
 			 TPM_ALG_SHA256, digest, TPM_ALG_SHA256_SIZE,
 			 TPM_ALG_SHA1,   digest, TPM_ALG_SHA1_SIZE,
-			 EV_ACTION, resource_map[r].name);
-	if (rc)
-		return rc;
-	prlog(PR_NOTICE, "STB: %s measured to pcr%d\n", resource_map[r].name,
-	      resource_map[r].pcr);
-	return 0;
+			 EV_ACTION, resource_map[r].name, &measured, &failed);
+
+	if (rc > 0)
+		prlog(PR_NOTICE, "STB: %s not measured. No tpm registered\n",
+		      resource_map[r].name);
+	else
+		prlog(PR_NOTICE, "STB: %s (pcr%d) measured on %d tpms and "
+		      "failed on %d tpms\n", resource_map[r].name,
+		      resource_map[r].pcr, measured, failed);
+	return rc;
 }
 
 int sb_verify(enum resource_id id, void *buf, size_t len)
diff --git a/libstb/tpm_chip.c b/libstb/tpm_chip.c
index 1bfeb9a..0c81548 100644
--- a/libstb/tpm_chip.c
+++ b/libstb/tpm_chip.c
@@ -187,12 +187,12 @@ void tpm_init(void)
 
 	if (list_empty(&tpm_list))
 		/**
-		 * @fwts-label TPMNotInitialized
+		 * @fwts-label NoTPMRegistered
 		 * @fwts-advice No TPM chip has been initialized. We may not
 		 * have a compatible tpm driver or there is no tpm node in the
 		 * device tree with the expected bindings.
 		 */
-		prlog(PR_ERR, "TPM: no tpm chip has been initialized\n");
+		prlog(PR_ERR, "TPM: no tpm chip registered\n");
 
 }
 
@@ -214,15 +214,26 @@ void tpm_cleanup(void)
 	list_head_init(&tpm_list);
 }
 
+static void tpm_disable(struct tpm_chip *tpm)
+{
+	if (tpm) {
+		tpm->enabled = false;
+		prlog(PR_NOTICE, "STB: tpm%d disabled\n", tpm->id);
+	}
+}
+
 int tpm_extendl(TPM_Pcr pcr,
 		TPM_Alg_Id alg1, uint8_t* digest1, size_t size1,
 		TPM_Alg_Id alg2, uint8_t* digest2, size_t size2,
-		uint32_t event_type, const char* event_msg)
+		uint32_t event_type, const char* event_msg,
+		int *tpm_measured, int *tpm_failed)
 {
-	int rc;
+	int rc, measured, failed;
 	TCG_PCR_EVENT2 event;
 	struct tpm_chip *tpm = NULL;
 
+	measured = 0;
+	failed = 0;
 	rc = 0;
 
 	list_for_each(&tpm_list, tpm, link) {
@@ -247,8 +258,9 @@ int tpm_extendl(TPM_Pcr pcr,
 			 */
 			prlog(PR_ERR, "TPM: %s -> elog%d FAILED: pcr%d et=%x rc=%d\n",
 			      event_msg, tpm->id, pcr, event_type, rc);
-			rc = STB_EVENTLOG_FAILED;
-			goto error;
+			tpm_disable(tpm);
+			failed++;
+			continue;
 		}
 #ifdef STB_DEBUG
 		prlog(PR_NOTICE, "TPM: %s -> elog%d: pcr%d et=%x ls=%d\n",
@@ -275,9 +287,12 @@ int tpm_extendl(TPM_Pcr pcr,
 			 */
 			prlog(PR_ERR, "TPM: %s -> tpm%d FAILED: pcr%d rc=%d\n",
 			      event_msg, tpm->id, pcr, rc);
-			rc = STB_PCR_EXTEND_FAILED;
-			goto error;
+			tpm_disable(tpm);
+			failed++;
+			continue;
 		}
+		measured++;
+
 #ifdef STB_DEBUG
 		prlog(PR_NOTICE, "TPM: %s -> tpm%d: pcr%d\n", event_msg,
 		      tpm->id, pcr);
@@ -285,9 +300,14 @@ int tpm_extendl(TPM_Pcr pcr,
 		tpm_print_pcr(tpm, pcr, alg2, size2);
 #endif
 	}
-	return rc;
-error:
-	tpm->enabled = false;
+
+	if (failed > 0)
+		rc = STB_MEASURE_FAILED;
+
+	if (tpm_measured)
+		*tpm_measured = measured;
+	if (tpm_failed)
+		*tpm_failed = failed;
 	return rc;
 }
 
diff --git a/libstb/tpm_chip.h b/libstb/tpm_chip.h
index d7363e7..bca8409 100644
--- a/libstb/tpm_chip.h
+++ b/libstb/tpm_chip.h
@@ -91,13 +91,18 @@ extern int tpm_register_chip(struct dt_node *node, struct tpm_dev *dev,
  * @size2: size of digest2. Either TPM_ALG_SHA1_SIZE or TPM_ALG_SHA256_SIZE
  * @event_type: event type log. In skiboot, either EV_ACTION or EV_SEPARATOR.
  * @event_msg: event log message that describes the event
+ * @measured: [optional] will have the number of tpms successfully measured
+ * @failed: [optional] will have the number of tpms failed to measure
  *
- * Returns O for success or a negative number if it fails.
+ * Returns: O for success,
+ *          STB_MEASURE_FAILED if no tpm initialized,
+ *          or a negative number if it fails.
  */
 extern int tpm_extendl(TPM_Pcr pcr,
 		       TPM_Alg_Id alg1, uint8_t* digest1, size_t size1,
 		       TPM_Alg_Id alg2, uint8_t* digest2, size_t size2,
-		       uint32_t event_type, const char* event_msg);
+		       uint32_t event_type, const char* event_msg,
+		       int *measured, int *failed);
 
 /* Add status property to the TPM devices */
 extern void tpm_add_status_property(void);
-- 
1.9.1



More information about the Skiboot mailing list