]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/HashLibTdx/HashLibTdx.c
Security: Add HashLibTdx
[mirror_edk2.git] / SecurityPkg / Library / HashLibTdx / HashLibTdx.c
diff --git a/SecurityPkg/Library/HashLibTdx/HashLibTdx.c b/SecurityPkg/Library/HashLibTdx/HashLibTdx.c
new file mode 100644 (file)
index 0000000..75d96ee
--- /dev/null
@@ -0,0 +1,207 @@
+/** @file\r
+  This library is HashLib for Tdx.\r
+\r
+Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved. <BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/HashLib.h>\r
+#include <Library/TdxLib.h>\r
+#include <Protocol/CcMeasurement.h>\r
+\r
+EFI_GUID  mSha384Guid = HASH_ALGORITHM_SHA384_GUID;\r
+\r
+//\r
+// Currently TDX supports SHA384.\r
+//\r
+HASH_INTERFACE  mHashInterface =  {\r
+  { 0 }, NULL, NULL, NULL\r
+};\r
+\r
+UINTN  mHashInterfaceCount = 0;\r
+\r
+/**\r
+  Start hash sequence.\r
+\r
+  @param HashHandle Hash handle.\r
+\r
+  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.\r
+  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashStart (\r
+  OUT HASH_HANDLE  *HashHandle\r
+  )\r
+{\r
+  HASH_HANDLE  HashCtx;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    ASSERT (FALSE);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = 0;\r
+  mHashInterface.HashInit (&HashCtx);\r
+\r
+  *HashHandle = HashCtx;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update hash sequence data.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence updated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashUpdate (\r
+  IN HASH_HANDLE  HashHandle,\r
+  IN VOID         *DataToHash,\r
+  IN UINTN        DataToHashLen\r
+  )\r
+{\r
+  if (mHashInterfaceCount == 0) {\r
+    ASSERT (FALSE);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  mHashInterface.HashUpdate (HashHandle, DataToHash, DataToHashLen);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Hash sequence complete and extend to PCR.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashCompleteAndExtend (\r
+  IN HASH_HANDLE          HashHandle,\r
+  IN TPMI_DH_PCR          PcrIndex,\r
+  IN VOID                 *DataToHash,\r
+  IN UINTN                DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES  *DigestList\r
+  )\r
+{\r
+  TPML_DIGEST_VALUES  Digest;\r
+  EFI_STATUS          Status;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    ASSERT (FALSE);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ZeroMem (DigestList, sizeof (*DigestList));\r
+\r
+  mHashInterface.HashUpdate (HashHandle, DataToHash, DataToHashLen);\r
+  mHashInterface.HashFinal (HashHandle, &Digest);\r
+\r
+  CopyMem (\r
+    &DigestList->digests[0],\r
+    &Digest.digests[0],\r
+    sizeof (Digest.digests[0])\r
+    );\r
+  DigestList->count++;\r
+\r
+  ASSERT (DigestList->count == 1 && DigestList->digests[0].hashAlg == TPM_ALG_SHA384);\r
+\r
+  Status = TdExtendRtmr (\r
+             (UINT32 *)DigestList->digests[0].digest.sha384,\r
+             SHA384_DIGEST_SIZE,\r
+             (UINT8)PcrIndex\r
+             );\r
+\r
+  ASSERT (!EFI_ERROR (Status));\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Hash data and extend to RTMR.\r
+\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash data and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashAndExtend (\r
+  IN TPMI_DH_PCR          PcrIndex,\r
+  IN VOID                 *DataToHash,\r
+  IN UINTN                DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES  *DigestList\r
+  )\r
+{\r
+  HASH_HANDLE  HashHandle;\r
+  EFI_STATUS   Status;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    ASSERT (FALSE);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ASSERT (TdIsEnabled ());\r
+\r
+  HashStart (&HashHandle);\r
+  HashUpdate (HashHandle, DataToHash, DataToHashLen);\r
+  Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This service register Hash.\r
+\r
+  @param HashInterface  Hash interface\r
+\r
+  @retval EFI_SUCCESS          This hash interface is registered successfully.\r
+  @retval EFI_UNSUPPORTED      System does not support register this interface.\r
+  @retval EFI_ALREADY_STARTED  System already register this interface.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterHashInterfaceLib (\r
+  IN HASH_INTERFACE  *HashInterface\r
+  )\r
+{\r
+  ASSERT (TdIsEnabled ());\r
+\r
+  //\r
+  // Only SHA384 is allowed.\r
+  //\r
+  if (!CompareGuid (&mSha384Guid, &HashInterface->HashGuid)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (mHashInterfaceCount != 0) {\r
+    ASSERT (FALSE);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  CopyMem (&mHashInterface, HashInterface, sizeof (*HashInterface));\r
+  mHashInterfaceCount++;\r
+\r
+  return EFI_SUCCESS;\r
+}\r