VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/LockBoxLib/LockBoxLib.c@ 61380

最後變更 在這個檔案從61380是 58466,由 vboxsync 提交於 9 年 前

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 .

  • 屬性 svn:eol-style 設為 native
檔案大小: 11.0 KB
 
1/** @file
2
3 Library implementing the LockBox interface for OVMF
4
5 Copyright (C) 2013, Red Hat, Inc.
6 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
7
8 This program and the accompanying materials are licensed and made available
9 under the terms and conditions of the BSD License which accompanies this
10 distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
14 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16**/
17
18#include <Uefi.h>
19#include <Library/BaseMemoryLib.h>
20#include <Library/DebugLib.h>
21#include <Library/LockBoxLib.h>
22#include <Library/PcdLib.h>
23#include <LockBoxLib.h>
24
25#pragma pack(1)
26typedef struct {
27 EFI_GUID Guid;
28 EFI_PHYSICAL_ADDRESS OrigAddress;
29 EFI_PHYSICAL_ADDRESS CopyAddress;
30 UINT32 Size;
31 UINT64 Attributes;
32} LOCK_BOX_ENTRY;
33#pragma pack()
34
35LOCK_BOX_GLOBAL *mLockBoxGlobal = NULL;
36STATIC LOCK_BOX_ENTRY *StartOfEntries = NULL;
37STATIC LOCK_BOX_ENTRY *EndOfEntries = NULL;
38
39RETURN_STATUS
40EFIAPI
41LockBoxLibInitialize (
42 VOID
43 )
44{
45 UINTN NumEntries;
46
47 if (PcdGet32 (PcdOvmfLockBoxStorageSize) < sizeof (LOCK_BOX_GLOBAL)) {
48 return RETURN_UNSUPPORTED;
49 }
50
51 mLockBoxGlobal = (LOCK_BOX_GLOBAL *)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase);
52 StartOfEntries = ((LOCK_BOX_ENTRY *) (mLockBoxGlobal + 1));
53 NumEntries = ((PcdGet32 (PcdOvmfLockBoxStorageSize) - sizeof (LOCK_BOX_GLOBAL)) /
54 sizeof (LOCK_BOX_ENTRY));
55 EndOfEntries = StartOfEntries + NumEntries;
56 if (mLockBoxGlobal->Signature != LOCK_BOX_GLOBAL_SIGNATURE) {
57 //
58 // Note: This code depends on the lock box being cleared in early
59 // PEI before usage, so the SubPageBuffer and SubPageRemaining
60 // fields don't need to be set to 0.
61 //
62 mLockBoxGlobal->Signature = LOCK_BOX_GLOBAL_SIGNATURE;
63 }
64 return RETURN_SUCCESS;
65}
66
67
68/**
69 Find LockBox entry based on GUID.
70
71 @param[in] Guid The GUID to search for.
72
73 @return Address of the LOCK_BOX_ENTRY found.
74
75 If NULL, then the item was not found, and there is no space
76 left to store a new item.
77
78 If non-NULL and LOCK_BOX_ENTRY.Size == 0, then the item was not
79 found, but a new item can be inserted at the returned location.
80
81 If non-NULL and LOCK_BOX_ENTRY.Size > 0, then the item was found.
82**/
83STATIC
84LOCK_BOX_ENTRY *
85EFIAPI
86FindHeaderByGuid (
87 IN CONST EFI_GUID *Guid
88 )
89{
90 LOCK_BOX_ENTRY *Header;
91
92 for (Header = StartOfEntries; Header < EndOfEntries; Header++) {
93 if (Header->Size == 0 || CompareGuid (Guid, &Header->Guid)) {
94 return Header;
95 }
96 }
97
98 return NULL;
99}
100
101
102/**
103 This function will save confidential information to lockbox.
104
105 @param Guid the guid to identify the confidential information
106 @param Buffer the address of the confidential information
107 @param Length the length of the confidential information
108
109 @retval RETURN_SUCCESS the information is saved successfully.
110 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
111 Length is 0
112 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
113 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
114 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
115 @retval RETURN_NOT_STARTED it is too early to invoke this interface
116 @retval RETURN_UNSUPPORTED the service is not supported by
117 implementaion.
118**/
119RETURN_STATUS
120EFIAPI
121SaveLockBox (
122 IN GUID *Guid,
123 IN VOID *Buffer,
124 IN UINTN Length
125 )
126{
127 LOCK_BOX_ENTRY *Header;
128 VOID *CopyBuffer;
129
130 DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Buffer=%p Length=0x%x\n", __FUNCTION__,
131 Guid, Buffer, (UINT32) Length));
132
133 if (Guid == NULL || Buffer == NULL || Length == 0) {
134 return RETURN_INVALID_PARAMETER;
135 }
136
137 if (Length > 0xFFFFFFFF) {
138 return RETURN_OUT_OF_RESOURCES;
139 }
140
141 Header = FindHeaderByGuid (Guid);
142 if (Header == NULL) {
143 return RETURN_OUT_OF_RESOURCES;
144 }
145
146 if (Header->Size > 0) {
147 return RETURN_ALREADY_STARTED;
148 }
149
150 CopyBuffer = AllocateAcpiNvsPool (Length);
151 if (CopyBuffer == NULL) {
152 return RETURN_OUT_OF_RESOURCES;
153 }
154
155 //
156 // overwrite the current terminator header with new metadata
157 //
158 CopyGuid (&Header->Guid, Guid);
159 Header->OrigAddress = (UINTN) Buffer;
160 Header->CopyAddress = (UINTN) CopyBuffer;
161 Header->Size = (UINT32) Length;
162 Header->Attributes = 0;
163
164 //
165 // copy contents
166 //
167 CopyMem (CopyBuffer, Buffer, Length);
168
169 return RETURN_SUCCESS;
170}
171
172
173/**
174 This function will set lockbox attributes.
175
176 @param Guid the guid to identify the confidential information
177 @param Attributes the attributes of the lockbox
178
179 @retval RETURN_SUCCESS the information is saved successfully.
180 @retval RETURN_INVALID_PARAMETER attributes is invalid.
181 @retval RETURN_NOT_FOUND the requested GUID not found.
182 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
183 @retval RETURN_NOT_STARTED it is too early to invoke this interface
184 @retval RETURN_UNSUPPORTED the service is not supported by
185 implementaion.
186**/
187RETURN_STATUS
188EFIAPI
189SetLockBoxAttributes (
190 IN GUID *Guid,
191 IN UINT64 Attributes
192 )
193{
194 LOCK_BOX_ENTRY *Header;
195
196 DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Attributes=0x%Lx\n", __FUNCTION__, Guid,
197 Attributes));
198
199 if (Guid == NULL) {
200 return RETURN_INVALID_PARAMETER;
201 }
202
203 Header = FindHeaderByGuid (Guid);
204 if (!Header || Header->Size == 0) {
205 return RETURN_NOT_FOUND;
206 }
207 Header->Attributes = Attributes;
208
209 return RETURN_SUCCESS;
210}
211
212
213/**
214 This function will update confidential information to lockbox.
215
216 @param Guid the guid to identify the original confidential information
217 @param Offset the offset of the original confidential information
218 @param Buffer the address of the updated confidential information
219 @param Length the length of the updated confidential information
220
221 @retval RETURN_SUCCESS the information is saved successfully.
222 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
223 Length is 0.
224 @retval RETURN_NOT_FOUND the requested GUID not found.
225 @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold
226 new information.
227 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
228 @retval RETURN_NOT_STARTED it is too early to invoke this interface
229 @retval RETURN_UNSUPPORTED the service is not supported by
230 implementaion.
231**/
232RETURN_STATUS
233EFIAPI
234UpdateLockBox (
235 IN GUID *Guid,
236 IN UINTN Offset,
237 IN VOID *Buffer,
238 IN UINTN Length
239 )
240{
241 LOCK_BOX_ENTRY *Header;
242
243 DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Offset=0x%x Length=0x%x\n", __FUNCTION__,
244 Guid, (UINT32) Offset, (UINT32) Length));
245
246 if (Guid == NULL || Buffer == NULL || Length == 0) {
247 return RETURN_INVALID_PARAMETER;
248 }
249
250 Header = FindHeaderByGuid (Guid);
251 if (!Header || Header->Size == 0) {
252 return RETURN_NOT_FOUND;
253 }
254
255 if (Header->Size < Offset ||
256 Length > Header->Size - Offset) {
257 return RETURN_BUFFER_TOO_SMALL;
258 }
259
260 CopyMem ((UINT8 *)(UINTN) (Header->CopyAddress) + Offset, Buffer, Length);
261
262 return RETURN_SUCCESS;
263}
264
265
266/**
267 This function will restore confidential information from lockbox.
268
269 @param Guid the guid to identify the confidential information
270 @param Buffer the address of the restored confidential information
271 NULL means restored to original address, Length MUST be NULL at
272 same time.
273 @param Length the length of the restored confidential information
274
275 @retval RETURN_SUCCESS the information is restored successfully.
276 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and
277 Length is NULL.
278 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox
279 has no LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
280 attribute.
281 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the
282 confidential information.
283 @retval RETURN_NOT_FOUND the requested GUID not found.
284 @retval RETURN_NOT_STARTED it is too early to invoke this interface
285 @retval RETURN_ACCESS_DENIED not allow to restore to the address
286 @retval RETURN_UNSUPPORTED the service is not supported by
287 implementaion.
288**/
289RETURN_STATUS
290EFIAPI
291RestoreLockBox (
292 IN GUID *Guid,
293 IN VOID *Buffer, OPTIONAL
294 IN OUT UINTN *Length OPTIONAL
295 )
296{
297 LOCK_BOX_ENTRY *Header;
298
299 DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Buffer=%p\n", __FUNCTION__, Guid,
300 Buffer));
301
302 if ((Guid == NULL) ||
303 ((Buffer == NULL) && (Length != NULL)) ||
304 ((Buffer != NULL) && (Length == NULL))) {
305 return EFI_INVALID_PARAMETER;
306 }
307
308 Header = FindHeaderByGuid (Guid);
309 if (!Header || Header->Size == 0) {
310 return RETURN_NOT_FOUND;
311 }
312
313 if (Buffer == NULL) {
314 if (!(Header->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE)) {
315 return RETURN_WRITE_PROTECTED;
316 }
317 if (Header->OrigAddress + (Header->Size - 1) > MAX_ADDRESS) {
318 return RETURN_UNSUPPORTED;
319 }
320 Buffer = (VOID *)(UINTN) Header->OrigAddress;
321 }
322
323 //
324 // Set RestoreLength
325 //
326 if (Length != NULL) {
327 if (Header->Size > *Length) {
328 //
329 // Input buffer is too small to hold all data.
330 //
331 *Length = Header->Size;
332 return EFI_BUFFER_TOO_SMALL;
333 }
334 *Length = Header->Size;
335 }
336
337 CopyMem (Buffer, (VOID*)(UINTN) Header->CopyAddress, Header->Size);
338
339 return RETURN_SUCCESS;
340}
341
342
343/**
344 This function will restore confidential information from all lockbox which
345 have RestoreInPlace attribute.
346
347 @retval RETURN_SUCCESS the information is restored successfully.
348 @retval RETURN_NOT_STARTED it is too early to invoke this interface
349 @retval RETURN_UNSUPPORTED the service is not supported by
350 implementaion.
351**/
352RETURN_STATUS
353EFIAPI
354RestoreAllLockBoxInPlace (
355 VOID
356 )
357{
358 LOCK_BOX_ENTRY *Header;
359
360 for (Header = StartOfEntries;
361 Header < EndOfEntries && Header->Size > 0;
362 Header++) {
363 if (Header->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) {
364 VOID *Buffer;
365
366 if (Header->OrigAddress + (Header->Size - 1) > MAX_ADDRESS) {
367 return RETURN_UNSUPPORTED;
368 }
369 Buffer = (VOID *)(UINTN) Header->OrigAddress;
370 CopyMem (Buffer, (VOID*)(UINTN)Header->CopyAddress, Header->Size);
371 DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Buffer=%p\n", __FUNCTION__,
372 Header->Guid, Buffer));
373 }
374 }
375 return RETURN_SUCCESS;
376}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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