3 Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/MmServicesTableLib.h>
11 #include <Library/BaseLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/LockBoxLib.h>
14 #include <Library/DebugLib.h>
15 #include <Guid/SmmLockBox.h>
16 #include <Guid/EndOfS3Resume.h>
17 #include <Protocol/MmReadyToLock.h>
18 #include <Protocol/MmEndOfDxe.h>
19 #include <Protocol/SmmSxDispatch2.h>
21 #include "SmmLockBoxLibPrivate.h"
24 We need handle this library carefully. Only one library instance will construct the environment.
25 Below 2 global variable can only be used in constructor. They should NOT be used in any other library functions.
27 SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext
;
28 LIST_ENTRY mLockBoxQueue
= INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue
);
30 BOOLEAN mSmmConfigurationTableInstalled
= FALSE
;
31 VOID
*mSmmLockBoxRegistrationSmmEndOfDxe
= NULL
;
32 VOID
*mSmmLockBoxRegistrationSmmReadyToLock
= NULL
;
33 VOID
*mSmmLockBoxRegistrationEndOfS3Resume
= NULL
;
34 BOOLEAN mSmmLockBoxSmmReadyToLock
= FALSE
;
35 BOOLEAN mSmmLockBoxDuringS3Resume
= FALSE
;
38 This function return SmmLockBox context from SMST.
40 @return SmmLockBox context from SMST.
42 SMM_LOCK_BOX_CONTEXT
*
43 InternalGetSmmLockBoxContext (
50 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
52 for (Index
= 0; Index
< gMmst
->NumberOfTableEntries
; Index
++) {
53 if (CompareGuid (&gMmst
->MmConfigurationTable
[Index
].VendorGuid
, &gEfiSmmLockBoxCommunicationGuid
)) {
55 // Found. That means some other library instance is already run.
56 // No need to install again, just return.
58 return (SMM_LOCK_BOX_CONTEXT
*)gMmst
->MmConfigurationTable
[Index
].VendorTable
;
69 Notification for SMM ReadyToLock protocol.
71 @param[in] Protocol Points to the protocol's unique identifier.
72 @param[in] Interface Points to the interface instance.
73 @param[in] Handle The handle on which the interface was installed.
75 @retval EFI_SUCCESS Notification runs successfully.
79 SmmLockBoxSmmReadyToLockNotify (
80 IN CONST EFI_GUID
*Protocol
,
85 mSmmLockBoxSmmReadyToLock
= TRUE
;
90 Main entry point for an SMM handler dispatch or communicate-based callback.
92 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
93 @param[in] Context Points to an optional handler context which was specified when the
94 handler was registered.
95 @param[in,out] CommBuffer A pointer to a collection of data in memory that will
96 be conveyed from a non-SMM environment into an SMM environment.
97 @param[in,out] CommBufferSize The size of the CommBuffer.
99 @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
100 should still be called.
101 @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
103 @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
105 @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
109 SmmLockBoxS3EntryCallBack (
110 IN EFI_HANDLE DispatchHandle
,
111 IN CONST VOID
*Context OPTIONAL
,
112 IN OUT VOID
*CommBuffer OPTIONAL
,
113 IN OUT UINTN
*CommBufferSize OPTIONAL
116 mSmmLockBoxDuringS3Resume
= TRUE
;
121 Notification for SMM EndOfDxe protocol.
123 @param[in] Protocol Points to the protocol's unique identifier.
124 @param[in] Interface Points to the interface instance.
125 @param[in] Handle The handle on which the interface was installed.
127 @retval EFI_SUCCESS Notification runs successfully.
131 SmmLockBoxSmmEndOfDxeNotify (
132 IN CONST EFI_GUID
*Protocol
,
138 EFI_SMM_SX_DISPATCH2_PROTOCOL
*SxDispatch
;
139 EFI_SMM_SX_REGISTER_CONTEXT EntryRegisterContext
;
140 EFI_HANDLE S3EntryHandle
;
143 // Locate SmmSxDispatch2 protocol.
145 Status
= gMmst
->MmLocateProtocol (
146 &gEfiMmSxDispatchProtocolGuid
,
150 if (!EFI_ERROR (Status
) && (SxDispatch
!= NULL
)) {
152 // Register a S3 entry callback function to
153 // determine if it will be during S3 resume.
155 EntryRegisterContext
.Type
= SxS3
;
156 EntryRegisterContext
.Phase
= SxEntry
;
157 Status
= SxDispatch
->Register (
159 SmmLockBoxS3EntryCallBack
,
160 &EntryRegisterContext
,
163 ASSERT_EFI_ERROR (Status
);
170 Notification for SMM EndOfS3Resume protocol.
172 @param[in] Protocol Points to the protocol's unique identifier.
173 @param[in] Interface Points to the interface instance.
174 @param[in] Handle The handle on which the interface was installed.
176 @retval EFI_SUCCESS Notification runs successfully.
180 SmmLockBoxEndOfS3ResumeNotify (
181 IN CONST EFI_GUID
*Protocol
,
186 mSmmLockBoxDuringS3Resume
= FALSE
;
191 Constructor for SmmLockBox library.
192 This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.
195 @return Others Some error occurs.
198 SmmLockBoxMmConstructor (
203 SMM_LOCK_BOX_CONTEXT
*SmmLockBoxContext
;
205 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxMmConstructor - Enter\n"));
208 // Register SmmReadyToLock notification.
210 Status
= gMmst
->MmRegisterProtocolNotify (
211 &gEfiMmReadyToLockProtocolGuid
,
212 SmmLockBoxSmmReadyToLockNotify
,
213 &mSmmLockBoxRegistrationSmmReadyToLock
215 ASSERT_EFI_ERROR (Status
);
218 // Register SmmEndOfDxe notification.
220 Status
= gMmst
->MmRegisterProtocolNotify (
221 &gEfiMmEndOfDxeProtocolGuid
,
222 SmmLockBoxSmmEndOfDxeNotify
,
223 &mSmmLockBoxRegistrationSmmEndOfDxe
225 ASSERT_EFI_ERROR (Status
);
228 // Register EndOfS3Resume notification.
230 Status
= gMmst
->MmRegisterProtocolNotify (
231 &gEdkiiEndOfS3ResumeGuid
,
232 SmmLockBoxEndOfS3ResumeNotify
,
233 &mSmmLockBoxRegistrationEndOfS3Resume
235 ASSERT_EFI_ERROR (Status
);
238 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
240 SmmLockBoxContext
= InternalGetSmmLockBoxContext ();
241 if (SmmLockBoxContext
!= NULL
) {
243 // Find it. That means some other library instance is already run.
244 // No need to install again, just return.
246 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxContext - already installed\n"));
247 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxMmConstructor - Exit\n"));
252 // If no one install this, it means this is first instance. Install it.
254 if (sizeof (UINTN
) == sizeof (UINT64
)) {
255 mSmmLockBoxContext
.Signature
= SMM_LOCK_BOX_SIGNATURE_64
;
257 mSmmLockBoxContext
.Signature
= SMM_LOCK_BOX_SIGNATURE_32
;
260 mSmmLockBoxContext
.LockBoxDataAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)&mLockBoxQueue
;
262 Status
= gMmst
->MmInstallConfigurationTable (
264 &gEfiSmmLockBoxCommunicationGuid
,
266 sizeof (mSmmLockBoxContext
)
268 ASSERT_EFI_ERROR (Status
);
269 mSmmConfigurationTableInstalled
= TRUE
;
271 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN
)&mSmmLockBoxContext
));
272 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN
)&mLockBoxQueue
));
273 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxMmConstructor - Exit\n"));
279 Destructor for SmmLockBox library.
280 This is used to uninstall SmmLockBoxCommunication configuration table
281 if it has been installed in Constructor.
283 @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.
287 SmmLockBoxMmDestructor (
293 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxMmDestructor in %a module\n", gEfiCallerBaseName
));
295 if (mSmmConfigurationTableInstalled
) {
296 Status
= gMmst
->MmInstallConfigurationTable (
298 &gEfiSmmLockBoxCommunicationGuid
,
302 ASSERT_EFI_ERROR (Status
);
303 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib uninstall SmmLockBoxCommunication configuration table\n"));
306 if (mSmmLockBoxRegistrationSmmReadyToLock
!= NULL
) {
308 // Unregister SmmReadyToLock notification.
310 Status
= gMmst
->MmRegisterProtocolNotify (
311 &gEfiMmReadyToLockProtocolGuid
,
313 &mSmmLockBoxRegistrationSmmReadyToLock
315 ASSERT_EFI_ERROR (Status
);
318 if (mSmmLockBoxRegistrationSmmEndOfDxe
!= NULL
) {
320 // Unregister SmmEndOfDxe notification.
322 Status
= gMmst
->MmRegisterProtocolNotify (
323 &gEfiMmEndOfDxeProtocolGuid
,
325 &mSmmLockBoxRegistrationSmmEndOfDxe
327 ASSERT_EFI_ERROR (Status
);
330 if (mSmmLockBoxRegistrationEndOfS3Resume
!= NULL
) {
332 // Unregister EndOfS3Resume notification.
334 Status
= gMmst
->MmRegisterProtocolNotify (
335 &gEdkiiEndOfS3ResumeGuid
,
337 &mSmmLockBoxRegistrationEndOfS3Resume
339 ASSERT_EFI_ERROR (Status
);
346 This function return SmmLockBox queue address.
348 @return SmmLockBox queue address.
351 InternalGetLockBoxQueue (
355 SMM_LOCK_BOX_CONTEXT
*SmmLockBoxContext
;
357 SmmLockBoxContext
= InternalGetSmmLockBoxContext ();
358 ASSERT (SmmLockBoxContext
!= NULL
);
359 if (SmmLockBoxContext
== NULL
) {
363 return (LIST_ENTRY
*)(UINTN
)SmmLockBoxContext
->LockBoxDataAddress
;
367 This function find LockBox by GUID.
369 @param Guid The guid to indentify the LockBox
374 InternalFindLockBoxByGuid (
379 SMM_LOCK_BOX_DATA
*LockBox
;
380 LIST_ENTRY
*LockBoxQueue
;
382 LockBoxQueue
= InternalGetLockBoxQueue ();
383 ASSERT (LockBoxQueue
!= NULL
);
385 for (Link
= LockBoxQueue
->ForwardLink
;
386 Link
!= LockBoxQueue
;
387 Link
= Link
->ForwardLink
)
394 if (CompareGuid (&LockBox
->Guid
, Guid
)) {
403 This function will save confidential information to lockbox.
405 @param Guid the guid to identify the confidential information
406 @param Buffer the address of the confidential information
407 @param Length the length of the confidential information
409 @retval RETURN_SUCCESS the information is saved successfully.
410 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
411 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
412 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
413 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
414 @retval RETURN_NOT_STARTED it is too early to invoke this interface
415 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
425 SMM_LOCK_BOX_DATA
*LockBox
;
426 EFI_PHYSICAL_ADDRESS SmramBuffer
;
428 LIST_ENTRY
*LockBoxQueue
;
430 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));
435 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
436 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
437 return EFI_INVALID_PARAMETER
;
443 LockBox
= InternalFindLockBoxByGuid (Guid
);
444 if (LockBox
!= NULL
) {
445 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED
));
446 return EFI_ALREADY_STARTED
;
450 // Allocate SMRAM buffer
452 Status
= gMmst
->MmAllocatePages (
454 EfiRuntimeServicesData
,
455 EFI_SIZE_TO_PAGES (Length
),
458 ASSERT_EFI_ERROR (Status
);
459 if (EFI_ERROR (Status
)) {
460 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
461 return EFI_OUT_OF_RESOURCES
;
467 Status
= gMmst
->MmAllocatePool (
468 EfiRuntimeServicesData
,
472 ASSERT_EFI_ERROR (Status
);
473 if (EFI_ERROR (Status
)) {
474 gMmst
->MmFreePages (SmramBuffer
, EFI_SIZE_TO_PAGES (Length
));
475 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
476 return EFI_OUT_OF_RESOURCES
;
482 CopyMem ((VOID
*)(UINTN
)SmramBuffer
, (VOID
*)(UINTN
)Buffer
, Length
);
485 // Insert LockBox to queue
487 LockBox
->Signature
= SMM_LOCK_BOX_DATA_SIGNATURE
;
488 CopyMem (&LockBox
->Guid
, Guid
, sizeof (EFI_GUID
));
489 LockBox
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
490 LockBox
->Length
= (UINT64
)Length
;
491 LockBox
->Attributes
= 0;
492 LockBox
->SmramBuffer
= SmramBuffer
;
496 "LockBoxGuid - %g, SmramBuffer - 0x%lx, Length - 0x%lx\n",
498 LockBox
->SmramBuffer
,
502 LockBoxQueue
= InternalGetLockBoxQueue ();
503 ASSERT (LockBoxQueue
!= NULL
);
504 InsertTailList (LockBoxQueue
, &LockBox
->Link
);
509 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS
));
514 This function will set lockbox attributes.
516 @param Guid the guid to identify the confidential information
517 @param Attributes the attributes of the lockbox
519 @retval RETURN_SUCCESS the information is saved successfully.
520 @retval RETURN_INVALID_PARAMETER attributes is invalid.
521 @retval RETURN_NOT_FOUND the requested GUID not found.
522 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
523 @retval RETURN_NOT_STARTED it is too early to invoke this interface
524 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
528 SetLockBoxAttributes (
533 SMM_LOCK_BOX_DATA
*LockBox
;
535 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));
540 if ((Guid
== NULL
) ||
541 ((Attributes
& ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
| LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
)) != 0))
543 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER
));
544 return EFI_INVALID_PARAMETER
;
547 if (((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
548 ((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0))
550 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER
));
551 DEBUG ((DEBUG_INFO
, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
552 DEBUG ((DEBUG_INFO
, " can not be set together\n"));
553 return EFI_INVALID_PARAMETER
;
559 LockBox
= InternalFindLockBoxByGuid (Guid
);
560 if (LockBox
== NULL
) {
561 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND
));
562 return EFI_NOT_FOUND
;
565 if ((((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
566 ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0)) ||
567 (((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
568 ((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0)))
570 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes 0x%lx 0x%lx - Exit (%r)\n", LockBox
->Attributes
, Attributes
, EFI_INVALID_PARAMETER
));
571 DEBUG ((DEBUG_INFO
, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
572 DEBUG ((DEBUG_INFO
, " can not be set together\n"));
573 return EFI_INVALID_PARAMETER
;
579 LockBox
->Attributes
= Attributes
;
584 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS
));
589 This function will update confidential information to lockbox.
591 @param Guid the guid to identify the original confidential information
592 @param Offset the offset of the original confidential information
593 @param Buffer the address of the updated confidential information
594 @param Length the length of the updated confidential information
596 @retval RETURN_SUCCESS the information is saved successfully.
597 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
598 @retval RETURN_NOT_FOUND the requested GUID not found.
599 @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
600 the original buffer to too small to hold new information.
601 @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
602 no enough resource to save the information.
603 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
604 @retval RETURN_NOT_STARTED it is too early to invoke this interface
605 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
616 SMM_LOCK_BOX_DATA
*LockBox
;
617 EFI_PHYSICAL_ADDRESS SmramBuffer
;
620 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));
625 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0) ||
626 (Length
> MAX_UINTN
- Offset
))
628 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
629 return EFI_INVALID_PARAMETER
;
635 LockBox
= InternalFindLockBoxByGuid (Guid
);
636 if (LockBox
== NULL
) {
637 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_NOT_FOUND
));
638 return EFI_NOT_FOUND
;
644 if (LockBox
->Length
< Offset
+ Length
) {
645 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0) {
647 // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is set, enlarge the
652 "SmmLockBoxSmmLib UpdateLockBox - Origin LockBox too small, enlarge.\n"
655 if (EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ((UINTN
)LockBox
->Length
)) < Offset
+ Length
) {
657 // In SaveLockBox(), the SMRAM buffer allocated for LockBox is of page
658 // granularity. Here, if the required size is larger than the origin size
659 // of the pages, allocate new buffer from SMRAM to enlarge the LockBox.
663 "SmmLockBoxSmmLib UpdateLockBox - Allocate new buffer to enlarge.\n"
665 Status
= gMmst
->MmAllocatePages (
667 EfiRuntimeServicesData
,
668 EFI_SIZE_TO_PAGES (Offset
+ Length
),
671 if (EFI_ERROR (Status
)) {
672 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
673 return EFI_OUT_OF_RESOURCES
;
677 // Copy origin data to the new SMRAM buffer and wipe the content in the
678 // origin SMRAM buffer.
680 CopyMem ((VOID
*)(UINTN
)SmramBuffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
681 ZeroMem ((VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
682 gMmst
->MmFreePages (LockBox
->SmramBuffer
, EFI_SIZE_TO_PAGES ((UINTN
)LockBox
->Length
));
684 LockBox
->SmramBuffer
= SmramBuffer
;
688 // Handle uninitialized content in the LockBox.
690 if (Offset
> LockBox
->Length
) {
692 (VOID
*)((UINTN
)LockBox
->SmramBuffer
+ (UINTN
)LockBox
->Length
),
693 Offset
- (UINTN
)LockBox
->Length
697 LockBox
->Length
= Offset
+ Length
;
700 // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is NOT set, return
701 // EFI_BUFFER_TOO_SMALL directly.
703 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL
));
704 return EFI_BUFFER_TOO_SMALL
;
708 ASSERT ((UINTN
)LockBox
->SmramBuffer
<= (MAX_ADDRESS
- Offset
));
709 CopyMem ((VOID
*)((UINTN
)LockBox
->SmramBuffer
+ Offset
), Buffer
, Length
);
714 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS
));
719 This function will restore confidential information from lockbox.
721 @param Guid the guid to identify the confidential information
722 @param Buffer the address of the restored confidential information
723 NULL means restored to original address, Length MUST be NULL at same time.
724 @param Length the length of the restored confidential information
726 @retval RETURN_SUCCESS the information is restored successfully.
727 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
728 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
729 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
730 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
731 @retval RETURN_NOT_FOUND the requested GUID not found.
732 @retval RETURN_NOT_STARTED it is too early to invoke this interface
733 @retval RETURN_ACCESS_DENIED not allow to restore to the address
734 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
740 IN VOID
*Buffer OPTIONAL
,
741 IN OUT UINTN
*Length OPTIONAL
744 SMM_LOCK_BOX_DATA
*LockBox
;
747 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));
750 // Restore this, Buffer and Length MUST be both NULL or both non-NULL
752 if ((Guid
== NULL
) ||
753 ((Buffer
== NULL
) && (Length
!= NULL
)) ||
754 ((Buffer
!= NULL
) && (Length
== NULL
)))
756 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
757 return EFI_INVALID_PARAMETER
;
763 LockBox
= InternalFindLockBoxByGuid (Guid
);
764 if (LockBox
== NULL
) {
768 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND
));
769 return EFI_NOT_FOUND
;
772 if (((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0) &&
773 mSmmLockBoxSmmReadyToLock
&&
774 !mSmmLockBoxDuringS3Resume
)
777 // With LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
778 // this LockBox can be restored in S3 resume only.
780 return EFI_ACCESS_DENIED
;
786 if (Buffer
!= NULL
) {
788 // restore to new buffer
790 RestoreBuffer
= Buffer
;
793 // restore to original buffer
795 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) == 0) {
796 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED
));
797 return EFI_WRITE_PROTECTED
;
800 RestoreBuffer
= (VOID
*)(UINTN
)LockBox
->Buffer
;
806 if (Length
!= NULL
) {
807 if (*Length
< (UINTN
)LockBox
->Length
) {
809 // Input buffer is too small to hold all data.
811 *Length
= (UINTN
)LockBox
->Length
;
812 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL
));
813 return EFI_BUFFER_TOO_SMALL
;
816 *Length
= (UINTN
)LockBox
->Length
;
822 CopyMem (RestoreBuffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
827 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS
));
832 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
834 @retval RETURN_SUCCESS the information is restored successfully.
835 @retval RETURN_NOT_STARTED it is too early to invoke this interface
836 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
840 RestoreAllLockBoxInPlace (
844 SMM_LOCK_BOX_DATA
*LockBox
;
846 LIST_ENTRY
*LockBoxQueue
;
848 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));
850 LockBoxQueue
= InternalGetLockBoxQueue ();
851 ASSERT (LockBoxQueue
!= NULL
);
854 // Restore all, Buffer and Length MUST be NULL
856 for (Link
= LockBoxQueue
->ForwardLink
;
857 Link
!= LockBoxQueue
;
858 Link
= Link
->ForwardLink
)
865 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) {
869 CopyMem ((VOID
*)(UINTN
)LockBox
->Buffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
876 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS
));