]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
SecurityPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Integrity.c
index 88dcc0afe221ba172d8a3a57809dbb67e31f9056..ddb15178fb6a5e434c71d5623b4f2978b2372c47 100644 (file)
@@ -1,14 +1,8 @@
 /** @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
@@ -120,16 +114,16 @@ Tpm2PcrExtend (
   // 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
@@ -241,7 +235,7 @@ Tpm2PcrEvent (
 \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
@@ -279,6 +273,11 @@ Tpm2PcrEvent (
   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
@@ -306,7 +305,7 @@ Tpm2PcrEvent (
   @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
@@ -333,7 +332,7 @@ Tpm2PcrRead (
   //\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
@@ -383,6 +382,11 @@ Tpm2PcrRead (
     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
@@ -390,6 +394,9 @@ Tpm2PcrRead (
   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
@@ -398,9 +405,20 @@ Tpm2PcrRead (
   //\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
@@ -418,7 +436,7 @@ Tpm2PcrRead (
   @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
@@ -470,7 +488,7 @@ Tpm2PcrAllocate (
     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
@@ -485,15 +503,19 @@ Tpm2PcrAllocate (
   // 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
@@ -502,7 +524,8 @@ Tpm2PcrAllocate (
   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
@@ -510,7 +533,8 @@ Tpm2PcrAllocate (
   //\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
@@ -521,5 +545,145 @@ Tpm2PcrAllocate (
   *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