Implement Tcg2MeasurePpi. The interface will be available before & after Memory Ready

Signed-off-by: Zhang, Chao B <chao.b.zhang@intel.com>
diff --git a/MdePkg/Include/Ppi/Tcg2Measure.h b/MdePkg/Include/Ppi/Tcg2Measure.h
new file mode 100644
index 0000000..1ca3325
--- /dev/null
+++ b/MdePkg/Include/Ppi/Tcg2Measure.h
@@ -0,0 +1,63 @@
+/** @file
+  This file provides function for TCG2 measure in PEI phase.
+
+  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef __TCG2_MEASURE_PPI_H__
+#define __TCG2_MEASURE_PPI_H__
+
+///
+/// The GUID is used to identify TCG2 Measure PPI.
+/// 
+typedef struct _EFI_PEI_TCG2_MEASURE_PPI   EFI_PEI_TCG2_MEASURE_PPI;
+
+
+/**
+  The EFI_TCG2_MEASURE_PPI. HashLogExtendEvent function call provides callers with
+  an opportunity to extend and optionally log events without requiring
+  knowledge of actual TPM commands. 
+  The extend operation will occur even if this function cannot create an event
+  log entry. The interface is designed to be called before Memory Ready
+
+  @param[in]  This                Points to this instance of the
+                                EFI_PEI_FIRMWARE_VOLUME_PPI.
+  @param[in]  Flags              Bitmap providing additional information. Defined in Tcg2Protocol.h
+  @param[in]  DataToHash         Physical address of the start of the data buffer to be hashed. 
+  @param[in]  DataToHashLen      The length in bytes of the buffer referenced by DataToHash.
+  @param[in]  Event              Pointer to data buffer containing information about the event.
+
+  @retval EFI_SUCCESS            Operation completed successfully.
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
+  @retval EFI_VOLUME_FULL        The extend operation occurred, but the event could not be written to one or more event logs.
+  @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.
+  
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_TCG2_HASH_LOG_EXTEND_EVENT)(
+  IN  UINT64                           Flags,
+  IN  UINT8                            *HashData,
+  IN  UINTN                            HashDataLen,
+  IN  EFI_TCG2_EVENT                   *Event
+);
+
+
+///
+/// This file provides function for TCG2 measure in PEI phase.
+///
+struct _EFI_PEI_TCG2_MEASURE_PPI {
+  EFI_PEI_TCG2_HASH_LOG_EXTEND_EVENT       HashLogExtendEvent;
+};
+
+extern EFI_GUID gEdkiiTcg2MeasurePpiGuid;
+
+#endif 
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index 8d64b4f..08f8974 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -206,6 +206,9 @@
   ## Include/Ppi/FirmwareVolumeInfoPrehashedFV.h

   gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid = { 0x3ce1e631, 0x7008, 0x477c, { 0xad, 0xa7, 0x5d, 0xcf, 0xc7, 0xc1, 0x49, 0x4b } }

 

+  ## Include/Ppi/Tcg2Measure.h

+  gEdkiiTcg2MeasurePpiGuid = { 0x31e0789c, 0x210a, 0x4037, { 0x8f, 0x3f, 0xed, 0x3d, 0x10, 0x2a, 0x0, 0x44 } }

+

 #

 # [Error.gEfiSecurityPkgTokenSpaceGuid]

 #   0x80000001 | Invalid value provided.

diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
index 74cdd1f..1153c14 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
@@ -16,6 +16,8 @@
 #include <PiPei.h>

 

 #include <IndustryStandard/UefiTcgPlatform.h>

+#include <Protocol/Tcg2Protocol.h>

+

 #include <Ppi/FirmwareVolumeInfo.h>

 #include <Ppi/FirmwareVolumeInfo2.h>

 #include <Ppi/TpmInitialized.h>

@@ -23,6 +25,7 @@
 #include <Ppi/EndOfPeiPhase.h>

 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>

 #include <Ppi/FirmwareVolumeInfoPrehashedFV.h>

+#include <Ppi/Tcg2Measure.h>

 

 #include <Guid/TcgEventHob.h>

 #include <Guid/MeasuredFvHob.h>

@@ -38,7 +41,6 @@
 #include <Library/HobLib.h>

 #include <Library/PcdLib.h>

 #include <Library/PeiServicesTablePointerLib.h>

-#include <Protocol/Tcg2Protocol.h>

 #include <Library/PerformanceLib.h>

 #include <Library/MemoryAllocationLib.h>

 #include <Library/ReportStatusCodeLib.h>

@@ -115,6 +117,45 @@
   IN VOID                          *Ppi

   );

 

+/**

+  The EFI_TCG2_MEASURE_PPI. HashLogExtendEvent function call provides callers with

+  an opportunity to extend and optionally log events without requiring

+  knowledge of actual TPM commands. 

+  The extend operation will occur even if this function cannot create an event

+  log entry. The interface can be called before Memory Ready

+

+  Be noted that the interface will not save any FV measuring information. If want Tcg2Pei to

+  remember this info, user should install properly

+

+  @param[in]  This                Points to this instance of the

+                                EFI_PEI_FIRMWARE_VOLUME_PPI.

+  @param[in]  Flags              Bitmap providing additional information. Defined in Tcg2Protocol.h

+  @param[in]  DataToHash         Physical address of the start of the data buffer to be hashed. 

+  @param[in]  DataToHashLen      The length in bytes of the buffer referenced by DataToHash.

+  @param[in]  Event              Pointer to data buffer containing information about the event.

+

+  @retval EFI_SUCCESS            Operation completed successfully.

+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.

+  @retval EFI_VOLUME_FULL        The extend operation occurred, but the event could not be written to one or more event logs.

+  @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.

+  

+**/

