SecurityPkg: Add TCG PFP 1.06 support.
Add new api Tpm2ExtendNvIndex. It is uesd in HashCompleteAndExtend when PcrIndex > MAX_PCR_INDEX. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Signed-off-by: Wenxing Hou <wenxing.hou@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
		
				
					committed by
					
						![mergify[bot]](/avatar/e3df20cd7a67969c41a65f03bea54961?size=40) mergify[bot]
						mergify[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							d8e4c4b000
						
					
				
				
					commit
					c3f615a1bd
				
			| @@ -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. | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user