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
;
55 return mLockBoxSmmCommProtocol
;
59 Get smm communication buffer for lockbox.
61 @return Pointer to smm communication buffer, NULL if not found.
65 LockBoxGetSmmCommBuffer (
70 UINTN MinimalSizeNeeded
;
71 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
73 EFI_MEMORY_DESCRIPTOR
*Entry
;
77 // If the buffer has been got previously, return it.
79 if (mLockBoxSmmCommBuffer
!= NULL
) {
80 return mLockBoxSmmCommBuffer
;
83 MinimalSizeNeeded
= sizeof (EFI_GUID
) +
86 sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
),
88 sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
),
90 sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
),
92 sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
),
93 sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)
99 Status
= EfiGetSystemConfigurationTable (
100 &gEdkiiPiSmmCommunicationRegionTableGuid
,
101 (VOID
**)&PiSmmCommunicationRegionTable
103 if (EFI_ERROR (Status
)) {
104 mLockBoxSmmCommBuffer
= NULL
;
105 return mLockBoxSmmCommBuffer
;
108 ASSERT (PiSmmCommunicationRegionTable
!= NULL
);
109 Entry
= (EFI_MEMORY_DESCRIPTOR
*)(PiSmmCommunicationRegionTable
+ 1);
111 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
112 if (Entry
->Type
== EfiConventionalMemory
) {
113 Size
= EFI_PAGES_TO_SIZE ((UINTN
)Entry
->NumberOfPages
);
114 if (Size
>= MinimalSizeNeeded
) {
119 Entry
= (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
122 if (Index
>= PiSmmCommunicationRegionTable
->NumberOfEntries
) {
123 mLockBoxSmmCommBuffer
= NULL
;
125 mLockBoxSmmCommBuffer
= (UINT8
*)(UINTN
)Entry
->PhysicalStart
;
128 return mLockBoxSmmCommBuffer
;
132 This function will save confidential information to lockbox.
134 @param Guid the guid to identify the confidential information
135 @param Buffer the address of the confidential information
136 @param Length the length of the confidential information
138 @retval RETURN_SUCCESS the information is saved successfully.
139 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
140 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
141 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
142 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
143 @retval RETURN_NOT_STARTED it is too early to invoke this interface
144 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
155 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
156 EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*LockBoxParameterSave
;
157 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
158 UINT8 TempCommBuffer
[sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
)];
162 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SaveLockBox - Enter\n"));
167 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
168 return EFI_INVALID_PARAMETER
;
171 SmmCommunication
= LockBoxGetSmmCommProtocol ();
172 if (SmmCommunication
== NULL
) {
173 return EFI_NOT_STARTED
;
179 CommBuffer
= LockBoxGetSmmCommBuffer ();
180 if (CommBuffer
== NULL
) {
181 CommBuffer
= &TempCommBuffer
[0];
184 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
185 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof (gEfiSmmLockBoxCommunicationGuid
));
186 CommHeader
->MessageLength
= sizeof (*LockBoxParameterSave
);
188 LockBoxParameterSave
= (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
189 LockBoxParameterSave
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_SAVE
;
190 LockBoxParameterSave
->Header
.DataLength
= sizeof (*LockBoxParameterSave
);
191 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)-1;
192 CopyMem (&LockBoxParameterSave
->Guid
, Guid
, sizeof (*Guid
));
193 LockBoxParameterSave
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
194 LockBoxParameterSave
->Length
= (UINT64
)Length
;
199 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
);
200 Status
= SmmCommunication
->Communicate (
205 ASSERT_EFI_ERROR (Status
);
207 Status
= (EFI_STATUS
)LockBoxParameterSave
->Header
.ReturnStatus
;
209 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SaveLockBox - Exit (%r)\n", Status
));
218 This function will set lockbox attributes.
220 @param Guid the guid to identify the confidential information
221 @param Attributes the attributes of the lockbox
223 @retval RETURN_SUCCESS the information is saved successfully.
224 @retval RETURN_INVALID_PARAMETER attributes is invalid.
225 @retval RETURN_NOT_FOUND the requested GUID not found.
226 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
227 @retval RETURN_NOT_STARTED it is too early to invoke this interface
228 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
232 SetLockBoxAttributes (
238 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
239 EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*LockBoxParameterSetAttributes
;
240 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
241 UINT8 TempCommBuffer
[sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
)];
245 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SetLockBoxAttributes - Enter\n"));
250 if ((Guid
== NULL
) ||
251 ((Attributes
& ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
| LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
)) != 0))
253 return EFI_INVALID_PARAMETER
;
256 SmmCommunication
= LockBoxGetSmmCommProtocol ();
257 if (SmmCommunication
== NULL
) {
258 return EFI_NOT_STARTED
;
264 CommBuffer
= LockBoxGetSmmCommBuffer ();
265 if (CommBuffer
== NULL
) {
266 CommBuffer
= &TempCommBuffer
[0];
269 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
270 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof (gEfiSmmLockBoxCommunicationGuid
));
271 CommHeader
->MessageLength
= sizeof (*LockBoxParameterSetAttributes
);
273 LockBoxParameterSetAttributes
= (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
274 LockBoxParameterSetAttributes
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES
;
275 LockBoxParameterSetAttributes
->Header
.DataLength
= sizeof (*LockBoxParameterSetAttributes
);
276 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)-1;
277 CopyMem (&LockBoxParameterSetAttributes
->Guid
, Guid
, sizeof (*Guid
));
278 LockBoxParameterSetAttributes
->Attributes
= (UINT64
)Attributes
;
283 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
);
284 Status
= SmmCommunication
->Communicate (
289 ASSERT_EFI_ERROR (Status
);
291 Status
= (EFI_STATUS
)LockBoxParameterSetAttributes
->Header
.ReturnStatus
;
293 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SetLockBoxAttributes - Exit (%r)\n", Status
));
302 This function will update confidential information to lockbox.
304 @param Guid the guid to identify the original confidential information
305 @param Offset the offset of the original confidential information
306 @param Buffer the address of the updated confidential information
307 @param Length the length of the updated confidential information
309 @retval RETURN_SUCCESS the information is saved successfully.
310 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
311 @retval RETURN_NOT_FOUND the requested GUID not found.
312 @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
313 the original buffer to too small to hold new information.
314 @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
315 no enough resource to save the information.
316 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
317 @retval RETURN_NOT_STARTED it is too early to invoke this interface
318 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
330 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
331 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*LockBoxParameterUpdate
;
332 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
333 UINT8 TempCommBuffer
[sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
)];
337 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib UpdateLockBox - Enter\n"));
342 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
343 return EFI_INVALID_PARAMETER
;
346 SmmCommunication
= LockBoxGetSmmCommProtocol ();
347 if (SmmCommunication
== NULL
) {
348 return EFI_NOT_STARTED
;
354 CommBuffer
= LockBoxGetSmmCommBuffer ();
355 if (CommBuffer
== NULL
) {
356 CommBuffer
= &TempCommBuffer
[0];
359 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
360 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof (gEfiSmmLockBoxCommunicationGuid
));
361 CommHeader
->MessageLength
= sizeof (*LockBoxParameterUpdate
);
363 LockBoxParameterUpdate
= (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*)(UINTN
)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
364 LockBoxParameterUpdate
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_UPDATE
;
365 LockBoxParameterUpdate
->Header
.DataLength
= sizeof (*LockBoxParameterUpdate
);
366 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)-1;
367 CopyMem (&LockBoxParameterUpdate
->Guid
, Guid
, sizeof (*Guid
));
368 LockBoxParameterUpdate
->Offset
= (UINT64
)Offset
;
369 LockBoxParameterUpdate
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
370 LockBoxParameterUpdate
->Length
= (UINT64
)Length
;
375 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
);
376 Status
= SmmCommunication
->Communicate (
381 ASSERT_EFI_ERROR (Status
);
383 Status
= (EFI_STATUS
)LockBoxParameterUpdate
->Header
.ReturnStatus
;
385 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib UpdateLockBox - Exit (%r)\n", Status
));
394 This function will restore confidential information from lockbox.
396 @param Guid the guid to identify the confidential information
397 @param Buffer the address of the restored confidential information
398 NULL means restored to original address, Length MUST be NULL at same time.
399 @param Length the length of the restored confidential information
401 @retval RETURN_SUCCESS the information is restored successfully.
402 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
403 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
404 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
405 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
406 @retval RETURN_NOT_FOUND the requested GUID not found.
407 @retval RETURN_NOT_STARTED it is too early to invoke this interface
408 @retval RETURN_ACCESS_DENIED not allow to restore to the address
409 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
415 IN VOID
*Buffer OPTIONAL
,
416 IN OUT UINTN
*Length OPTIONAL
420 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
421 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*LockBoxParameterRestore
;
422 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
423 UINT8 TempCommBuffer
[sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
)];
427 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreLockBox - Enter\n"));
432 if ((Guid
== NULL
) ||
433 ((Buffer
== NULL
) && (Length
!= NULL
)) ||
434 ((Buffer
!= NULL
) && (Length
== NULL
)))
436 return EFI_INVALID_PARAMETER
;
439 SmmCommunication
= LockBoxGetSmmCommProtocol ();
440 if (SmmCommunication
== NULL
) {
441 return EFI_NOT_STARTED
;
447 CommBuffer
= LockBoxGetSmmCommBuffer ();
448 if (CommBuffer
== NULL
) {
449 CommBuffer
= &TempCommBuffer
[0];
452 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
453 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof (gEfiSmmLockBoxCommunicationGuid
));
454 CommHeader
->MessageLength
= sizeof (*LockBoxParameterRestore
);
456 LockBoxParameterRestore
= (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
457 LockBoxParameterRestore
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_RESTORE
;
458 LockBoxParameterRestore
->Header
.DataLength
= sizeof (*LockBoxParameterRestore
);
459 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)-1;
460 CopyMem (&LockBoxParameterRestore
->Guid
, Guid
, sizeof (*Guid
));
461 LockBoxParameterRestore
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
462 if (Length
!= NULL
) {
463 LockBoxParameterRestore
->Length
= (EFI_PHYSICAL_ADDRESS
)*Length
;
465 LockBoxParameterRestore
->Length
= 0;
471 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
);
472 Status
= SmmCommunication
->Communicate (
477 ASSERT_EFI_ERROR (Status
);
479 if (Length
!= NULL
) {
480 *Length
= (UINTN
)LockBoxParameterRestore
->Length
;
483 Status
= (EFI_STATUS
)LockBoxParameterRestore
->Header
.ReturnStatus
;
485 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreLockBox - Exit (%r)\n", Status
));
494 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
496 @retval RETURN_SUCCESS the information is restored successfully.
497 @retval RETURN_NOT_STARTED it is too early to invoke this interface
498 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
502 RestoreAllLockBoxInPlace (
507 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
508 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*LockBoxParameterRestoreAllInPlace
;
509 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
510 UINT8 TempCommBuffer
[sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)];
514 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Enter\n"));
516 SmmCommunication
= LockBoxGetSmmCommProtocol ();
517 if (SmmCommunication
== NULL
) {
518 return EFI_NOT_STARTED
;
524 CommBuffer
= LockBoxGetSmmCommBuffer ();
525 if (CommBuffer
== NULL
) {
526 CommBuffer
= &TempCommBuffer
[0];
529 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
530 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof (gEfiSmmLockBoxCommunicationGuid
));
531 CommHeader
->MessageLength
= sizeof (*LockBoxParameterRestoreAllInPlace
);
533 LockBoxParameterRestoreAllInPlace
= (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
534 LockBoxParameterRestoreAllInPlace
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE
;
535 LockBoxParameterRestoreAllInPlace
->Header
.DataLength
= sizeof (*LockBoxParameterRestoreAllInPlace
);
536 LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
= (UINT64
)-1;
541 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
);
542 Status
= SmmCommunication
->Communicate (
547 ASSERT_EFI_ERROR (Status
);
549 Status
= (EFI_STATUS
)LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
;
551 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status
));