3 Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The
8 full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/UefiBootServicesTableLib.h>
18 #include <Library/UefiRuntimeServicesTableLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/LockBoxLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/UefiLib.h>
24 #include <Protocol/SmmCommunication.h>
25 #include <Guid/SmmLockBox.h>
26 #include <Guid/PiSmmCommunicationRegionTable.h>
28 #include "SmmLockBoxLibPrivate.h"
30 EFI_SMM_COMMUNICATION_PROTOCOL
*mLockBoxSmmCommProtocol
= NULL
;
31 UINT8
*mLockBoxSmmCommBuffer
= NULL
;
34 Get smm communication protocol for lockbox.
36 @return Pointer to smm communication protocol, NULL if not found.
39 EFI_SMM_COMMUNICATION_PROTOCOL
*
40 LockBoxGetSmmCommProtocol (
47 // If the protocol has been got previously, return it.
49 if (mLockBoxSmmCommProtocol
!= NULL
) {
50 return mLockBoxSmmCommProtocol
;
53 Status
= gBS
->LocateProtocol (
54 &gEfiSmmCommunicationProtocolGuid
,
56 (VOID
**)&mLockBoxSmmCommProtocol
58 if (EFI_ERROR (Status
)) {
59 mLockBoxSmmCommProtocol
= NULL
;
61 return mLockBoxSmmCommProtocol
;
65 Get smm communication buffer for lockbox.
67 @return Pointer to smm communication buffer, NULL if not found.
71 LockBoxGetSmmCommBuffer (
76 UINTN MinimalSizeNeeded
;
77 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
79 EFI_MEMORY_DESCRIPTOR
*Entry
;
83 // If the buffer has been got previously, return it.
85 if (mLockBoxSmmCommBuffer
!= NULL
) {
86 return mLockBoxSmmCommBuffer
;
89 MinimalSizeNeeded
= sizeof (EFI_GUID
) +
91 MAX (sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
),
92 MAX (sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
),
93 MAX (sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
),
94 MAX (sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
),
95 sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)))));
97 Status
= EfiGetSystemConfigurationTable (
98 &gEdkiiPiSmmCommunicationRegionTableGuid
,
99 (VOID
**) &PiSmmCommunicationRegionTable
101 if (EFI_ERROR (Status
)) {
102 mLockBoxSmmCommBuffer
= NULL
;
103 return mLockBoxSmmCommBuffer
;
105 ASSERT (PiSmmCommunicationRegionTable
!= NULL
);
106 Entry
= (EFI_MEMORY_DESCRIPTOR
*) (PiSmmCommunicationRegionTable
+ 1);
108 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
109 if (Entry
->Type
== EfiConventionalMemory
) {
110 Size
= EFI_PAGES_TO_SIZE ((UINTN
) Entry
->NumberOfPages
);
111 if (Size
>= MinimalSizeNeeded
) {
115 Entry
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
117 if (Index
>= PiSmmCommunicationRegionTable
->NumberOfEntries
) {
118 mLockBoxSmmCommBuffer
= NULL
;
120 mLockBoxSmmCommBuffer
= (UINT8
*) (UINTN
) Entry
->PhysicalStart
;
122 return mLockBoxSmmCommBuffer
;
126 This function will save confidential information to lockbox.
128 @param Guid the guid to identify the confidential information
129 @param Buffer the address of the confidential information
130 @param Length the length of the confidential information
132 @retval RETURN_SUCCESS the information is saved successfully.
133 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
134 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
135 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
136 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
137 @retval RETURN_NOT_STARTED it is too early to invoke this interface
138 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
149 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
150 EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*LockBoxParameterSave
;
151 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
152 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE
)];
156 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SaveLockBox - Enter\n"));
161 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
162 return EFI_INVALID_PARAMETER
;
165 SmmCommunication
= LockBoxGetSmmCommProtocol ();
166 if (SmmCommunication
== NULL
) {
167 return EFI_NOT_STARTED
;
173 CommBuffer
= LockBoxGetSmmCommBuffer ();
174 if (CommBuffer
== NULL
) {
175 CommBuffer
= &TempCommBuffer
[0];
177 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
178 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
179 CommHeader
->MessageLength
= sizeof(*LockBoxParameterSave
);
181 LockBoxParameterSave
= (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
182 LockBoxParameterSave
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_SAVE
;
183 LockBoxParameterSave
->Header
.DataLength
= sizeof(*LockBoxParameterSave
);
184 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)-1;
185 CopyMem (&LockBoxParameterSave
->Guid
, Guid
, sizeof(*Guid
));
186 LockBoxParameterSave
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
187 LockBoxParameterSave
->Length
= (UINT64
)Length
;
192 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE
);
193 Status
= SmmCommunication
->Communicate (
198 ASSERT_EFI_ERROR (Status
);
200 Status
= (EFI_STATUS
)LockBoxParameterSave
->Header
.ReturnStatus
;
202 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SaveLockBox - Exit (%r)\n", Status
));
211 This function will set lockbox attributes.
213 @param Guid the guid to identify the confidential information
214 @param Attributes the attributes of the lockbox
216 @retval RETURN_SUCCESS the information is saved successfully.
217 @retval RETURN_INVALID_PARAMETER attributes is invalid.
218 @retval RETURN_NOT_FOUND the requested GUID not found.
219 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
220 @retval RETURN_NOT_STARTED it is too early to invoke this interface
221 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
225 SetLockBoxAttributes (
231 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
232 EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*LockBoxParameterSetAttributes
;
233 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
234 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
)];
238 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SetLockBoxAttributes - Enter\n"));
243 if ((Guid
== NULL
) ||
244 ((Attributes
& ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
| LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
)) != 0)) {
245 return EFI_INVALID_PARAMETER
;
248 SmmCommunication
= LockBoxGetSmmCommProtocol ();
249 if (SmmCommunication
== NULL
) {
250 return EFI_NOT_STARTED
;
256 CommBuffer
= LockBoxGetSmmCommBuffer ();
257 if (CommBuffer
== NULL
) {
258 CommBuffer
= &TempCommBuffer
[0];
260 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
261 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
262 CommHeader
->MessageLength
= sizeof(*LockBoxParameterSetAttributes
);
264 LockBoxParameterSetAttributes
= (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
265 LockBoxParameterSetAttributes
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES
;
266 LockBoxParameterSetAttributes
->Header
.DataLength
= sizeof(*LockBoxParameterSetAttributes
);
267 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)-1;
268 CopyMem (&LockBoxParameterSetAttributes
->Guid
, Guid
, sizeof(*Guid
));
269 LockBoxParameterSetAttributes
->Attributes
= (UINT64
)Attributes
;
274 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
);
275 Status
= SmmCommunication
->Communicate (
280 ASSERT_EFI_ERROR (Status
);
282 Status
= (EFI_STATUS
)LockBoxParameterSetAttributes
->Header
.ReturnStatus
;
284 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib SetLockBoxAttributes - Exit (%r)\n", Status
));
293 This function will update confidential information to lockbox.
295 @param Guid the guid to identify the original confidential information
296 @param Offset the offset of the original confidential information
297 @param Buffer the address of the updated confidential information
298 @param Length the length of the updated confidential information
300 @retval RETURN_SUCCESS the information is saved successfully.
301 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
302 @retval RETURN_NOT_FOUND the requested GUID not found.
303 @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
304 the original buffer to too small to hold new information.
305 @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
306 no enough resource to save the information.
307 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
308 @retval RETURN_NOT_STARTED it is too early to invoke this interface
309 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
321 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
322 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*LockBoxParameterUpdate
;
323 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
324 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
)];
328 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib UpdateLockBox - Enter\n"));
333 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
334 return EFI_INVALID_PARAMETER
;
337 SmmCommunication
= LockBoxGetSmmCommProtocol ();
338 if (SmmCommunication
== NULL
) {
339 return EFI_NOT_STARTED
;
345 CommBuffer
= LockBoxGetSmmCommBuffer ();
346 if (CommBuffer
== NULL
) {
347 CommBuffer
= &TempCommBuffer
[0];
349 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
350 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
351 CommHeader
->MessageLength
= sizeof(*LockBoxParameterUpdate
);
353 LockBoxParameterUpdate
= (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*)(UINTN
)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
354 LockBoxParameterUpdate
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_UPDATE
;
355 LockBoxParameterUpdate
->Header
.DataLength
= sizeof(*LockBoxParameterUpdate
);
356 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)-1;
357 CopyMem (&LockBoxParameterUpdate
->Guid
, Guid
, sizeof(*Guid
));
358 LockBoxParameterUpdate
->Offset
= (UINT64
)Offset
;
359 LockBoxParameterUpdate
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
360 LockBoxParameterUpdate
->Length
= (UINT64
)Length
;
365 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
);
366 Status
= SmmCommunication
->Communicate (
371 ASSERT_EFI_ERROR (Status
);
373 Status
= (EFI_STATUS
)LockBoxParameterUpdate
->Header
.ReturnStatus
;
375 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib UpdateLockBox - Exit (%r)\n", Status
));
384 This function will restore confidential information from lockbox.
386 @param Guid the guid to identify the confidential information
387 @param Buffer the address of the restored confidential information
388 NULL means restored to original address, Length MUST be NULL at same time.
389 @param Length the length of the restored confidential information
391 @retval RETURN_SUCCESS the information is restored successfully.
392 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
393 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
394 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
395 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
396 @retval RETURN_NOT_FOUND the requested GUID not found.
397 @retval RETURN_NOT_STARTED it is too early to invoke this interface
398 @retval RETURN_ACCESS_DENIED not allow to restore to the address
399 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
405 IN VOID
*Buffer
, OPTIONAL
406 IN OUT UINTN
*Length OPTIONAL
410 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
411 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*LockBoxParameterRestore
;
412 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
413 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
)];
417 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreLockBox - Enter\n"));
422 if ((Guid
== NULL
) ||
423 ((Buffer
== NULL
) && (Length
!= NULL
)) ||
424 ((Buffer
!= NULL
) && (Length
== NULL
))) {
425 return EFI_INVALID_PARAMETER
;
428 SmmCommunication
= LockBoxGetSmmCommProtocol ();
429 if (SmmCommunication
== NULL
) {
430 return EFI_NOT_STARTED
;
436 CommBuffer
= LockBoxGetSmmCommBuffer ();
437 if (CommBuffer
== NULL
) {
438 CommBuffer
= &TempCommBuffer
[0];
440 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
441 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
442 CommHeader
->MessageLength
= sizeof(*LockBoxParameterRestore
);
444 LockBoxParameterRestore
= (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
445 LockBoxParameterRestore
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_RESTORE
;
446 LockBoxParameterRestore
->Header
.DataLength
= sizeof(*LockBoxParameterRestore
);
447 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)-1;
448 CopyMem (&LockBoxParameterRestore
->Guid
, Guid
, sizeof(*Guid
));
449 LockBoxParameterRestore
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
450 if (Length
!= NULL
) {
451 LockBoxParameterRestore
->Length
= (EFI_PHYSICAL_ADDRESS
)*Length
;
453 LockBoxParameterRestore
->Length
= 0;
459 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
);
460 Status
= SmmCommunication
->Communicate (
465 ASSERT_EFI_ERROR (Status
);
467 if (Length
!= NULL
) {
468 *Length
= (UINTN
)LockBoxParameterRestore
->Length
;
471 Status
= (EFI_STATUS
)LockBoxParameterRestore
->Header
.ReturnStatus
;
473 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreLockBox - Exit (%r)\n", Status
));
482 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
484 @retval RETURN_SUCCESS the information is restored successfully.
485 @retval RETURN_NOT_STARTED it is too early to invoke this interface
486 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
490 RestoreAllLockBoxInPlace (
495 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
496 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*LockBoxParameterRestoreAllInPlace
;
497 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
498 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)];
502 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Enter\n"));
504 SmmCommunication
= LockBoxGetSmmCommProtocol ();
505 if (SmmCommunication
== NULL
) {
506 return EFI_NOT_STARTED
;
512 CommBuffer
= LockBoxGetSmmCommBuffer ();
513 if (CommBuffer
== NULL
) {
514 CommBuffer
= &TempCommBuffer
[0];
516 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
517 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
518 CommHeader
->MessageLength
= sizeof(*LockBoxParameterRestoreAllInPlace
);
520 LockBoxParameterRestoreAllInPlace
= (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
521 LockBoxParameterRestoreAllInPlace
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE
;
522 LockBoxParameterRestoreAllInPlace
->Header
.DataLength
= sizeof(*LockBoxParameterRestoreAllInPlace
);
523 LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
= (UINT64
)-1;
528 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
);
529 Status
= SmmCommunication
->Communicate (
534 ASSERT_EFI_ERROR (Status
);
536 Status
= (EFI_STATUS
)LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
;
538 DEBUG ((DEBUG_INFO
, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status
));