3 Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The
8 full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/SmmServicesTableLib.h>
18 #include <Library/BaseLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/LockBoxLib.h>
21 #include <Library/DebugLib.h>
22 #include <Guid/SmmLockBox.h>
23 #include <Guid/EndOfS3Resume.h>
24 #include <Protocol/SmmReadyToLock.h>
25 #include <Protocol/SmmEndOfDxe.h>
26 #include <Protocol/SmmSxDispatch2.h>
28 #include "SmmLockBoxLibPrivate.h"
31 We need handle this library carefully. Only one library instance will construct the environment.
32 Below 2 global variable can only be used in constructor. They should NOT be used in any other library functions.
34 SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext
;
35 LIST_ENTRY mLockBoxQueue
= INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue
);
37 BOOLEAN mSmmConfigurationTableInstalled
= FALSE
;
38 VOID
*mSmmLockBoxRegistrationSmmEndOfDxe
= NULL
;
39 VOID
*mSmmLockBoxRegistrationSmmReadyToLock
= NULL
;
40 VOID
*mSmmLockBoxRegistrationEndOfS3Resume
= NULL
;
41 BOOLEAN mSmmLockBoxSmmReadyToLock
= FALSE
;
42 BOOLEAN mSmmLockBoxDuringS3Resume
= FALSE
;
45 This function return SmmLockBox context from SMST.
47 @return SmmLockBox context from SMST.
49 SMM_LOCK_BOX_CONTEXT
*
50 InternalGetSmmLockBoxContext (
57 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
59 for (Index
= 0; Index
< gSmst
->NumberOfTableEntries
; Index
++) {
60 if (CompareGuid (&gSmst
->SmmConfigurationTable
[Index
].VendorGuid
, &gEfiSmmLockBoxCommunicationGuid
)) {
62 // Found. That means some other library instance is already run.
63 // No need to install again, just return.
65 return (SMM_LOCK_BOX_CONTEXT
*)gSmst
->SmmConfigurationTable
[Index
].VendorTable
;
76 Notification for SMM ReadyToLock protocol.
78 @param[in] Protocol Points to the protocol's unique identifier.
79 @param[in] Interface Points to the interface instance.
80 @param[in] Handle The handle on which the interface was installed.
82 @retval EFI_SUCCESS Notification runs successfully.
86 SmmLockBoxSmmReadyToLockNotify (
87 IN CONST EFI_GUID
*Protocol
,
92 mSmmLockBoxSmmReadyToLock
= TRUE
;
97 Main entry point for an SMM handler dispatch or communicate-based callback.
99 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
100 @param[in] Context Points to an optional handler context which was specified when the
101 handler was registered.
102 @param[in,out] CommBuffer A pointer to a collection of data in memory that will
103 be conveyed from a non-SMM environment into an SMM environment.
104 @param[in,out] CommBufferSize The size of the CommBuffer.
106 @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
107 should still be called.
108 @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
110 @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
112 @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
116 SmmLockBoxS3EntryCallBack (
117 IN EFI_HANDLE DispatchHandle
,
118 IN CONST VOID
*Context OPTIONAL
,
119 IN OUT VOID
*CommBuffer OPTIONAL
,
120 IN OUT UINTN
*CommBufferSize OPTIONAL
123 mSmmLockBoxDuringS3Resume
= TRUE
;
128 Notification for SMM EndOfDxe protocol.
130 @param[in] Protocol Points to the protocol's unique identifier.
131 @param[in] Interface Points to the interface instance.
132 @param[in] Handle The handle on which the interface was installed.
134 @retval EFI_SUCCESS Notification runs successfully.
138 SmmLockBoxSmmEndOfDxeNotify (
139 IN CONST EFI_GUID
*Protocol
,
145 EFI_SMM_SX_DISPATCH2_PROTOCOL
*SxDispatch
;
146 EFI_SMM_SX_REGISTER_CONTEXT EntryRegisterContext
;
147 EFI_HANDLE S3EntryHandle
;
150 // Locate SmmSxDispatch2 protocol.
152 Status
= gSmst
->SmmLocateProtocol (
153 &gEfiSmmSxDispatch2ProtocolGuid
,
157 if (!EFI_ERROR (Status
) && (SxDispatch
!= NULL
)) {
159 // Register a S3 entry callback function to
160 // determine if it will be during S3 resume.
162 EntryRegisterContext
.Type
= SxS3
;
163 EntryRegisterContext
.Phase
= SxEntry
;
164 Status
= SxDispatch
->Register (
166 SmmLockBoxS3EntryCallBack
,
167 &EntryRegisterContext
,
170 ASSERT_EFI_ERROR (Status
);
177 Notification for SMM EndOfS3Resume protocol.
179 @param[in] Protocol Points to the protocol's unique identifier.
180 @param[in] Interface Points to the interface instance.
181 @param[in] Handle The handle on which the interface was installed.
183 @retval EFI_SUCCESS Notification runs successfully.
187 SmmLockBoxEndOfS3ResumeNotify (
188 IN CONST EFI_GUID
*Protocol
,
193 mSmmLockBoxDuringS3Resume
= FALSE
;
198 Constructor for SmmLockBox library.
199 This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.
201 @param[in] ImageHandle Image handle of this driver.
202 @param[in] SystemTable A Pointer to the EFI System Table.
205 @return Others Some error occurs.
209 SmmLockBoxSmmConstructor (
210 IN EFI_HANDLE ImageHandle
,
211 IN EFI_SYSTEM_TABLE
*SystemTable
215 SMM_LOCK_BOX_CONTEXT
*SmmLockBoxContext
;
217 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter\n"));
220 // Register SmmReadyToLock notification.
222 Status
= gSmst
->SmmRegisterProtocolNotify (
223 &gEfiSmmReadyToLockProtocolGuid
,
224 SmmLockBoxSmmReadyToLockNotify
,
225 &mSmmLockBoxRegistrationSmmReadyToLock
227 ASSERT_EFI_ERROR (Status
);
230 // Register SmmEndOfDxe notification.
232 Status
= gSmst
->SmmRegisterProtocolNotify (
233 &gEfiSmmEndOfDxeProtocolGuid
,
234 SmmLockBoxSmmEndOfDxeNotify
,
235 &mSmmLockBoxRegistrationSmmEndOfDxe
237 ASSERT_EFI_ERROR (Status
);
240 // Register EndOfS3Resume notification.
242 Status
= gSmst
->SmmRegisterProtocolNotify (
243 &gEdkiiEndOfS3ResumeGuid
,
244 SmmLockBoxEndOfS3ResumeNotify
,
245 &mSmmLockBoxRegistrationEndOfS3Resume
247 ASSERT_EFI_ERROR (Status
);
250 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
252 SmmLockBoxContext
= InternalGetSmmLockBoxContext ();
253 if (SmmLockBoxContext
!= NULL
) {
255 // Find it. That means some other library instance is already run.
256 // No need to install again, just return.
258 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxContext - already installed\n"));
259 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit\n"));
264 // If no one install this, it means this is first instance. Install it.
266 if (sizeof(UINTN
) == sizeof(UINT64
)) {
267 mSmmLockBoxContext
.Signature
= SMM_LOCK_BOX_SIGNATURE_64
;
269 mSmmLockBoxContext
.Signature
= SMM_LOCK_BOX_SIGNATURE_32
;
271 mSmmLockBoxContext
.LockBoxDataAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)&mLockBoxQueue
;
273 Status
= gSmst
->SmmInstallConfigurationTable (
275 &gEfiSmmLockBoxCommunicationGuid
,
277 sizeof(mSmmLockBoxContext
)
279 ASSERT_EFI_ERROR (Status
);
280 mSmmConfigurationTableInstalled
= TRUE
;
282 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN
)&mSmmLockBoxContext
));
283 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN
)&mLockBoxQueue
));
284 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit\n"));
290 Destructor for SmmLockBox library.
291 This is used to uninstall SmmLockBoxCommunication configuration table
292 if it has been installed in Constructor.
294 @param[in] ImageHandle Image handle of this driver.
295 @param[in] SystemTable A Pointer to the EFI System Table.
297 @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.
302 SmmLockBoxSmmDestructor (
303 IN EFI_HANDLE ImageHandle
,
304 IN EFI_SYSTEM_TABLE
*SystemTable
309 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxSmmDestructor in %a module\n", gEfiCallerBaseName
));
311 if (mSmmConfigurationTableInstalled
) {
312 Status
= gSmst
->SmmInstallConfigurationTable (
314 &gEfiSmmLockBoxCommunicationGuid
,
318 ASSERT_EFI_ERROR (Status
);
319 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib uninstall SmmLockBoxCommunication configuration table\n"));
322 if (mSmmLockBoxRegistrationSmmReadyToLock
!= NULL
) {
324 // Unregister SmmReadyToLock notification.
326 Status
= gSmst
->SmmRegisterProtocolNotify (
327 &gEfiSmmReadyToLockProtocolGuid
,
329 &mSmmLockBoxRegistrationSmmReadyToLock
331 ASSERT_EFI_ERROR (Status
);
333 if (mSmmLockBoxRegistrationSmmEndOfDxe
!= NULL
) {
335 // Unregister SmmEndOfDxe notification.
337 Status
= gSmst
->SmmRegisterProtocolNotify (
338 &gEfiSmmEndOfDxeProtocolGuid
,
340 &mSmmLockBoxRegistrationSmmEndOfDxe
342 ASSERT_EFI_ERROR (Status
);
344 if (mSmmLockBoxRegistrationEndOfS3Resume
!= NULL
) {
346 // Unregister EndOfS3Resume notification.
348 Status
= gSmst
->SmmRegisterProtocolNotify (
349 &gEdkiiEndOfS3ResumeGuid
,
351 &mSmmLockBoxRegistrationEndOfS3Resume
353 ASSERT_EFI_ERROR (Status
);
360 This function return SmmLockBox queue address.
362 @return SmmLockBox queue address.
365 InternalGetLockBoxQueue (
369 SMM_LOCK_BOX_CONTEXT
*SmmLockBoxContext
;
371 SmmLockBoxContext
= InternalGetSmmLockBoxContext ();
372 ASSERT (SmmLockBoxContext
!= NULL
);
373 if (SmmLockBoxContext
== NULL
) {
376 return (LIST_ENTRY
*)(UINTN
)SmmLockBoxContext
->LockBoxDataAddress
;
380 This function find LockBox by GUID.
382 @param Guid The guid to indentify the LockBox
387 InternalFindLockBoxByGuid (
392 SMM_LOCK_BOX_DATA
*LockBox
;
393 LIST_ENTRY
*LockBoxQueue
;
395 LockBoxQueue
= InternalGetLockBoxQueue ();
396 ASSERT (LockBoxQueue
!= NULL
);
398 for (Link
= LockBoxQueue
->ForwardLink
;
399 Link
!= LockBoxQueue
;
400 Link
= Link
->ForwardLink
) {
406 if (CompareGuid (&LockBox
->Guid
, Guid
)) {
414 This function will save confidential information to lockbox.
416 @param Guid the guid to identify the confidential information
417 @param Buffer the address of the confidential information
418 @param Length the length of the confidential information
420 @retval RETURN_SUCCESS the information is saved successfully.
421 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
422 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
423 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
424 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
425 @retval RETURN_NOT_STARTED it is too early to invoke this interface
426 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
436 SMM_LOCK_BOX_DATA
*LockBox
;
437 EFI_PHYSICAL_ADDRESS SmramBuffer
;
439 LIST_ENTRY
*LockBoxQueue
;
441 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));
446 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
447 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
448 return EFI_INVALID_PARAMETER
;
454 LockBox
= InternalFindLockBoxByGuid (Guid
);
455 if (LockBox
!= NULL
) {
456 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED
));
457 return EFI_ALREADY_STARTED
;
461 // Allocate SMRAM buffer
463 Status
= gSmst
->SmmAllocatePages (
465 EfiRuntimeServicesData
,
466 EFI_SIZE_TO_PAGES (Length
),
469 ASSERT_EFI_ERROR (Status
);
470 if (EFI_ERROR (Status
)) {
471 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
472 return EFI_OUT_OF_RESOURCES
;
478 Status
= gSmst
->SmmAllocatePool (
479 EfiRuntimeServicesData
,
483 ASSERT_EFI_ERROR (Status
);
484 if (EFI_ERROR (Status
)) {
485 gSmst
->SmmFreePages (SmramBuffer
, EFI_SIZE_TO_PAGES (Length
));
486 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
487 return EFI_OUT_OF_RESOURCES
;
493 CopyMem ((VOID
*)(UINTN
)SmramBuffer
, (VOID
*)(UINTN
)Buffer
, Length
);
496 // Insert LockBox to queue
498 LockBox
->Signature
= SMM_LOCK_BOX_DATA_SIGNATURE
;
499 CopyMem (&LockBox
->Guid
, Guid
, sizeof(EFI_GUID
));
500 LockBox
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
501 LockBox
->Length
= (UINT64
)Length
;
502 LockBox
->Attributes
= 0;
503 LockBox
->SmramBuffer
= SmramBuffer
;
507 "LockBoxGuid - %g, SmramBuffer - 0x%lx, Length - 0x%lx\n",
509 LockBox
->SmramBuffer
,
513 LockBoxQueue
= InternalGetLockBoxQueue ();
514 ASSERT (LockBoxQueue
!= NULL
);
515 InsertTailList (LockBoxQueue
, &LockBox
->Link
);
520 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS
));
525 This function will set lockbox attributes.
527 @param Guid the guid to identify the confidential information
528 @param Attributes the attributes of the lockbox
530 @retval RETURN_SUCCESS the information is saved successfully.
531 @retval RETURN_INVALID_PARAMETER attributes is invalid.
532 @retval RETURN_NOT_FOUND the requested GUID not found.
533 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
534 @retval RETURN_NOT_STARTED it is too early to invoke this interface
535 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
539 SetLockBoxAttributes (
544 SMM_LOCK_BOX_DATA
*LockBox
;
546 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));
551 if ((Guid
== NULL
) ||
552 ((Attributes
& ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
| LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
)) != 0)) {
553 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER
));
554 return EFI_INVALID_PARAMETER
;
557 if (((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
558 ((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0)) {
559 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER
));
560 DEBUG ((DEBUG_INFO
, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
561 DEBUG ((DEBUG_INFO
, " can not be set together\n"));
562 return EFI_INVALID_PARAMETER
;
568 LockBox
= InternalFindLockBoxByGuid (Guid
);
569 if (LockBox
== NULL
) {
570 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND
));
571 return EFI_NOT_FOUND
;
574 if ((((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
575 ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0)) ||
576 (((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
577 ((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0))) {
578 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes 0x%lx 0x%lx - Exit (%r)\n", LockBox
->Attributes
, Attributes
, EFI_INVALID_PARAMETER
));
579 DEBUG ((DEBUG_INFO
, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
580 DEBUG ((DEBUG_INFO
, " can not be set together\n"));
581 return EFI_INVALID_PARAMETER
;
587 LockBox
->Attributes
= Attributes
;
592 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS
));
597 This function will update confidential information to lockbox.
599 @param Guid the guid to identify the original confidential information
600 @param Offset the offset of the original confidential information
601 @param Buffer the address of the updated confidential information
602 @param Length the length of the updated confidential information
604 @retval RETURN_SUCCESS the information is saved successfully.
605 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
606 @retval RETURN_NOT_FOUND the requested GUID not found.
607 @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold new information.
608 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
609 @retval RETURN_NOT_STARTED it is too early to invoke this interface
610 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
621 SMM_LOCK_BOX_DATA
*LockBox
;
623 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));
628 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
629 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
630 return EFI_INVALID_PARAMETER
;
636 LockBox
= InternalFindLockBoxByGuid (Guid
);
637 if (LockBox
== NULL
) {
638 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_NOT_FOUND
));
639 return EFI_NOT_FOUND
;
645 if (LockBox
->Length
< Offset
+ Length
) {
646 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL
));
647 return EFI_BUFFER_TOO_SMALL
;
649 ASSERT ((UINTN
)LockBox
->SmramBuffer
<= (MAX_ADDRESS
- Offset
));
650 CopyMem ((VOID
*)((UINTN
)LockBox
->SmramBuffer
+ Offset
), Buffer
, Length
);
655 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS
));
660 This function will restore confidential information from lockbox.
662 @param Guid the guid to identify the confidential information
663 @param Buffer the address of the restored confidential information
664 NULL means restored to original address, Length MUST be NULL at same time.
665 @param Length the length of the restored confidential information
667 @retval RETURN_SUCCESS the information is restored successfully.
668 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
669 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
670 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
671 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
672 @retval RETURN_NOT_FOUND the requested GUID not found.
673 @retval RETURN_NOT_STARTED it is too early to invoke this interface
674 @retval RETURN_ACCESS_DENIED not allow to restore to the address
675 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
681 IN VOID
*Buffer
, OPTIONAL
682 IN OUT UINTN
*Length OPTIONAL
685 SMM_LOCK_BOX_DATA
*LockBox
;
688 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));
691 // Restore this, Buffer and Length MUST be both NULL or both non-NULL
693 if ((Guid
== NULL
) ||
694 ((Buffer
== NULL
) && (Length
!= NULL
)) ||
695 ((Buffer
!= NULL
) && (Length
== NULL
))) {
696 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
697 return EFI_INVALID_PARAMETER
;
703 LockBox
= InternalFindLockBoxByGuid (Guid
);
704 if (LockBox
== NULL
) {
708 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND
));
709 return EFI_NOT_FOUND
;
712 if (((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0) &&
713 mSmmLockBoxSmmReadyToLock
&&
714 !mSmmLockBoxDuringS3Resume
) {
716 // With LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
717 // this LockBox can be restored in S3 resume only.
719 return EFI_ACCESS_DENIED
;
725 if (Buffer
!= NULL
) {
727 // restore to new buffer
729 RestoreBuffer
= Buffer
;
732 // restore to original buffer
734 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) == 0) {
735 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED
));
736 return EFI_WRITE_PROTECTED
;
738 RestoreBuffer
= (VOID
*)(UINTN
)LockBox
->Buffer
;
744 if (Length
!= NULL
) {
745 if (*Length
< (UINTN
)LockBox
->Length
) {
747 // Input buffer is too small to hold all data.
749 *Length
= (UINTN
)LockBox
->Length
;
750 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL
));
751 return EFI_BUFFER_TOO_SMALL
;
753 *Length
= (UINTN
)LockBox
->Length
;
759 CopyMem (RestoreBuffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
764 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS
));
769 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
771 @retval RETURN_SUCCESS the information is restored successfully.
772 @retval RETURN_NOT_STARTED it is too early to invoke this interface
773 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
777 RestoreAllLockBoxInPlace (
781 SMM_LOCK_BOX_DATA
*LockBox
;
783 LIST_ENTRY
*LockBoxQueue
;
785 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));
787 LockBoxQueue
= InternalGetLockBoxQueue ();
788 ASSERT (LockBoxQueue
!= NULL
);
791 // Restore all, Buffer and Length MUST be NULL
793 for (Link
= LockBoxQueue
->ForwardLink
;
794 Link
!= LockBoxQueue
;
795 Link
= Link
->ForwardLink
) {
801 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) {
805 CopyMem ((VOID
*)(UINTN
)LockBox
->Buffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
811 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS
));