]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
SecurityPkg/TPM2: Move CopyDigestListToBuffer() to Tpm2CommandLib
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Pei / Tcg2Pei.c
index ec94c24e4c40c0fd88e498da3d33c7a8b4b872dc..a72b8d9bda1f56077abcb53b826185e228d714f8 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Initialize TPM2 device and measure FVs before handing off control to DXE.\r
 \r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials \r
 are licensed and made available under the terms and conditions of the BSD License \r
 which accompanies this distribution.  The full text of the license may be found at \r
@@ -134,41 +134,6 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
 \r
 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;\r
 \r
-/**\r
-  This function get digest from digest list.\r
-\r
-  @param HashAlg    digest algorithm\r
-  @param DigestList digest list\r
-  @param Digest     digest\r
-\r
-  @retval EFI_SUCCESS   Sha1Digest is found and returned.\r
-  @retval EFI_NOT_FOUND Sha1Digest is not found.\r
-**/\r
-EFI_STATUS\r
-Tpm2GetDigestFromDigestList (\r
-  IN TPMI_ALG_HASH      HashAlg,\r
-  IN TPML_DIGEST_VALUES *DigestList,\r
-  IN VOID               *Digest\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-\r
-  DigestSize = GetHashSizeFromAlgo (HashAlg);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    if (DigestList->digests[Index].hashAlg == HashAlg) {\r
-      CopyMem (\r
-        Digest,\r
-        &DigestList->digests[Index].digest,\r
-        DigestSize\r
-        );\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
 /**\r
   Record all measured Firmware Volum Information into a Guid Hob\r
   Guid Hob payload layout is \r
@@ -225,140 +190,7 @@ EndofPeiSignalNotifyCallBack (
 }\r
 \r
 /**\r
-  Check if buffer is all zero.\r
-\r
-  @param[in] Buffer      Buffer to be checked.\r
-  @param[in] BufferSize  Size of buffer to be checked.\r
-\r
-  @retval TRUE  Buffer is all zero.\r
-  @retval FALSE Buffer is not all zero.\r
-**/\r
-BOOLEAN\r
-IsZeroBuffer (\r
-  IN VOID  *Buffer,\r
-  IN UINTN BufferSize\r
-  )\r
-{\r
-  UINT8 *BufferData;\r
-  UINTN Index;\r
-\r
-  BufferData = Buffer;\r
-  for (Index = 0; Index < BufferSize; Index++) {\r
-    if (BufferData[Index] != 0) {\r
-      return FALSE;\r
-    }\r
-  }\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Get TPML_DIGEST_VALUES data size.\r
-\r
-  @param[in]     DigestList    TPML_DIGEST_VALUES data.\r
-\r
-  @return TPML_DIGEST_VALUES data size.\r
-**/\r
-UINT32\r
-GetDigestListSize (\r
-  IN TPML_DIGEST_VALUES             *DigestList\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-  UINT32 TotalSize;\r
-\r
-  TotalSize = sizeof(DigestList->count);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
-    TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize;\r
-  }\r
-\r
-  return TotalSize;\r
-}\r
-\r
-/**\r
-  Return if hash alg is supported in TPM PCR bank.\r
-\r
-  @param HashAlg  Hash algorithm to be checked.\r
-\r
-  @retval TRUE  Hash algorithm is supported.\r
-  @retval FALSE Hash algorithm is not supported.\r
-**/\r
-BOOLEAN\r
-IsHashAlgSupportedInPcrBank (\r
-  IN TPMI_ALG_HASH  HashAlg\r
-  )\r
-{\r
-  UINT32  ActivePcrBanks;\r
-\r
-  ActivePcrBanks = PcdGet32 (PcdTpm2HashMask);\r
-  switch (HashAlg) {\r
-  case TPM_ALG_SHA1:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA256:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA384:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA512:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SM3_256:\r
-    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Copy TPML_DIGEST_VALUES into a buffer\r
-\r
-  @param[in,out] Buffer        Buffer to hold TPML_DIGEST_VALUES.\r
-  @param[in]     DigestList    TPML_DIGEST_VALUES to be copied.\r
-\r
-  @return The end of buffer to hold TPML_DIGEST_VALUES.\r
-**/\r
-VOID *\r
-CopyDigestListToBuffer (\r
-  IN OUT VOID                       *Buffer,\r
-  IN TPML_DIGEST_VALUES             *DigestList\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-\r
-  CopyMem (Buffer, &DigestList->count, sizeof(DigestList->count));\r
-  Buffer = (UINT8 *)Buffer + sizeof(DigestList->count);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    if (!IsHashAlgSupportedInPcrBank (DigestList->digests[Index].hashAlg)) {\r
-      DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));\r
-      continue;\r
-    }\r
-    CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg));\r
-    Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg);\r
-    DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
-    CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);\r
-    Buffer = (UINT8 *)Buffer + DigestSize;\r
-  }\r
-\r
-  return Buffer;\r
-}\r
-\r
-/**\r
-  Set Tpm2HashMask PCD value accroding to TPM2 PCR bank.\r
+  Set Tpm2HashMask PCD value according to TPM2 PCR bank.\r
 **/\r
 VOID\r
 SetTpm2HashMask (\r
@@ -410,7 +242,8 @@ SetTpm2HashMask (
       }\r
     }\r
   }\r
-  PcdSet32 (PcdTpm2HashMask, ActivePcrBanks);\r
+  Status = PcdSet32S (PcdTpm2HashMask, ActivePcrBanks);\r
+  ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
 /**\r
@@ -446,7 +279,7 @@ LogHashEvent (
       DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));\r
       switch (mTcg2EventInfo[Index].LogFormat) {\r
       case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
-        Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
+        Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
         if (!EFI_ERROR (Status)) {\r
           HobData = BuildGuidHob (\r
                      &gTcgEventEntryHobGuid,\r
@@ -476,7 +309,7 @@ LogHashEvent (
         TcgPcrEvent2->PCRIndex = NewEventHdr->PCRIndex;\r
         TcgPcrEvent2->EventType = NewEventHdr->EventType;\r
         DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest;\r
-        DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList);\r
+        DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList, PcdGet32 (PcdTpm2HashMask));\r
         CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(TcgPcrEvent2->EventSize));\r
         DigestBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);\r
         CopyMem (DigestBuffer, NewEventData, NewEventHdr->EventSize);\r
@@ -648,8 +481,8 @@ MeasureFvImage (
   //\r
   // Add new FV into the measured FV list.\r
   //\r
-  ASSERT (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
-  if (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
+  ASSERT (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));\r
+  if (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
     mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase   = FvBase;\r
     mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;\r
     mMeasuredBaseFvIndex++;\r
@@ -760,8 +593,8 @@ FirmwareVolmeInfoPpiNotifyCallback (
   //\r
   if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {\r
     \r
-    ASSERT (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
-    if (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
+    ASSERT (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));\r
+    if (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
       //\r
       // Check whether FV is in the measured child FV list.\r
       //\r
@@ -827,6 +660,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
@@ -846,6 +706,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
@@ -884,11 +746,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
@@ -902,6 +768,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