3 Copyright (c) 2010 - 2018, 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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 the original buffer to too small to hold new information.
304 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
305 @retval RETURN_NOT_STARTED it is too early to invoke this interface
306 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
318 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
319 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*LockBoxParameterUpdate
;
320 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
321 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
)];
325 DEBUG ((EFI_D_INFO
, "SmmLockBoxDxeLib UpdateLockBox - Enter\n"));
330 if ((Guid
== NULL
) || (Buffer
== NULL
) || (Length
== 0)) {
331 return EFI_INVALID_PARAMETER
;
334 SmmCommunication
= LockBoxGetSmmCommProtocol ();
335 if (SmmCommunication
== NULL
) {
336 return EFI_NOT_STARTED
;
342 CommBuffer
= LockBoxGetSmmCommBuffer ();
343 if (CommBuffer
== NULL
) {
344 CommBuffer
= &TempCommBuffer
[0];
346 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
347 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
348 CommHeader
->MessageLength
= sizeof(*LockBoxParameterUpdate
);
350 LockBoxParameterUpdate
= (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*)(UINTN
)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
351 LockBoxParameterUpdate
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_UPDATE
;
352 LockBoxParameterUpdate
->Header
.DataLength
= sizeof(*LockBoxParameterUpdate
);
353 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)-1;
354 CopyMem (&LockBoxParameterUpdate
->Guid
, Guid
, sizeof(*Guid
));
355 LockBoxParameterUpdate
->Offset
= (UINT64
)Offset
;
356 LockBoxParameterUpdate
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
357 LockBoxParameterUpdate
->Length
= (UINT64
)Length
;
362 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
);
363 Status
= SmmCommunication
->Communicate (
368 ASSERT_EFI_ERROR (Status
);
370 Status
= (EFI_STATUS
)LockBoxParameterUpdate
->Header
.ReturnStatus
;
372 DEBUG ((EFI_D_INFO
, "SmmLockBoxDxeLib UpdateLockBox - Exit (%r)\n", Status
));
381 This function will restore confidential information from lockbox.
383 @param Guid the guid to identify the confidential information
384 @param Buffer the address of the restored confidential information
385 NULL means restored to original address, Length MUST be NULL at same time.
386 @param Length the length of the restored confidential information
388 @retval RETURN_SUCCESS the information is restored successfully.
389 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
390 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
391 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
392 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
393 @retval RETURN_NOT_FOUND the requested GUID not found.
394 @retval RETURN_NOT_STARTED it is too early to invoke this interface
395 @retval RETURN_ACCESS_DENIED not allow to restore to the address
396 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
402 IN VOID
*Buffer
, OPTIONAL
403 IN OUT UINTN
*Length OPTIONAL
407 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
408 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*LockBoxParameterRestore
;
409 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
410 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
)];
414 DEBUG ((EFI_D_INFO
, "SmmLockBoxDxeLib RestoreLockBox - Enter\n"));
419 if ((Guid
== NULL
) ||
420 ((Buffer
== NULL
) && (Length
!= NULL
)) ||
421 ((Buffer
!= NULL
) && (Length
== NULL
))) {
422 return EFI_INVALID_PARAMETER
;
425 SmmCommunication
= LockBoxGetSmmCommProtocol ();
426 if (SmmCommunication
== NULL
) {
427 return EFI_NOT_STARTED
;
433 CommBuffer
= LockBoxGetSmmCommBuffer ();
434 if (CommBuffer
== NULL
) {
435 CommBuffer
= &TempCommBuffer
[0];
437 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
438 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
439 CommHeader
->MessageLength
= sizeof(*LockBoxParameterRestore
);
441 LockBoxParameterRestore
= (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
442 LockBoxParameterRestore
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_RESTORE
;
443 LockBoxParameterRestore
->Header
.DataLength
= sizeof(*LockBoxParameterRestore
);
444 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)-1;
445 CopyMem (&LockBoxParameterRestore
->Guid
, Guid
, sizeof(*Guid
));
446 LockBoxParameterRestore
->Buffer
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
447 if (Length
!= NULL
) {
448 LockBoxParameterRestore
->Length
= (EFI_PHYSICAL_ADDRESS
)*Length
;
450 LockBoxParameterRestore
->Length
= 0;
456 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
);
457 Status
= SmmCommunication
->Communicate (
462 ASSERT_EFI_ERROR (Status
);
464 if (Length
!= NULL
) {
465 *Length
= (UINTN
)LockBoxParameterRestore
->Length
;
468 Status
= (EFI_STATUS
)LockBoxParameterRestore
->Header
.ReturnStatus
;
470 DEBUG ((EFI_D_INFO
, "SmmLockBoxDxeLib RestoreLockBox - Exit (%r)\n", Status
));
479 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
481 @retval RETURN_SUCCESS the information is restored successfully.
482 @retval RETURN_NOT_STARTED it is too early to invoke this interface
483 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
487 RestoreAllLockBoxInPlace (
492 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
493 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*LockBoxParameterRestoreAllInPlace
;
494 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
495 UINT8 TempCommBuffer
[sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)];
499 DEBUG ((EFI_D_INFO
, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Enter\n"));
501 SmmCommunication
= LockBoxGetSmmCommProtocol ();
502 if (SmmCommunication
== NULL
) {
503 return EFI_NOT_STARTED
;
509 CommBuffer
= LockBoxGetSmmCommBuffer ();
510 if (CommBuffer
== NULL
) {
511 CommBuffer
= &TempCommBuffer
[0];
513 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
514 CopyMem (&CommHeader
->HeaderGuid
, &gEfiSmmLockBoxCommunicationGuid
, sizeof(gEfiSmmLockBoxCommunicationGuid
));
515 CommHeader
->MessageLength
= sizeof(*LockBoxParameterRestoreAllInPlace
);
517 LockBoxParameterRestoreAllInPlace
= (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
518 LockBoxParameterRestoreAllInPlace
->Header
.Command
= EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE
;
519 LockBoxParameterRestoreAllInPlace
->Header
.DataLength
= sizeof(*LockBoxParameterRestoreAllInPlace
);
520 LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
= (UINT64
)-1;
525 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
);
526 Status
= SmmCommunication
->Communicate (
531 ASSERT_EFI_ERROR (Status
);
533 Status
= (EFI_STATUS
)LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
;
535 DEBUG ((EFI_D_INFO
, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status
));