]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c
MdeModulePkg/CapsuleLib: Fix runtime issue
[mirror_edk2.git] / MdeModulePkg / Library / SmmLockBoxLib / SmmLockBoxDxeLib.c
1 /** @file
2
3 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
4
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
10
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.
13
14 **/
15
16 #include <PiDxe.h>
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 <Protocol/SmmCommunication.h>
24 #include <Guid/SmmLockBox.h>
25
26 #include "SmmLockBoxLibPrivate.h"
27
28 /**
29 This function will save confidential information to lockbox.
30
31 @param Guid the guid to identify the confidential information
32 @param Buffer the address of the confidential information
33 @param Length the length of the confidential information
34
35 @retval RETURN_SUCCESS the information is saved successfully.
36 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
37 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
38 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
39 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
40 @retval RETURN_NOT_STARTED it is too early to invoke this interface
41 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
42 **/
43 RETURN_STATUS
44 EFIAPI
45 SaveLockBox (
46 IN GUID *Guid,
47 IN VOID *Buffer,
48 IN UINTN Length
49 )
50 {
51 EFI_STATUS Status;
52 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
53 EFI_SMM_LOCK_BOX_PARAMETER_SAVE *LockBoxParameterSave;
54 EFI_SMM_COMMUNICATE_HEADER *CommHeader;
55 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE)];
56 UINTN CommSize;
57
58 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SaveLockBox - Enter\n"));
59
60 //
61 // Basic check
62 //
63 if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {
64 return EFI_INVALID_PARAMETER;
65 }
66
67 //
68 // Get needed resource
69 //
70 Status = gBS->LocateProtocol (
71 &gEfiSmmCommunicationProtocolGuid,
72 NULL,
73 (VOID **)&SmmCommunication
74 );
75 if (EFI_ERROR (Status)) {
76 return EFI_NOT_STARTED;
77 }
78
79 //
80 // Prepare parameter
81 //
82 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
83 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
84 CommHeader->MessageLength = sizeof(*LockBoxParameterSave);
85
86 LockBoxParameterSave = (EFI_SMM_LOCK_BOX_PARAMETER_SAVE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
87 LockBoxParameterSave->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_SAVE;
88 LockBoxParameterSave->Header.DataLength = sizeof(*LockBoxParameterSave);
89 LockBoxParameterSave->Header.ReturnStatus = (UINT64)-1;
90 CopyMem (&LockBoxParameterSave->Guid, Guid, sizeof(*Guid));
91 LockBoxParameterSave->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
92 LockBoxParameterSave->Length = (UINT64)Length;
93
94 //
95 // Send command
96 //
97 CommSize = sizeof(CommBuffer);
98 Status = SmmCommunication->Communicate (
99 SmmCommunication,
100 &CommBuffer[0],
101 &CommSize
102 );
103 ASSERT_EFI_ERROR (Status);
104
105 Status = (EFI_STATUS)LockBoxParameterSave->Header.ReturnStatus;
106
107 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SaveLockBox - Exit (%r)\n", Status));
108
109 //
110 // Done
111 //
112 return Status;
113 }
114
115 /**
116 This function will set lockbox attributes.
117
118 @param Guid the guid to identify the confidential information
119 @param Attributes the attributes of the lockbox
120
121 @retval RETURN_SUCCESS the information is saved successfully.
122 @retval RETURN_INVALID_PARAMETER attributes is invalid.
123 @retval RETURN_NOT_FOUND the requested GUID not found.
124 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
125 @retval RETURN_NOT_STARTED it is too early to invoke this interface
126 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
127 **/
128 RETURN_STATUS
129 EFIAPI
130 SetLockBoxAttributes (
131 IN GUID *Guid,
132 IN UINT64 Attributes
133 )
134 {
135 EFI_STATUS Status;
136 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
137 EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes;
138 EFI_SMM_COMMUNICATE_HEADER *CommHeader;
139 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)];
140 UINTN CommSize;
141
142 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SetLockBoxAttributes - Enter\n"));
143
144 //
145 // Basic check
146 //
147 if ((Guid == NULL) ||
148 ((Attributes & ~LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0)) {
149 return EFI_INVALID_PARAMETER;
150 }
151
152 //
153 // Get needed resource
154 //
155 Status = gBS->LocateProtocol (
156 &gEfiSmmCommunicationProtocolGuid,
157 NULL,
158 (VOID **)&SmmCommunication
159 );
160 if (EFI_ERROR (Status)) {
161 return EFI_NOT_STARTED;
162 }
163
164 //
165 // Prepare parameter
166 //
167 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
168 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
169 CommHeader->MessageLength = sizeof(*LockBoxParameterSetAttributes);
170
171 LockBoxParameterSetAttributes = (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
172 LockBoxParameterSetAttributes->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES;
173 LockBoxParameterSetAttributes->Header.DataLength = sizeof(*LockBoxParameterSetAttributes);
174 LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)-1;
175 CopyMem (&LockBoxParameterSetAttributes->Guid, Guid, sizeof(*Guid));
176 LockBoxParameterSetAttributes->Attributes = (UINT64)Attributes;
177
178 //
179 // Send command
180 //
181 CommSize = sizeof(CommBuffer);
182 Status = SmmCommunication->Communicate (
183 SmmCommunication,
184 &CommBuffer[0],
185 &CommSize
186 );
187 ASSERT_EFI_ERROR (Status);
188
189 Status = (EFI_STATUS)LockBoxParameterSetAttributes->Header.ReturnStatus;
190
191 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SetLockBoxAttributes - Exit (%r)\n", Status));
192
193 //
194 // Done
195 //
196 return Status;
197 }
198
199 /**
200 This function will update confidential information to lockbox.
201
202 @param Guid the guid to identify the original confidential information
203 @param Offset the offset of the original confidential information
204 @param Buffer the address of the updated confidential information
205 @param Length the length of the updated confidential information
206
207 @retval RETURN_SUCCESS the information is saved successfully.
208 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
209 @retval RETURN_NOT_FOUND the requested GUID not found.
210 @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold new information.
211 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
212 @retval RETURN_NOT_STARTED it is too early to invoke this interface
213 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
214 **/
215 RETURN_STATUS
216 EFIAPI
217 UpdateLockBox (
218 IN GUID *Guid,
219 IN UINTN Offset,
220 IN VOID *Buffer,
221 IN UINTN Length
222 )
223 {
224 EFI_STATUS Status;
225 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
226 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *LockBoxParameterUpdate;
227 EFI_SMM_COMMUNICATE_HEADER *CommHeader;
228 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)];
229 UINTN CommSize;
230
231 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib UpdateLockBox - Enter\n"));
232
233 //
234 // Basic check
235 //
236 if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {
237 return EFI_INVALID_PARAMETER;
238 }
239
240 //
241 // Get needed resource
242 //
243 Status = gBS->LocateProtocol (
244 &gEfiSmmCommunicationProtocolGuid,
245 NULL,
246 (VOID **)&SmmCommunication
247 );
248 if (EFI_ERROR (Status)) {
249 return EFI_NOT_STARTED;
250 }
251
252 //
253 // Prepare parameter
254 //
255 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
256 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
257 CommHeader->MessageLength = sizeof(*LockBoxParameterUpdate);
258
259 LockBoxParameterUpdate = (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *)(UINTN)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
260 LockBoxParameterUpdate->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_UPDATE;
261 LockBoxParameterUpdate->Header.DataLength = sizeof(*LockBoxParameterUpdate);
262 LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)-1;
263 CopyMem (&LockBoxParameterUpdate->Guid, Guid, sizeof(*Guid));
264 LockBoxParameterUpdate->Offset = (UINT64)Offset;
265 LockBoxParameterUpdate->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
266 LockBoxParameterUpdate->Length = (UINT64)Length;
267
268 //
269 // Send command
270 //
271 CommSize = sizeof(CommBuffer);
272 Status = SmmCommunication->Communicate (
273 SmmCommunication,
274 &CommBuffer[0],
275 &CommSize
276 );
277 ASSERT_EFI_ERROR (Status);
278
279 Status = (EFI_STATUS)LockBoxParameterUpdate->Header.ReturnStatus;
280
281 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib UpdateLockBox - Exit (%r)\n", Status));
282
283 //
284 // Done
285 //
286 return Status;
287 }
288
289 /**
290 This function will restore confidential information from lockbox.
291
292 @param Guid the guid to identify the confidential information
293 @param Buffer the address of the restored confidential information
294 NULL means restored to original address, Length MUST be NULL at same time.
295 @param Length the length of the restored confidential information
296
297 @retval RETURN_SUCCESS the information is restored successfully.
298 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
299 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
300 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
301 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
302 @retval RETURN_NOT_FOUND the requested GUID not found.
303 @retval RETURN_NOT_STARTED it is too early to invoke this interface
304 @retval RETURN_ACCESS_DENIED not allow to restore to the address
305 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
306 **/
307 RETURN_STATUS
308 EFIAPI
309 RestoreLockBox (
310 IN GUID *Guid,
311 IN VOID *Buffer, OPTIONAL
312 IN OUT UINTN *Length OPTIONAL
313 )
314 {
315 EFI_STATUS Status;
316 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
317 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore;
318 EFI_SMM_COMMUNICATE_HEADER *CommHeader;
319 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)];
320 UINTN CommSize;
321
322 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreLockBox - Enter\n"));
323
324 //
325 // Basic check
326 //
327 if ((Guid == NULL) ||
328 ((Buffer == NULL) && (Length != NULL)) ||
329 ((Buffer != NULL) && (Length == NULL))) {
330 return EFI_INVALID_PARAMETER;
331 }
332
333 //
334 // Get needed resource
335 //
336 Status = gBS->LocateProtocol (
337 &gEfiSmmCommunicationProtocolGuid,
338 NULL,
339 (VOID **)&SmmCommunication
340 );
341 if (EFI_ERROR (Status)) {
342 return EFI_NOT_STARTED;
343 }
344
345 //
346 // Prepare parameter
347 //
348 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
349 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
350 CommHeader->MessageLength = sizeof(*LockBoxParameterRestore);
351
352 LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
353 LockBoxParameterRestore->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE;
354 LockBoxParameterRestore->Header.DataLength = sizeof(*LockBoxParameterRestore);
355 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)-1;
356 CopyMem (&LockBoxParameterRestore->Guid, Guid, sizeof(*Guid));
357 LockBoxParameterRestore->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
358 if (Length != NULL) {
359 LockBoxParameterRestore->Length = (EFI_PHYSICAL_ADDRESS)*Length;
360 } else {
361 LockBoxParameterRestore->Length = 0;
362 }
363
364 //
365 // Send command
366 //
367 CommSize = sizeof(CommBuffer);
368 Status = SmmCommunication->Communicate (
369 SmmCommunication,
370 &CommBuffer[0],
371 &CommSize
372 );
373 ASSERT_EFI_ERROR (Status);
374
375 if (Length != NULL) {
376 *Length = (UINTN)LockBoxParameterRestore->Length;
377 }
378
379 Status = (EFI_STATUS)LockBoxParameterRestore->Header.ReturnStatus;
380
381 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreLockBox - Exit (%r)\n", Status));
382
383 //
384 // Done
385 //
386 return Status;
387 }
388
389 /**
390 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
391
392 @retval RETURN_SUCCESS the information is restored successfully.
393 @retval RETURN_NOT_STARTED it is too early to invoke this interface
394 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
395 **/
396 RETURN_STATUS
397 EFIAPI
398 RestoreAllLockBoxInPlace (
399 VOID
400 )
401 {
402 EFI_STATUS Status;
403 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
404 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace;
405 EFI_SMM_COMMUNICATE_HEADER *CommHeader;
406 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)];
407 UINTN CommSize;
408
409 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Enter\n"));
410
411 //
412 // Get needed resource
413 //
414 Status = gBS->LocateProtocol (
415 &gEfiSmmCommunicationProtocolGuid,
416 NULL,
417 (VOID **)&SmmCommunication
418 );
419 if (EFI_ERROR (Status)) {
420 return EFI_NOT_STARTED;
421 }
422
423 //
424 // Prepare parameter
425 //
426 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
427 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
428 CommHeader->MessageLength = sizeof(*LockBoxParameterRestoreAllInPlace);
429
430 LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
431 LockBoxParameterRestoreAllInPlace->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE;
432 LockBoxParameterRestoreAllInPlace->Header.DataLength = sizeof(*LockBoxParameterRestoreAllInPlace);
433 LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)-1;
434
435 //
436 // Send command
437 //
438 CommSize = sizeof(CommBuffer);
439 Status = SmmCommunication->Communicate (
440 SmmCommunication,
441 &CommBuffer[0],
442 &CommSize
443 );
444 ASSERT_EFI_ERROR (Status);
445
446 Status = (EFI_STATUS)LockBoxParameterRestoreAllInPlace->Header.ReturnStatus;
447
448 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));
449
450 //
451 // Done
452 //
453 return Status;
454 }
455