[Skiboot] [PATCH v2 1/3] tpm_extendl: disable all failed tpms rather than only the first

Claudio Carvalho cclaudio at linux.vnet.ibm.com
Wed Nov 2 09:40:25 AEDT 2016


Each tpm_chip structure is associated with one tpm device and one firmware
event log. If tpm_extendl() returns when the first tpm_chip operation (pcr
extend or event log record) fails, the remaining registered tpm_chips will be
in an inconsistent state, i.e, missing one measurement.

This walks through all registered tpm_chips and disable all tpm_chips that
failed rather than only first one.

Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
 libstb/status_codes.h |  3 +--
 libstb/tpm_chip.c     | 45 +++++++++++++++++++++++++++++----------------
 2 files changed, 30 insertions(+), 18 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/tpm_chip.c b/libstb/tpm_chip.c
index 1bfeb9a..d4075bd 100644
--- a/libstb/tpm_chip.c
+++ b/libstb/tpm_chip.c
@@ -214,16 +214,24 @@ 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)
 {
-	int rc;
+	int rc, failed;
 	TCG_PCR_EVENT2 event;
 	struct tpm_chip *tpm = NULL;
 
-	rc = 0;
+	failed = 0;
 
 	list_for_each(&tpm_list, tpm, link) {
 		if (!tpm->enabled)
@@ -247,12 +255,15 @@ 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",
-		      event_msg, tpm->id, pcr, event_type, tpm->logmgr.logSize);
+		if (rc == 0)
+			prlog(PR_NOTICE, "TPM: %s -> elog%d: pcr%d et=%x "
+			      "ls=%d\n", event_msg, tpm->id, pcr,
+			      event_type, tpm->logmgr.logSize);
 		tpm_print_pcr(tpm, pcr, alg1, size1);
 		tpm_print_pcr(tpm, pcr, alg2, size2);
 #endif
@@ -275,20 +286,22 @@ 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;
 		}
 #ifdef STB_DEBUG
-		prlog(PR_NOTICE, "TPM: %s -> tpm%d: pcr%d\n", event_msg,
-		      tpm->id, pcr);
-		tpm_print_pcr(tpm, pcr, alg1, size1);
-		tpm_print_pcr(tpm, pcr, alg2, size2);
+		if (rc == 0) {
+			prlog(PR_NOTICE, "TPM: %s -> tpm%d: pcr%d\n",
+			      event_msg, tpm->id, pcr);
+			tpm_print_pcr(tpm, pcr, alg1, size1);
+			tpm_print_pcr(tpm, pcr, alg2, size2);
+		}
 #endif
 	}
-	return rc;
-error:
-	tpm->enabled = false;
-	return rc;
+	if (failed > 0)
+		return STB_MEASURE_FAILED;
+	return 0;
 }
 
 void tpm_add_status_property(void) {
-- 
1.9.1



More information about the Skiboot mailing list