3 Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/UefiBootServicesTableLib.h>
11 #include <Library/UefiRuntimeServicesTableLib.h>
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/LockBoxLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/UefiLib.h>
17 #include <Protocol/SmmCommunication.h>
18 #include <Guid/SmmLockBox.h>
19 #include <Guid/PiSmmCommunicationRegionTable.h>
21 #include "SmmLockBoxLibPrivate.h"
23 EFI_SMM_COMMUNICATION_PROTOCOL
*mLockBoxSmmCommProtocol
= NULL
;
24 UINT8
*mLockBoxSmmCommBuffer
= NULL
;
27 Get smm communication protocol for lockbox.
29 @return Pointer to smm communication protocol, NULL if not found.
32 EFI_SMM_COMMUNICATION_PROTOCOL
*
33 LockBoxGetSmmCommProtocol (
40 // If the protocol has been got previously, return it.
42 if (mLockBoxSmmCommProtocol
!= NULL
) {
43 return mLockBoxSmmCommProtocol
;
46 Status
= gBS
->LocateProtocol (
47 &gEfiSmmCommunicationProtocolGuid
,
49 (VOID
**)&mLockBoxSmmCommProtocol
51 if (EFI_ERROR (Status
)) {
52 mLockBoxSmmCommProtocol
= NULL
;
54 return mLockBoxSmmCommProtocol
;
58 Get smm communication buffer for lockbox.
60 @return Pointer to smm communication buffer, NULL if not found.
64 LockBoxGetSmmCommBuffer (
69 UINTN MinimalSizeNeeded
;
70 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
72 EFI_MEMORY_DESCRIPTOR
*Entry
;
76 // If the buffer has been got previously, return it.
78 if (mLockBoxSmmCommBuffer
!= NULL
) {
79 return mLockBoxSmmCommBuffer
;
82 MinimalSizeNeeded
= sizeof (EFI_GUID
) +
84 MAX (sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
),
85 MAX (sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
),
86 MAX (sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
),
87 MAX (sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
),
88 sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)))));
90 Status
= EfiGetSystemConfigurationTable (
91 &gEdkiiPiSmmCommunicationRegionTableGuid
,
92 (VOID
**) &PiSmmCommunicationRegionTable
94 if (EFI_ERROR (Status
)) {
95 mLockBoxSmmCommBuffer
= NULL
;
96 return mLockBoxSmmCommBuffer
;
98 ASSERT (PiSmmCommunicationRegionTable
!= NULL
);
99 Entry
= (EFI_MEMORY_DESCRIPTOR
*) (PiSmmCommunicationRegionTable
+ 1);
101 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
102 if (Entry
->Type
== EfiConventionalMemory
) {
103 Size
= EFI_PAGES_TO_SIZE ((UINTN
) Entry
->NumberOfPages
);
104 if (Size
>= MinimalSizeNeeded
) {
108 Entry
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
110 if (Index
>= PiSmmCommunicationRegionTable
->NumberOfEntries
) {
111 mLockBoxSmmCommBuffer
= NULL
;
113 mLockBoxSmmCommBuffer
= (UINT8
*) (UINTN
) Entry
->PhysicalStart
;
115 return mLockBoxSmmCommBuffer
;
119 This function will save confidential information to lockbox.
121 @param Guid the guid to identify the confidential information
122 @param Buffer the address of the confidential information
123 @param Length the length of the confidential information
125 @retval RETURN_SUCCESS the information is saved successfully.
126 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
127 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
128 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
129 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
130 @retval RETURN_NOT_STARTED it is too early to invoke this interface
131 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
142 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
143 EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*LockBoxParameterSave
;
144 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
145 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE
)];
149 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SaveLockBox - Enter\n"));
154 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
155 return EFI_INVALID_PARAMETER
;
158 SmmCommunication
= LockBoxGetSmmCommProtocol ();
159 if (SmmCommunication
== NULL
) {
160 return EFI_NOT_STARTED
;
166 CommBuffer
= LockBoxGetSmmCommBuffer ();
167 if (CommBuffer
== NULL
) {
168 CommBuffer
= &TempCommBuffer
[0];
170 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
171 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
172 CommHeader
->MessageLength
= sizeof(*LockBoxParameterSave
);
174 LockBoxParameterSave
= (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
175 LockBoxParameterSave
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_SAVE
;
176 LockBoxParameterSave
->Header
.DataLength
= sizeof(*LockBoxParameterSave
);
177 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)-1;
178 CopyMem (&LockBoxParameterSave
->Guid
, Guid
, sizeof(*Guid
));
179 LockBoxParameterSave
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
180 LockBoxParameterSave
->Length
= (UINT64
)Length
;
185 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE
);
186 Status
= SmmCommunication
->Communicate (
191 ASSERT_EFI_ERROR (Status
);
193 Status
= (EFI_STATUS
)LockBoxParameterSave
->Header
.ReturnStatus
;
195 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SaveLockBox - Exit (%r)\n", Status
));
204 This function will set lockbox attributes.
206 @param Guid the guid to identify the confidential information
207 @param Attributes the attributes of the lockbox
209 @retval RETURN_SUCCESS the information is saved successfully.
210 @retval RETURN_INVALID_PARAMETER attributes is invalid.
211 @retval RETURN_NOT_FOUND the requested GUID not found.
212 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
213 @retval RETURN_NOT_STARTED it is too early to invoke this interface
214 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
218 SetLockBoxAttributes (
224 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
225 EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*LockBoxParameterSetAttributes
;
226 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
227 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
)];
231 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SetLockBoxAttributes - Enter\n"));
236 if ((Guid
== NULL
) ||
237 ((Attributes
& ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
| LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
)) != 0)) {
238 return EFI_INVALID_PARAMETER
;
241 SmmCommunication
= LockBoxGetSmmCommProtocol ();
242 if (SmmCommunication
== NULL
) {
243 return EFI_NOT_STARTED
;
249 CommBuffer
= LockBoxGetSmmCommBuffer ();
250 if (CommBuffer
== NULL
) {
251 CommBuffer
= &TempCommBuffer
[0];
253 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
254 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
255 CommHeader
->MessageLength
= sizeof(*LockBoxParameterSetAttributes
);
257 LockBoxParameterSetAttributes
= (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
258 LockBoxParameterSetAttributes
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES
;
259 LockBoxParameterSetAttributes
->Header
.DataLength
= sizeof(*LockBoxParameterSetAttributes
);
260 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)-1;
261 CopyMem (&LockBoxParameterSetAttributes
->Guid
, Guid
, sizeof(*Guid
));
262 LockBoxParameterSetAttributes
->Attributes
= (UINT64
)Attributes
;
267 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
);
268 Status
= SmmCommunication
->Communicate (
273 ASSERT_EFI_ERROR (Status
);
275 Status
= (EFI_STATUS
)LockBoxParameterSetAttributes
->Header
.ReturnStatus
;
277 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SetLockBoxAttributes - Exit (%r)\n", Status
));
286 This function will update confidential information to lockbox.
288 @param Guid the guid to identify the original confidential information
289 @param Offset the offset of the original confidential information
290 @param Buffer the address of the updated confidential information
291 @param Length the length of the updated confidential information
293 @retval RETURN_SUCCESS the information is saved successfully.
294 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
295 @retval RETURN_NOT_FOUND the requested GUID not found.
296 @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
297 the original buffer to too small to hold new information.
298 @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
299 no enough resource to save the information.
300 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
301 @retval RETURN_NOT_STARTED it is too early to invoke this interface
302 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
314 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
315 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*LockBoxParameterUpdate
;
316 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
317 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
)];
321 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib UpdateLockBox - Enter\n"));
326 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
327 return EFI_INVALID_PARAMETER
;
330 SmmCommunication
= LockBoxGetSmmCommProtocol ();
331 if (SmmCommunication
== NULL
) {
332 return EFI_NOT_STARTED
;
338 CommBuffer
= LockBoxGetSmmCommBuffer ();
339 if (CommBuffer
== NULL
) {
340 CommBuffer
= &TempCommBuffer
[0];
342 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
343 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
344 CommHeader
->MessageLength
= sizeof(*LockBoxParameterUpdate
);
346 LockBoxParameterUpdate
= (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*)(UINTN
)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
347 LockBoxParameterUpdate
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_UPDATE
;
348 LockBoxParameterUpdate
->Header
.DataLength
= sizeof(*LockBoxParameterUpdate
);
349 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)-1;
350 CopyMem (&LockBoxParameterUpdate
->Guid
, Guid
, sizeof(*Guid
));
351 LockBoxParameterUpdate
->Offset
= (UINT64
)Offset
;
352 LockBoxParameterUpdate
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
353 LockBoxParameterUpdate
->Length
= (UINT64
)Length
;
358 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
);
359 Status
= SmmCommunication
->Communicate (
364 ASSERT_EFI_ERROR (Status
);
366 Status
= (EFI_STATUS
)LockBoxParameterUpdate
->Header
.ReturnStatus
;
368 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib UpdateLockBox - Exit (%r)\n", Status
));
377 This function will restore confidential information from lockbox.
379 @param Guid the guid to identify the confidential information
380 @param Buffer the address of the restored confidential information
381 NULL means restored to original address, Length MUST be NULL at same time.
382 @param Length the length of the restored confidential information
384 @retval RETURN_SUCCESS the information is restored successfully.
385 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
386 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
387 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
388 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
389 @retval RETURN_NOT_FOUND the requested GUID not found.
390 @retval RETURN_NOT_STARTED it is too early to invoke this interface
391 @retval RETURN_ACCESS_DENIED not allow to restore to the address
392 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
398 IN VOID
*Buffer
, OPTIONAL
399 IN OUT UINTN
*Length OPTIONAL
403 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
404 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*LockBoxParameterRestore
;
405 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
406 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
)];
410 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreLockBox - Enter\n"));
415 if ((Guid
== NULL
) ||
416 ((Buffer
== NULL
) && (Length
!= NULL
)) ||
417 ((Buffer
!= NULL
) && (Length
== NULL
))) {
418 return EFI_INVALID_PARAMETER
;
421 SmmCommunication
= LockBoxGetSmmCommProtocol ();
422 if (SmmCommunication
== NULL
) {
423 return EFI_NOT_STARTED
;
429 CommBuffer
= LockBoxGetSmmCommBuffer ();
430 if (CommBuffer
== NULL
) {
431 CommBuffer
= &TempCommBuffer
[0];
433 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
434 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
435 CommHeader
->MessageLength
= sizeof(*LockBoxParameterRestore
);
437 LockBoxParameterRestore
= (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
438 LockBoxParameterRestore
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_RESTORE
;
439 LockBoxParameterRestore
->Header
.DataLength
= sizeof(*LockBoxParameterRestore
);
440 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)-1;
441 CopyMem (&LockBoxParameterRestore
->Guid
, Guid
, sizeof(*Guid
));
442 LockBoxParameterRestore
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
443 if (Length
!= NULL
) {
444 LockBoxParameterRestore
->Length
= (EFI_PHYSICAL_ADDRESS
)*Length
;
446 LockBoxParameterRestore
->Length
= 0;
452 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
);
453 Status
= SmmCommunication
->Communicate (
458 ASSERT_EFI_ERROR (Status
);
460 if (Length
!= NULL
) {
461 *Length
= (UINTN
)LockBoxParameterRestore
->Length
;
464 Status
= (EFI_STATUS
)LockBoxParameterRestore
->Header
.ReturnStatus
;
466 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreLockBox - Exit (%r)\n", Status
));
475 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
477 @retval RETURN_SUCCESS the information is restored successfully.
478 @retval RETURN_NOT_STARTED it is too early to invoke this interface
479 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
483 RestoreAllLockBoxInPlace (
488 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
489 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*LockBoxParameterRestoreAllInPlace
;
490 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
491 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)];
495 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Enter\n"));
497 SmmCommunication
= LockBoxGetSmmCommProtocol ();
498 if (SmmCommunication
== NULL
) {
499 return EFI_NOT_STARTED
;
505 CommBuffer
= LockBoxGetSmmCommBuffer ();
506 if (CommBuffer
== NULL
) {
507 CommBuffer
= &TempCommBuffer
[0];
509 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
510 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
511 CommHeader
->MessageLength
= sizeof(*LockBoxParameterRestoreAllInPlace
);
513 LockBoxParameterRestoreAllInPlace
= (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
514 LockBoxParameterRestoreAllInPlace
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE
;
515 LockBoxParameterRestoreAllInPlace
->Header
.DataLength
= sizeof(*LockBoxParameterRestoreAllInPlace
);
516 LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
= (UINT64
)-1;
521 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
);
522 Status
= SmmCommunication
->Communicate (
527 ASSERT_EFI_ERROR (Status
);
529 Status
= (EFI_STATUS
)LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
;
531 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status
));