Add error handling for TPM in S3 resume failure.
authorYao, Jiewen <jiewen.yao@intel.com>
Tue, 10 Nov 2015 02:03:40 +0000 (02:03 +0000)
committerjyao1 <jyao1@Edk2>
Tue, 10 Nov 2015 02:03:40 +0000 (02:03 +0000)
If TPM2_Startup(TPM_SU_STATE) to return an error, the system
 firmware that resumes from S3 MUST deal with a TPM2_Startup
 error appropriately.
For example, issuing a TPM2_Startup(TPM_SU_CLEAR) command and
 configuring the device securely by taking actions like extending
 a separator with an error digest (0x01) into PCRs 0 through 7.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <jiewen.yao@intel.com>
Reviewed-by: "Zhang, Chao B" <chao.b.zhang@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18760 6f19259b-4bc3-4df7-8a09-765794883524

SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c

index 4ecfbe3b844b1f63006e2307c59f445bc76fc05e..63045f1c5903808ca40a2796195f832b0abb2628 100644 (file)
@@ -828,6 +828,33 @@ PeimEntryMP (
   return Status;\r
 }\r
 \r
+/**\r
+  Measure and log Separator event with error, and extend the measurement result into a specific PCR.\r
+\r
+  @param[in] PCRIndex         PCR index.  \r
+\r
+  @retval EFI_SUCCESS         Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureSeparatorEventWithError (\r
+  IN      TPM_PCRINDEX              PCRIndex\r
+  )\r
+{\r
+  TCG_PCR_EVENT_HDR                 TcgEvent;\r
+  UINT32                            EventData;\r
+\r
+  //\r
+  // Use EventData 0x1 to indicate there is error.\r
+  //\r
+  EventData = 0x1;\r
+  TcgEvent.PCRIndex  = PCRIndex;\r
+  TcgEvent.EventType = EV_SEPARATOR;\r
+  TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
+  return HashLogExtendEvent(0,(UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent,(UINT8 *)&EventData);\r
+}\r
+\r
 /**\r
   Entry point of this module.\r
 \r
@@ -847,6 +874,8 @@ PeimEntryMA (
   EFI_STATUS                        Status;\r
   EFI_STATUS                        Status2;\r
   EFI_BOOT_MODE                     BootMode;\r
+  TPM_PCRINDEX                      PcrIndex;\r
+  BOOLEAN                           S3ErrorReport;\r
 \r
   if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
       CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
@@ -885,11 +914,15 @@ PeimEntryMA (
       goto Done;\r
     }\r
 \r
+    S3ErrorReport = FALSE;\r
     if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {\r
       if (BootMode == BOOT_ON_S3_RESUME) {\r
         Status = Tpm2Startup (TPM_SU_STATE);\r
         if (EFI_ERROR (Status) ) {\r
           Status = Tpm2Startup (TPM_SU_CLEAR);\r
+          if (!EFI_ERROR(Status)) {\r
+            S3ErrorReport = TRUE;\r
+          }\r
         }\r
       } else {\r
         Status = Tpm2Startup (TPM_SU_CLEAR);\r
@@ -903,6 +936,23 @@ PeimEntryMA (
     // Update Tpm2HashMask according to PCR bank.\r
     //\r
     SetTpm2HashMask ();\r
+\r
+    if (S3ErrorReport) {\r
+      //\r
+      // The system firmware that resumes from S3 MUST deal with a\r
+      // TPM2_Startup error appropriately.\r
+      // For example, issue a TPM2_Startup(TPM_SU_CLEAR) command and\r
+      // configuring the device securely by taking actions like extending a\r
+      // separator with an error digest (0x01) into PCRs 0 through 7.\r
+      //\r
+      for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {\r
+        Status = MeasureSeparatorEventWithError (PcrIndex);\r
+        if (EFI_ERROR (Status)) {\r
+          DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n"));\r
+        }\r
+      }\r
+    }\r
+\r
     //\r
     // TpmSelfTest is optional on S3 path, skip it to save S3 time\r
     //\r