[edk2-devel] [PATCH] SecurityPkg: Add TPM NVIndex Extend support.

Qi Zhang posted 1 patch 1 year, 10 months ago
Failed in applying to current master (apply log)
There is a newer version of this series
SecurityPkg/Include/Library/Tpm2CommandLib.h  |  21 +++
.../HashLibBaseCryptoRouterDxe.c              |  77 +++++++++--
.../Library/Tpm2CommandLib/Tpm2NVStorage.c    | 120 ++++++++++++++++++
SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c             |  26 +++-
4 files changed, 229 insertions(+), 15 deletions(-)
[edk2-devel] [PATCH] SecurityPkg: Add TPM NVIndex Extend support.
Posted by Qi Zhang 1 year, 10 months ago
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Qi Zhang <qi1.zhang@intel.com>
---
 SecurityPkg/Include/Library/Tpm2CommandLib.h  |  21 +++
 .../HashLibBaseCryptoRouterDxe.c              |  77 +++++++++--
 .../Library/Tpm2CommandLib/Tpm2NVStorage.c    | 120 ++++++++++++++++++
 SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c             |  26 +++-
 4 files changed, 229 insertions(+), 15 deletions(-)

diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Include/Library/Tpm2CommandLib.h
index a2fb97f18d..f2ff3a5c0c 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -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..264f500dc6 100644
--- a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
+++ b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
@@ -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,40 @@ HashUpdate (
   return EFI_SUCCESS;
 }
 
+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 +184,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 +215,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..6f8badad3f 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
@@ -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..dfb7f28251 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
@@ -1230,12 +1230,26 @@ 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 +1331,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;
   }
 
-- 
2.31.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#91058): https://edk2.groups.io/g/devel/message/91058
Mute This Topic: https://groups.io/mt/92180525/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-