]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
SecurityPkg/Tcg2Pei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098)
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Pei / Tcg2Pei.c
index 4852d8690617e9d80b8205316d90ad512417e15a..246968bb7f8d08b28462b3c1821b9f80d0f9efee 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 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>\r
 Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
@@ -17,10 +17,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Ppi/EndOfPeiPhase.h>\r
 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>\r
 #include <Ppi/FirmwareVolumeInfoPrehashedFV.h>\r
+#include <Ppi/Tcg.h>\r
 \r
 #include <Guid/TcgEventHob.h>\r
 #include <Guid/MeasuredFvHob.h>\r
 #include <Guid/TpmInstance.h>\r
+#include <Guid/MigratedFvInfo.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
@@ -66,6 +68,48 @@ EFI_PEI_PPI_DESCRIPTOR  mTpmInitializationDonePpiList = {
   NULL\r
 };\r
 \r
+/**\r
+  Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
+  and build a GUIDed HOB recording the event which will be passed to the DXE phase and\r
+  added into the Event Log.\r
+\r
+  @param[in]      This          Indicates the calling context\r
+  @param[in]      Flags         Bitmap providing additional information.\r
+  @param[in]      HashData      If BIT0 of Flags is 0, it is physical address of the\r
+                                start of the data buffer to be hashed, extended, and logged.\r
+                                If BIT0 of Flags is 1, it is physical address of the\r
+                                start of the pre-hash data buffter to be extended, and logged.\r
+                                The pre-hash data format is TPML_DIGEST_VALUES.\r
+  @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData.\r
+  @param[in]      NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.\r
+  @param[in]      NewEventData  Pointer to the new event data.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashLogExtendEvent (\r
+  IN      EDKII_TCG_PPI             *This,\r
+  IN      UINT64                    Flags,\r
+  IN      UINT8                     *HashData,\r
+  IN      UINTN                     HashDataLen,\r
+  IN      TCG_PCR_EVENT_HDR         *NewEventHdr,\r
+  IN      UINT8                     *NewEventData\r
+  );\r
+\r
+EDKII_TCG_PPI mEdkiiTcgPpi = {\r
+  HashLogExtendEvent\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR  mTcgPpiList = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gEdkiiTcgPpiGuid,\r
+  &mEdkiiTcgPpi\r
+};\r
+\r
 //\r
 // Number of firmware blobs to grow by each time we run out of room\r
 //\r
@@ -375,9 +419,13 @@ LogHashEvent (
   and build a GUIDed HOB recording the event which will be passed to the DXE phase and\r
   added into the Event Log.\r
 \r
+  @param[in]      This          Indicates the calling context\r
   @param[in]      Flags         Bitmap providing additional information.\r
-  @param[in]      HashData      Physical address of the start of the data buffer\r
-                                to be hashed, extended, and logged.\r
+  @param[in]      HashData      If BIT0 of Flags is 0, it is physical address of the\r
+                                start of the data buffer to be hashed, extended, and logged.\r
+                                If BIT0 of Flags is 1, it is physical address of the\r
+                                start of the pre-hash data buffter to be extended, and logged.\r
+                                The pre-hash data format is TPML_DIGEST_VALUES.\r
   @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData.\r
   @param[in]      NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.\r
   @param[in]      NewEventData  Pointer to the new event data.\r
@@ -388,7 +436,9 @@ LogHashEvent (
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 HashLogExtendEvent (\r
+  IN      EDKII_TCG_PPI             *This,\r
   IN      UINT64                    Flags,\r
   IN      UINT8                     *HashData,\r
   IN      UINTN                     HashDataLen,\r
@@ -403,16 +453,23 @@ HashLogExtendEvent (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  Status = HashAndExtend (\r
-             NewEventHdr->PCRIndex,\r
-             HashData,\r
-             HashDataLen,\r
+  if(Flags & EDKII_TCG_PRE_HASH) {\r
+    ZeroMem (&DigestList, sizeof(DigestList));\r
+    CopyMem (&DigestList, HashData, sizeof(DigestList));\r
+    Status = Tpm2PcrExtend (\r
+             0,\r
              &DigestList\r
              );\r
+  } else {\r
+    Status = HashAndExtend (\r
+               NewEventHdr->PCRIndex,\r
+               HashData,\r
+               HashDataLen,\r
+               &DigestList\r
+               );\r
+  }\r
   if (!EFI_ERROR (Status)) {\r
-    if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
-      Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
-    }\r
+    Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
   }\r
 \r
   if (Status == EFI_DEVICE_ERROR) {\r
@@ -452,6 +509,7 @@ MeasureCRTMVersion (
   TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));\r
 \r
   return HashLogExtendEvent (\r
+           &mEdkiiTcgPpi,\r
            0,\r
            (UINT8*)PcdGetPtr (PcdFirmwareVersionString),\r
            TcgEventHdr.EventSize,\r
@@ -536,6 +594,10 @@ MeasureFvImage (
   EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI       *PrehashedFvPpi;\r
   HASH_INFO                                             *PreHashInfo;\r
   UINT32                                                HashAlgoMask;\r
+  EFI_PHYSICAL_ADDRESS                                  FvOrgBase;\r
+  EFI_PHYSICAL_ADDRESS                                  FvDataBase;\r
+  EFI_PEI_HOB_POINTERS                                  Hob;\r
+  EDKII_MIGRATED_FV_INFO                                *MigratedFvInfo;\r
 \r
   //\r
   // Check Excluded FV list\r
@@ -621,6 +683,26 @@ MeasureFvImage (
     Instance++;\r
   } while (!EFI_ERROR(Status));\r
 \r
+  //\r
+  // Search the matched migration FV info\r
+  //\r
+  FvOrgBase  = FvBase;\r
+  FvDataBase = FvBase;\r
+  Hob.Raw  = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);\r
+  while (Hob.Raw != NULL) {\r
+    MigratedFvInfo = GET_GUID_HOB_DATA (Hob);\r
+    if ((MigratedFvInfo->FvNewBase == (UINT32) FvBase) && (MigratedFvInfo->FvLength == (UINT32) FvLength)) {\r
+      //\r
+      // Found the migrated FV info\r
+      //\r
+      FvOrgBase  = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvOrgBase;\r
+      FvDataBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvDataBase;\r
+      break;\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+    Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);\r
+  }\r
+\r
   //\r
   // Init the log event for FV measurement\r
   //\r
@@ -631,13 +713,14 @@ MeasureFvImage (
     if (FvName != NULL) {\r
       AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);\r
     }\r
-    FvBlob2.BlobBase      = FvBase;\r
+    FvBlob2.BlobBase      = FvOrgBase;\r
     FvBlob2.BlobLength    = FvLength;\r
+    TcgEventHdr.PCRIndex  = 0;\r
     TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;\r
     TcgEventHdr.EventSize = sizeof (FvBlob2);\r
     EventData             = &FvBlob2;\r
   } else {\r
-    FvBlob.BlobBase       = FvBase;\r
+    FvBlob.BlobBase       = FvOrgBase;\r
     FvBlob.BlobLength     = FvLength;\r
     TcgEventHdr.PCRIndex  = 0;\r
     TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
@@ -650,29 +733,24 @@ MeasureFvImage (
     // FV pre-hash algos comply with current TPM hash requirement\r
     // Skip hashing step in measure, only extend DigestList to PCR and log event\r
     //\r
-    Status = Tpm2PcrExtend(\r
-               0,\r
-               &DigestList\r
+    Status = HashLogExtendEvent (\r
+               &mEdkiiTcgPpi,\r
+               EDKII_TCG_PRE_HASH,\r
+               (UINT8*) &DigestList,        // HashData\r
+               (UINTN) sizeof(DigestList),  // HashDataLen\r
+               &TcgEventHdr,                // EventHdr\r
+               EventData                    // EventData\r
                );\r
-\r
-    if (!EFI_ERROR(Status)) {\r
-       Status = LogHashEvent (&DigestList, &TcgEventHdr, EventData);\r
-       DEBUG ((DEBUG_INFO, "The pre-hashed FV which is extended & logged by Tcg2Pei starts at: 0x%x\n", FvBase));\r
-       DEBUG ((DEBUG_INFO, "The pre-hashed FV which is extended & logged by Tcg2Pei has the size: 0x%x\n", FvLength));\r
-    } else if (Status == EFI_DEVICE_ERROR) {\r
-      BuildGuidHob (&gTpmErrorHobGuid,0);\r
-      REPORT_STATUS_CODE (\r
-        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-        (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
-        );\r
-    }\r
+    DEBUG ((DEBUG_INFO, "The pre-hashed FV which is extended & logged by Tcg2Pei starts at: 0x%x\n", FvBase));\r
+    DEBUG ((DEBUG_INFO, "The pre-hashed FV which is extended & logged by Tcg2Pei has the size: 0x%x\n", FvLength));\r
   } else {\r
     //\r
     // Hash the FV, extend digest to the TPM and log TCG event\r
     //\r
     Status = HashLogExtendEvent (\r
+               &mEdkiiTcgPpi,\r
                0,\r
-               (UINT8*) (UINTN) FvBase, // HashData\r
+               (UINT8*) (UINTN) FvDataBase, // HashData\r
                (UINTN) FvLength,        // HashDataLen\r
                &TcgEventHdr,            // EventHdr\r
                EventData                // EventData\r
@@ -848,6 +926,12 @@ PeimEntryMP (
 {\r
   EFI_STATUS                        Status;\r
 \r
+  //\r
+  // install Tcg Services\r
+  //\r
+  Status = PeiServicesInstallPpi (&mTcgPpiList);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) {\r
     Status = MeasureCRTMVersion ();\r
   }\r
@@ -892,7 +976,7 @@ MeasureSeparatorEventWithError (
   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
+  return HashLogExtendEvent(&mEdkiiTcgPpi, 0, (UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent,(UINT8 *)&EventData);\r
 }\r
 \r
 /**\r