]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
Add TPM2 implementation.
[mirror_edk2.git] / SecurityPkg / Library / HashLibBaseCryptoRouter / HashLibBaseCryptoRouterDxe.c
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
new file mode 100644 (file)
index 0000000..8e93335
--- /dev/null
@@ -0,0 +1,221 @@
+/** @file\r
+  Ihis library is BaseCrypto router. It will redirect hash request to each individual\r
+  hash handler registerd, such as SHA1, SHA256.\r
+  Platform can use PcdTpm2HashMask to mask some hash engines.\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
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/HashLib.h>\r
+\r
+#include "HashLibBaseCryptoRouterCommon.h"\r
+\r
+HASH_INTERFACE   mHashInterface[HASH_COUNT] = {0};\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
+  UINTN        Index;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = AllocatePool (sizeof(*HashCtx) * mHashInterfaceCount);\r
+  ASSERT (HashCtx != NULL);\r
+\r
+  for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
+    mHashInterface[Index].HashInit (&HashCtx[Index]);\r
+  }\r
+\r
+  *HashHandle = (HASH_HANDLE)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
+  HASH_HANDLE  *HashCtx;\r
+  UINTN        Index;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = (HASH_HANDLE *)HashHandle;\r
+\r
+  for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
+    mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+  }\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
+  HASH_HANDLE        *HashCtx;\r
+  UINTN              Index;\r
+  EFI_STATUS         Status;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = (HASH_HANDLE *)HashHandle;\r
+  ZeroMem (DigestList, sizeof(*DigestList));\r
+\r
+  for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
+    mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+    mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);\r
+    Tpm2SetHashToDigestList (DigestList, &Digest);\r
+  }\r
+\r
+  FreePool (HashCtx);\r
+\r
+  Status = Tpm2PcrExtend (\r
+             PcrIndex,\r
+             DigestList\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Hash data and extend to PCR.\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
+    return EFI_UNSUPPORTED;\r
+  }\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
+  UINTN              Index;\r
+  UINT32             HashMask;\r
+\r
+  //\r
+  // Check allow\r
+  //\r
+  HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);\r
+  if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Check duplication\r
+  //\r
+  for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
+    if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) {\r
+      return EFI_ALREADY_STARTED;\r
+    }\r
+  }\r
+\r
+  CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface));\r
+  mHashInterfaceCount ++;\r
+  \r
+  return EFI_SUCCESS;\r
+}
\ No newline at end of file