VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c@ 58466

Last change on this file since 58466 was 58466, checked in by vboxsync, 9 years ago

EFI/Firmware: Merged in the svn:eol-style, svn:mime-type and trailing whitespace cleanup that was done after the initial UDK2014.SP1 import: svn merge /vendor/edk2/UDK2014.SP1 /vendor/edk2/current .

  • Property svn:eol-style set to native
File size: 16.2 KB
Line 
1/** @file
2
3Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
4
5This program and the accompanying materials
6are licensed and made available under the terms and conditions
7of the BSD License which accompanies this distribution. The
8full text of the license may be found at
9http://opensource.org/licenses/bsd-license.php
10
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16#include <PiSmm.h>
17#include <Library/SmmServicesTableLib.h>
18#include <Library/BaseLib.h>
19#include <Library/BaseMemoryLib.h>
20#include <Library/LockBoxLib.h>
21#include <Library/DebugLib.h>
22#include <Guid/SmmLockBox.h>
23
24#include "SmmLockBoxLibPrivate.h"
25
26/**
27 We need handle this library carefully. Only one library instance will construct the environment.
28 Below 2 global variable can only be used in constructor. They should NOT be used in any other library functions.
29**/
30SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext;
31LIST_ENTRY mLockBoxQueue = INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue);
32
33/**
34 This function return SmmLockBox context from SMST.
35
36 @return SmmLockBox context from SMST.
37**/
38SMM_LOCK_BOX_CONTEXT *
39InternalGetSmmLockBoxContext (
40 VOID
41 )
42{
43 UINTN Index;
44
45 //
46 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
47 //
48 for (Index = 0; Index < gSmst->NumberOfTableEntries; Index++) {
49 if (CompareGuid (&gSmst->SmmConfigurationTable[Index].VendorGuid, &gEfiSmmLockBoxCommunicationGuid)) {
50 //
51 // Found. That means some other library instance is already run.
52 // No need to install again, just return.
53 //
54 return (SMM_LOCK_BOX_CONTEXT *)gSmst->SmmConfigurationTable[Index].VendorTable;
55 }
56 }
57
58 //
59 // Not found.
60 //
61 return NULL;
62}
63
64/**
65 Constructor for SmmLockBox library.
66 This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.
67
68 @param[in] ImageHandle Image handle of this driver.
69 @param[in] SystemTable A Pointer to the EFI System Table.
70
71 @retval EFI_SUCEESS
72 @return Others Some error occurs.
73**/
74EFI_STATUS
75EFIAPI
76SmmLockBoxSmmConstructuor (
77 IN EFI_HANDLE ImageHandle,
78 IN EFI_SYSTEM_TABLE *SystemTable
79 )
80{
81 EFI_STATUS Status;
82 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;
83
84 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Enter\n"));
85
86 //
87 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
88 //
89 SmmLockBoxContext = InternalGetSmmLockBoxContext ();
90 if (SmmLockBoxContext != NULL) {
91 //
92 // Find it. That means some other library instance is already run.
93 // No need to install again, just return.
94 //
95 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - already installed\n"));
96 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Exit\n"));
97 return EFI_SUCCESS;
98 }
99
100 //
101 // If no one install this, it means this is first instance. Install it.
102 //
103 if (sizeof(UINTN) == sizeof(UINT64)) {
104 mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_64;
105 } else {
106 mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_32;
107 }
108 mSmmLockBoxContext.LockBoxDataAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)&mLockBoxQueue;
109
110 Status = gSmst->SmmInstallConfigurationTable (
111 gSmst,
112 &gEfiSmmLockBoxCommunicationGuid,
113 &mSmmLockBoxContext,
114 sizeof(mSmmLockBoxContext)
115 );
116 ASSERT_EFI_ERROR (Status);
117
118 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN)&mSmmLockBoxContext));
119 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN)&mLockBoxQueue));
120 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Exit\n"));
121
122 return Status;
123}
124
125/**
126 This function return SmmLockBox queue address.
127
128 @return SmmLockBox queue address.
129**/
130LIST_ENTRY *
131InternalGetLockBoxQueue (
132 VOID
133 )
134{
135 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;
136
137 SmmLockBoxContext = InternalGetSmmLockBoxContext ();
138 ASSERT (SmmLockBoxContext != NULL);
139 if (SmmLockBoxContext == NULL) {
140 return NULL;
141 }
142 return (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;
143}
144
145/**
146 This function find LockBox by GUID.
147
148 @param Guid The guid to indentify the LockBox
149
150 @return LockBoxData
151**/
152SMM_LOCK_BOX_DATA *
153InternalFindLockBoxByGuid (
154 IN EFI_GUID *Guid
155 )
156{
157 LIST_ENTRY *Link;
158 SMM_LOCK_BOX_DATA *LockBox;
159 LIST_ENTRY *LockBoxQueue;
160
161 LockBoxQueue = InternalGetLockBoxQueue ();
162 ASSERT (LockBoxQueue != NULL);
163
164 for (Link = LockBoxQueue->ForwardLink;
165 Link != LockBoxQueue;
166 Link = Link->ForwardLink) {
167 LockBox = BASE_CR (
168 Link,
169 SMM_LOCK_BOX_DATA,
170 Link
171 );
172 if (CompareGuid (&LockBox->Guid, Guid)) {
173 return LockBox;
174 }
175 }
176 return NULL;
177}
178
179/**
180 This function will save confidential information to lockbox.
181
182 @param Guid the guid to identify the confidential information
183 @param Buffer the address of the confidential information
184 @param Length the length of the confidential information
185
186 @retval RETURN_SUCCESS the information is saved successfully.
187 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
188 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
189 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
190 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
191 @retval RETURN_NOT_STARTED it is too early to invoke this interface
192 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
193**/
194RETURN_STATUS
195EFIAPI
196SaveLockBox (
197 IN GUID *Guid,
198 IN VOID *Buffer,
199 IN UINTN Length
200 )
201{
202 SMM_LOCK_BOX_DATA *LockBox;
203 EFI_PHYSICAL_ADDRESS SmramBuffer;
204 EFI_STATUS Status;
205 LIST_ENTRY *LockBoxQueue;
206
207 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));
208
209 //
210 // Basic check
211 //
212 if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {
213 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));
214 return EFI_INVALID_PARAMETER;
215 }
216
217 //
218 // Find LockBox
219 //
220 LockBox = InternalFindLockBoxByGuid (Guid);
221 if (LockBox != NULL) {
222 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED));
223 return EFI_ALREADY_STARTED;
224 }
225
226 //
227 // Allocate SMRAM buffer
228 //
229 Status = gSmst->SmmAllocatePages (
230 AllocateAnyPages,
231 EfiRuntimeServicesData,
232 EFI_SIZE_TO_PAGES (Length),
233 &SmramBuffer
234 );
235 ASSERT_EFI_ERROR (Status);
236 if (EFI_ERROR (Status)) {
237 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));
238 return EFI_OUT_OF_RESOURCES;
239 }
240
241 //
242 // Allocate LockBox
243 //
244 Status = gSmst->SmmAllocatePool (
245 EfiRuntimeServicesData,
246 sizeof(*LockBox),
247 (VOID **)&LockBox
248 );
249 ASSERT_EFI_ERROR (Status);
250 if (EFI_ERROR (Status)) {
251 gSmst->SmmFreePages (SmramBuffer, EFI_SIZE_TO_PAGES (Length));
252 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));
253 return EFI_OUT_OF_RESOURCES;
254 }
255
256 //
257 // Save data
258 //
259 CopyMem ((VOID *)(UINTN)SmramBuffer, (VOID *)(UINTN)Buffer, Length);
260
261 //
262 // Insert LockBox to queue
263 //
264 LockBox->Signature = SMM_LOCK_BOX_DATA_SIGNATURE;
265 CopyMem (&LockBox->Guid, Guid, sizeof(EFI_GUID));
266 LockBox->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
267 LockBox->Length = (UINT64)Length;
268 LockBox->Attributes = 0;
269 LockBox->SmramBuffer = SmramBuffer;
270
271 DEBUG ((
272 EFI_D_INFO,
273 "LockBoxGuid - %g, SmramBuffer - 0x%lx, Length - 0x%lx\n",
274 &LockBox->Guid,
275 LockBox->SmramBuffer,
276 LockBox->Length
277 ));
278
279 LockBoxQueue = InternalGetLockBoxQueue ();
280 ASSERT (LockBoxQueue != NULL);
281 InsertTailList (LockBoxQueue, &LockBox->Link);
282
283 //
284 // Done
285 //
286 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS));
287 return EFI_SUCCESS;
288}
289
290/**
291 This function will set lockbox attributes.
292
293 @param Guid the guid to identify the confidential information
294 @param Attributes the attributes of the lockbox
295
296 @retval RETURN_SUCCESS the information is saved successfully.
297 @retval RETURN_INVALID_PARAMETER attributes is invalid.
298 @retval RETURN_NOT_FOUND the requested GUID not found.
299 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
300 @retval RETURN_NOT_STARTED it is too early to invoke this interface
301 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
302**/
303RETURN_STATUS
304EFIAPI
305SetLockBoxAttributes (
306 IN GUID *Guid,
307 IN UINT64 Attributes
308 )
309{
310 SMM_LOCK_BOX_DATA *LockBox;
311
312 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));
313
314 //
315 // Basic check
316 //
317 if ((Guid == NULL) ||
318 ((Attributes & ~LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0)) {
319 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));
320 return EFI_INVALID_PARAMETER;
321 }
322
323 //
324 // Find LockBox
325 //
326 LockBox = InternalFindLockBoxByGuid (Guid);
327 if (LockBox == NULL) {
328 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND));
329 return EFI_NOT_FOUND;
330 }
331
332 //
333 // Update data
334 //
335 LockBox->Attributes = Attributes;
336
337 //
338 // Done
339 //
340 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS));
341 return EFI_SUCCESS;
342}
343
344/**
345 This function will update confidential information to lockbox.
346
347 @param Guid the guid to identify the original confidential information
348 @param Offset the offset of the original confidential information
349 @param Buffer the address of the updated confidential information
350 @param Length the length of the updated confidential information
351
352 @retval RETURN_SUCCESS the information is saved successfully.
353 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
354 @retval RETURN_NOT_FOUND the requested GUID not found.
355 @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold new information.
356 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
357 @retval RETURN_NOT_STARTED it is too early to invoke this interface
358 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
359**/
360RETURN_STATUS
361EFIAPI
362UpdateLockBox (
363 IN GUID *Guid,
364 IN UINTN Offset,
365 IN VOID *Buffer,
366 IN UINTN Length
367 )
368{
369 SMM_LOCK_BOX_DATA *LockBox;
370
371 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));
372
373 //
374 // Basic check
375 //
376 if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {
377 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));
378 return EFI_INVALID_PARAMETER;
379 }
380
381 //
382 // Find LockBox
383 //
384 LockBox = InternalFindLockBoxByGuid (Guid);
385 if (LockBox == NULL) {
386 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_NOT_FOUND));
387 return EFI_NOT_FOUND;
388 }
389
390 //
391 // Update data
392 //
393 if (LockBox->Length < Offset + Length) {
394 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));
395 return EFI_BUFFER_TOO_SMALL;
396 }
397 CopyMem ((VOID *)((UINTN)LockBox->SmramBuffer + Offset), Buffer, Length);
398
399 //
400 // Done
401 //
402 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS));
403 return EFI_SUCCESS;
404}
405
406/**
407 This function will restore confidential information from lockbox.
408
409 @param Guid the guid to identify the confidential information
410 @param Buffer the address of the restored confidential information
411 NULL means restored to original address, Length MUST be NULL at same time.
412 @param Length the length of the restored confidential information
413
414 @retval RETURN_SUCCESS the information is restored successfully.
415 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
416 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
417 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
418 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
419 @retval RETURN_NOT_FOUND the requested GUID not found.
420 @retval RETURN_NOT_STARTED it is too early to invoke this interface
421 @retval RETURN_ACCESS_DENIED not allow to restore to the address
422 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
423**/
424RETURN_STATUS
425EFIAPI
426RestoreLockBox (
427 IN GUID *Guid,
428 IN VOID *Buffer, OPTIONAL
429 IN OUT UINTN *Length OPTIONAL
430 )
431{
432 SMM_LOCK_BOX_DATA *LockBox;
433 VOID *RestoreBuffer;
434
435 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));
436
437 //
438 // Restore this, Buffer and Length MUST be both NULL or both non-NULL
439 //
440 if ((Guid == NULL) ||
441 ((Buffer == NULL) && (Length != NULL)) ||
442 ((Buffer != NULL) && (Length == NULL))) {
443 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));
444 return EFI_INVALID_PARAMETER;
445 }
446
447 //
448 // Find LockBox
449 //
450 LockBox = InternalFindLockBoxByGuid (Guid);
451 if (LockBox == NULL) {
452 //
453 // Not found
454 //
455 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND));
456 return EFI_NOT_FOUND;
457 }
458
459 //
460 // Set RestoreBuffer
461 //
462 if (Buffer != NULL) {
463 //
464 // restore to new buffer
465 //
466 RestoreBuffer = Buffer;
467 } else {
468 //
469 // restore to original buffer
470 //
471 if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {
472 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED));
473 return EFI_WRITE_PROTECTED;
474 }
475 RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;
476 }
477
478 //
479 // Set RestoreLength
480 //
481 if (Length != NULL) {
482 if (*Length < (UINTN)LockBox->Length) {
483 //
484 // Input buffer is too small to hold all data.
485 //
486 *Length = (UINTN)LockBox->Length;
487 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));
488 return EFI_BUFFER_TOO_SMALL;
489 }
490 *Length = (UINTN)LockBox->Length;
491 }
492
493 //
494 // Restore data
495 //
496 CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);
497
498 //
499 // Done
500 //
501 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS));
502 return EFI_SUCCESS;
503}
504
505/**
506 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
507
508 @retval RETURN_SUCCESS the information is restored successfully.
509 @retval RETURN_NOT_STARTED it is too early to invoke this interface
510 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
511**/
512RETURN_STATUS
513EFIAPI
514RestoreAllLockBoxInPlace (
515 VOID
516 )
517{
518 SMM_LOCK_BOX_DATA *LockBox;
519 LIST_ENTRY *Link;
520 LIST_ENTRY *LockBoxQueue;
521
522 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));
523
524 LockBoxQueue = InternalGetLockBoxQueue ();
525 ASSERT (LockBoxQueue != NULL);
526
527 //
528 // Restore all, Buffer and Length MUST be NULL
529 //
530 for (Link = LockBoxQueue->ForwardLink;
531 Link != LockBoxQueue;
532 Link = Link->ForwardLink) {
533 LockBox = BASE_CR (
534 Link,
535 SMM_LOCK_BOX_DATA,
536 Link
537 );
538 if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) {
539 //
540 // Restore data
541 //
542 CopyMem ((VOID *)(UINTN)LockBox->Buffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);
543 }
544 }
545 //
546 // Done
547 //
548 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS));
549 return EFI_SUCCESS;
550}
551
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette