3 Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/SmmServicesTableLib.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/SmmReadyToLock.h>
18 #include <Protocol/SmmEndOfDxe.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
< gSmst
->NumberOfTableEntries
; Index
++) {
53 if (CompareGuid (&gSmst
->SmmConfigurationTable
[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
*)gSmst
->SmmConfigurationTable
[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
= gSmst
->SmmLocateProtocol (
146 &gEfiSmmSxDispatch2ProtocolGuid
,
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.
194 @param[in] ImageHandle Image handle of this driver.
195 @param[in] SystemTable A Pointer to the EFI System Table.
198 @return Others Some error occurs.
202 SmmLockBoxSmmConstructor (
203 IN EFI_HANDLE ImageHandle
,
204 IN EFI_SYSTEM_TABLE
*SystemTable
208 SMM_LOCK_BOX_CONTEXT
*SmmLockBoxContext
;
210 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter\n"));
213 // Register SmmReadyToLock notification.
215 Status
= gSmst
->SmmRegisterProtocolNotify (
216 &gEfiSmmReadyToLockProtocolGuid
,
217 SmmLockBoxSmmReadyToLockNotify
,
218 &mSmmLockBoxRegistrationSmmReadyToLock
220 ASSERT_EFI_ERROR (Status
);
223 // Register SmmEndOfDxe notification.
225 Status
= gSmst
->SmmRegisterProtocolNotify (
226 &gEfiSmmEndOfDxeProtocolGuid
,
227 SmmLockBoxSmmEndOfDxeNotify
,
228 &mSmmLockBoxRegistrationSmmEndOfDxe
230 ASSERT_EFI_ERROR (Status
);
233 // Register EndOfS3Resume notification.
235 Status
= gSmst
->SmmRegisterProtocolNotify (
236 &gEdkiiEndOfS3ResumeGuid
,
237 SmmLockBoxEndOfS3ResumeNotify
,
238 &mSmmLockBoxRegistrationEndOfS3Resume
240 ASSERT_EFI_ERROR (Status
);
243 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
245 SmmLockBoxContext
= InternalGetSmmLockBoxContext ();
246 if (SmmLockBoxContext
!= NULL
) {
248 // Find it. That means some other library instance is already run.
249 // No need to install again, just return.
251 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxContext - already installed\n"));
252 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit\n"));
257 // If no one install this, it means this is first instance. Install it.
259 if (sizeof(UINTN
) == sizeof(UINT64
)) {
260 mSmmLockBoxContext
.Signature
= SMM_LOCK_BOX_SIGNATURE_64
;
262 mSmmLockBoxContext
.Signature
= SMM_LOCK_BOX_SIGNATURE_32
;
264 mSmmLockBoxContext
.LockBoxDataAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)&mLockBoxQueue
;
266 Status
= gSmst
->SmmInstallConfigurationTable (
268 &gEfiSmmLockBoxCommunicationGuid
,
270 sizeof(mSmmLockBoxContext
)
272 ASSERT_EFI_ERROR (Status
);
273 mSmmConfigurationTableInstalled
= TRUE
;
275 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN
)&mSmmLockBoxContext
));
276 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN
)&mLockBoxQueue
));
277 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit\n"));
283 Destructor for SmmLockBox library.
284 This is used to uninstall SmmLockBoxCommunication configuration table
285 if it has been installed in Constructor.
287 @param[in] ImageHandle Image handle of this driver.
288 @param[in] SystemTable A Pointer to the EFI System Table.
290 @retval EFI_SUCEESS The destructor always returns EFI_SUCCESS.
295 SmmLockBoxSmmDestructor (
296 IN EFI_HANDLE ImageHandle
,
297 IN EFI_SYSTEM_TABLE
*SystemTable
302 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SmmLockBoxSmmDestructor in %a module\n", gEfiCallerBaseName
));
304 if (mSmmConfigurationTableInstalled
) {
305 Status
= gSmst
->SmmInstallConfigurationTable (
307 &gEfiSmmLockBoxCommunicationGuid
,
311 ASSERT_EFI_ERROR (Status
);
312 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib uninstall SmmLockBoxCommunication configuration table\n"));
315 if (mSmmLockBoxRegistrationSmmReadyToLock
!= NULL
) {
317 // Unregister SmmReadyToLock notification.
319 Status
= gSmst
->SmmRegisterProtocolNotify (
320 &gEfiSmmReadyToLockProtocolGuid
,
322 &mSmmLockBoxRegistrationSmmReadyToLock
324 ASSERT_EFI_ERROR (Status
);
326 if (mSmmLockBoxRegistrationSmmEndOfDxe
!= NULL
) {
328 // Unregister SmmEndOfDxe notification.
330 Status
= gSmst
->SmmRegisterProtocolNotify (
331 &gEfiSmmEndOfDxeProtocolGuid
,
333 &mSmmLockBoxRegistrationSmmEndOfDxe
335 ASSERT_EFI_ERROR (Status
);
337 if (mSmmLockBoxRegistrationEndOfS3Resume
!= NULL
) {
339 // Unregister EndOfS3Resume notification.
341 Status
= gSmst
->SmmRegisterProtocolNotify (
342 &gEdkiiEndOfS3ResumeGuid
,
344 &mSmmLockBoxRegistrationEndOfS3Resume
346 ASSERT_EFI_ERROR (Status
);
353 This function return SmmLockBox queue address.
355 @return SmmLockBox queue address.
358 InternalGetLockBoxQueue (
362 SMM_LOCK_BOX_CONTEXT
*SmmLockBoxContext
;
364 SmmLockBoxContext
= InternalGetSmmLockBoxContext ();
365 ASSERT (SmmLockBoxContext
!= NULL
);
366 if (SmmLockBoxContext
== NULL
) {
369 return (LIST_ENTRY
*)(UINTN
)SmmLockBoxContext
->LockBoxDataAddress
;
373 This function find LockBox by GUID.
375 @param Guid The guid to indentify the LockBox
380 InternalFindLockBoxByGuid (
385 SMM_LOCK_BOX_DATA
*LockBox
;
386 LIST_ENTRY
*LockBoxQueue
;
388 LockBoxQueue
= InternalGetLockBoxQueue ();
389 ASSERT (LockBoxQueue
!= NULL
);
391 for (Link
= LockBoxQueue
->ForwardLink
;
392 Link
!= LockBoxQueue
;
393 Link
= Link
->ForwardLink
) {
399 if (CompareGuid (&LockBox
->Guid
, Guid
)) {
407 This function will save confidential information to lockbox.
409 @param Guid the guid to identify the confidential information
410 @param Buffer the address of the confidential information
411 @param Length the length of the confidential information
413 @retval RETURN_SUCCESS the information is saved successfully.
414 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
415 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
416 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
417 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
418 @retval RETURN_NOT_STARTED it is too early to invoke this interface
419 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
429 SMM_LOCK_BOX_DATA
*LockBox
;
430 EFI_PHYSICAL_ADDRESS SmramBuffer
;
432 LIST_ENTRY
*LockBoxQueue
;
434 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));
439 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
440 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
441 return EFI_INVALID_PARAMETER
;
447 LockBox
= InternalFindLockBoxByGuid (Guid
);
448 if (LockBox
!= NULL
) {
449 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED
));
450 return EFI_ALREADY_STARTED
;
454 // Allocate SMRAM buffer
456 Status
= gSmst
->SmmAllocatePages (
458 EfiRuntimeServicesData
,
459 EFI_SIZE_TO_PAGES (Length
),
462 ASSERT_EFI_ERROR (Status
);
463 if (EFI_ERROR (Status
)) {
464 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
465 return EFI_OUT_OF_RESOURCES
;
471 Status
= gSmst
->SmmAllocatePool (
472 EfiRuntimeServicesData
,
476 ASSERT_EFI_ERROR (Status
);
477 if (EFI_ERROR (Status
)) {
478 gSmst
->SmmFreePages (SmramBuffer
, EFI_SIZE_TO_PAGES (Length
));
479 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES
));
480 return EFI_OUT_OF_RESOURCES
;
486 CopyMem ((VOID
*)(UINTN
)SmramBuffer
, (VOID
*)(UINTN
)Buffer
, Length
);
489 // Insert LockBox to queue
491 LockBox
->Signature
= SMM_LOCK_BOX_DATA_SIGNATURE
;
492 CopyMem (&LockBox
->Guid
, Guid
, sizeof(EFI_GUID
));
493 LockBox
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
494 LockBox
->Length
= (UINT64
)Length
;
495 LockBox
->Attributes
= 0;
496 LockBox
->SmramBuffer
= SmramBuffer
;
500 "LockBoxGuid - %g, SmramBuffer - 0x%lx, Length - 0x%lx\n",
502 LockBox
->SmramBuffer
,
506 LockBoxQueue
= InternalGetLockBoxQueue ();
507 ASSERT (LockBoxQueue
!= NULL
);
508 InsertTailList (LockBoxQueue
, &LockBox
->Link
);
513 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS
));
518 This function will set lockbox attributes.
520 @param Guid the guid to identify the confidential information
521 @param Attributes the attributes of the lockbox
523 @retval RETURN_SUCCESS the information is saved successfully.
524 @retval RETURN_INVALID_PARAMETER attributes is invalid.
525 @retval RETURN_NOT_FOUND the requested GUID not found.
526 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
527 @retval RETURN_NOT_STARTED it is too early to invoke this interface
528 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
532 SetLockBoxAttributes (
537 SMM_LOCK_BOX_DATA
*LockBox
;
539 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));
544 if ((Guid
== NULL
) ||
545 ((Attributes
& ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
| LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
)) != 0)) {
546 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER
));
547 return EFI_INVALID_PARAMETER
;
550 if (((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
551 ((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0)) {
552 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER
));
553 DEBUG ((DEBUG_INFO
, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
554 DEBUG ((DEBUG_INFO
, " can not be set together\n"));
555 return EFI_INVALID_PARAMETER
;
561 LockBox
= InternalFindLockBoxByGuid (Guid
);
562 if (LockBox
== NULL
) {
563 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND
));
564 return EFI_NOT_FOUND
;
567 if ((((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
568 ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0)) ||
569 (((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) &&
570 ((Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0))) {
571 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes 0x%lx 0x%lx - Exit (%r)\n", LockBox
->Attributes
, Attributes
, EFI_INVALID_PARAMETER
));
572 DEBUG ((DEBUG_INFO
, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
573 DEBUG ((DEBUG_INFO
, " can not be set together\n"));
574 return EFI_INVALID_PARAMETER
;
580 LockBox
->Attributes
= Attributes
;
585 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS
));
590 This function will update confidential information to lockbox.
592 @param Guid the guid to identify the original confidential information
593 @param Offset the offset of the original confidential information
594 @param Buffer the address of the updated confidential information
595 @param Length the length of the updated confidential information
597 @retval RETURN_SUCCESS the information is saved successfully.
598 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
599 @retval RETURN_NOT_FOUND the requested GUID not found.
600 @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
601 the original buffer to too small to hold new information.
602 @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
603 no enough resource to save the information.
604 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
605 @retval RETURN_NOT_STARTED it is too early to invoke this interface
606 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
617 SMM_LOCK_BOX_DATA
*LockBox
;
618 EFI_PHYSICAL_ADDRESS SmramBuffer
;
621 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));
626 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0) ||
627 (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
= gSmst
->SmmAllocatePages (
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 gSmst
->SmmFreePages (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
696 LockBox
->Length
= Offset
+ Length
;
699 // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is NOT set, return
700 // EFI_BUFFER_TOO_SMALL directly.
702 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL
));
703 return EFI_BUFFER_TOO_SMALL
;
706 ASSERT ((UINTN
)LockBox
->SmramBuffer
<= (MAX_ADDRESS
- Offset
));
707 CopyMem ((VOID
*)((UINTN
)LockBox
->SmramBuffer
+ Offset
), Buffer
, Length
);
712 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS
));
717 This function will restore confidential information from lockbox.
719 @param Guid the guid to identify the confidential information
720 @param Buffer the address of the restored confidential information
721 NULL means restored to original address, Length MUST be NULL at same time.
722 @param Length the length of the restored confidential information
724 @retval RETURN_SUCCESS the information is restored successfully.
725 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
726 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
727 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
728 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
729 @retval RETURN_NOT_FOUND the requested GUID not found.
730 @retval RETURN_NOT_STARTED it is too early to invoke this interface
731 @retval RETURN_ACCESS_DENIED not allow to restore to the address
732 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
738 IN VOID
*Buffer
, OPTIONAL
739 IN OUT UINTN
*Length OPTIONAL
742 SMM_LOCK_BOX_DATA
*LockBox
;
745 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));
748 // Restore this, Buffer and Length MUST be both NULL or both non-NULL
750 if ((Guid
== NULL
) ||
751 ((Buffer
== NULL
) && (Length
!= NULL
)) ||
752 ((Buffer
!= NULL
) && (Length
== NULL
))) {
753 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER
));
754 return EFI_INVALID_PARAMETER
;
760 LockBox
= InternalFindLockBoxByGuid (Guid
);
761 if (LockBox
== NULL
) {
765 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND
));
766 return EFI_NOT_FOUND
;
769 if (((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
) != 0) &&
770 mSmmLockBoxSmmReadyToLock
&&
771 !mSmmLockBoxDuringS3Resume
) {
773 // With LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
774 // this LockBox can be restored in S3 resume only.
776 return EFI_ACCESS_DENIED
;
782 if (Buffer
!= NULL
) {
784 // restore to new buffer
786 RestoreBuffer
= Buffer
;
789 // restore to original buffer
791 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) == 0) {
792 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED
));
793 return EFI_WRITE_PROTECTED
;
795 RestoreBuffer
= (VOID
*)(UINTN
)LockBox
->Buffer
;
801 if (Length
!= NULL
) {
802 if (*Length
< (UINTN
)LockBox
->Length
) {
804 // Input buffer is too small to hold all data.
806 *Length
= (UINTN
)LockBox
->Length
;
807 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL
));
808 return EFI_BUFFER_TOO_SMALL
;
810 *Length
= (UINTN
)LockBox
->Length
;
816 CopyMem (RestoreBuffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
821 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS
));
826 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
828 @retval RETURN_SUCCESS the information is restored successfully.
829 @retval RETURN_NOT_STARTED it is too early to invoke this interface
830 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
834 RestoreAllLockBoxInPlace (
838 SMM_LOCK_BOX_DATA
*LockBox
;
840 LIST_ENTRY
*LockBoxQueue
;
842 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));
844 LockBoxQueue
= InternalGetLockBoxQueue ();
845 ASSERT (LockBoxQueue
!= NULL
);
848 // Restore all, Buffer and Length MUST be NULL
850 for (Link
= LockBoxQueue
->ForwardLink
;
851 Link
!= LockBoxQueue
;
852 Link
= Link
->ForwardLink
) {
858 if ((LockBox
->Attributes
& LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
) != 0) {
862 CopyMem ((VOID
*)(UINTN
)LockBox
->Buffer
, (VOID
*)(UINTN
)LockBox
->SmramBuffer
, (UINTN
)LockBox
->Length
);
868 DEBUG ((DEBUG_INFO
, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS
));