\r
#pragma pack()\r
\r
+/**\r
+ Constructor for SmmLockBox library.\r
+ This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.\r
+\r
+ @retval EFI_SUCEESS\r
+ @return Others Some error occurs.\r
+**/\r
+EFI_STATUS\r
+SmmLockBoxMmConstructor (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Destructor for SmmLockBox library.\r
+ This is used to uninstall SmmLockBoxCommunication configuration table\r
+ if it has been installed in Constructor.\r
+\r
+ @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+SmmLockBoxMmDestructor (\r
+ VOID\r
+ );\r
+\r
#endif\r
\r
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiMm.h>\r
+#include <Library/MmServicesTableLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/LockBoxLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Guid/SmmLockBox.h>\r
+#include <Guid/EndOfS3Resume.h>\r
+#include <Protocol/MmReadyToLock.h>\r
+#include <Protocol/MmEndOfDxe.h>\r
+#include <Protocol/SmmSxDispatch2.h>\r
+\r
+#include "SmmLockBoxLibPrivate.h"\r
+\r
+/**\r
+ We need handle this library carefully. Only one library instance will construct the environment.\r
+ Below 2 global variable can only be used in constructor. They should NOT be used in any other library functions.\r
+**/\r
+SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext;\r
+LIST_ENTRY mLockBoxQueue = INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue);\r
+\r
+BOOLEAN mSmmConfigurationTableInstalled = FALSE;\r
+VOID *mSmmLockBoxRegistrationSmmEndOfDxe = NULL;\r
+VOID *mSmmLockBoxRegistrationSmmReadyToLock = NULL;\r
+VOID *mSmmLockBoxRegistrationEndOfS3Resume = NULL;\r
+BOOLEAN mSmmLockBoxSmmReadyToLock = FALSE;\r
+BOOLEAN mSmmLockBoxDuringS3Resume = FALSE;\r
+\r
+/**\r
+ This function return SmmLockBox context from SMST.\r
+\r
+ @return SmmLockBox context from SMST.\r
+**/\r
+SMM_LOCK_BOX_CONTEXT *\r
+InternalGetSmmLockBoxContext (\r
+ VOID\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ //\r
+ // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone\r
+ //\r
+ for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {\r
+ if (CompareGuid (&gMmst->MmConfigurationTable[Index].VendorGuid, &gEfiSmmLockBoxCommunicationGuid)) {\r
+ //\r
+ // Found. That means some other library instance is already run.\r
+ // No need to install again, just return.\r
+ //\r
+ return (SMM_LOCK_BOX_CONTEXT *)gMmst->MmConfigurationTable[Index].VendorTable;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Not found.\r
+ //\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Notification for SMM ReadyToLock protocol.\r
+\r
+ @param[in] Protocol Points to the protocol's unique identifier.\r
+ @param[in] Interface Points to the interface instance.\r
+ @param[in] Handle The handle on which the interface was installed.\r
+\r
+ @retval EFI_SUCCESS Notification runs successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLockBoxSmmReadyToLockNotify (\r
+ IN CONST EFI_GUID *Protocol,\r
+ IN VOID *Interface,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ mSmmLockBoxSmmReadyToLock = TRUE;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Main entry point for an SMM handler dispatch or communicate-based callback.\r
+\r
+ @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
+ @param[in] Context Points to an optional handler context which was specified when the\r
+ handler was registered.\r
+ @param[in,out] CommBuffer A pointer to a collection of data in memory that will\r
+ be conveyed from a non-SMM environment into an SMM environment.\r
+ @param[in,out] CommBufferSize The size of the CommBuffer.\r
+\r
+ @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers\r
+ should still be called.\r
+ @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should\r
+ still be called.\r
+ @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still\r
+ be called.\r
+ @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLockBoxS3EntryCallBack (\r
+ IN EFI_HANDLE DispatchHandle,\r
+ IN CONST VOID *Context OPTIONAL,\r
+ IN OUT VOID *CommBuffer OPTIONAL,\r
+ IN OUT UINTN *CommBufferSize OPTIONAL\r
+ )\r
+{\r
+ mSmmLockBoxDuringS3Resume = TRUE;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Notification for SMM EndOfDxe protocol.\r
+\r
+ @param[in] Protocol Points to the protocol's unique identifier.\r
+ @param[in] Interface Points to the interface instance.\r
+ @param[in] Handle The handle on which the interface was installed.\r
+\r
+ @retval EFI_SUCCESS Notification runs successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLockBoxSmmEndOfDxeNotify (\r
+ IN CONST EFI_GUID *Protocol,\r
+ IN VOID *Interface,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatch;\r
+ EFI_SMM_SX_REGISTER_CONTEXT EntryRegisterContext;\r
+ EFI_HANDLE S3EntryHandle;\r
+\r
+ //\r
+ // Locate SmmSxDispatch2 protocol.\r
+ //\r
+ Status = gMmst->MmLocateProtocol (\r
+ &gEfiMmSxDispatchProtocolGuid,\r
+ NULL,\r
+ (VOID **)&SxDispatch\r
+ );\r
+ if (!EFI_ERROR (Status) && (SxDispatch != NULL)) {\r
+ //\r
+ // Register a S3 entry callback function to\r
+ // determine if it will be during S3 resume.\r
+ //\r
+ EntryRegisterContext.Type = SxS3;\r
+ EntryRegisterContext.Phase = SxEntry;\r
+ Status = SxDispatch->Register (\r
+ SxDispatch,\r
+ SmmLockBoxS3EntryCallBack,\r
+ &EntryRegisterContext,\r
+ &S3EntryHandle\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Notification for SMM EndOfS3Resume protocol.\r
+\r
+ @param[in] Protocol Points to the protocol's unique identifier.\r
+ @param[in] Interface Points to the interface instance.\r
+ @param[in] Handle The handle on which the interface was installed.\r
+\r
+ @retval EFI_SUCCESS Notification runs successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLockBoxEndOfS3ResumeNotify (\r
+ IN CONST EFI_GUID *Protocol,\r
+ IN VOID *Interface,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ mSmmLockBoxDuringS3Resume = FALSE;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Constructor for SmmLockBox library.\r
+ This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.\r
+\r
+ @retval EFI_SUCEESS\r
+ @return Others Some error occurs.\r
+**/\r
+EFI_STATUS\r
+SmmLockBoxMmConstructor (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxMmConstructor - Enter\n"));\r
+\r
+ //\r
+ // Register SmmReadyToLock notification.\r
+ //\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEfiMmReadyToLockProtocolGuid,\r
+ SmmLockBoxSmmReadyToLockNotify,\r
+ &mSmmLockBoxRegistrationSmmReadyToLock\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Register SmmEndOfDxe notification.\r
+ //\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEfiMmEndOfDxeProtocolGuid,\r
+ SmmLockBoxSmmEndOfDxeNotify,\r
+ &mSmmLockBoxRegistrationSmmEndOfDxe\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Register EndOfS3Resume notification.\r
+ //\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEdkiiEndOfS3ResumeGuid,\r
+ SmmLockBoxEndOfS3ResumeNotify,\r
+ &mSmmLockBoxRegistrationEndOfS3Resume\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone\r
+ //\r
+ SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
+ if (SmmLockBoxContext != NULL) {\r
+ //\r
+ // Find it. That means some other library instance is already run.\r
+ // No need to install again, just return.\r
+ //\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - already installed\n"));\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxMmConstructor - Exit\n"));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // If no one install this, it means this is first instance. Install it.\r
+ //\r
+ if (sizeof(UINTN) == sizeof(UINT64)) {\r
+ mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_64;\r
+ } else {\r
+ mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_32;\r
+ }\r
+ mSmmLockBoxContext.LockBoxDataAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)&mLockBoxQueue;\r
+\r
+ Status = gMmst->MmInstallConfigurationTable (\r
+ gMmst,\r
+ &gEfiSmmLockBoxCommunicationGuid,\r
+ &mSmmLockBoxContext,\r
+ sizeof(mSmmLockBoxContext)\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ mSmmConfigurationTableInstalled = TRUE;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN)&mSmmLockBoxContext));\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN)&mLockBoxQueue));\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxMmConstructor - Exit\n"));\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Destructor for SmmLockBox library.\r
+ This is used to uninstall SmmLockBoxCommunication configuration table\r
+ if it has been installed in Constructor.\r
+\r
+ @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+SmmLockBoxMmDestructor (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxMmDestructor in %a module\n", gEfiCallerBaseName));\r
+\r
+ if (mSmmConfigurationTableInstalled) {\r
+ Status = gMmst->MmInstallConfigurationTable (\r
+ gMmst,\r
+ &gEfiSmmLockBoxCommunicationGuid,\r
+ NULL,\r
+ 0\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib uninstall SmmLockBoxCommunication configuration table\n"));\r
+ }\r
+\r
+ if (mSmmLockBoxRegistrationSmmReadyToLock != NULL) {\r
+ //\r
+ // Unregister SmmReadyToLock notification.\r
+ //\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEfiMmReadyToLockProtocolGuid,\r
+ NULL,\r
+ &mSmmLockBoxRegistrationSmmReadyToLock\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ if (mSmmLockBoxRegistrationSmmEndOfDxe != NULL) {\r
+ //\r
+ // Unregister SmmEndOfDxe notification.\r
+ //\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEfiMmEndOfDxeProtocolGuid,\r
+ NULL,\r
+ &mSmmLockBoxRegistrationSmmEndOfDxe\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ if (mSmmLockBoxRegistrationEndOfS3Resume != NULL) {\r
+ //\r
+ // Unregister EndOfS3Resume notification.\r
+ //\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEdkiiEndOfS3ResumeGuid,\r
+ NULL,\r
+ &mSmmLockBoxRegistrationEndOfS3Resume\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function return SmmLockBox queue address.\r
+\r
+ @return SmmLockBox queue address.\r
+**/\r
+LIST_ENTRY *\r
+InternalGetLockBoxQueue (\r
+ VOID\r
+ )\r
+{\r
+ SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
+\r
+ SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
+ ASSERT (SmmLockBoxContext != NULL);\r
+ if (SmmLockBoxContext == NULL) {\r
+ return NULL;\r
+ }\r
+ return (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;\r
+}\r
+\r
+/**\r
+ This function find LockBox by GUID.\r
+\r
+ @param Guid The guid to indentify the LockBox\r
+\r
+ @return LockBoxData\r
+**/\r
+SMM_LOCK_BOX_DATA *\r
+InternalFindLockBoxByGuid (\r
+ IN EFI_GUID *Guid\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ SMM_LOCK_BOX_DATA *LockBox;\r
+ LIST_ENTRY *LockBoxQueue;\r
+\r
+ LockBoxQueue = InternalGetLockBoxQueue ();\r
+ ASSERT (LockBoxQueue != NULL);\r
+\r
+ for (Link = LockBoxQueue->ForwardLink;\r
+ Link != LockBoxQueue;\r
+ Link = Link->ForwardLink) {\r
+ LockBox = BASE_CR (\r
+ Link,\r
+ SMM_LOCK_BOX_DATA,\r
+ Link\r
+ );\r
+ if (CompareGuid (&LockBox->Guid, Guid)) {\r
+ return LockBox;\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ This function will save confidential information to lockbox.\r
+\r
+ @param Guid the guid to identify the confidential information\r
+ @param Buffer the address of the confidential information\r
+ @param Length the length of the confidential information\r
+\r
+ @retval RETURN_SUCCESS the information is saved successfully.\r
+ @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0\r
+ @retval RETURN_ALREADY_STARTED the requested GUID already exist.\r
+ @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.\r
+ @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
+ @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SaveLockBox (\r
+ IN GUID *Guid,\r
+ IN VOID *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ SMM_LOCK_BOX_DATA *LockBox;\r
+ EFI_PHYSICAL_ADDRESS SmramBuffer;\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *LockBoxQueue;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));\r
+\r
+ //\r
+ // Basic check\r
+ //\r
+ if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Find LockBox\r
+ //\r
+ LockBox = InternalFindLockBoxByGuid (Guid);\r
+ if (LockBox != NULL) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED));\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ //\r
+ // Allocate SMRAM buffer\r
+ //\r
+ Status = gMmst->MmAllocatePages (\r
+ AllocateAnyPages,\r
+ EfiRuntimeServicesData,\r
+ EFI_SIZE_TO_PAGES (Length),\r
+ &SmramBuffer\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Allocate LockBox\r
+ //\r
+ Status = gMmst->MmAllocatePool (\r
+ EfiRuntimeServicesData,\r
+ sizeof(*LockBox),\r
+ (VOID **)&LockBox\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ gMmst->MmFreePages (SmramBuffer, EFI_SIZE_TO_PAGES (Length));\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Save data\r
+ //\r
+ CopyMem ((VOID *)(UINTN)SmramBuffer, (VOID *)(UINTN)Buffer, Length);\r
+\r
+ //\r
+ // Insert LockBox to queue\r
+ //\r
+ LockBox->Signature = SMM_LOCK_BOX_DATA_SIGNATURE;\r
+ CopyMem (&LockBox->Guid, Guid, sizeof(EFI_GUID));\r
+ LockBox->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
+ LockBox->Length = (UINT64)Length;\r
+ LockBox->Attributes = 0;\r
+ LockBox->SmramBuffer = SmramBuffer;\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "LockBoxGuid - %g, SmramBuffer - 0x%lx, Length - 0x%lx\n",\r
+ &LockBox->Guid,\r
+ LockBox->SmramBuffer,\r
+ LockBox->Length\r
+ ));\r
+\r
+ LockBoxQueue = InternalGetLockBoxQueue ();\r
+ ASSERT (LockBoxQueue != NULL);\r
+ InsertTailList (LockBoxQueue, &LockBox->Link);\r
+\r
+ //\r
+ // Done\r
+ //\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function will set lockbox attributes.\r
+\r
+ @param Guid the guid to identify the confidential information\r
+ @param Attributes the attributes of the lockbox\r
+\r
+ @retval RETURN_SUCCESS the information is saved successfully.\r
+ @retval RETURN_INVALID_PARAMETER attributes is invalid.\r
+ @retval RETURN_NOT_FOUND the requested GUID not found.\r
+ @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
+ @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SetLockBoxAttributes (\r
+ IN GUID *Guid,\r
+ IN UINT64 Attributes\r
+ )\r
+{\r
+ SMM_LOCK_BOX_DATA *LockBox;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));\r
+\r
+ //\r
+ // Basic check\r
+ //\r
+ if ((Guid == NULL) ||\r
+ ((Attributes & ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE | LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY)) != 0)) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&\r
+ ((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0)) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
+ DEBUG ((DEBUG_INFO, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));\r
+ DEBUG ((DEBUG_INFO, " can not be set together\n"));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Find LockBox\r
+ //\r
+ LockBox = InternalFindLockBoxByGuid (Guid);\r
+ if (LockBox == NULL) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if ((((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&\r
+ ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0)) ||\r
+ (((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&\r
+ ((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0))) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes 0x%lx 0x%lx - Exit (%r)\n", LockBox->Attributes, Attributes, EFI_INVALID_PARAMETER));\r
+ DEBUG ((DEBUG_INFO, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));\r
+ DEBUG ((DEBUG_INFO, " can not be set together\n"));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Update data\r
+ //\r
+ LockBox->Attributes = Attributes;\r
+\r
+ //\r
+ // Done\r
+ //\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function will update confidential information to lockbox.\r
+\r
+ @param Guid the guid to identify the original confidential information\r
+ @param Offset the offset of the original confidential information\r
+ @param Buffer the address of the updated confidential information\r
+ @param Length the length of the updated confidential information\r
+\r
+ @retval RETURN_SUCCESS the information is saved successfully.\r
+ @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.\r
+ @retval RETURN_NOT_FOUND the requested GUID not found.\r
+ @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,\r
+ the original buffer to too small to hold new information.\r
+ @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,\r
+ no enough resource to save the information.\r
+ @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
+ @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+UpdateLockBox (\r
+ IN GUID *Guid,\r
+ IN UINTN Offset,\r
+ IN VOID *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ SMM_LOCK_BOX_DATA *LockBox;\r
+ EFI_PHYSICAL_ADDRESS SmramBuffer;\r
+ EFI_STATUS Status;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));\r
+\r
+ //\r
+ // Basic check\r
+ //\r
+ if ((Guid == NULL) || (Buffer == NULL) || (Length == 0) ||\r
+ (Length > MAX_UINTN - Offset)) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Find LockBox\r
+ //\r
+ LockBox = InternalFindLockBoxByGuid (Guid);\r
+ if (LockBox == NULL) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_NOT_FOUND));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Update data\r
+ //\r
+ if (LockBox->Length < Offset + Length) {\r
+ if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0) {\r
+ //\r
+ // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is set, enlarge the\r
+ // LockBox.\r
+ //\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "SmmLockBoxSmmLib UpdateLockBox - Origin LockBox too small, enlarge.\n"\r
+ ));\r
+\r
+ if (EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ((UINTN)LockBox->Length)) < Offset + Length) {\r
+ //\r
+ // In SaveLockBox(), the SMRAM buffer allocated for LockBox is of page\r
+ // granularity. Here, if the required size is larger than the origin size\r
+ // of the pages, allocate new buffer from SMRAM to enlarge the LockBox.\r
+ //\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "SmmLockBoxSmmLib UpdateLockBox - Allocate new buffer to enlarge.\n"\r
+ ));\r
+ Status = gMmst->MmAllocatePages (\r
+ AllocateAnyPages,\r
+ EfiRuntimeServicesData,\r
+ EFI_SIZE_TO_PAGES (Offset + Length),\r
+ &SmramBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Copy origin data to the new SMRAM buffer and wipe the content in the\r
+ // origin SMRAM buffer.\r
+ //\r
+ CopyMem ((VOID *)(UINTN)SmramBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
+ ZeroMem ((VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
+ gMmst->MmFreePages (LockBox->SmramBuffer, EFI_SIZE_TO_PAGES ((UINTN)LockBox->Length));\r
+\r
+ LockBox->SmramBuffer = SmramBuffer;\r
+ }\r
+\r
+ //\r
+ // Handle uninitialized content in the LockBox.\r
+ //\r
+ if (Offset > LockBox->Length) {\r
+ ZeroMem (\r
+ (VOID *)((UINTN)LockBox->SmramBuffer + (UINTN)LockBox->Length),\r
+ Offset - (UINTN)LockBox->Length\r
+ );\r
+ }\r
+ LockBox->Length = Offset + Length;\r
+ } else {\r
+ //\r
+ // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is NOT set, return\r
+ // EFI_BUFFER_TOO_SMALL directly.\r
+ //\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+ }\r
+ ASSERT ((UINTN)LockBox->SmramBuffer <= (MAX_ADDRESS - Offset));\r
+ CopyMem ((VOID *)((UINTN)LockBox->SmramBuffer + Offset), Buffer, Length);\r
+\r
+ //\r
+ // Done\r
+ //\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function will restore confidential information from lockbox.\r
+\r
+ @param Guid the guid to identify the confidential information\r
+ @param Buffer the address of the restored confidential information\r
+ NULL means restored to original address, Length MUST be NULL at same time.\r
+ @param Length the length of the restored confidential information\r
+\r
+ @retval RETURN_SUCCESS the information is restored successfully.\r
+ @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.\r
+ @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no\r
+ LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.\r
+ @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.\r
+ @retval RETURN_NOT_FOUND the requested GUID not found.\r
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
+ @retval RETURN_ACCESS_DENIED not allow to restore to the address\r
+ @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+RestoreLockBox (\r
+ IN GUID *Guid,\r
+ IN VOID *Buffer, OPTIONAL\r
+ IN OUT UINTN *Length OPTIONAL\r
+ )\r
+{\r
+ SMM_LOCK_BOX_DATA *LockBox;\r
+ VOID *RestoreBuffer;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));\r
+\r
+ //\r
+ // Restore this, Buffer and Length MUST be both NULL or both non-NULL\r
+ //\r
+ if ((Guid == NULL) ||\r
+ ((Buffer == NULL) && (Length != NULL)) ||\r
+ ((Buffer != NULL) && (Length == NULL))) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Find LockBox\r
+ //\r
+ LockBox = InternalFindLockBoxByGuid (Guid);\r
+ if (LockBox == NULL) {\r
+ //\r
+ // Not found\r
+ //\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0) &&\r
+ mSmmLockBoxSmmReadyToLock &&\r
+ !mSmmLockBoxDuringS3Resume) {\r
+ //\r
+ // With LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,\r
+ // this LockBox can be restored in S3 resume only.\r
+ //\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ //\r
+ // Set RestoreBuffer\r
+ //\r
+ if (Buffer != NULL) {\r
+ //\r
+ // restore to new buffer\r
+ //\r
+ RestoreBuffer = Buffer;\r
+ } else {\r
+ //\r
+ // restore to original buffer\r
+ //\r
+ if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED));\r
+ return EFI_WRITE_PROTECTED;\r
+ }\r
+ RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;\r
+ }\r
+\r
+ //\r
+ // Set RestoreLength\r
+ //\r
+ if (Length != NULL) {\r
+ if (*Length < (UINTN)LockBox->Length) {\r
+ //\r
+ // Input buffer is too small to hold all data.\r
+ //\r
+ *Length = (UINTN)LockBox->Length;\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+ *Length = (UINTN)LockBox->Length;\r
+ }\r
+\r
+ //\r
+ // Restore data\r
+ //\r
+ CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
+\r
+ //\r
+ // Done\r
+ //\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function will restore confidential information from all lockbox which have RestoreInPlace attribute.\r
+\r
+ @retval RETURN_SUCCESS the information is restored successfully.\r
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
+ @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+RestoreAllLockBoxInPlace (\r
+ VOID\r
+ )\r
+{\r
+ SMM_LOCK_BOX_DATA *LockBox;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *LockBoxQueue;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));\r
+\r
+ LockBoxQueue = InternalGetLockBoxQueue ();\r
+ ASSERT (LockBoxQueue != NULL);\r
+\r
+ //\r
+ // Restore all, Buffer and Length MUST be NULL\r
+ //\r
+ for (Link = LockBoxQueue->ForwardLink;\r
+ Link != LockBoxQueue;\r
+ Link = Link->ForwardLink) {\r
+ LockBox = BASE_CR (\r
+ Link,\r
+ SMM_LOCK_BOX_DATA,\r
+ Link\r
+ );\r
+ if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) {\r
+ //\r
+ // Restore data\r
+ //\r
+ CopyMem ((VOID *)(UINTN)LockBox->Buffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
+ }\r
+ }\r
+ //\r
+ // Done\r
+ //\r
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+++ /dev/null
-/** @file\r
-\r
-Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <PiSmm.h>\r
-#include <Library/SmmServicesTableLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/LockBoxLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Guid/SmmLockBox.h>\r
-#include <Guid/EndOfS3Resume.h>\r
-#include <Protocol/SmmReadyToLock.h>\r
-#include <Protocol/SmmEndOfDxe.h>\r
-#include <Protocol/SmmSxDispatch2.h>\r
-\r
-#include "SmmLockBoxLibPrivate.h"\r
-\r
-/**\r
- We need handle this library carefully. Only one library instance will construct the environment.\r
- Below 2 global variable can only be used in constructor. They should NOT be used in any other library functions.\r
-**/\r
-SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext;\r
-LIST_ENTRY mLockBoxQueue = INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue);\r
-\r
-BOOLEAN mSmmConfigurationTableInstalled = FALSE;\r
-VOID *mSmmLockBoxRegistrationSmmEndOfDxe = NULL;\r
-VOID *mSmmLockBoxRegistrationSmmReadyToLock = NULL;\r
-VOID *mSmmLockBoxRegistrationEndOfS3Resume = NULL;\r
-BOOLEAN mSmmLockBoxSmmReadyToLock = FALSE;\r
-BOOLEAN mSmmLockBoxDuringS3Resume = FALSE;\r
-\r
-/**\r
- This function return SmmLockBox context from SMST.\r
-\r
- @return SmmLockBox context from SMST.\r
-**/\r
-SMM_LOCK_BOX_CONTEXT *\r
-InternalGetSmmLockBoxContext (\r
- VOID\r
- )\r
-{\r
- UINTN Index;\r
-\r
- //\r
- // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone\r
- //\r
- for (Index = 0; Index < gSmst->NumberOfTableEntries; Index++) {\r
- if (CompareGuid (&gSmst->SmmConfigurationTable[Index].VendorGuid, &gEfiSmmLockBoxCommunicationGuid)) {\r
- //\r
- // Found. That means some other library instance is already run.\r
- // No need to install again, just return.\r
- //\r
- return (SMM_LOCK_BOX_CONTEXT *)gSmst->SmmConfigurationTable[Index].VendorTable;\r
- }\r
- }\r
-\r
- //\r
- // Not found.\r
- //\r
- return NULL;\r
-}\r
-\r
-/**\r
- Notification for SMM ReadyToLock protocol.\r
-\r
- @param[in] Protocol Points to the protocol's unique identifier.\r
- @param[in] Interface Points to the interface instance.\r
- @param[in] Handle The handle on which the interface was installed.\r
-\r
- @retval EFI_SUCCESS Notification runs successfully.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmLockBoxSmmReadyToLockNotify (\r
- IN CONST EFI_GUID *Protocol,\r
- IN VOID *Interface,\r
- IN EFI_HANDLE Handle\r
- )\r
-{\r
- mSmmLockBoxSmmReadyToLock = TRUE;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Main entry point for an SMM handler dispatch or communicate-based callback.\r
-\r
- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
- @param[in] Context Points to an optional handler context which was specified when the\r
- handler was registered.\r
- @param[in,out] CommBuffer A pointer to a collection of data in memory that will\r
- be conveyed from a non-SMM environment into an SMM environment.\r
- @param[in,out] CommBufferSize The size of the CommBuffer.\r
-\r
- @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers\r
- should still be called.\r
- @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should\r
- still be called.\r
- @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still\r
- be called.\r
- @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmLockBoxS3EntryCallBack (\r
- IN EFI_HANDLE DispatchHandle,\r
- IN CONST VOID *Context OPTIONAL,\r
- IN OUT VOID *CommBuffer OPTIONAL,\r
- IN OUT UINTN *CommBufferSize OPTIONAL\r
- )\r
-{\r
- mSmmLockBoxDuringS3Resume = TRUE;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Notification for SMM EndOfDxe protocol.\r
-\r
- @param[in] Protocol Points to the protocol's unique identifier.\r
- @param[in] Interface Points to the interface instance.\r
- @param[in] Handle The handle on which the interface was installed.\r
-\r
- @retval EFI_SUCCESS Notification runs successfully.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmLockBoxSmmEndOfDxeNotify (\r
- IN CONST EFI_GUID *Protocol,\r
- IN VOID *Interface,\r
- IN EFI_HANDLE Handle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatch;\r
- EFI_SMM_SX_REGISTER_CONTEXT EntryRegisterContext;\r
- EFI_HANDLE S3EntryHandle;\r
-\r
- //\r
- // Locate SmmSxDispatch2 protocol.\r
- //\r
- Status = gSmst->SmmLocateProtocol (\r
- &gEfiSmmSxDispatch2ProtocolGuid,\r
- NULL,\r
- (VOID **)&SxDispatch\r
- );\r
- if (!EFI_ERROR (Status) && (SxDispatch != NULL)) {\r
- //\r
- // Register a S3 entry callback function to\r
- // determine if it will be during S3 resume.\r
- //\r
- EntryRegisterContext.Type = SxS3;\r
- EntryRegisterContext.Phase = SxEntry;\r
- Status = SxDispatch->Register (\r
- SxDispatch,\r
- SmmLockBoxS3EntryCallBack,\r
- &EntryRegisterContext,\r
- &S3EntryHandle\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Notification for SMM EndOfS3Resume protocol.\r
-\r
- @param[in] Protocol Points to the protocol's unique identifier.\r
- @param[in] Interface Points to the interface instance.\r
- @param[in] Handle The handle on which the interface was installed.\r
-\r
- @retval EFI_SUCCESS Notification runs successfully.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmLockBoxEndOfS3ResumeNotify (\r
- IN CONST EFI_GUID *Protocol,\r
- IN VOID *Interface,\r
- IN EFI_HANDLE Handle\r
- )\r
-{\r
- mSmmLockBoxDuringS3Resume = FALSE;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Constructor for SmmLockBox library.\r
- This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.\r
-\r
- @param[in] ImageHandle Image handle of this driver.\r
- @param[in] SystemTable A Pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCEESS\r
- @return Others Some error occurs.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmLockBoxSmmConstructor (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
-\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter\n"));\r
-\r
- //\r
- // Register SmmReadyToLock notification.\r
- //\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEfiSmmReadyToLockProtocolGuid,\r
- SmmLockBoxSmmReadyToLockNotify,\r
- &mSmmLockBoxRegistrationSmmReadyToLock\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register SmmEndOfDxe notification.\r
- //\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEfiSmmEndOfDxeProtocolGuid,\r
- SmmLockBoxSmmEndOfDxeNotify,\r
- &mSmmLockBoxRegistrationSmmEndOfDxe\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register EndOfS3Resume notification.\r
- //\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEdkiiEndOfS3ResumeGuid,\r
- SmmLockBoxEndOfS3ResumeNotify,\r
- &mSmmLockBoxRegistrationEndOfS3Resume\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone\r
- //\r
- SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
- if (SmmLockBoxContext != NULL) {\r
- //\r
- // Find it. That means some other library instance is already run.\r
- // No need to install again, just return.\r
- //\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - already installed\n"));\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit\n"));\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // If no one install this, it means this is first instance. Install it.\r
- //\r
- if (sizeof(UINTN) == sizeof(UINT64)) {\r
- mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_64;\r
- } else {\r
- mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_32;\r
- }\r
- mSmmLockBoxContext.LockBoxDataAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)&mLockBoxQueue;\r
-\r
- Status = gSmst->SmmInstallConfigurationTable (\r
- gSmst,\r
- &gEfiSmmLockBoxCommunicationGuid,\r
- &mSmmLockBoxContext,\r
- sizeof(mSmmLockBoxContext)\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- mSmmConfigurationTableInstalled = TRUE;\r
-\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN)&mSmmLockBoxContext));\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN)&mLockBoxQueue));\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit\n"));\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Destructor for SmmLockBox library.\r
- This is used to uninstall SmmLockBoxCommunication configuration table\r
- if it has been installed in Constructor.\r
-\r
- @param[in] ImageHandle Image handle of this driver.\r
- @param[in] SystemTable A Pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmLockBoxSmmDestructor (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmDestructor in %a module\n", gEfiCallerBaseName));\r
-\r
- if (mSmmConfigurationTableInstalled) {\r
- Status = gSmst->SmmInstallConfigurationTable (\r
- gSmst,\r
- &gEfiSmmLockBoxCommunicationGuid,\r
- NULL,\r
- 0\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib uninstall SmmLockBoxCommunication configuration table\n"));\r
- }\r
-\r
- if (mSmmLockBoxRegistrationSmmReadyToLock != NULL) {\r
- //\r
- // Unregister SmmReadyToLock notification.\r
- //\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEfiSmmReadyToLockProtocolGuid,\r
- NULL,\r
- &mSmmLockBoxRegistrationSmmReadyToLock\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
- if (mSmmLockBoxRegistrationSmmEndOfDxe != NULL) {\r
- //\r
- // Unregister SmmEndOfDxe notification.\r
- //\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEfiSmmEndOfDxeProtocolGuid,\r
- NULL,\r
- &mSmmLockBoxRegistrationSmmEndOfDxe\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
- if (mSmmLockBoxRegistrationEndOfS3Resume != NULL) {\r
- //\r
- // Unregister EndOfS3Resume notification.\r
- //\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEdkiiEndOfS3ResumeGuid,\r
- NULL,\r
- &mSmmLockBoxRegistrationEndOfS3Resume\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function return SmmLockBox queue address.\r
-\r
- @return SmmLockBox queue address.\r
-**/\r
-LIST_ENTRY *\r
-InternalGetLockBoxQueue (\r
- VOID\r
- )\r
-{\r
- SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
-\r
- SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
- ASSERT (SmmLockBoxContext != NULL);\r
- if (SmmLockBoxContext == NULL) {\r
- return NULL;\r
- }\r
- return (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;\r
-}\r
-\r
-/**\r
- This function find LockBox by GUID.\r
-\r
- @param Guid The guid to indentify the LockBox\r
-\r
- @return LockBoxData\r
-**/\r
-SMM_LOCK_BOX_DATA *\r
-InternalFindLockBoxByGuid (\r
- IN EFI_GUID *Guid\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- SMM_LOCK_BOX_DATA *LockBox;\r
- LIST_ENTRY *LockBoxQueue;\r
-\r
- LockBoxQueue = InternalGetLockBoxQueue ();\r
- ASSERT (LockBoxQueue != NULL);\r
-\r
- for (Link = LockBoxQueue->ForwardLink;\r
- Link != LockBoxQueue;\r
- Link = Link->ForwardLink) {\r
- LockBox = BASE_CR (\r
- Link,\r
- SMM_LOCK_BOX_DATA,\r
- Link\r
- );\r
- if (CompareGuid (&LockBox->Guid, Guid)) {\r
- return LockBox;\r
- }\r
- }\r
- return NULL;\r
-}\r
-\r
-/**\r
- This function will save confidential information to lockbox.\r
-\r
- @param Guid the guid to identify the confidential information\r
- @param Buffer the address of the confidential information\r
- @param Length the length of the confidential information\r
-\r
- @retval RETURN_SUCCESS the information is saved successfully.\r
- @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0\r
- @retval RETURN_ALREADY_STARTED the requested GUID already exist.\r
- @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.\r
- @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
- @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
- @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
-**/\r
-RETURN_STATUS\r
-EFIAPI\r
-SaveLockBox (\r
- IN GUID *Guid,\r
- IN VOID *Buffer,\r
- IN UINTN Length\r
- )\r
-{\r
- SMM_LOCK_BOX_DATA *LockBox;\r
- EFI_PHYSICAL_ADDRESS SmramBuffer;\r
- EFI_STATUS Status;\r
- LIST_ENTRY *LockBoxQueue;\r
-\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));\r
-\r
- //\r
- // Basic check\r
- //\r
- if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Find LockBox\r
- //\r
- LockBox = InternalFindLockBoxByGuid (Guid);\r
- if (LockBox != NULL) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED));\r
- return EFI_ALREADY_STARTED;\r
- }\r
-\r
- //\r
- // Allocate SMRAM buffer\r
- //\r
- Status = gSmst->SmmAllocatePages (\r
- AllocateAnyPages,\r
- EfiRuntimeServicesData,\r
- EFI_SIZE_TO_PAGES (Length),\r
- &SmramBuffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Allocate LockBox\r
- //\r
- Status = gSmst->SmmAllocatePool (\r
- EfiRuntimeServicesData,\r
- sizeof(*LockBox),\r
- (VOID **)&LockBox\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- gSmst->SmmFreePages (SmramBuffer, EFI_SIZE_TO_PAGES (Length));\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Save data\r
- //\r
- CopyMem ((VOID *)(UINTN)SmramBuffer, (VOID *)(UINTN)Buffer, Length);\r
-\r
- //\r
- // Insert LockBox to queue\r
- //\r
- LockBox->Signature = SMM_LOCK_BOX_DATA_SIGNATURE;\r
- CopyMem (&LockBox->Guid, Guid, sizeof(EFI_GUID));\r
- LockBox->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
- LockBox->Length = (UINT64)Length;\r
- LockBox->Attributes = 0;\r
- LockBox->SmramBuffer = SmramBuffer;\r
-\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "LockBoxGuid - %g, SmramBuffer - 0x%lx, Length - 0x%lx\n",\r
- &LockBox->Guid,\r
- LockBox->SmramBuffer,\r
- LockBox->Length\r
- ));\r
-\r
- LockBoxQueue = InternalGetLockBoxQueue ();\r
- ASSERT (LockBoxQueue != NULL);\r
- InsertTailList (LockBoxQueue, &LockBox->Link);\r
-\r
- //\r
- // Done\r
- //\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function will set lockbox attributes.\r
-\r
- @param Guid the guid to identify the confidential information\r
- @param Attributes the attributes of the lockbox\r
-\r
- @retval RETURN_SUCCESS the information is saved successfully.\r
- @retval RETURN_INVALID_PARAMETER attributes is invalid.\r
- @retval RETURN_NOT_FOUND the requested GUID not found.\r
- @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
- @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
- @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
-**/\r
-RETURN_STATUS\r
-EFIAPI\r
-SetLockBoxAttributes (\r
- IN GUID *Guid,\r
- IN UINT64 Attributes\r
- )\r
-{\r
- SMM_LOCK_BOX_DATA *LockBox;\r
-\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));\r
-\r
- //\r
- // Basic check\r
- //\r
- if ((Guid == NULL) ||\r
- ((Attributes & ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE | LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY)) != 0)) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&\r
- ((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0)) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
- DEBUG ((DEBUG_INFO, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));\r
- DEBUG ((DEBUG_INFO, " can not be set together\n"));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Find LockBox\r
- //\r
- LockBox = InternalFindLockBoxByGuid (Guid);\r
- if (LockBox == NULL) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND));\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if ((((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&\r
- ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0)) ||\r
- (((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&\r
- ((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0))) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes 0x%lx 0x%lx - Exit (%r)\n", LockBox->Attributes, Attributes, EFI_INVALID_PARAMETER));\r
- DEBUG ((DEBUG_INFO, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));\r
- DEBUG ((DEBUG_INFO, " can not be set together\n"));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Update data\r
- //\r
- LockBox->Attributes = Attributes;\r
-\r
- //\r
- // Done\r
- //\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function will update confidential information to lockbox.\r
-\r
- @param Guid the guid to identify the original confidential information\r
- @param Offset the offset of the original confidential information\r
- @param Buffer the address of the updated confidential information\r
- @param Length the length of the updated confidential information\r
-\r
- @retval RETURN_SUCCESS the information is saved successfully.\r
- @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.\r
- @retval RETURN_NOT_FOUND the requested GUID not found.\r
- @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,\r
- the original buffer to too small to hold new information.\r
- @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,\r
- no enough resource to save the information.\r
- @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
- @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
- @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
-**/\r
-RETURN_STATUS\r
-EFIAPI\r
-UpdateLockBox (\r
- IN GUID *Guid,\r
- IN UINTN Offset,\r
- IN VOID *Buffer,\r
- IN UINTN Length\r
- )\r
-{\r
- SMM_LOCK_BOX_DATA *LockBox;\r
- EFI_PHYSICAL_ADDRESS SmramBuffer;\r
- EFI_STATUS Status;\r
-\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));\r
-\r
- //\r
- // Basic check\r
- //\r
- if ((Guid == NULL) || (Buffer == NULL) || (Length == 0) ||\r
- (Length > MAX_UINTN - Offset)) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Find LockBox\r
- //\r
- LockBox = InternalFindLockBoxByGuid (Guid);\r
- if (LockBox == NULL) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_NOT_FOUND));\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Update data\r
- //\r
- if (LockBox->Length < Offset + Length) {\r
- if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0) {\r
- //\r
- // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is set, enlarge the\r
- // LockBox.\r
- //\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "SmmLockBoxSmmLib UpdateLockBox - Origin LockBox too small, enlarge.\n"\r
- ));\r
-\r
- if (EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ((UINTN)LockBox->Length)) < Offset + Length) {\r
- //\r
- // In SaveLockBox(), the SMRAM buffer allocated for LockBox is of page\r
- // granularity. Here, if the required size is larger than the origin size\r
- // of the pages, allocate new buffer from SMRAM to enlarge the LockBox.\r
- //\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "SmmLockBoxSmmLib UpdateLockBox - Allocate new buffer to enlarge.\n"\r
- ));\r
- Status = gSmst->SmmAllocatePages (\r
- AllocateAnyPages,\r
- EfiRuntimeServicesData,\r
- EFI_SIZE_TO_PAGES (Offset + Length),\r
- &SmramBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Copy origin data to the new SMRAM buffer and wipe the content in the\r
- // origin SMRAM buffer.\r
- //\r
- CopyMem ((VOID *)(UINTN)SmramBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
- ZeroMem ((VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
- gSmst->SmmFreePages (LockBox->SmramBuffer, EFI_SIZE_TO_PAGES ((UINTN)LockBox->Length));\r
-\r
- LockBox->SmramBuffer = SmramBuffer;\r
- }\r
-\r
- //\r
- // Handle uninitialized content in the LockBox.\r
- //\r
- if (Offset > LockBox->Length) {\r
- ZeroMem (\r
- (VOID *)((UINTN)LockBox->SmramBuffer + (UINTN)LockBox->Length),\r
- Offset - (UINTN)LockBox->Length\r
- );\r
- }\r
- LockBox->Length = Offset + Length;\r
- } else {\r
- //\r
- // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is NOT set, return\r
- // EFI_BUFFER_TOO_SMALL directly.\r
- //\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
- }\r
- ASSERT ((UINTN)LockBox->SmramBuffer <= (MAX_ADDRESS - Offset));\r
- CopyMem ((VOID *)((UINTN)LockBox->SmramBuffer + Offset), Buffer, Length);\r
-\r
- //\r
- // Done\r
- //\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function will restore confidential information from lockbox.\r
-\r
- @param Guid the guid to identify the confidential information\r
- @param Buffer the address of the restored confidential information\r
- NULL means restored to original address, Length MUST be NULL at same time.\r
- @param Length the length of the restored confidential information\r
-\r
- @retval RETURN_SUCCESS the information is restored successfully.\r
- @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.\r
- @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no\r
- LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.\r
- @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.\r
- @retval RETURN_NOT_FOUND the requested GUID not found.\r
- @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
- @retval RETURN_ACCESS_DENIED not allow to restore to the address\r
- @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
-**/\r
-RETURN_STATUS\r
-EFIAPI\r
-RestoreLockBox (\r
- IN GUID *Guid,\r
- IN VOID *Buffer, OPTIONAL\r
- IN OUT UINTN *Length OPTIONAL\r
- )\r
-{\r
- SMM_LOCK_BOX_DATA *LockBox;\r
- VOID *RestoreBuffer;\r
-\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));\r
-\r
- //\r
- // Restore this, Buffer and Length MUST be both NULL or both non-NULL\r
- //\r
- if ((Guid == NULL) ||\r
- ((Buffer == NULL) && (Length != NULL)) ||\r
- ((Buffer != NULL) && (Length == NULL))) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Find LockBox\r
- //\r
- LockBox = InternalFindLockBoxByGuid (Guid);\r
- if (LockBox == NULL) {\r
- //\r
- // Not found\r
- //\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND));\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0) &&\r
- mSmmLockBoxSmmReadyToLock &&\r
- !mSmmLockBoxDuringS3Resume) {\r
- //\r
- // With LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,\r
- // this LockBox can be restored in S3 resume only.\r
- //\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- //\r
- // Set RestoreBuffer\r
- //\r
- if (Buffer != NULL) {\r
- //\r
- // restore to new buffer\r
- //\r
- RestoreBuffer = Buffer;\r
- } else {\r
- //\r
- // restore to original buffer\r
- //\r
- if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED));\r
- return EFI_WRITE_PROTECTED;\r
- }\r
- RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;\r
- }\r
-\r
- //\r
- // Set RestoreLength\r
- //\r
- if (Length != NULL) {\r
- if (*Length < (UINTN)LockBox->Length) {\r
- //\r
- // Input buffer is too small to hold all data.\r
- //\r
- *Length = (UINTN)LockBox->Length;\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
- *Length = (UINTN)LockBox->Length;\r
- }\r
-\r
- //\r
- // Restore data\r
- //\r
- CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
-\r
- //\r
- // Done\r
- //\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function will restore confidential information from all lockbox which have RestoreInPlace attribute.\r
-\r
- @retval RETURN_SUCCESS the information is restored successfully.\r
- @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
- @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
-**/\r
-RETURN_STATUS\r
-EFIAPI\r
-RestoreAllLockBoxInPlace (\r
- VOID\r
- )\r
-{\r
- SMM_LOCK_BOX_DATA *LockBox;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *LockBoxQueue;\r
-\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));\r
-\r
- LockBoxQueue = InternalGetLockBoxQueue ();\r
- ASSERT (LockBoxQueue != NULL);\r
-\r
- //\r
- // Restore all, Buffer and Length MUST be NULL\r
- //\r
- for (Link = LockBoxQueue->ForwardLink;\r
- Link != LockBoxQueue;\r
- Link = Link->ForwardLink) {\r
- LockBox = BASE_CR (\r
- Link,\r
- SMM_LOCK_BOX_DATA,\r
- Link\r
- );\r
- if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) {\r
- //\r
- // Restore data\r
- //\r
- CopyMem ((VOID *)(UINTN)LockBox->Buffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
- }\r
- }\r
- //\r
- // Done\r
- //\r
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS));\r
- return EFI_SUCCESS;\r
-}\r
-\r
MODULE_TYPE = DXE_SMM_DRIVER\r
VERSION_STRING = 1.0\r
LIBRARY_CLASS = LockBoxLib|DXE_SMM_DRIVER\r
- CONSTRUCTOR = SmmLockBoxSmmConstructor\r
- DESTRUCTOR = SmmLockBoxSmmDestructor\r
+ CONSTRUCTOR = SmmLockBoxTraditionalConstructor\r
+ DESTRUCTOR = SmmLockBoxTraditionalDestructor\r
\r
#\r
# The following information is for reference only and not required by the build tools.\r
#\r
\r
[Sources]\r
- SmmLockBoxSmmLib.c\r
+ SmmLockBoxTraditionalMmLib.c\r
+ SmmLockBoxMmLib.c\r
SmmLockBoxLibPrivate.h\r
\r
[Packages]\r
MdeModulePkg/MdeModulePkg.dec\r
\r
[LibraryClasses]\r
- SmmServicesTableLib\r
+ MmServicesTableLib\r
BaseLib\r
DebugLib\r
\r
[Protocols]\r
- gEfiSmmReadyToLockProtocolGuid ## NOTIFY\r
- gEfiSmmEndOfDxeProtocolGuid ## NOTIFY\r
- gEfiSmmSxDispatch2ProtocolGuid ## NOTIFY\r
+ gEfiMmReadyToLockProtocolGuid ## NOTIFY\r
+ gEfiMmEndOfDxeProtocolGuid ## NOTIFY\r
+ gEfiMmSxDispatchProtocolGuid ## NOTIFY\r
\r
[Guids]\r
## SOMETIMES_CONSUMES ## UNDEFINED # SmmSystemTable\r
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) Microsoft Corporation.\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiMm.h>\r
+\r
+#include "SmmLockBoxLibPrivate.h"\r
+\r
+/**\r
+ Constructor for SmmLockBox library.\r
+ This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.\r
+\r
+ @param[in] ImageHandle Image handle of this driver.\r
+ @param[in] SystemTable A Pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCEESS\r
+ @return Others Some error occurs.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLockBoxStandaloneMmConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_MM_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ return SmmLockBoxMmConstructor ();\r
+}\r
+\r
+/**\r
+ Destructor for SmmLockBox library.\r
+ This is used to uninstall SmmLockBoxCommunication configuration table\r
+ if it has been installed in Constructor.\r
+\r
+ @param[in] ImageHandle Image handle of this driver.\r
+ @param[in] SystemTable A Pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLockBoxStandaloneMmDestructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_MM_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ return SmmLockBoxMmDestructor ();\r
+}\r
--- /dev/null
+## @file\r
+# SMM LockBox library instance.\r
+#\r
+# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) Microsoft Corporation.\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = SmmLockBoxStandaloneMmLib\r
+ FILE_GUID = 3C05978B-30CA-4544-9C5A-AB99265EFC31\r
+ MODULE_TYPE = MM_STANDALONE\r
+ VERSION_STRING = 1.0\r
+ PI_SPECIFICATION_VERSION = 0x00010032\r
+ LIBRARY_CLASS = LockBoxLib|MM_STANDALONE\r
+ CONSTRUCTOR = SmmLockBoxStandaloneMmConstructor\r
+ DESTRUCTOR = SmmLockBoxStandaloneMmDestructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64\r
+#\r
+\r
+[Sources]\r
+ SmmLockBoxStandaloneMmLib.c\r
+ SmmLockBoxMmLib.c\r
+ SmmLockBoxLibPrivate.h\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+ MmServicesTableLib\r
+ BaseLib\r
+ DebugLib\r
+\r
+[Protocols]\r
+ gEfiMmReadyToLockProtocolGuid ## NOTIFY\r
+ gEfiMmEndOfDxeProtocolGuid ## NOTIFY\r
+ gEfiMmSxDispatchProtocolGuid ## NOTIFY\r
+\r
+[Guids]\r
+ ## SOMETIMES_CONSUMES ## UNDEFINED # SmmSystemTable\r
+ ## SOMETIMES_PRODUCES ## UNDEFINED # SmmSystemTable\r
+ gEfiSmmLockBoxCommunicationGuid\r
+ ## CONSUMES ## UNDEFINED # Protocol notify\r
+ gEdkiiEndOfS3ResumeGuid\r
+\r
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) Microsoft Corporation.\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiSmm.h>\r
+\r
+#include "SmmLockBoxLibPrivate.h"\r
+\r
+/**\r
+ Constructor for SmmLockBox library.\r
+ This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.\r
+\r
+ @param[in] ImageHandle Image handle of this driver.\r
+ @param[in] SystemTable A Pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCEESS\r
+ @return Others Some error occurs.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLockBoxTraditionalConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ return SmmLockBoxMmConstructor ();\r
+}\r
+\r
+/**\r
+ Destructor for SmmLockBox library.\r
+ This is used to uninstall SmmLockBoxCommunication configuration table\r
+ if it has been installed in Constructor.\r
+\r
+ @param[in] ImageHandle Image handle of this driver.\r
+ @param[in] SystemTable A Pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLockBoxTraditionalDestructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ return SmmLockBoxMmDestructor ();\r
+}\r
MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf\r
StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf\r
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf\r
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxStandaloneMmLib.inf\r
\r
[LibraryClasses.ARM, LibraryClasses.AARCH64]\r
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf\r
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf\r
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf\r
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf\r
+ MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxStandaloneMmLib.inf\r
MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf\r
MdeModulePkg/Library/SmmSmiHandlerProfileLib/SmmSmiHandlerProfileLib.inf\r
MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaArchCustomDecompressLib.inf\r