+EFI_STATUS

+HashLogExtendEvent(

+  IN  UINT64                           Flags,

+  IN  UINT8                            *HashData,

+  IN  UINTN                            HashDataLen,

+  IN  EFI_TCG2_EVENT                   *Event

+);

+

+EFI_PEI_TCG2_MEASURE_PPI mTcg2MeasurePpi = {HashLogExtendEvent};

+

+EFI_PEI_PPI_DESCRIPTOR mPpiList = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEdkiiTcg2MeasurePpiGuid,

+  &mTcg2MeasurePpi

+};

+

 EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {

   {

     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,

@@ -370,7 +411,7 @@
 

 **/

 EFI_STATUS

-HashLogExtendEvent (

+HashLogExtendEventInternal (

   IN      UINT64                    Flags,

   IN      UINT8                     *HashData,

   IN      UINTN                     HashDataLen,

@@ -410,6 +451,40 @@
 }

 

 /**

+  Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,

+  and build a GUIDed HOB recording the event which will be passed to the DXE phase and

+  added into the Event Log.

+

+  @param[in]      Flags         Bitmap providing additional information.

+  @param[in]      HashData      Physical address of the start of the data buffer 

+                                to be hashed, extended, and logged.

+  @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData.

+  @param[in]      NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.  

+  @param[in]      NewEventData  Pointer to the new event data.  

+

+  @retval EFI_SUCCESS           Operation completed successfully.

+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.

+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.

+

+**/

+EFI_STATUS

+HashLogExtendEvent (

+  IN      UINT64                    Flags,

+  IN      UINT8                     *HashData,

+  IN      UINTN                     HashDataLen,

+  IN      EFI_TCG2_EVENT            *Event

+  )

+{

+  TCG_PCR_EVENT_HDR NewEventHdr;

+

+  NewEventHdr.PCRIndex  = Event->Header.PCRIndex;

+  NewEventHdr.EventType = Event->Header.EventType;

+  NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;

+

+  return HashLogExtendEventInternal(Flags, HashData, HashDataLen, &NewEventHdr, Event->Event);

+}

+

+/**

   Measure CRTM version.

 

   @retval EFI_SUCCESS           Operation completed successfully.

@@ -433,7 +508,7 @@
   TcgEventHdr.EventType = EV_S_CRTM_VERSION;

   TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));

 

-  return HashLogExtendEvent (

+  return HashLogExtendEventInternal (

            0,

            (UINT8*)PcdGetPtr (PcdFirmwareVersionString),

            TcgEventHdr.EventSize,

@@ -592,7 +667,7 @@
     //

     // Hash the FV, extend digest to the TPM and log TCG event

     //

-    Status = HashLogExtendEvent (

+    Status = HashLogExtendEventInternal (

                0,

                (UINT8*) (UINTN) FvBlob.BlobBase,

                (UINTN) FvBlob.BlobLength,

@@ -756,6 +831,8 @@
   )

 {

   EFI_STATUS                        Status;

+  EFI_PEI_PPI_DESCRIPTOR            *PpiDescriptor;

+  EFI_PEI_TCG2_MEASURE_PPI          *Tcg2Ppi;

 

   mMeasuredBaseFvInfo  = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));

   ASSERT (mMeasuredBaseFvInfo != NULL);

@@ -772,6 +849,23 @@
   }

 

   //

+  // Re-install Tcg2 Measure PPI after memory ready

+  //

+  Status = PeiServicesLocatePpi (

+             &gEdkiiTcg2MeasurePpiGuid,

+             0,

+             &PpiDescriptor,

+             (VOID **) &Tcg2Ppi

+             );

+  if (!EFI_ERROR (Status)) {

+    Status = PeiServicesReInstallPpi (PpiDescriptor, &mPpiList);

+    if (EFI_ERROR (Status)) {

+      ASSERT_EFI_ERROR (Status);

+      return Status;

+    }

+  }

+

+  //

   // Post callbacks:

   // for the FvInfoPpi services to measure and record

   // the additional Fvs to TPM

@@ -806,7 +900,7 @@
   TcgEvent.PCRIndex  = PCRIndex;

   TcgEvent.EventType = EV_SEPARATOR;

   TcgEvent.EventSize = (UINT32)sizeof (EventData);

-  return HashLogExtendEvent(0,(UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent,(UINT8 *)&EventData);

+  return HashLogExtendEventInternal(0,(UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent,(UINT8 *)&EventData);

 }

 

 /**

@@ -917,6 +1011,12 @@
           goto Done;

         }

       }

+

+      //

+      // Install Tcg2 Measure PPI

+      //

+      Status = PeiServicesInstallPpi (&mPpiList);

+      ASSERT_EFI_ERROR (Status);

     }

 

     //

diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
index 9608f9a..486f8b2 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
@@ -74,6 +74,7 @@
   gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid                  ## SOMETIMES_CONSUMES

   gPeiTpmInitializedPpiGuid                                            ## SOMETIMES_PRODUCES

   gPeiTpmInitializationDonePpiGuid                                     ## PRODUCES

+  gEdkiiTcg2MeasurePpiGuid                                             ## PRODUCES

   gEfiEndOfPeiSignalPpiGuid                                            ## SOMETIMES_CONSUMES     ## NOTIFY

   gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid                        ## SOMETIMES_CONSUMES