]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c
0df99d607ea0d612ddf82c9d90719d4c3f89f697
[mirror_edk2.git] / SecurityPkg / Tcg / TrEEConfig / TrEEConfigImpl.c
1 /** @file
2 HII Config Access protocol implementation of TREE configuration module.
3 NOTE: This module is only for reference only, each platform should have its own setup page.
4
5 Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The 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 "TrEEConfigImpl.h"
17 #include <Library/PcdLib.h>
18 #include <Library/Tpm2CommandLib.h>
19 #include <Guid/TpmInstance.h>
20
21 TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1] = TPM_INSTANCE_ID_LIST;
22
23 TREE_CONFIG_PRIVATE_DATA mTrEEConfigPrivateDateTemplate = {
24 TREE_CONFIG_PRIVATE_DATA_SIGNATURE,
25 {
26 TrEEExtractConfig,
27 TrEERouteConfig,
28 TrEECallback
29 }
30 };
31
32 HII_VENDOR_DEVICE_PATH mTrEEHiiVendorDevicePath = {
33 {
34 {
35 HARDWARE_DEVICE_PATH,
36 HW_VENDOR_DP,
37 {
38 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
39 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
40 }
41 },
42 TREE_CONFIG_FORM_SET_GUID
43 },
44 {
45 END_DEVICE_PATH_TYPE,
46 END_ENTIRE_DEVICE_PATH_SUBTYPE,
47 {
48 (UINT8) (END_DEVICE_PATH_LENGTH),
49 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
50 }
51 }
52 };
53
54 /**
55 This function allows a caller to extract the current configuration for one
56 or more named elements from the target driver.
57
58 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
59 @param[in] Request A null-terminated Unicode string in
60 <ConfigRequest> format.
61 @param[out] Progress On return, points to a character in the Request
62 string. Points to the string's null terminator if
63 request was successful. Points to the most recent
64 '&' before the first failing name/value pair (or
65 the beginning of the string if the failure is in
66 the first name/value pair) if the request was not
67 successful.
68 @param[out] Results A null-terminated Unicode string in
69 <ConfigAltResp> format which has all values filled
70 in for the names in the Request string. String to
71 be allocated by the called function.
72
73 @retval EFI_SUCCESS The Results is filled with the requested values.
74 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
75 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
76 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
77 driver.
78
79 **/
80 EFI_STATUS
81 EFIAPI
82 TrEEExtractConfig (
83 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
84 IN CONST EFI_STRING Request,
85 OUT EFI_STRING *Progress,
86 OUT EFI_STRING *Results
87 )
88 {
89 EFI_STATUS Status;
90 UINTN BufferSize;
91 TREE_CONFIGURATION Configuration;
92 TREE_CONFIG_PRIVATE_DATA *PrivateData;
93 EFI_STRING ConfigRequestHdr;
94 EFI_STRING ConfigRequest;
95 BOOLEAN AllocatedRequest;
96 UINTN Size;
97 UINTN Index;
98
99 if (Progress == NULL || Results == NULL) {
100 return EFI_INVALID_PARAMETER;
101 }
102
103 *Progress = Request;
104 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTrEEConfigFormSetGuid, TREE_STORAGE_NAME)) {
105 return EFI_NOT_FOUND;
106 }
107
108 ConfigRequestHdr = NULL;
109 ConfigRequest = NULL;
110 AllocatedRequest = FALSE;
111 Size = 0;
112
113 PrivateData = TREE_CONFIG_PRIVATE_DATA_FROM_THIS (This);
114
115 //
116 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
117 //
118 BufferSize = sizeof (Configuration);
119 Status = gRT->GetVariable (
120 TREE_STORAGE_NAME,
121 &gTrEEConfigFormSetGuid,
122 NULL,
123 &BufferSize,
124 &Configuration
125 );
126 ASSERT_EFI_ERROR (Status);
127
128 //
129 // Get data from PCD to make sure data consistant - platform driver is suppose to construct this PCD accroding to Variable
130 //
131 for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
132 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
133 Configuration.TpmDevice = mTpmInstanceId[Index].TpmDevice;
134 break;
135 }
136 }
137
138 BufferSize = sizeof (Configuration);
139 ConfigRequest = Request;
140 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
141 //
142 // Request has no request element, construct full request string.
143 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
144 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
145 //
146 ConfigRequestHdr = HiiConstructConfigHdr (&gTrEEConfigFormSetGuid, TREE_STORAGE_NAME, PrivateData->DriverHandle);
147 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
148 ConfigRequest = AllocateZeroPool (Size);
149 ASSERT (ConfigRequest != NULL);
150 AllocatedRequest = TRUE;
151 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);
152 FreePool (ConfigRequestHdr);
153 }
154
155 Status = gHiiConfigRouting->BlockToConfig (
156 gHiiConfigRouting,
157 ConfigRequest,
158 (UINT8 *) &Configuration,
159 BufferSize,
160 Results,
161 Progress
162 );
163 //
164 // Free the allocated config request string.
165 //
166 if (AllocatedRequest) {
167 FreePool (ConfigRequest);
168 }
169 //
170 // Set Progress string to the original request string.
171 //
172 if (Request == NULL) {
173 *Progress = NULL;
174 } else if (StrStr (Request, L"OFFSET") == NULL) {
175 *Progress = Request + StrLen (Request);
176 }
177
178 return Status;
179 }
180
181 /**
182 Save TPM request to variable space.
183
184 @param[in] PpRequest Physical Presence request command.
185
186 @retval EFI_SUCCESS The operation is finished successfully.
187 @retval Others Other errors as indicated.
188
189 **/
190 EFI_STATUS
191 SaveTrEEPpRequest (
192 IN UINT8 PpRequest
193 )
194 {
195 EFI_STATUS Status;
196 UINTN DataSize;
197 EFI_TREE_PHYSICAL_PRESENCE PpData;
198
199 //
200 // Save TPM command to variable.
201 //
202 DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
203 Status = gRT->GetVariable (
204 TREE_PHYSICAL_PRESENCE_VARIABLE,
205 &gEfiTrEEPhysicalPresenceGuid,
206 NULL,
207 &DataSize,
208 &PpData
209 );
210 if (EFI_ERROR (Status)) {
211 return Status;
212 }
213
214 PpData.PPRequest = PpRequest;
215 Status = gRT->SetVariable (
216 TREE_PHYSICAL_PRESENCE_VARIABLE,
217 &gEfiTrEEPhysicalPresenceGuid,
218 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
219 DataSize,
220 &PpData
221 );
222 if (EFI_ERROR(Status)) {
223 return Status;
224 }
225
226 return EFI_SUCCESS;
227 }
228
229 /**
230 This function processes the results of changes in configuration.
231
232 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
233 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
234 format.
235 @param[out] Progress A pointer to a string filled in with the offset of
236 the most recent '&' before the first failing
237 name/value pair (or the beginning of the string if
238 the failure is in the first name/value pair) or
239 the terminating NULL if all was successful.
240
241 @retval EFI_SUCCESS The Results is processed successfully.
242 @retval EFI_INVALID_PARAMETER Configuration is NULL.
243 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
244 driver.
245
246 **/
247 EFI_STATUS
248 EFIAPI
249 TrEERouteConfig (
250 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
251 IN CONST EFI_STRING Configuration,
252 OUT EFI_STRING *Progress
253 )
254 {
255 EFI_STATUS Status;
256 UINTN BufferSize;
257 TREE_CONFIGURATION TrEEConfiguration;
258
259 if (Configuration == NULL || Progress == NULL) {
260 return EFI_INVALID_PARAMETER;
261 }
262
263 *Progress = Configuration;
264 if (!HiiIsConfigHdrMatch (Configuration, &gTrEEConfigFormSetGuid, TREE_STORAGE_NAME)) {
265 return EFI_NOT_FOUND;
266 }
267
268 BufferSize = sizeof (TrEEConfiguration);
269 Status = gRT->GetVariable (
270 TREE_STORAGE_NAME,
271 &gTrEEConfigFormSetGuid,
272 NULL,
273 &BufferSize,
274 &TrEEConfiguration
275 );
276 ASSERT_EFI_ERROR (Status);
277
278 //
279 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
280 //
281 BufferSize = sizeof (TREE_CONFIGURATION);
282 Status = gHiiConfigRouting->ConfigToBlock (
283 gHiiConfigRouting,
284 Configuration,
285 (UINT8 *) &TrEEConfiguration,
286 &BufferSize,
287 Progress
288 );
289 if (EFI_ERROR (Status)) {
290 return Status;
291 }
292
293 //
294 // Save to variable so platform driver can get it.
295 //
296 Status = gRT->SetVariable (
297 TREE_STORAGE_NAME,
298 &gTrEEConfigFormSetGuid,
299 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
300 sizeof(TrEEConfiguration),
301 &TrEEConfiguration
302 );
303
304 SaveTrEEPpRequest (TrEEConfiguration.Tpm2Operation
305 );
306
307 return Status;
308 }
309
310 /**
311 This function processes the results of changes in configuration.
312
313 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
314 @param[in] Action Specifies the type of action taken by the browser.
315 @param[in] QuestionId A unique value which is sent to the original
316 exporting driver so that it can identify the type
317 of data to expect.
318 @param[in] Type The type of value for the question.
319 @param[in] Value A pointer to the data being sent to the original
320 exporting driver.
321 @param[out] ActionRequest On return, points to the action requested by the
322 callback function.
323
324 @retval EFI_SUCCESS The callback successfully handled the action.
325 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
326 variable and its data.
327 @retval EFI_DEVICE_ERROR The variable could not be saved.
328 @retval EFI_UNSUPPORTED The specified Action is not supported by the
329 callback.
330
331 **/
332 EFI_STATUS
333 EFIAPI
334 TrEECallback (
335 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
336 IN EFI_BROWSER_ACTION Action,
337 IN EFI_QUESTION_ID QuestionId,
338 IN UINT8 Type,
339 IN EFI_IFR_TYPE_VALUE *Value,
340 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
341 )
342 {
343 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
344 return EFI_INVALID_PARAMETER;
345 }
346
347 if ((Action != EFI_BROWSER_ACTION_CHANGED) ||
348 (QuestionId != KEY_TPM_DEVICE)) {
349 return EFI_UNSUPPORTED;
350 }
351
352 return EFI_SUCCESS;
353 }
354
355 /**
356 This function publish the TREE configuration Form for TPM device.
357
358 @param[in, out] PrivateData Points to TREE configuration private data.
359
360 @retval EFI_SUCCESS HII Form is installed for this network device.
361 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
362 @retval Others Other errors as indicated.
363
364 **/
365 EFI_STATUS
366 InstallTrEEConfigForm (
367 IN OUT TREE_CONFIG_PRIVATE_DATA *PrivateData
368 )
369 {
370 EFI_STATUS Status;
371 EFI_HII_HANDLE HiiHandle;
372 EFI_HANDLE DriverHandle;
373 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
374
375 DriverHandle = NULL;
376 ConfigAccess = &PrivateData->ConfigAccess;
377 Status = gBS->InstallMultipleProtocolInterfaces (
378 &DriverHandle,
379 &gEfiDevicePathProtocolGuid,
380 &mTrEEHiiVendorDevicePath,
381 &gEfiHiiConfigAccessProtocolGuid,
382 ConfigAccess,
383 NULL
384 );
385 if (EFI_ERROR (Status)) {
386 return Status;
387 }
388
389 PrivateData->DriverHandle = DriverHandle;
390
391 //
392 // Publish the HII package list
393 //
394 HiiHandle = HiiAddPackages (
395 &gTrEEConfigFormSetGuid,
396 DriverHandle,
397 TrEEConfigDxeStrings,
398 TrEEConfigBin,
399 NULL
400 );
401 if (HiiHandle == NULL) {
402 gBS->UninstallMultipleProtocolInterfaces (
403 DriverHandle,
404 &gEfiDevicePathProtocolGuid,
405 &mTrEEHiiVendorDevicePath,
406 &gEfiHiiConfigAccessProtocolGuid,
407 ConfigAccess,
408 NULL
409 );
410
411 return EFI_OUT_OF_RESOURCES;
412 }
413
414 PrivateData->HiiHandle = HiiHandle;
415
416 return EFI_SUCCESS;
417 }
418
419 /**
420 This function removes TREE configuration Form.
421
422 @param[in, out] PrivateData Points to TREE configuration private data.
423
424 **/
425 VOID
426 UninstallTrEEConfigForm (
427 IN OUT TREE_CONFIG_PRIVATE_DATA *PrivateData
428 )
429 {
430 //
431 // Uninstall HII package list
432 //
433 if (PrivateData->HiiHandle != NULL) {
434 HiiRemovePackages (PrivateData->HiiHandle);
435 PrivateData->HiiHandle = NULL;
436 }
437
438 //
439 // Uninstall HII Config Access Protocol
440 //
441 if (PrivateData->DriverHandle != NULL) {
442 gBS->UninstallMultipleProtocolInterfaces (
443 PrivateData->DriverHandle,
444 &gEfiDevicePathProtocolGuid,
445 &mTrEEHiiVendorDevicePath,
446 &gEfiHiiConfigAccessProtocolGuid,
447 &PrivateData->ConfigAccess,
448 NULL
449 );
450 PrivateData->DriverHandle = NULL;
451 }
452
453 FreePool (PrivateData);
454 }