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
;
259 mSmmLockBoxContext
.LockBoxDataAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)&mLockBoxQueue
;
261 Status
= gMmst
->MmInstallConfigurationTable (
263 &gEfiSmmLockBoxCommunicationGuid
,
265 sizeof(mSmmLockBoxContext
)
267 ASSERT_EFI_ERROR (Status
);
268 mSmmConfigurationTableInstalled
= TRUE
;
270 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN
)&mSmmLockBoxContext
));
271 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN
)&mLockBoxQueue
));
272 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxMmConstructor - Exit\n"));
278 Destructor for SmmLockBox library.
279 This is used to uninstall SmmLockBoxCommunication configuration table
280 if it has been installed in Constructor.
282 @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.
286 SmmLockBoxMmDestructor (
292 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxMmDestructor in %a module\n", gEfiCallerBaseName
));
294 if (mSmmConfigurationTableInstalled
) {
295 Status
= gMmst
->MmInstallConfigurationTable (
297 &gEfiSmmLockBoxCommunicationGuid
,
301 ASSERT_EFI_ERROR (Status
);
302 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib uninstall SmmLockBoxCommunication configuration table\n"));
305 if (mSmmLockBoxRegistrationSmmReadyToLock
!= NULL
) {
307 // Unregister SmmReadyToLock notification.
309 Status
= gMmst
->MmRegisterProtocolNotify (
310 &gEfiMmReadyToLockProtocolGuid
,
312 &mSmmLockBoxRegistrationSmmReadyToLock
314 ASSERT_EFI_ERROR (Status
);
316 if (mSmmLockBoxRegistrationSmmEndOfDxe
!= NULL
) {
318 // Unregister SmmEndOfDxe notification.
320 Status
= gMmst
->MmRegisterProtocolNotify (
321 &gEfiMmEndOfDxeProtocolGuid
,
323 &mSmmLockBoxRegistrationSmmEndOfDxe
325 ASSERT_EFI_ERROR (Status
);
327 if (mSmmLockBoxRegistrationEndOfS3Resume
!= NULL
) {
329 // Unregister EndOfS3Resume notification.
331 Status
= gMmst
->MmRegisterProtocolNotify (
332 &gEdkiiEndOfS3ResumeGuid
,
334 &mSmmLockBoxRegistrationEndOfS3Resume
336 ASSERT_EFI_ERROR (Status
);
343 This function return SmmLockBox queue address.
345 @return SmmLockBox queue address.
348 InternalGetLockBoxQueue (
352 SMM_LOCK_BOX_CONTEXT
*SmmLockBoxContext
;
354 SmmLockBoxContext
= InternalGetSmmLockBoxContext ();
355 ASSERT (SmmLockBoxContext
!= NULL
);
356 if (SmmLockBoxContext
== NULL
) {
359 return (LIST_ENTRY
*)(UINTN
)SmmLockBoxContext
->LockBoxDataAddress
;
363 This function find LockBox by GUID.
365 @param Guid The guid to indentify the LockBox
370 InternalFindLockBoxByGuid (
375 SMM_LOCK_BOX_DATA
*LockBox
;
376 LIST_ENTRY
*LockBoxQueue
;
378 LockBoxQueue
= InternalGetLockBoxQueue ();
379 ASSERT (LockBoxQueue
!= NULL
);
381 for (Link
= LockBoxQueue
->ForwardLink
;
382 Link
!= LockBoxQueue
;
383 Link
= Link
->ForwardLink
) {
389 if (CompareGuid (&LockBox
->Guid
, Guid
)) {
397 This function will save confidential information to lockbox.
399 @param Guid the guid to identify the confidential information
400 @param Buffer the address of the confidential information
401 @param Length the length of the confidential information
403 @retval RETURN_SUCCESS the information is saved successfully.
404 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
405 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
406 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
407 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
408 @retval RETURN_NOT_STARTED it is too early to invoke this interface
409 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
419 SMM_LOCK_BOX_DATA
*LockBox
;
420 EFI_PHYSICAL_ADDRESS SmramBuffer
;
422 LIST_ENTRY
*LockBoxQueue
;
424 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));
429 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
430 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
431 return EFI_INVALID_PARAMETER
;
437 LockBox
= InternalFindLockBoxByGuid (Guid
);
438 if (LockBox
!= NULL
) {
439 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED
));
440 return EFI_ALREADY_STARTED
;
444 // Allocate SMRAM buffer
446 Status
= gMmst
->MmAllocatePages (
448 EfiRuntimeServicesData
,
449 EFI_SIZE_TO_PAGES (Length
),
452 ASSERT_EFI_ERROR (Status
);
453 if (EFI_ERROR (Status
)) {
454 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
455 return EFI_OUT_OF_RESOURCES
;
461 Status
= gMmst
->MmAllocatePool (
462 EfiRuntimeServicesData
,
466 ASSERT_EFI_ERROR (Status
);
467 if (EFI_ERROR (Status
)) {
468 gMmst
->MmFreePages (SmramBuffer
, EFI_SIZE_TO_PAGES (Length
));
469 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
470 return EFI_OUT_OF_RESOURCES
;
476 CopyMem ((VOID
*)(UINTN
)SmramBuffer
, (VOID
*)(UINTN
)Buffer
, Length
);
479 // Insert LockBox to queue
481 LockBox
->Signature
= SMM_LOCK_BOX_DATA_SIGNATURE
;
482 CopyMem (&LockBox
->Guid
, Guid
, sizeof(EFI_GUID
));
483 LockBox
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
484 LockBox
->Length
= (UINT64
)Length
;
485 LockBox
->Attributes
= 0;
486 LockBox
->SmramBuffer
= SmramBuffer
;
490 "LockBoxGuid - %g, SmramBuffer - 0x%lx, Length - 0x%lx\n",
492 LockBox
->SmramBuffer
,
496 LockBoxQueue
= InternalGetLockBoxQueue ();
497 ASSERT (LockBoxQueue
!= NULL
);
498 InsertTailList (LockBoxQueue
, &LockBox
->Link
);
503 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS
));
508 This function will set lockbox attributes.
510 @param Guid the guid to identify the confidential information
511 @param Attributes the attributes of the lockbox
513 @retval RETURN_SUCCESS the information is saved successfully.
514 @retval RETURN_INVALID_PARAMETER attributes is invalid.
515 @retval RETURN_NOT_FOUND the requested GUID not found.
516 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
517 @retval RETURN_NOT_STARTED it is too early to invoke this interface
518 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
522 SetLockBoxAttributes (
527 SMM_LOCK_BOX_DATA
*LockBox
;
529 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));
534 if ((Guid
== NULL
) ||
535 ((Attributes
& ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
| LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
)) != 0)) {
536 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER
));
537 return EFI_INVALID_PARAMETER
;
540 if (((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
541 ((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0)) {
542 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER
));
543 DEBUG ((DEBUG_INFO
, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
544 DEBUG ((DEBUG_INFO
, " can not be set together\n"));
545 return EFI_INVALID_PARAMETER
;
551 LockBox
= InternalFindLockBoxByGuid (Guid
);
552 if (LockBox
== NULL
) {
553 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND
));
554 return EFI_NOT_FOUND
;
557 if ((((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
558 ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0)) ||
559 (((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
560 ((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0))) {
561 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes 0x%lx 0x%lx - Exit (%r)\n", LockBox
->Attributes
, Attributes
, EFI_INVALID_PARAMETER
));
562 DEBUG ((DEBUG_INFO
, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
563 DEBUG ((DEBUG_INFO
, " can not be set together\n"));
564 return EFI_INVALID_PARAMETER
;
570 LockBox
->Attributes
= Attributes
;
575 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS
));
580 This function will update confidential information to lockbox.
582 @param Guid the guid to identify the original confidential information
583 @param Offset the offset of the original confidential information
584 @param Buffer the address of the updated confidential information
585 @param Length the length of the updated confidential information
587 @retval RETURN_SUCCESS the information is saved successfully.
588 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
589 @retval RETURN_NOT_FOUND the requested GUID not found.
590 @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
591 the original buffer to too small to hold new information.
592 @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
593 no enough resource to save the information.
594 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
595 @retval RETURN_NOT_STARTED it is too early to invoke this interface
596 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
607 SMM_LOCK_BOX_DATA
*LockBox
;
608 EFI_PHYSICAL_ADDRESS SmramBuffer
;
611 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));
616 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0) ||
617 (Length
> MAX_UINTN
- Offset
)) {
618 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
619 return EFI_INVALID_PARAMETER
;
625 LockBox
= InternalFindLockBoxByGuid (Guid
);
626 if (LockBox
== NULL
) {
627 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_NOT_FOUND
));
628 return EFI_NOT_FOUND
;
634 if (LockBox
->Length
< Offset
+ Length
) {
635 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0) {
637 // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is set, enlarge the
642 "SmmLockBoxSmmLib UpdateLockBox - Origin LockBox too small, enlarge.\n"
645 if (EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ((UINTN
)LockBox
->Length
)) < Offset
+ Length
) {
647 // In SaveLockBox(), the SMRAM buffer allocated for LockBox is of page
648 // granularity. Here, if the required size is larger than the origin size
649 // of the pages, allocate new buffer from SMRAM to enlarge the LockBox.
653 "SmmLockBoxSmmLib UpdateLockBox - Allocate new buffer to enlarge.\n"
655 Status
= gMmst
->MmAllocatePages (
657 EfiRuntimeServicesData
,
658 EFI_SIZE_TO_PAGES (Offset
+ Length
),
661 if (EFI_ERROR (Status
)) {
662 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
663 return EFI_OUT_OF_RESOURCES
;
667 // Copy origin data to the new SMRAM buffer and wipe the content in the
668 // origin SMRAM buffer.
670 CopyMem ((VOID
*)(UINTN
)SmramBuffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
671 ZeroMem ((VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
672 gMmst
->MmFreePages (LockBox
->SmramBuffer
, EFI_SIZE_TO_PAGES ((UINTN
)LockBox
->Length
));
674 LockBox
->SmramBuffer
= SmramBuffer
;
678 // Handle uninitialized content in the LockBox.
680 if (Offset
> LockBox
->Length
) {
682 (VOID
*)((UINTN
)LockBox
->SmramBuffer
+ (UINTN
)LockBox
->Length
),
683 Offset
- (UINTN
)LockBox
->Length
686 LockBox
->Length
= Offset
+ Length
;
689 // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is NOT set, return
690 // EFI_BUFFER_TOO_SMALL directly.
692 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL
));
693 return EFI_BUFFER_TOO_SMALL
;
696 ASSERT ((UINTN
)LockBox
->SmramBuffer
<= (MAX_ADDRESS
- Offset
));
697 CopyMem ((VOID
*)((UINTN
)LockBox
->SmramBuffer
+ Offset
), Buffer
, Length
);
702 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS
));
707 This function will restore confidential information from lockbox.
709 @param Guid the guid to identify the confidential information
710 @param Buffer the address of the restored confidential information
711 NULL means restored to original address, Length MUST be NULL at same time.
712 @param Length the length of the restored confidential information
714 @retval RETURN_SUCCESS the information is restored successfully.
715 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
716 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
717 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
718 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
719 @retval RETURN_NOT_FOUND the requested GUID not found.
720 @retval RETURN_NOT_STARTED it is too early to invoke this interface
721 @retval RETURN_ACCESS_DENIED not allow to restore to the address
722 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
728 IN VOID
*Buffer
, OPTIONAL
729 IN OUT UINTN
*Length OPTIONAL
732 SMM_LOCK_BOX_DATA
*LockBox
;
735 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));
738 // Restore this, Buffer and Length MUST be both NULL or both non-NULL
740 if ((Guid
== NULL
) ||
741 ((Buffer
== NULL
) && (Length
!= NULL
)) ||
742 ((Buffer
!= NULL
) && (Length
== NULL
))) {
743 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
744 return EFI_INVALID_PARAMETER
;
750 LockBox
= InternalFindLockBoxByGuid (Guid
);
751 if (LockBox
== NULL
) {
755 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND
));
756 return EFI_NOT_FOUND
;
759 if (((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0) &&
760 mSmmLockBoxSmmReadyToLock
&&
761 !mSmmLockBoxDuringS3Resume
) {
763 // With LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
764 // this LockBox can be restored in S3 resume only.
766 return EFI_ACCESS_DENIED
;
772 if (Buffer
!= NULL
) {
774 // restore to new buffer
776 RestoreBuffer
= Buffer
;
779 // restore to original buffer
781 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) == 0) {
782 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED
));
783 return EFI_WRITE_PROTECTED
;
785 RestoreBuffer
= (VOID
*)(UINTN
)LockBox
->Buffer
;
791 if (Length
!= NULL
) {
792 if (*Length
< (UINTN
)LockBox
->Length
) {
794 // Input buffer is too small to hold all data.
796 *Length
= (UINTN
)LockBox
->Length
;
797 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL
));
798 return EFI_BUFFER_TOO_SMALL
;
800 *Length
= (UINTN
)LockBox
->Length
;
806 CopyMem (RestoreBuffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
811 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS
));
816 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
818 @retval RETURN_SUCCESS the information is restored successfully.
819 @retval RETURN_NOT_STARTED it is too early to invoke this interface
820 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
824 RestoreAllLockBoxInPlace (
828 SMM_LOCK_BOX_DATA
*LockBox
;
830 LIST_ENTRY
*LockBoxQueue
;
832 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));
834 LockBoxQueue
= InternalGetLockBoxQueue ();
835 ASSERT (LockBoxQueue
!= NULL
);
838 // Restore all, Buffer and Length MUST be NULL
840 for (Link
= LockBoxQueue
->ForwardLink
;
841 Link
!= LockBoxQueue
;
842 Link
= Link
->ForwardLink
) {
848 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) {
852 CopyMem ((VOID
*)(UINTN
)LockBox
->Buffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
858 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS
));