Add new api Tpm2ExtendNvIndex.
It is uesd in HashCompleteAndExtend when PcrIndex > MAX_PCR_INDEX.

Cc: Jiewen Yao <jiewen....@intel.com>
Cc: Rahul Kumar <rahul1.ku...@intel.com>
Signed-off-by: Wenxing Hou <wenxing....@intel.com>
---
 SecurityPkg/Include/Library/Tpm2CommandLib.h  |  23 +++-
 .../HashLibBaseCryptoRouterDxe.c              |  88 +++++++++++--
 .../Library/Tpm2CommandLib/Tpm2NVStorage.c    | 122 +++++++++++++++++-
 SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c             |  61 ++++++++-
 SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf           |   4 +-
 5 files changed, 278 insertions(+), 20 deletions(-)

diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h 
b/SecurityPkg/Include/Library/Tpm2CommandLib.h
index a2fb97f18d..70eec84c90 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -1,7 +1,7 @@
 /** @file
   This library is used by other modules to send TPM2 command.
 
-Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -467,6 +467,27 @@ Tpm2NvGlobalWriteLock (
   IN      TPMS_AUTH_COMMAND  *AuthSession OPTIONAL
   );
 
+/**
+  This command extends a value to an area in NV memory that was previously 
defined by TPM2_NV_DefineSpace().
+
+  @param[in]  AuthHandle         the handle indicating the source of the 
authorization value.
+  @param[in]  NvIndex            The NV Index of the area to extend.
+  @param[in]  AuthSession        Auth Session context
+  @param[in]  InData             The data to extend.
+
+  @retval EFI_SUCCESS            Operation completed successfully.
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
+  @retval EFI_NOT_FOUND          The command was returned successfully, but 
NvIndex is not found.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2NvExtend (
+  IN      TPMI_RH_NV_AUTH    AuthHandle,
+  IN      TPMI_RH_NV_INDEX   NvIndex,
+  IN      TPMS_AUTH_COMMAND  *AuthSession  OPTIONAL,
+  IN      TPM2B_MAX_BUFFER   *InData
+  );
+
 /**
   This command is used to cause an update to the indicated PCR.
   The digests parameter contains one or more tagged digest value identified by 
an algorithm ID.
diff --git 
a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c 
b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
index ee8fe6e06e..2169c5e185 100644
--- a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
+++ b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
@@ -3,7 +3,7 @@
   hash handler registered, such as SHA1, SHA256.
   Platform can use PcdTpm2HashMask to mask some hash engines.
 
-Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
 #include <Library/HashLib.h>
+#include <Protocol/Tcg2Protocol.h>
 
 #include "HashLibBaseCryptoRouterCommon.h"
 
@@ -128,6 +129,49 @@ HashUpdate (
   return EFI_SUCCESS;
 }
 
+/**
+  Extend to TPM NvIndex.
+
+  @param[in]  NvIndex            The NV Index of the area to extend.
+  @param[in]  DataSize           The data size to extend.
+  @param[in]  Data               The data to extend.
+
+  @retval EFI_SUCCESS            Operation completed successfully.
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
+  @retval EFI_NOT_FOUND          The command was returned successfully, but 
NvIndex is not found.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2ExtendNvIndex (
+  TPMI_RH_NV_INDEX  NvIndex,
+  UINT16            DataSize,
+  BYTE              *Data
+  )
+{
+  EFI_STATUS        Status;
+  TPMI_RH_NV_AUTH   AuthHandle;
+  TPM2B_MAX_BUFFER  NvExtendData;
+
+  AuthHandle = TPM_RH_PLATFORM;
+  ZeroMem (&NvExtendData, sizeof (NvExtendData));
+  CopyMem (NvExtendData.buffer, Data, DataSize);
+  NvExtendData.size = DataSize;
+  Status            = Tpm2NvExtend (
+                        AuthHandle,
+                        NvIndex,
+                        NULL,
+                        &NvExtendData
+                        );
+  if (EFI_ERROR (Status)) {
+    DEBUG (
+      (DEBUG_ERROR, "Extend TPM NV index failed, Index: 0x%x Status: %d\n",
+       NvIndex, Status)
+      );
+  }
+
+  return Status;
+}
+
 /**
   Hash sequence complete and extend to PCR.
 
@@ -149,11 +193,16 @@ HashCompleteAndExtend (
   OUT TPML_DIGEST_VALUES  *DigestList
   )
 {
-  TPML_DIGEST_VALUES  Digest;
-  HASH_HANDLE         *HashCtx;
-  UINTN               Index;
-  EFI_STATUS          Status;
-  UINT32              HashMask;
+  TPML_DIGEST_VALUES               Digest;
+  HASH_HANDLE                      *HashCtx;
+  UINTN                            Index;
+  EFI_STATUS                       Status;
+  UINT32                           HashMask;
+  TPML_DIGEST_VALUES               TcgPcrEvent2Digest;
+  EFI_TCG2_EVENT_ALGORITHM_BITMAP  TpmHashAlgorithmBitmap;
+  UINT32                           ActivePcrBanks;
+  UINT32                           *BufferPtr;
+  UINT32                           DigestListBinSize;
 
   if (mHashInterfaceCount == 0) {
     return EFI_UNSUPPORTED;
@@ -175,10 +224,29 @@ HashCompleteAndExtend (
 
   FreePool (HashCtx);
 
-  Status = Tpm2PcrExtend (
-             PcrIndex,
-             DigestList
-             );
+  if (PcrIndex <= MAX_PCR_INDEX) {
+    Status = Tpm2PcrExtend (
+               PcrIndex,
+               DigestList
+               );
+  } else {
+    Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, 
&ActivePcrBanks);
+    ASSERT_EFI_ERROR (Status);
+    ActivePcrBanks = ActivePcrBanks & mSupportedHashMaskCurrent;
+    ZeroMem (&TcgPcrEvent2Digest, sizeof (TcgPcrEvent2Digest));
+    BufferPtr         = CopyDigestListToBuffer (&TcgPcrEvent2Digest, 
DigestList, ActivePcrBanks);
+    DigestListBinSize = (UINT32)((UINT8 *)BufferPtr - (UINT8 
*)&TcgPcrEvent2Digest);
+
+    //
+    // Extend to TPM NvIndex
+    //
+    Status = Tpm2ExtendNvIndex (
+               PcrIndex,
+               (UINT16)DigestListBinSize,
+               (BYTE *)&TcgPcrEvent2Digest
+               );
+  }
+
   return Status;
 }
 
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c 
b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
index 5077ace7c2..f11f7696b1 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
@@ -1,7 +1,7 @@
 /** @file
   Implement TPM2 NVStorage related command.
 
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -148,6 +148,22 @@ typedef struct {
   TPMS_AUTH_RESPONSE      AuthSession;
 } TPM2_NV_GLOBALWRITELOCK_RESPONSE;
 
+typedef struct {
+  TPM2_COMMAND_HEADER    Header;
+  TPMI_RH_NV_AUTH        AuthHandle;
+  TPMI_RH_NV_INDEX       NvIndex;
+  UINT32                 AuthSessionSize;
+  TPMS_AUTH_COMMAND      AuthSession;
+  TPM2B_MAX_BUFFER       Data;
+  UINT16                 Offset;
+} TPM2_NV_EXTEND_COMMAND;
+
+typedef struct {
+  TPM2_RESPONSE_HEADER    Header;
+  UINT32                  AuthSessionSize;
+  TPMS_AUTH_RESPONSE      AuthSession;
+} TPM2_NV_EXTEND_RESPONSE;
+
 #pragma pack()
 
 /**
@@ -1052,3 +1068,107 @@ Done:
   ZeroMem (&RecvBuffer, sizeof (RecvBuffer));
   return Status;
 }
+
+/**
+  This command extends a value to an area in NV memory that was previously 
defined by TPM2_NV_DefineSpace().
+
+  @param[in]  AuthHandle         the handle indicating the source of the 
authorization value.
+  @param[in]  NvIndex            The NV Index of the area to extend.
+  @param[in]  AuthSession        Auth Session context
+  @param[in]  InData             The data to extend.
+
+  @retval EFI_SUCCESS            Operation completed successfully.
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
+  @retval EFI_NOT_FOUND          The command was returned successfully, but 
NvIndex is not found.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2NvExtend (
+  IN      TPMI_RH_NV_AUTH    AuthHandle,
+  IN      TPMI_RH_NV_INDEX   NvIndex,
+  IN      TPMS_AUTH_COMMAND  *AuthSession  OPTIONAL,
+  IN      TPM2B_MAX_BUFFER   *InData
+  )
+{
+  EFI_STATUS               Status;
+  TPM2_NV_EXTEND_COMMAND   SendBuffer;
+  TPM2_NV_EXTEND_RESPONSE  RecvBuffer;
+  UINT32                   SendBufferSize;
+  UINT32                   RecvBufferSize;
+  UINT8                    *Buffer;
+  UINT32                   SessionInfoSize;
+  TPM_RC                   ResponseCode;
+
+  //
+  // Construct command
+  //
+  SendBuffer.Header.tag         = SwapBytes16 (TPM_ST_SESSIONS);
+  SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_NV_Extend);
+
+  SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
+  SendBuffer.NvIndex    = SwapBytes32 (NvIndex);
+
+  //
+  // Add in Auth session
+  //
+  Buffer = (UINT8 *)&SendBuffer.AuthSession;
+
+  // sessionInfoSize
+  SessionInfoSize            = CopyAuthSessionCommand (AuthSession, Buffer);
+  Buffer                    += SessionInfoSize;
+  SendBuffer.AuthSessionSize = SwapBytes32 (SessionInfoSize);
+
+  WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (InData->size));
+  Buffer += sizeof (UINT16);
+  CopyMem (Buffer, InData->buffer, InData->size);
+  Buffer += InData->size;
+
+  SendBufferSize              = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
+  SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+  //
+  // send Tpm command
+  //
+  RecvBufferSize = sizeof (RecvBuffer);
+  Status         = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, 
&RecvBufferSize, (UINT8 *)&RecvBuffer);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+    DEBUG ((DEBUG_ERROR, "Tpm2NvExtend - RecvBufferSize Error - %x\n", 
RecvBufferSize));
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
+  ResponseCode = SwapBytes32 (RecvBuffer.Header.responseCode);
+  if (ResponseCode != TPM_RC_SUCCESS) {
+    DEBUG ((DEBUG_ERROR, "Tpm2NvExtend - responseCode - %x\n", ResponseCode));
+  }
+
+  switch (ResponseCode) {
+    case TPM_RC_SUCCESS:
+      // return data
+      break;
+    case TPM_RC_ATTRIBUTES:
+      Status = EFI_UNSUPPORTED;
+      break;
+    case TPM_RC_NV_AUTHORIZATION:
+      Status = EFI_SECURITY_VIOLATION;
+      break;
+    case TPM_RC_NV_LOCKED:
+      Status = EFI_ACCESS_DENIED;
+      break;
+    default:
+      Status = EFI_DEVICE_ERROR;
+      break;
+  }
+
+Done:
+  //
+  // Clear AuthSession Content
+  //
+  ZeroMem (&SendBuffer, sizeof (SendBuffer));
+  ZeroMem (&RecvBuffer, sizeof (RecvBuffer));
+  return Status;
+}
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c 
b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
index f6ea8b2bbf..b8f50e25df 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
@@ -1,7 +1,7 @@
 /** @file
   This module implements Tcg2 Protocol.
 
-Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Guid/EventExitBootServiceFailed.h>
 #include <Guid/ImageAuthentication.h>
 #include <Guid/TpmInstance.h>
+#include <Guid/DeviceAuthentication.h>
 
 #include <Protocol/DevicePath.h>
 #include <Protocol/MpService.h>
@@ -1230,10 +1231,25 @@ TcgDxeHashLogExtendEvent (
     //
     // Do not do TPM extend for EV_NO_ACTION
     //
-    Status = EFI_SUCCESS;
-    InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
-    if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
-      Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, 
NewEventData);
+    if (NewEventHdr->PCRIndex <= MAX_PCR_INDEX) {
+      Status = EFI_SUCCESS;
+      InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
+      if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
+        Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, 
NewEventData);
+      }
+    } else {
+      //
+      // Extend to NvIndex
+      //
+      Status = HashAndExtend (
+                 NewEventHdr->PCRIndex,
+                 HashData,
+                 (UINTN)HashDataLen,
+                 &DigestList
+                 );
+      if (!EFI_ERROR (Status)) {
+        Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
+      }
     }
 
     return Status;
@@ -1317,7 +1333,7 @@ Tcg2HashLogExtendEvent (
     return EFI_INVALID_PARAMETER;
   }
 
-  if (Event->Header.PCRIndex > MAX_PCR_INDEX) {
+  if ((Event->Header.EventType != EV_NO_ACTION) && (Event->Header.PCRIndex > 
MAX_PCR_INDEX)) {
     return EFI_INVALID_PARAMETER;
   }
 
@@ -2063,7 +2079,7 @@ MeasureVariable (
       );
   }
 
-  if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
+  if ((EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) || (EventType == 
EV_EFI_SPDM_DEVICE_POLICY)) {
     //
     // Digest is the event data (UEFI_VARIABLE_DATA)
     //
@@ -2319,6 +2335,37 @@ MeasureAllSecureVariables (
     DEBUG ((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", 
EFI_IMAGE_SECURITY_DATABASE2));
   }
 
+  //
+  // Meaurement UEFI device signature database
+  //
+  if ((PcdGet32 (PcdTcgPfpMeasurementRevision) >= 
TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106) &&
+      (PcdGet8 (PcdEnableSpdmDeviceAuthentication) != 0))
+  {
+    Status = GetVariable2 (EFI_DEVICE_SECURITY_DATABASE, 
&gEfiDeviceSignatureDatabaseGuid, &Data, &DataSize);
+    if (Status == EFI_SUCCESS) {
+      Status = MeasureVariable (
+                 PCR_INDEX_FOR_SIGNATURE_DB,
+                 EV_EFI_SPDM_DEVICE_POLICY,
+                 EFI_DEVICE_SECURITY_DATABASE,
+                 &gEfiDeviceSignatureDatabaseGuid,
+                 Data,
+                 DataSize
+                 );
+      FreePool (Data);
+    } else if (Status == EFI_NOT_FOUND) {
+      Data     = NULL;
+      DataSize = 0;
+      Status   = MeasureVariable (
+                   PCR_INDEX_FOR_SIGNATURE_DB,
+                   EV_EFI_SPDM_DEVICE_POLICY,
+                   EFI_DEVICE_SECURITY_DATABASE,
+                   &gEfiDeviceSignatureDatabaseGuid,
+                   Data,
+                   DataSize
+                   );
+    }
+  }
+
   return EFI_SUCCESS;
 }
 
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf 
b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
index 7dc7a2683d..a645474bf3 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
@@ -16,7 +16,7 @@
 #  This external input must be validated carefully to avoid security issue like
 #  buffer overflow, integer overflow.
 #
-# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -86,6 +86,7 @@
   gTcgEvent2EntryHobGuid                             ## SOMETIMES_CONSUMES  ## 
HOB
   gTpm2StartupLocalityHobGuid                        ## SOMETIMES_CONSUMES  ## 
HOB
   gTcg800155PlatformIdEventHobGuid                   ## SOMETIMES_CONSUMES  ## 
HOB
+  gEfiDeviceSignatureDatabaseGuid
 
 [Protocols]
   gEfiTcg2ProtocolGuid                               ## PRODUCES
@@ -107,6 +108,7 @@
   gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLaml                        ## 
PRODUCES
   gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLasa                        ## 
PRODUCES
   gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision               ## 
CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication           
## CONSUMES
 
 [Depex]
   # According to PcdTpm2AcpiTableRev definition in SecurityPkg.dec
-- 
2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117731): https://edk2.groups.io/g/devel/message/117731
Mute This Topic: https://groups.io/mt/105528206/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to