/** @file\r
Implement TPM2 Integrity related command.\r
\r
-Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#pragma pack(1)\r
\r
typedef struct {\r
- TPM2_COMMAND_HEADER Header;\r
- TPMI_DH_PCR PcrHandle;\r
- UINT32 AuthorizationSize;\r
- TPMS_AUTH_COMMAND AuthSessionPcr;\r
- TPML_DIGEST_VALUES DigestValues;\r
+ TPM2_COMMAND_HEADER Header;\r
+ TPMI_DH_PCR PcrHandle;\r
+ UINT32 AuthorizationSize;\r
+ TPMS_AUTH_COMMAND AuthSessionPcr;\r
+ TPML_DIGEST_VALUES DigestValues;\r
} TPM2_PCR_EXTEND_COMMAND;\r
\r
typedef struct {\r
- TPM2_RESPONSE_HEADER Header;\r
- UINT32 ParameterSize;\r
- TPMS_AUTH_RESPONSE AuthSessionPcr;\r
+ TPM2_RESPONSE_HEADER Header;\r
+ UINT32 ParameterSize;\r
+ TPMS_AUTH_RESPONSE AuthSessionPcr;\r
} TPM2_PCR_EXTEND_RESPONSE;\r
\r
typedef struct {\r
- TPM2_COMMAND_HEADER Header;\r
- TPMI_DH_PCR PcrHandle;\r
- UINT32 AuthorizationSize;\r
- TPMS_AUTH_COMMAND AuthSessionPcr;\r
- TPM2B_EVENT EventData;\r
+ TPM2_COMMAND_HEADER Header;\r
+ TPMI_DH_PCR PcrHandle;\r
+ UINT32 AuthorizationSize;\r
+ TPMS_AUTH_COMMAND AuthSessionPcr;\r
+ TPM2B_EVENT EventData;\r
} TPM2_PCR_EVENT_COMMAND;\r
\r
typedef struct {\r
- TPM2_RESPONSE_HEADER Header;\r
- UINT32 ParameterSize;\r
- TPML_DIGEST_VALUES Digests;\r
- TPMS_AUTH_RESPONSE AuthSessionPcr;\r
+ TPM2_RESPONSE_HEADER Header;\r
+ UINT32 ParameterSize;\r
+ TPML_DIGEST_VALUES Digests;\r
+ TPMS_AUTH_RESPONSE AuthSessionPcr;\r
} TPM2_PCR_EVENT_RESPONSE;\r
\r
typedef struct {\r
- TPM2_COMMAND_HEADER Header;\r
- TPML_PCR_SELECTION PcrSelectionIn;\r
+ TPM2_COMMAND_HEADER Header;\r
+ TPML_PCR_SELECTION PcrSelectionIn;\r
} TPM2_PCR_READ_COMMAND;\r
\r
typedef struct {\r
- TPM2_RESPONSE_HEADER Header;\r
- UINT32 PcrUpdateCounter;\r
- TPML_PCR_SELECTION PcrSelectionOut;\r
- TPML_DIGEST PcrValues;\r
+ TPM2_RESPONSE_HEADER Header;\r
+ UINT32 PcrUpdateCounter;\r
+ TPML_PCR_SELECTION PcrSelectionOut;\r
+ TPML_DIGEST PcrValues;\r
} TPM2_PCR_READ_RESPONSE;\r
\r
typedef struct {\r
- TPM2_COMMAND_HEADER Header;\r
- TPMI_RH_PLATFORM AuthHandle;\r
- UINT32 AuthSessionSize;\r
- TPMS_AUTH_COMMAND AuthSession;\r
- TPML_PCR_SELECTION PcrAllocation;\r
+ TPM2_COMMAND_HEADER Header;\r
+ TPMI_RH_PLATFORM AuthHandle;\r
+ UINT32 AuthSessionSize;\r
+ TPMS_AUTH_COMMAND AuthSession;\r
+ TPML_PCR_SELECTION PcrAllocation;\r
} TPM2_PCR_ALLOCATE_COMMAND;\r
\r
typedef struct {\r
- TPM2_RESPONSE_HEADER Header;\r
- UINT32 AuthSessionSize;\r
- TPMI_YES_NO AllocationSuccess;\r
- UINT32 MaxPCR;\r
- UINT32 SizeNeeded;\r
- UINT32 SizeAvailable;\r
- TPMS_AUTH_RESPONSE AuthSession;\r
+ TPM2_RESPONSE_HEADER Header;\r
+ UINT32 AuthSessionSize;\r
+ TPMI_YES_NO AllocationSuccess;\r
+ UINT32 MaxPCR;\r
+ UINT32 SizeNeeded;\r
+ UINT32 SizeAvailable;\r
+ TPMS_AUTH_RESPONSE AuthSession;\r
} TPM2_PCR_ALLOCATE_RESPONSE;\r
\r
#pragma pack()\r
EFI_STATUS\r
EFIAPI\r
Tpm2PcrExtend (\r
- IN TPMI_DH_PCR PcrHandle,\r
- IN TPML_DIGEST_VALUES *Digests\r
+ IN TPMI_DH_PCR PcrHandle,\r
+ IN TPML_DIGEST_VALUES *Digests\r
)\r
{\r
- EFI_STATUS Status;\r
- TPM2_PCR_EXTEND_COMMAND Cmd;\r
- TPM2_PCR_EXTEND_RESPONSE Res;\r
- UINT32 CmdSize;\r
- UINT32 RespSize;\r
- UINT32 ResultBufSize;\r
- UINT8 *Buffer;\r
- UINTN Index;\r
- UINT32 SessionInfoSize;\r
- UINT16 DigestSize;\r
-\r
- Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
- Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);\r
- Cmd.PcrHandle = SwapBytes32(PcrHandle);\r
-\r
+ EFI_STATUS Status;\r
+ TPM2_PCR_EXTEND_COMMAND Cmd;\r
+ TPM2_PCR_EXTEND_RESPONSE Res;\r
+ UINT32 CmdSize;\r
+ UINT32 RespSize;\r
+ UINT32 ResultBufSize;\r
+ UINT8 *Buffer;\r
+ UINTN Index;\r
+ UINT32 SessionInfoSize;\r
+ UINT16 DigestSize;\r
+\r
+ Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);\r
+ Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Extend);\r
+ Cmd.PcrHandle = SwapBytes32 (PcrHandle);\r
\r
//\r
// Add in Auth session\r
//\r
Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
- \r
+\r
// sessionInfoSize\r
- SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
- Buffer += SessionInfoSize;\r
- Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
- \r
- //Digest Count\r
- WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Digests->count));\r
- Buffer += sizeof(UINT32);\r
- \r
- //Digest\r
+ SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
+ Buffer += SessionInfoSize;\r
+ Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);\r
+\r
+ // Digest Count\r
+ WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Digests->count));\r
+ Buffer += sizeof (UINT32);\r
+\r
+ // Digest\r
for (Index = 0; Index < Digests->count; Index++) {\r
- WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Digests->digests[Index].hashAlg));\r
- Buffer += sizeof(UINT16);\r
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Digests->digests[Index].hashAlg));\r
+ Buffer += sizeof (UINT16);\r
DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
if (DigestSize == 0) {\r
- DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
+ DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
return EFI_DEVICE_ERROR;\r
}\r
- CopyMem(\r
+\r
+ CopyMem (\r
Buffer,\r
&Digests->digests[Index].digest,\r
DigestSize\r
);\r
+\r
+ DEBUG_CODE_BEGIN ();\r
+ UINTN Index2;\r
+ DEBUG ((\r
+ DEBUG_VERBOSE,\r
+ "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest = ",\r
+ Digests->digests[Index].hashAlg,\r
+ (UINT8)PcrHandle\r
+ ));\r
+\r
+ for (Index2 = 0; Index2 < DigestSize; Index2++) {\r
+ DEBUG ((DEBUG_VERBOSE, "%02x ", Buffer[Index2]));\r
+ }\r
+\r
+ DEBUG ((DEBUG_VERBOSE, "\n"));\r
+ DEBUG_CODE_END ();\r
+\r
Buffer += DigestSize;\r
}\r
\r
CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
- Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
+ Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
\r
- ResultBufSize = sizeof(Res);\r
- Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
- if (EFI_ERROR(Status)) {\r
+ ResultBufSize = sizeof (Res);\r
+ Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
+ if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- if (ResultBufSize > sizeof(Res)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
+ if (ResultBufSize > sizeof (Res)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
return EFI_BUFFER_TOO_SMALL;\r
}\r
\r
//\r
// Validate response headers\r
//\r
- RespSize = SwapBytes32(Res.Header.paramSize);\r
- if (RespSize > sizeof(Res)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));\r
+ RespSize = SwapBytes32 (Res.Header.paramSize);\r
+ if (RespSize > sizeof (Res)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));\r
return EFI_BUFFER_TOO_SMALL;\r
}\r
\r
//\r
// Fail if command failed\r
//\r
- if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
+ if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
return EFI_DEVICE_ERROR;\r
}\r
\r
+ DEBUG_CODE_BEGIN ();\r
+ DEBUG ((DEBUG_VERBOSE, "Tpm2PcrExtend: PCR read after extend...\n"));\r
+ Tpm2PcrReadForActiveBank (PcrHandle, NULL);\r
+ DEBUG_CODE_END ();\r
+\r
//\r
// Unmarshal the response\r
//\r
EFI_STATUS\r
EFIAPI\r
Tpm2PcrEvent (\r
- IN TPMI_DH_PCR PcrHandle,\r
- IN TPM2B_EVENT *EventData,\r
- OUT TPML_DIGEST_VALUES *Digests\r
+ IN TPMI_DH_PCR PcrHandle,\r
+ IN TPM2B_EVENT *EventData,\r
+ OUT TPML_DIGEST_VALUES *Digests\r
)\r
{\r
- EFI_STATUS Status;\r
- TPM2_PCR_EVENT_COMMAND Cmd;\r
- TPM2_PCR_EVENT_RESPONSE Res;\r
- UINT32 CmdSize;\r
- UINT32 RespSize;\r
- UINT32 ResultBufSize;\r
- UINT8 *Buffer;\r
- UINTN Index;\r
- UINT32 SessionInfoSize;\r
- UINT16 DigestSize;\r
-\r
- Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
- Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Event);\r
- Cmd.PcrHandle = SwapBytes32(PcrHandle);\r
+ EFI_STATUS Status;\r
+ TPM2_PCR_EVENT_COMMAND Cmd;\r
+ TPM2_PCR_EVENT_RESPONSE Res;\r
+ UINT32 CmdSize;\r
+ UINT32 RespSize;\r
+ UINT32 ResultBufSize;\r
+ UINT8 *Buffer;\r
+ UINTN Index;\r
+ UINT32 SessionInfoSize;\r
+ UINT16 DigestSize;\r
+\r
+ Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);\r
+ Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Event);\r
+ Cmd.PcrHandle = SwapBytes32 (PcrHandle);\r
\r
//\r
// Add in Auth session\r
Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
\r
// sessionInfoSize\r
- SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
- Buffer += SessionInfoSize;\r
- Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
+ SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
+ Buffer += SessionInfoSize;\r
+ Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);\r
\r
// Event\r
- WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(EventData->size));\r
- Buffer += sizeof(UINT16);\r
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (EventData->size));\r
+ Buffer += sizeof (UINT16);\r
\r
CopyMem (Buffer, EventData->buffer, EventData->size);\r
Buffer += EventData->size;\r
- \r
+\r
CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
- Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
+ Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
\r
- ResultBufSize = sizeof(Res);\r
- Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
- if (EFI_ERROR(Status)) {\r
+ ResultBufSize = sizeof (Res);\r
+ Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
+ if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- if (ResultBufSize > sizeof(Res)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
+ if (ResultBufSize > sizeof (Res)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
return EFI_BUFFER_TOO_SMALL;\r
}\r
\r
//\r
// Validate response headers\r
//\r
- RespSize = SwapBytes32(Res.Header.paramSize);\r
- if (RespSize > sizeof(Res)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));\r
+ RespSize = SwapBytes32 (Res.Header.paramSize);\r
+ if (RespSize > sizeof (Res)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));\r
return EFI_BUFFER_TOO_SMALL;\r
}\r
\r
//\r
// Fail if command failed\r
//\r
- if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
+ if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
return EFI_DEVICE_ERROR;\r
}\r
\r
Buffer = (UINT8 *)&Res.Digests;\r
\r
Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));\r
- Buffer += sizeof(UINT32);\r
+ if (Digests->count > HASH_COUNT) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent - Digests->count error %x\n", Digests->count));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Buffer += sizeof (UINT32);\r
for (Index = 0; Index < Digests->count; Index++) {\r
Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
- Buffer += sizeof(UINT16);\r
- DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
+ Buffer += sizeof (UINT16);\r
+ DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
if (DigestSize == 0) {\r
- DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
+ DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
return EFI_DEVICE_ERROR;\r
}\r
- CopyMem(\r
+\r
+ CopyMem (\r
&Digests->digests[Index].digest,\r
Buffer,\r
DigestSize\r
@param[out] PcrUpdateCounter The current value of the PCR update counter.\r
@param[out] PcrSelectionOut The PCR in the returned list.\r
@param[out] PcrValues The contents of the PCR indicated in pcrSelect.\r
- \r
+\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_DEVICE_ERROR The command was unsuccessful.\r
**/\r
EFI_STATUS\r
EFIAPI\r
Tpm2PcrRead (\r
- IN TPML_PCR_SELECTION *PcrSelectionIn,\r
- OUT UINT32 *PcrUpdateCounter,\r
- OUT TPML_PCR_SELECTION *PcrSelectionOut,\r
- OUT TPML_DIGEST *PcrValues\r
+ IN TPML_PCR_SELECTION *PcrSelectionIn,\r
+ OUT UINT32 *PcrUpdateCounter,\r
+ OUT TPML_PCR_SELECTION *PcrSelectionOut,\r
+ OUT TPML_DIGEST *PcrValues\r
)\r
{\r
- EFI_STATUS Status;\r
- TPM2_PCR_READ_COMMAND SendBuffer;\r
- TPM2_PCR_READ_RESPONSE RecvBuffer;\r
- UINT32 SendBufferSize;\r
- UINT32 RecvBufferSize;\r
- UINTN Index;\r
- TPML_DIGEST *PcrValuesOut;\r
- TPM2B_DIGEST *Digests;\r
+ EFI_STATUS Status;\r
+ TPM2_PCR_READ_COMMAND SendBuffer;\r
+ TPM2_PCR_READ_RESPONSE RecvBuffer;\r
+ UINT32 SendBufferSize;\r
+ UINT32 RecvBufferSize;\r
+ UINTN Index;\r
+ TPML_DIGEST *PcrValuesOut;\r
+ TPM2B_DIGEST *Digests;\r
\r
//\r
// Construct command\r
//\r
- SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
- SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PCR_Read);\r
- \r
- SendBuffer.PcrSelectionIn.count = SwapBytes32(PcrSelectionIn->count);\r
+ SendBuffer.Header.tag = SwapBytes16 (TPM_ST_NO_SESSIONS);\r
+ SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Read);\r
+\r
+ SendBuffer.PcrSelectionIn.count = SwapBytes32 (PcrSelectionIn->count);\r
for (Index = 0; Index < PcrSelectionIn->count; Index++) {\r
- SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16(PcrSelectionIn->pcrSelections[Index].hash);\r
+ SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16 (PcrSelectionIn->pcrSelections[Index].hash);\r
SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;\r
CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);\r
}\r
\r
- SendBufferSize = sizeof(SendBuffer.Header) + sizeof(SendBuffer.PcrSelectionIn.count) + sizeof(SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;\r
+ SendBufferSize = sizeof (SendBuffer.Header) + sizeof (SendBuffer.PcrSelectionIn.count) + sizeof (SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;\r
SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
\r
//\r
// send Tpm command\r
//\r
RecvBufferSize = sizeof (RecvBuffer);\r
- Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
return EFI_DEVICE_ERROR;\r
}\r
- if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
+\r
+ if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));\r
return EFI_NOT_FOUND;\r
}\r
\r
//\r
// PcrUpdateCounter\r
//\r
- if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
return EFI_DEVICE_ERROR;\r
}\r
- *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);\r
+\r
+ *PcrUpdateCounter = SwapBytes32 (RecvBuffer.PcrUpdateCounter);\r
\r
//\r
// PcrSelectionOut\r
//\r
- if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
return EFI_DEVICE_ERROR;\r
}\r
- PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);\r
- if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+\r
+ PcrSelectionOut->count = SwapBytes32 (RecvBuffer.PcrSelectionOut.count);\r
+ if (PcrSelectionOut->count > HASH_COUNT) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));\r
return EFI_DEVICE_ERROR;\r
}\r
+\r
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
for (Index = 0; Index < PcrSelectionOut->count; Index++) {\r
- PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16(RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);\r
+ PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16 (RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);\r
PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;\r
+ if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);\r
}\r
\r
//\r
// PcrValues\r
//\r
- PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);\r
- PcrValues->count = SwapBytes32(PcrValuesOut->count);\r
+ PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);\r
+ PcrValues->count = SwapBytes32 (PcrValuesOut->count);\r
+ //\r
+ // The number of digests in list is not greater than 8 per TPML_DIGEST definition\r
+ //\r
+ if (PcrValues->count > 8) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues->count));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
Digests = PcrValuesOut->digests;\r
for (Index = 0; Index < PcrValues->count; Index++) {\r
- PcrValues->digests[Index].size = SwapBytes16(Digests->size);\r
+ PcrValues->digests[Index].size = SwapBytes16 (Digests->size);\r
+ if (PcrValues->digests[Index].size > sizeof (TPMU_HA)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);\r
- Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof(Digests->size) + PcrValues->digests[Index].size);\r
+ Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof (Digests->size) + PcrValues->digests[Index].size);\r
}\r
\r
return EFI_SUCCESS;\r
@param[out] MaxPCR maximum number of PCR that may be in a bank\r
@param[out] SizeNeeded number of octets required to satisfy the request\r
@param[out] SizeAvailable Number of octets available. Computed before the allocation\r
- \r
+\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_DEVICE_ERROR The command was unsuccessful.\r
**/\r
EFI_STATUS\r
EFIAPI\r
Tpm2PcrAllocate (\r
- IN TPMI_RH_PLATFORM AuthHandle,\r
- IN TPMS_AUTH_COMMAND *AuthSession,\r
- IN TPML_PCR_SELECTION *PcrAllocation,\r
- OUT TPMI_YES_NO *AllocationSuccess,\r
- OUT UINT32 *MaxPCR,\r
- OUT UINT32 *SizeNeeded,\r
- OUT UINT32 *SizeAvailable\r
+ IN TPMI_RH_PLATFORM AuthHandle,\r
+ IN TPMS_AUTH_COMMAND *AuthSession,\r
+ IN TPML_PCR_SELECTION *PcrAllocation,\r
+ OUT TPMI_YES_NO *AllocationSuccess,\r
+ OUT UINT32 *MaxPCR,\r
+ OUT UINT32 *SizeNeeded,\r
+ OUT UINT32 *SizeAvailable\r
)\r
{\r
EFI_STATUS Status;\r
//\r
// Construct command\r
//\r
- Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
- Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));\r
- Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Allocate);\r
- Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
+ Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);\r
+ Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));\r
+ Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Allocate);\r
+ Cmd.AuthHandle = SwapBytes32 (AuthHandle);\r
\r
//\r
// Add in Auth session\r
Buffer = (UINT8 *)&Cmd.AuthSession;\r
\r
// sessionInfoSize\r
- SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
- Buffer += SessionInfoSize;\r
- Cmd.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
+ Buffer += SessionInfoSize;\r
+ Cmd.AuthSessionSize = SwapBytes32 (SessionInfoSize);\r
\r
// Count\r
- WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(PcrAllocation->count));\r
- Buffer += sizeof(UINT32);\r
+ WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (PcrAllocation->count));\r
+ Buffer += sizeof (UINT32);\r
for (Index = 0; Index < PcrAllocation->count; Index++) {\r
- WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PcrAllocation->pcrSelections[Index].hash));\r
- Buffer += sizeof(UINT16);\r
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (PcrAllocation->pcrSelections[Index].hash));\r
+ Buffer += sizeof (UINT16);\r
*(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;\r
Buffer++;\r
CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);\r
Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;\r
}\r
\r
- CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
- Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
+ Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
\r
- ResultBuf = (UINT8 *) &Res;\r
- ResultBufSize = sizeof(Res);\r
+ ResultBuf = (UINT8 *)&Res;\r
+ ResultBufSize = sizeof (Res);\r
\r
//\r
// Call the TPM\r
//\r
Status = Tpm2SubmitCommand (\r
- CmdSize, \r
- (UINT8 *)&Cmd, \r
+ CmdSize,\r
+ (UINT8 *)&Cmd,\r
&ResultBufSize,\r
ResultBuf\r
);\r
- if (EFI_ERROR(Status)) {\r
+ if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- if (ResultBufSize > sizeof(Res)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
+ if (ResultBufSize > sizeof (Res)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
Status = EFI_BUFFER_TOO_SMALL;\r
goto Done;\r
}\r
//\r
// Validate response headers\r
//\r
- RespSize = SwapBytes32(Res.Header.paramSize);\r
- if (RespSize > sizeof(Res)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));\r
+ RespSize = SwapBytes32 (Res.Header.paramSize);\r
+ if (RespSize > sizeof (Res)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));\r
Status = EFI_BUFFER_TOO_SMALL;\r
goto Done;\r
}\r
//\r
// Fail if command failed\r
//\r
- if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
- DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
+ if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
Status = EFI_DEVICE_ERROR;\r
goto Done;\r
}\r
// Return the response\r
//\r
*AllocationSuccess = Res.AllocationSuccess;\r
- *MaxPCR = SwapBytes32(Res.MaxPCR);\r
- *SizeNeeded = SwapBytes32(Res.SizeNeeded);\r
- *SizeAvailable = SwapBytes32(Res.SizeAvailable);\r
+ *MaxPCR = SwapBytes32 (Res.MaxPCR);\r
+ *SizeNeeded = SwapBytes32 (Res.SizeNeeded);\r
+ *SizeAvailable = SwapBytes32 (Res.SizeAvailable);\r
\r
Done:\r
//\r
// Clear AuthSession Content\r
//\r
- ZeroMem (&Cmd, sizeof(Cmd));\r
- ZeroMem (&Res, sizeof(Res));\r
+ ZeroMem (&Cmd, sizeof (Cmd));\r
+ ZeroMem (&Res, sizeof (Res));\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Alloc PCR data.\r
+\r
+ @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
+ @param[in] SupportedPCRBanks Supported PCR banks\r
+ @param[in] PCRBanks PCR banks\r
+\r
+ @retval EFI_SUCCESS Operation completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrAllocateBanks (\r
+ IN TPM2B_AUTH *PlatformAuth OPTIONAL,\r
+ IN UINT32 SupportedPCRBanks,\r
+ IN UINT32 PCRBanks\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ TPMS_AUTH_COMMAND *AuthSession;\r
+ TPMS_AUTH_COMMAND LocalAuthSession;\r
+ TPML_PCR_SELECTION PcrAllocation;\r
+ TPMI_YES_NO AllocationSuccess;\r
+ UINT32 MaxPCR;\r
+ UINT32 SizeNeeded;\r
+ UINT32 SizeAvailable;\r
+\r
+ if (PlatformAuth == NULL) {\r
+ AuthSession = NULL;\r
+ } else {\r
+ AuthSession = &LocalAuthSession;\r
+ ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));\r
+ LocalAuthSession.sessionHandle = TPM_RS_PW;\r
+ LocalAuthSession.hmac.size = PlatformAuth->size;\r
+ CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
+ }\r
+\r
+ //\r
+ // Fill input\r
+ //\r
+ ZeroMem (&PcrAllocation, sizeof (PcrAllocation));\r
+ if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+ if ((HASH_ALG_SHA1 & PCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+ } else {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+ }\r
+\r
+ PcrAllocation.count++;\r
+ }\r
+\r
+ if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+ if ((HASH_ALG_SHA256 & PCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+ } else {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+ }\r
+\r
+ PcrAllocation.count++;\r
+ }\r
+\r
+ if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+ if ((HASH_ALG_SHA384 & PCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+ } else {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+ }\r
+\r
+ PcrAllocation.count++;\r
+ }\r
+\r
+ if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+ if ((HASH_ALG_SHA512 & PCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+ } else {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+ }\r
+\r
+ PcrAllocation.count++;\r
+ }\r
+\r
+ if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+ if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+ } else {\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+ PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+ }\r
+\r
+ PcrAllocation.count++;\r
+ }\r
+\r
+ Status = Tpm2PcrAllocate (\r
+ TPM_RH_PLATFORM,\r
+ AuthSession,\r
+ &PcrAllocation,\r
+ &AllocationSuccess,\r
+ &MaxPCR,\r
+ &SizeNeeded,\r
+ &SizeAvailable\r
+ );\r
+ DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));\r
+ DEBUG ((DEBUG_INFO, "MaxPCR - %08x\n", MaxPCR));\r
+ DEBUG ((DEBUG_INFO, "SizeNeeded - %08x\n", SizeNeeded));\r
+ DEBUG ((DEBUG_INFO, "SizeAvailable - %08x\n", SizeAvailable));\r
+\r
+Done:\r
+ ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));\r
return Status;\r
}\r
+\r
+/**\r
+ This function will query the TPM to determine which hashing algorithms and\r
+ get the digests of all active and supported PCR banks of a specific PCR register.\r
+\r
+ @param[in] PcrHandle The index of the PCR register to be read.\r
+ @param[out] HashList List of digests from PCR register being read.\r
+\r
+ @retval EFI_SUCCESS The Pcr was read successfully.\r
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrReadForActiveBank (\r
+ IN TPMI_DH_PCR PcrHandle,\r
+ OUT TPML_DIGEST *HashList\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ TPML_PCR_SELECTION Pcrs;\r
+ TPML_PCR_SELECTION PcrSelectionIn;\r
+ TPML_PCR_SELECTION PcrSelectionOut;\r
+ TPML_DIGEST PcrValues;\r
+ UINT32 PcrUpdateCounter;\r
+ UINT8 PcrIndex;\r
+ UINT32 TpmHashAlgorithmBitmap;\r
+ TPMI_ALG_HASH CurrentPcrBankHash;\r
+ UINT32 ActivePcrBanks;\r
+ UINT32 TcgRegistryHashAlg;\r
+ UINTN Index;\r
+ UINTN Index2;\r
+\r
+ PcrIndex = (UINT8)PcrHandle;\r
+\r
+ if ((PcrIndex < 0) ||\r
+ (PcrIndex >= IMPLEMENTATION_PCR))\r
+ {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ ZeroMem (&PcrSelectionIn, sizeof (PcrSelectionIn));\r
+ ZeroMem (&PcrUpdateCounter, sizeof (UINT32));\r
+ ZeroMem (&PcrSelectionOut, sizeof (PcrSelectionOut));\r
+ ZeroMem (&PcrValues, sizeof (PcrValues));\r
+ ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION));\r
+\r
+ DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));\r
+\r
+ //\r
+ // Read TPM capabilities\r
+ //\r
+ Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities\n"));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Get Active Pcrs\r
+ //\r
+ Status = Tpm2GetCapabilitySupportedAndActivePcrs (\r
+ &TpmHashAlgorithmBitmap,\r
+ &ActivePcrBanks\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities and active PCRs\n"));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Select from Active PCRs\r
+ //\r
+ for (Index = 0; Index < Pcrs.count; Index++) {\r
+ CurrentPcrBankHash = Pcrs.pcrSelections[Index].hash;\r
+\r
+ switch (CurrentPcrBankHash) {\r
+ case TPM_ALG_SHA1:\r
+ DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA1 Present\n"));\r
+ TcgRegistryHashAlg = HASH_ALG_SHA1;\r
+ break;\r
+ case TPM_ALG_SHA256:\r
+ DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA256 Present\n"));\r
+ TcgRegistryHashAlg = HASH_ALG_SHA256;\r
+ break;\r
+ case TPM_ALG_SHA384:\r
+ DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA384 Present\n"));\r
+ TcgRegistryHashAlg = HASH_ALG_SHA384;\r
+ break;\r
+ case TPM_ALG_SHA512:\r
+ DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA512 Present\n"));\r
+ TcgRegistryHashAlg = HASH_ALG_SHA512;\r
+ break;\r
+ case TPM_ALG_SM3_256:\r
+ DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SM3 Present\n"));\r
+ TcgRegistryHashAlg = HASH_ALG_SM3_256;\r
+ break;\r
+ default:\r
+ //\r
+ // Unsupported algorithm\r
+ //\r
+ DEBUG ((DEBUG_VERBOSE, "Unknown algorithm present\n"));\r
+ TcgRegistryHashAlg = 0;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Skip unsupported and inactive PCR banks\r
+ //\r
+ if ((TcgRegistryHashAlg & ActivePcrBanks) == 0) {\r
+ DEBUG ((DEBUG_VERBOSE, "Skipping unsupported or inactive bank: 0x%04x\n", CurrentPcrBankHash));\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Select PCR from current active bank\r
+ //\r
+ PcrSelectionIn.pcrSelections[PcrSelectionIn.count].hash = Pcrs.pcrSelections[Index].hash;\r
+ PcrSelectionIn.pcrSelections[PcrSelectionIn.count].sizeofSelect = PCR_SELECT_MAX;\r
+ PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[0] = (PcrIndex < 8) ? 1 << PcrIndex : 0;\r
+ PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[1] = (PcrIndex > 7) && (PcrIndex < 16) ? 1 << (PcrIndex - 8) : 0;\r
+ PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[2] = (PcrIndex > 15) ? 1 << (PcrIndex - 16) : 0;\r
+ PcrSelectionIn.count++;\r
+ }\r
+\r
+ //\r
+ // Read PCRs\r
+ //\r
+ Status = Tpm2PcrRead (\r
+ &PcrSelectionIn,\r
+ &PcrUpdateCounter,\r
+ &PcrSelectionOut,\r
+ &PcrValues\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Tpm2PcrRead failed Status = %r \n", Status));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ for (Index = 0; Index < PcrValues.count; Index++) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",\r
+ PcrSelectionOut.pcrSelections[Index].hash,\r
+ PcrIndex\r
+ ));\r
+\r
+ for (Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {\r
+ DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "\n"));\r
+ }\r
+\r
+ if (HashList != NULL) {\r
+ CopyMem (\r
+ HashList,\r
+ &PcrValues,\r
+ sizeof (TPML_DIGEST)\r
+ );\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r