[PATCH] SecurityPkg: Add TPM NVIndex Extend support.


Qi Zhang
 

Signed-off-by: Qi Zhang <qi1.zhang@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Rahul Kumar <rahul1.kumar@...>
Cc: Qi Zhang <qi1.zhang@...>
---
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/Inc=
lude/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=0D
);=0D
=0D
+/**=0D
+ This command extends a value to an area in NV memory that was previously=
defined by TPM2_NV_DefineSpace().=0D
+=0D
+ @param[in] AuthHandle the handle indicating the source of the a=
uthorization value.=0D
+ @param[in] NvIndex The NV Index of the area to extend.=0D
+ @param[in] AuthSession Auth Session context=0D
+ @param[in] InData The data to extend.=0D
+=0D
+ @retval EFI_SUCCESS Operation completed successfully.=0D
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.=0D
+ @retval EFI_NOT_FOUND The command was returned successfully, bu=
t NvIndex is not found.=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+Tpm2NvExtend (=0D
+ IN TPMI_RH_NV_AUTH AuthHandle,=0D
+ IN TPMI_RH_NV_INDEX NvIndex,=0D
+ IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL,=0D
+ IN TPM2B_MAX_BUFFER *InData=0D
+ );=0D
+=0D
/**=0D
This command is used to cause an update to the indicated PCR.=0D
The digests parameter contains one or more tagged digest value identifie=
d by an algorithm ID.=0D
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoR=
outerDxe.c b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoR=
outerDxe.c
index ee8fe6e06e..264f500dc6 100644
--- a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDx=
e.c
+++ b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDx=
e.c
@@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h>=0D
#include <Library/PcdLib.h>=0D
#include <Library/HashLib.h>=0D
+#include <Protocol/Tcg2Protocol.h>=0D
=0D
#include "HashLibBaseCryptoRouterCommon.h"=0D
=0D
@@ -128,6 +129,40 @@ HashUpdate (
return EFI_SUCCESS;=0D
}=0D
=0D
+EFI_STATUS=0D
+EFIAPI=0D
+Tpm2ExtendNvIndex (=0D
+ TPMI_RH_NV_INDEX NvIndex,=0D
+ UINT16 DataSize,=0D
+ BYTE *Data=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ TPMI_RH_NV_AUTH AuthHandle;=0D
+ TPM2B_MAX_BUFFER NvExtendData;=0D
+=0D
+ AuthHandle =3D TPM_RH_PLATFORM;=0D
+ ZeroMem (&NvExtendData, sizeof (NvExtendData));=0D
+ CopyMem (NvExtendData.buffer, Data, DataSize);=0D
+ NvExtendData.size =3D DataSize;=0D
+ Status =3D Tpm2NvExtend (=0D
+ AuthHandle,=0D
+ NvIndex,=0D
+ NULL,=0D
+ &NvExtendData=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((=0D
+ DEBUG_ERROR,=0D
+ "Extend TPM NV index failed, Index: 0x%x Status: %d\n",=0D
+ NvIndex,=0D
+ Status=0D
+ ));=0D
+ }=0D
+=0D
+ return Status;=0D
+}=0D
+=0D
/**=0D
Hash sequence complete and extend to PCR.=0D
=0D
@@ -149,11 +184,16 @@ HashCompleteAndExtend (
OUT TPML_DIGEST_VALUES *DigestList=0D
)=0D
{=0D
- TPML_DIGEST_VALUES Digest;=0D
- HASH_HANDLE *HashCtx;=0D
- UINTN Index;=0D
- EFI_STATUS Status;=0D
- UINT32 HashMask;=0D
+ TPML_DIGEST_VALUES Digest;=0D
+ HASH_HANDLE *HashCtx;=0D
+ UINTN Index;=0D
+ EFI_STATUS Status;=0D
+ UINT32 HashMask;=0D
+ TPML_DIGEST_VALUES TcgPcrEvent2Digest;=0D
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;=0D
+ UINT32 ActivePcrBanks;=0D
+ UINT32 *BufferPtr;=0D
+ UINT32 DigestListBinSize;=0D
=0D
if (mHashInterfaceCount =3D=3D 0) {=0D
return EFI_UNSUPPORTED;=0D
@@ -175,10 +215,29 @@ HashCompleteAndExtend (
=0D
FreePool (HashCtx);=0D
=0D
- Status =3D Tpm2PcrExtend (=0D
- PcrIndex,=0D
- DigestList=0D
- );=0D
+ if (PcrIndex <=3D MAX_PCR_INDEX) {=0D
+ Status =3D Tpm2PcrExtend (=0D
+ PcrIndex,=0D
+ DigestList=0D
+ );=0D
+ } else {=0D
+ Status =3D Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmB=
itmap, &ActivePcrBanks);=0D
+ ASSERT_EFI_ERROR (Status);=0D
+ ActivePcrBanks =3D ActivePcrBanks & mSupportedHashMaskCurrent;=0D
+ ZeroMem (&TcgPcrEvent2Digest, sizeof (TcgPcrEvent2Digest));=0D
+ BufferPtr =3D CopyDigestListToBuffer (&TcgPcrEvent2Digest, Dig=
estList, ActivePcrBanks);=0D
+ DigestListBinSize =3D (UINT32)((UINT8 *)BufferPtr - (UINT8 *)&TcgPcrEv=
ent2Digest);=0D
+=0D
+ //=0D
+ // Extend to TPM NvIndex=0D
+ //=0D
+ Status =3D Tpm2ExtendNvIndex (=0D
+ PcrIndex,=0D
+ (UINT16)DigestListBinSize,=0D
+ (BYTE *)&TcgPcrEvent2Digest=0D
+ );=0D
+ }=0D
+=0D
return Status;=0D
}=0D
=0D
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c b/SecurityP=
kg/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;=0D
} TPM2_NV_GLOBALWRITELOCK_RESPONSE;=0D
=0D
+typedef struct {=0D
+ TPM2_COMMAND_HEADER Header;=0D
+ TPMI_RH_NV_AUTH AuthHandle;=0D
+ TPMI_RH_NV_INDEX NvIndex;=0D
+ UINT32 AuthSessionSize;=0D
+ TPMS_AUTH_COMMAND AuthSession;=0D
+ TPM2B_MAX_BUFFER Data;=0D
+ UINT16 Offset;=0D
+} TPM2_NV_EXTEND_COMMAND;=0D
+=0D
+typedef struct {=0D
+ TPM2_RESPONSE_HEADER Header;=0D
+ UINT32 AuthSessionSize;=0D
+ TPMS_AUTH_RESPONSE AuthSession;=0D
+} TPM2_NV_EXTEND_RESPONSE;=0D
+=0D
#pragma pack()=0D
=0D
/**=0D
@@ -1052,3 +1068,107 @@ Done:
ZeroMem (&RecvBuffer, sizeof (RecvBuffer));=0D
return Status;=0D
}=0D
+=0D
+/**=0D
+ This command extends a value to an area in NV memory that was previously=
defined by TPM2_NV_DefineSpace().=0D
+=0D
+ @param[in] AuthHandle the handle indicating the source of the a=
uthorization value.=0D
+ @param[in] NvIndex The NV Index of the area to extend.=0D
+ @param[in] AuthSession Auth Session context=0D
+ @param[in] InData The data to extend.=0D
+=0D
+ @retval EFI_SUCCESS Operation completed successfully.=0D
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.=0D
+ @retval EFI_NOT_FOUND The command was returned successfully, bu=
t NvIndex is not found.=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+Tpm2NvExtend (=0D
+ IN TPMI_RH_NV_AUTH AuthHandle,=0D
+ IN TPMI_RH_NV_INDEX NvIndex,=0D
+ IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL,=0D
+ IN TPM2B_MAX_BUFFER *InData=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ TPM2_NV_EXTEND_COMMAND SendBuffer;=0D
+ TPM2_NV_EXTEND_RESPONSE RecvBuffer;=0D
+ UINT32 SendBufferSize;=0D
+ UINT32 RecvBufferSize;=0D
+ UINT8 *Buffer;=0D
+ UINT32 SessionInfoSize;=0D
+ TPM_RC ResponseCode;=0D
+=0D
+ //=0D
+ // Construct command=0D
+ //=0D
+ SendBuffer.Header.tag =3D SwapBytes16 (TPM_ST_SESSIONS);=0D
+ SendBuffer.Header.commandCode =3D SwapBytes32 (TPM_CC_NV_Extend);=0D
+=0D
+ SendBuffer.AuthHandle =3D SwapBytes32 (AuthHandle);=0D
+ SendBuffer.NvIndex =3D SwapBytes32 (NvIndex);=0D
+=0D
+ //=0D
+ // Add in Auth session=0D
+ //=0D
+ Buffer =3D (UINT8 *)&SendBuffer.AuthSession;=0D
+=0D
+ // sessionInfoSize=0D
+ SessionInfoSize =3D CopyAuthSessionCommand (AuthSession, Buff=
er);=0D
+ Buffer +=3D SessionInfoSize;=0D
+ SendBuffer.AuthSessionSize =3D SwapBytes32 (SessionInfoSize);=0D
+=0D
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (InData->size));=0D
+ Buffer +=3D sizeof (UINT16);=0D
+ CopyMem (Buffer, InData->buffer, InData->size);=0D
+ Buffer +=3D InData->size;=0D
+=0D
+ SendBufferSize =3D (UINT32)(Buffer - (UINT8 *)&SendBuffer);=
=0D
+ SendBuffer.Header.paramSize =3D SwapBytes32 (SendBufferSize);=0D
+=0D
+ //=0D
+ // send Tpm command=0D
+ //=0D
+ RecvBufferSize =3D sizeof (RecvBuffer);=0D
+ Status =3D Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuff=
er, &RecvBufferSize, (UINT8 *)&RecvBuffer);=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto Done;=0D
+ }=0D
+=0D
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {=0D
+ DEBUG ((DEBUG_ERROR, "Tpm2NvExtend - RecvBufferSize Error - %x\n", Rec=
vBufferSize));=0D
+ Status =3D EFI_DEVICE_ERROR;=0D
+ goto Done;=0D
+ }=0D
+=0D
+ ResponseCode =3D SwapBytes32 (RecvBuffer.Header.responseCode);=0D
+ if (ResponseCode !=3D TPM_RC_SUCCESS) {=0D
+ DEBUG ((DEBUG_ERROR, "Tpm2NvExtend - responseCode - %x\n", ResponseCod=
e));=0D
+ }=0D
+=0D
+ switch (ResponseCode) {=0D
+ case TPM_RC_SUCCESS:=0D
+ // return data=0D
+ break;=0D
+ case TPM_RC_ATTRIBUTES:=0D
+ Status =3D EFI_UNSUPPORTED;=0D
+ break;=0D
+ case TPM_RC_NV_AUTHORIZATION:=0D
+ Status =3D EFI_SECURITY_VIOLATION;=0D
+ break;=0D
+ case TPM_RC_NV_LOCKED:=0D
+ Status =3D EFI_ACCESS_DENIED;=0D
+ break;=0D
+ default:=0D
+ Status =3D EFI_DEVICE_ERROR;=0D
+ break;=0D
+ }=0D
+=0D
+Done:=0D
+ //=0D
+ // Clear AuthSession Content=0D
+ //=0D
+ ZeroMem (&SendBuffer, sizeof (SendBuffer));=0D
+ ZeroMem (&RecvBuffer, sizeof (RecvBuffer));=0D
+ return Status;=0D
+}=0D
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tc=
g2Dxe.c
index f6ea8b2bbf..dfb7f28251 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
@@ -1230,12 +1230,26 @@ TcgDxeHashLogExtendEvent (
//=0D
// Do not do TPM extend for EV_NO_ACTION=0D
//=0D
- Status =3D EFI_SUCCESS;=0D
- InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);=0D
- if ((Flags & EFI_TCG2_EXTEND_ONLY) =3D=3D 0) {=0D
- Status =3D TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr=
, NewEventData);=0D
+ if (NewEventHdr->PCRIndex <=3D MAX_PCR_INDEX) {=0D
+ Status =3D EFI_SUCCESS;=0D
+ InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);=0D
+ if ((Flags & EFI_TCG2_EXTEND_ONLY) =3D=3D 0) {=0D
+ Status =3D TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventH=
dr, NewEventData);=0D
+ }=0D
+ } else {=0D
+ //=0D
+ // Extend to NvIndex=0D
+ //=0D
+ Status =3D HashAndExtend (=0D
+ NewEventHdr->PCRIndex,=0D
+ HashData,=0D
+ (UINTN)HashDataLen,=0D
+ &DigestList=0D
+ );=0D
+ if (!EFI_ERROR (Status)) {=0D
+ Status =3D TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventD=
ata);=0D
+ }=0D
}=0D
-=0D
return Status;=0D
}=0D
=0D
@@ -1317,7 +1331,7 @@ Tcg2HashLogExtendEvent (
return EFI_INVALID_PARAMETER;=0D
}=0D
=0D
- if (Event->Header.PCRIndex > MAX_PCR_INDEX) {=0D
+ if ((Event->Header.EventType !=3D EV_NO_ACTION) && (Event->Header.PCRInd=
ex > MAX_PCR_INDEX)) {=0D
return EFI_INVALID_PARAMETER;=0D
}=0D
=0D
--=20
2.31.1.windows.1