/** @file\r
Implement TPM2 Integrity related command.\r
\r
-Copyright (c) 2013, 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 - 2018, Intel Corporation. All rights reserved. <BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\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
+\r
//Digest Count\r
WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Digests->count));\r
Buffer += sizeof(UINT32);\r
- \r
+\r
//Digest\r
for (Index = 0; Index < Digests->count; Index++) {\r
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Digests->digests[Index].hashAlg));\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
\r
Buffer = (UINT8 *)&Res.Digests;\r
\r
Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));\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
@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
//\r
SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PCR_Read);\r
- \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
return EFI_DEVICE_ERROR;\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 ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
return EFI_DEVICE_ERROR;\r
for (Index = 0; Index < PcrSelectionOut->count; Index++) {\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
CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);\r
}\r
\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
+ //\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
Digests = PcrValuesOut->digests;\r
for (Index = 0; Index < PcrValues->count; Index++) {\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
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
}\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
WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PcrAllocation->pcrSelections[Index].hash));\r
Buffer += sizeof(UINT16);\r
*(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;\r
- Buffer += sizeof(UINT8);\r
+ Buffer++;\r
CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);\r
Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;\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
+ goto Done;\r
+ }\r
\r
if (ResultBufSize > sizeof(Res)) {\r
DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
- return EFI_BUFFER_TOO_SMALL;\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ goto Done;\r
}\r
\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
- return EFI_BUFFER_TOO_SMALL;\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ goto Done;\r
}\r
\r
//\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
- return EFI_DEVICE_ERROR;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
}\r
\r
//\r
*SizeNeeded = SwapBytes32(Res.SizeNeeded);\r
*SizeAvailable = SwapBytes32(Res.SizeAvailable);\r
\r
- return EFI_SUCCESS;\r
+Done:\r
+ //\r
+ // Clear AuthSession Content\r
+ //\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
+ PcrAllocation.count++;\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
+ PcrAllocation.count++;\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
+ PcrAllocation.count++;\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
+ PcrAllocation.count++;\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
+ PcrAllocation.count++;\r
+ }\r
+ Status = Tpm2PcrAllocate (\r
+ TPM_RH_PLATFORM,\r
+ AuthSession,\r
+ &PcrAllocation,\r
+ &AllocationSuccess,\r
+ &MaxPCR,\r
+ &SizeNeeded,\r
+ &SizeAvailable\r
+ );\r
+ DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));\r
+ DEBUG ((EFI_D_INFO, "MaxPCR - %08x\n", MaxPCR));\r
+ DEBUG ((EFI_D_INFO, "SizeNeeded - %08x\n", SizeNeeded));\r
+ DEBUG ((EFI_D_INFO, "SizeAvailable - %08x\n", SizeAvailable));\r
+\r
+Done:\r
+ ZeroMem(&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));\r
+ return Status;\r
}\r