+/** @file\r
+ Implements the GetCryptoServices() API that retuns a pointer to the EDK II\r
+ SMM Crypto Protocol.\r
+\r
+ Copyright (C) Microsoft Corporation. All rights reserved.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiSmm.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/SmmServicesTableLib.h>\r
+#include <Protocol/SmmCrypto.h>\r
+\r
+EDKII_SMM_CRYPTO_PROTOCOL *mSmmCryptoProtocol = NULL;\r
+\r
+/**\r
+ Internal worker function that returns the pointer to an EDK II Crypto\r
+ Protocol/PPI. The layout of the PPI, DXE Protocol, and SMM Protocol are\r
+ identical which allows the implementation of the BaseCryptLib functions that\r
+ call through a Protocol/PPI to be shared for the PEI, DXE, and SMM\r
+ implementations.\r
+\r
+ This SMM implementation returns the pointer to the EDK II SMM Crypto Protocol\r
+ that was found in the library constructor SmmCryptLibConstructor().\r
+**/\r
+VOID *\r
+GetCryptoServices (\r
+ VOID\r
+ )\r
+{\r
+ return (VOID *)mSmmCryptoProtocol;\r
+}\r
+\r
+/**\r
+ Constructor looks up the EDK II SMM Crypto Protocol and verifies that it is\r
+ not NULL and has a high enough version value to support all the BaseCryptLib\r
+ functions.\r
+\r
+ @param ImageHandle The firmware allocated handle for the EFI image.\r
+ @param SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The EDK II SMM Crypto Protocol was found.\r
+ @retval EFI_NOT_FOUND The EDK II SMM Crypto Protocol was not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmCryptLibConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Version;\r
+\r
+ Status = gSmst->SmmLocateProtocol (\r
+ &gEdkiiSmmCryptoProtocolGuid,\r
+ NULL,\r
+ (VOID **)&mSmmCryptoProtocol\r
+ );\r
+ if (EFI_ERROR (Status) || mSmmCryptoProtocol == NULL) {\r
+ DEBUG((DEBUG_ERROR, "[SmmCryptLib] Failed to locate Crypto SMM Protocol. Status = %r\n", Status));\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (mSmmCryptoProtocol != NULL);\r
+ mSmmCryptoProtocol = NULL;\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Version = mSmmCryptoProtocol->GetVersion ();\r
+ if (Version < EDKII_CRYPTO_VERSION) {\r
+ DEBUG((DEBUG_ERROR, "[SmmCryptLib] Crypto SMM Protocol unsupported version %d\n", Version));\r
+ ASSERT (Version >= EDKII_CRYPTO_VERSION);\r
+ mSmmCryptoProtocol = NULL;\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r