]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c
SecurityPkg: Change OPTIONAL keyword usage style
[mirror_edk2.git] / SecurityPkg / Tcg / TcgConfigDxe / TcgConfigImpl.c
CommitLineData
0c18794e 1/** @file\r
2 HII Config Access protocol implementation of TCG configuration module.\r
3\r
b49758c1 4Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>\r
289b714b 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
0c18794e 6\r
7**/\r
8\r
9#include "TcgConfigImpl.h"\r
10\r
0c18794e 11CHAR16 mTcgStorageName[] = L"TCG_CONFIGURATION";\r
12\r
13TCG_CONFIG_PRIVATE_DATA mTcgConfigPrivateDateTemplate = {\r
14 TCG_CONFIG_PRIVATE_DATA_SIGNATURE,\r
15 {\r
16 TcgExtractConfig,\r
17 TcgRouteConfig,\r
18 TcgCallback\r
19 }\r
20};\r
21\r
22HII_VENDOR_DEVICE_PATH mTcgHiiVendorDevicePath = {\r
23 {\r
24 {\r
25 HARDWARE_DEVICE_PATH,\r
26 HW_VENDOR_DP,\r
27 {\r
28 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
29 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
30 }\r
31 },\r
a0c56a82 32 TCG_CONFIG_FORM_SET_GUID\r
0c18794e 33 },\r
34 {\r
35 END_DEVICE_PATH_TYPE,\r
36 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
b3548d32 37 {\r
0c18794e 38 (UINT8) (END_DEVICE_PATH_LENGTH),\r
39 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
40 }\r
41 }\r
42};\r
43\r
44/**\r
45 Get current state of TPM device.\r
46\r
47 @param[in] TcgProtocol Point to EFI_TCG_PROTOCOL instance.\r
48 @param[out] TpmEnable Flag to indicate TPM is enabled or not.\r
49 @param[out] TpmActivate Flag to indicate TPM is activated or not.\r
50\r
51 @retval EFI_SUCCESS State is successfully returned.\r
52 @retval EFI_DEVICE_ERROR Failed to get TPM response.\r
53 @retval Others Other errors as indicated.\r
54\r
55**/\r
56EFI_STATUS\r
57GetTpmState (\r
58 IN EFI_TCG_PROTOCOL *TcgProtocol,\r
12710fe9 59 OUT BOOLEAN *TpmEnable OPTIONAL,\r
0c18794e 60 OUT BOOLEAN *TpmActivate OPTIONAL\r
61 )\r
62{\r
63 EFI_STATUS Status;\r
64 TPM_RSP_COMMAND_HDR *TpmRsp;\r
65 UINT32 TpmSendSize;\r
66 TPM_PERMANENT_FLAGS *TpmPermanentFlags;\r
67 UINT8 CmdBuf[64];\r
68\r
69 ASSERT (TcgProtocol != NULL);\r
b3548d32 70\r
0c18794e 71 //\r
72 // Get TPM Permanent flags (TpmEnable, TpmActivate)\r
73 //\r
74 if ((TpmEnable != NULL) || (TpmActivate != NULL)) {\r
75 TpmSendSize = sizeof (TPM_RQU_COMMAND_HDR) + sizeof (UINT32) * 3;\r
607599bf 76 *(UINT16*)&CmdBuf[0] = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
77 *(UINT32*)&CmdBuf[2] = SwapBytes32 (TpmSendSize);\r
78 *(UINT32*)&CmdBuf[6] = SwapBytes32 (TPM_ORD_GetCapability);\r
b3548d32 79\r
607599bf 80 *(UINT32*)&CmdBuf[10] = SwapBytes32 (TPM_CAP_FLAG);\r
81 *(UINT32*)&CmdBuf[14] = SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT));\r
82 *(UINT32*)&CmdBuf[18] = SwapBytes32 (TPM_CAP_FLAG_PERMANENT);\r
0c18794e 83\r
84 Status = TcgProtocol->PassThroughToTpm (\r
85 TcgProtocol,\r
86 TpmSendSize,\r
87 CmdBuf,\r
88 sizeof (CmdBuf),\r
89 CmdBuf\r
b3548d32 90 );\r
0c18794e 91 TpmRsp = (TPM_RSP_COMMAND_HDR *) &CmdBuf[0];\r
607599bf 92 if (EFI_ERROR (Status) || (TpmRsp->tag != SwapBytes16 (TPM_TAG_RSP_COMMAND)) || (TpmRsp->returnCode != 0)) {\r
0c18794e 93 return EFI_DEVICE_ERROR;\r
94 }\r
b3548d32 95\r
0c18794e 96 TpmPermanentFlags = (TPM_PERMANENT_FLAGS *) &CmdBuf[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];\r
97\r
98 if (TpmEnable != NULL) {\r
99 *TpmEnable = (BOOLEAN) !TpmPermanentFlags->disable;\r
100 }\r
101\r
102 if (TpmActivate != NULL) {\r
103 *TpmActivate = (BOOLEAN) !TpmPermanentFlags->deactivated;\r
104 }\r
105 }\r
b3548d32
LG
106\r
107 return EFI_SUCCESS;\r
0c18794e 108}\r
109\r
110/**\r
111 This function allows a caller to extract the current configuration for one\r
112 or more named elements from the target driver.\r
113\r
114 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
115 @param[in] Request A null-terminated Unicode string in\r
116 <ConfigRequest> format.\r
117 @param[out] Progress On return, points to a character in the Request\r
118 string. Points to the string's null terminator if\r
119 request was successful. Points to the most recent\r
120 '&' before the first failing name/value pair (or\r
121 the beginning of the string if the failure is in\r
122 the first name/value pair) if the request was not\r
123 successful.\r
124 @param[out] Results A null-terminated Unicode string in\r
125 <ConfigAltResp> format which has all values filled\r
126 in for the names in the Request string. String to\r
127 be allocated by the called function.\r
128\r
129 @retval EFI_SUCCESS The Results is filled with the requested values.\r
130 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
131 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
132 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
133 driver.\r
134\r
135**/\r
136EFI_STATUS\r
137EFIAPI\r
138TcgExtractConfig (\r
139 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
140 IN CONST EFI_STRING Request,\r
141 OUT EFI_STRING *Progress,\r
142 OUT EFI_STRING *Results\r
143 )\r
144{\r
145 EFI_STATUS Status;\r
0c18794e 146 TCG_CONFIG_PRIVATE_DATA *PrivateData;\r
147 EFI_STRING ConfigRequestHdr;\r
148 EFI_STRING ConfigRequest;\r
149 BOOLEAN AllocatedRequest;\r
150 UINTN Size;\r
151 BOOLEAN TpmEnable;\r
152 BOOLEAN TpmActivate;\r
0c18794e 153\r
154 if (Progress == NULL || Results == NULL) {\r
155 return EFI_INVALID_PARAMETER;\r
156 }\r
157\r
158 *Progress = Request;\r
a0c56a82 159 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTcgConfigFormSetGuid, mTcgStorageName)) {\r
0c18794e 160 return EFI_NOT_FOUND;\r
161 }\r
162\r
163 ConfigRequestHdr = NULL;\r
164 ConfigRequest = NULL;\r
165 AllocatedRequest = FALSE;\r
166 Size = 0;\r
167\r
168 PrivateData = TCG_CONFIG_PRIVATE_DATA_FROM_THIS (This);\r
169\r
170 //\r
171 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
b3548d32 172 //\r
b49758c1 173 PrivateData->Configuration->TpmOperation = PHYSICAL_PRESENCE_NO_ACTION;\r
0c18794e 174\r
175 //\r
1826b5e6 176 // Get current TPM state.\r
0c18794e 177 //\r
178 if (PrivateData->TcgProtocol != NULL) {\r
179 Status = GetTpmState (PrivateData->TcgProtocol, &TpmEnable, &TpmActivate);\r
180 if (EFI_ERROR (Status)) {\r
181 return Status;\r
182 }\r
183\r
1826b5e6
ZC
184 PrivateData->Configuration->TpmEnable = TpmEnable;\r
185 PrivateData->Configuration->TpmActivate = TpmActivate;\r
0c18794e 186 }\r
187\r
0c18794e 188 ConfigRequest = Request;\r
189 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
190 //\r
191 // Request has no request element, construct full request string.\r
192 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
193 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
194 //\r
a0c56a82 195 ConfigRequestHdr = HiiConstructConfigHdr (&gTcgConfigFormSetGuid, mTcgStorageName, PrivateData->DriverHandle);\r
0c18794e 196 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
197 ConfigRequest = AllocateZeroPool (Size);\r
198 ASSERT (ConfigRequest != NULL);\r
199 AllocatedRequest = TRUE;\r
1826b5e6 200 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, sizeof (TCG_CONFIGURATION));\r
0c18794e 201 FreePool (ConfigRequestHdr);\r
202 }\r
203\r
204 Status = gHiiConfigRouting->BlockToConfig (\r
205 gHiiConfigRouting,\r
206 ConfigRequest,\r
1826b5e6
ZC
207 (UINT8 *) PrivateData->Configuration,\r
208 sizeof (TCG_CONFIGURATION),\r
0c18794e 209 Results,\r
210 Progress\r
211 );\r
212 //\r
213 // Free the allocated config request string.\r
214 //\r
215 if (AllocatedRequest) {\r
216 FreePool (ConfigRequest);\r
217 }\r
218 //\r
219 // Set Progress string to the original request string.\r
220 //\r
221 if (Request == NULL) {\r
222 *Progress = NULL;\r
223 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
224 *Progress = Request + StrLen (Request);\r
225 }\r
226\r
227 return Status;\r
228}\r
229\r
230/**\r
231 This function processes the results of changes in configuration.\r
232\r
233 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
234 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
235 format.\r
236 @param[out] Progress A pointer to a string filled in with the offset of\r
237 the most recent '&' before the first failing\r
238 name/value pair (or the beginning of the string if\r
239 the failure is in the first name/value pair) or\r
240 the terminating NULL if all was successful.\r
241\r
242 @retval EFI_SUCCESS The Results is processed successfully.\r
243 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
244 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
245 driver.\r
246\r
247**/\r
248EFI_STATUS\r
249EFIAPI\r
250TcgRouteConfig (\r
251 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
252 IN CONST EFI_STRING Configuration,\r
253 OUT EFI_STRING *Progress\r
254 )\r
255{\r
256 EFI_STATUS Status;\r
257 UINTN BufferSize;\r
258 TCG_CONFIGURATION TcgConfiguration;\r
259\r
260 if (Configuration == NULL || Progress == NULL) {\r
261 return EFI_INVALID_PARAMETER;\r
262 }\r
263\r
264 *Progress = Configuration;\r
a0c56a82 265 if (!HiiIsConfigHdrMatch (Configuration, &gTcgConfigFormSetGuid, mTcgStorageName)) {\r
0c18794e 266 return EFI_NOT_FOUND;\r
267 }\r
268\r
269 //\r
270 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
271 //\r
272 BufferSize = sizeof (TCG_CONFIGURATION);\r
273 Status = gHiiConfigRouting->ConfigToBlock (\r
274 gHiiConfigRouting,\r
275 Configuration,\r
276 (UINT8 *) &TcgConfiguration,\r
277 &BufferSize,\r
278 Progress\r
279 );\r
280 if (EFI_ERROR (Status)) {\r
281 return Status;\r
282 }\r
283\r
0c18794e 284 return EFI_SUCCESS;\r
285}\r
286\r
287/**\r
288 Save TPM request to variable space.\r
289\r
290 @param[in] PpRequest Physical Presence request command.\r
291\r
292 @retval EFI_SUCCESS The operation is finished successfully.\r
293 @retval Others Other errors as indicated.\r
294\r
295**/\r
296EFI_STATUS\r
297SavePpRequest (\r
298 IN UINT8 PpRequest\r
299 )\r
300{\r
301 EFI_STATUS Status;\r
302 UINTN DataSize;\r
303 EFI_PHYSICAL_PRESENCE PpData;\r
304\r
305 //\r
306 // Save TPM command to variable.\r
307 //\r
308 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
309 Status = gRT->GetVariable (\r
310 PHYSICAL_PRESENCE_VARIABLE,\r
311 &gEfiPhysicalPresenceGuid,\r
312 NULL,\r
313 &DataSize,\r
314 &PpData\r
315 );\r
316 if (EFI_ERROR (Status)) {\r
317 return Status;\r
b3548d32
LG
318 }\r
319\r
0c18794e 320 PpData.PPRequest = PpRequest;\r
321 Status = gRT->SetVariable (\r
322 PHYSICAL_PRESENCE_VARIABLE,\r
323 &gEfiPhysicalPresenceGuid,\r
324 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
325 DataSize,\r
326 &PpData\r
327 );\r
328 if (EFI_ERROR(Status)) {\r
329 return Status;\r
330 }\r
331\r
0c18794e 332 return EFI_SUCCESS;\r
333}\r
334\r
335/**\r
336 This function processes the results of changes in configuration.\r
337\r
338 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
339 @param[in] Action Specifies the type of action taken by the browser.\r
340 @param[in] QuestionId A unique value which is sent to the original\r
341 exporting driver so that it can identify the type\r
342 of data to expect.\r
343 @param[in] Type The type of value for the question.\r
344 @param[in] Value A pointer to the data being sent to the original\r
345 exporting driver.\r
346 @param[out] ActionRequest On return, points to the action requested by the\r
347 callback function.\r
348\r
349 @retval EFI_SUCCESS The callback successfully handled the action.\r
350 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
351 variable and its data.\r
352 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
353 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
354 callback.\r
355\r
356**/\r
357EFI_STATUS\r
358EFIAPI\r
359TcgCallback (\r
360 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
361 IN EFI_BROWSER_ACTION Action,\r
362 IN EFI_QUESTION_ID QuestionId,\r
363 IN UINT8 Type,\r
364 IN EFI_IFR_TYPE_VALUE *Value,\r
365 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
366 )\r
367{\r
1826b5e6
ZC
368 TCG_CONFIG_PRIVATE_DATA *PrivateData;\r
369 CHAR16 State[32];\r
370\r
0c18794e 371 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
372 return EFI_INVALID_PARAMETER;\r
373 }\r
374\r
1826b5e6
ZC
375 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
376 if (QuestionId == KEY_TPM_ACTION) {\r
377\r
378 PrivateData = TCG_CONFIG_PRIVATE_DATA_FROM_THIS (This);\r
379 UnicodeSPrint (\r
380 State,\r
381 sizeof (State),\r
382 L"%s, and %s",\r
383 PrivateData->Configuration->TpmEnable ? L"Enabled" : L"Disabled",\r
384 PrivateData->Configuration->TpmActivate ? L"Activated" : L"Deactivated"\r
385 );\r
386 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM_STATE_CONTENT), State, NULL);\r
387 }\r
388 return EFI_SUCCESS;\r
389 }\r
390\r
fab10465 391 if ((Action != EFI_BROWSER_ACTION_CHANGED) || (QuestionId != KEY_TPM_ACTION)) {\r
0c18794e 392 return EFI_UNSUPPORTED;\r
393 }\r
394\r
395 SavePpRequest (Value->u8);\r
54a26282 396 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
b3548d32 397\r
0c18794e 398 return EFI_SUCCESS;\r
399}\r
400\r
401/**\r
402 This function publish the TCG configuration Form for TPM device.\r
403\r
404 @param[in, out] PrivateData Points to TCG configuration private data.\r
405\r
406 @retval EFI_SUCCESS HII Form is installed for this network device.\r
407 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
408 @retval Others Other errors as indicated.\r
409\r
410**/\r
411EFI_STATUS\r
412InstallTcgConfigForm (\r
413 IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData\r
414 )\r
415{\r
416 EFI_STATUS Status;\r
417 EFI_HII_HANDLE HiiHandle;\r
418 EFI_HANDLE DriverHandle;\r
0c18794e 419 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
420\r
421 DriverHandle = NULL;\r
422 ConfigAccess = &PrivateData->ConfigAccess;\r
423 Status = gBS->InstallMultipleProtocolInterfaces (\r
424 &DriverHandle,\r
425 &gEfiDevicePathProtocolGuid,\r
426 &mTcgHiiVendorDevicePath,\r
427 &gEfiHiiConfigAccessProtocolGuid,\r
428 ConfigAccess,\r
429 NULL\r
430 );\r
431 if (EFI_ERROR (Status)) {\r
432 return Status;\r
433 }\r
434\r
435 PrivateData->DriverHandle = DriverHandle;\r
436\r
437 //\r
438 // Publish the HII package list\r
439 //\r
440 HiiHandle = HiiAddPackages (\r
a0c56a82 441 &gTcgConfigFormSetGuid,\r
0c18794e 442 DriverHandle,\r
443 TcgConfigDxeStrings,\r
444 TcgConfigBin,\r
445 NULL\r
446 );\r
447 if (HiiHandle == NULL) {\r
448 gBS->UninstallMultipleProtocolInterfaces (\r
449 DriverHandle,\r
450 &gEfiDevicePathProtocolGuid,\r
451 &mTcgHiiVendorDevicePath,\r
452 &gEfiHiiConfigAccessProtocolGuid,\r
453 ConfigAccess,\r
454 NULL\r
b3548d32 455 );\r
0c18794e 456\r
457 return EFI_OUT_OF_RESOURCES;\r
458 }\r
b3548d32 459\r
0c18794e 460 PrivateData->HiiHandle = HiiHandle;\r
461\r
b3548d32 462 return EFI_SUCCESS;\r
0c18794e 463}\r
464\r
465/**\r
466 This function removes TCG configuration Form.\r
467\r
468 @param[in, out] PrivateData Points to TCG configuration private data.\r
469\r
470**/\r
471VOID\r
472UninstallTcgConfigForm (\r
473 IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData\r
474 )\r
475{\r
476 //\r
477 // Uninstall HII package list\r
478 //\r
479 if (PrivateData->HiiHandle != NULL) {\r
480 HiiRemovePackages (PrivateData->HiiHandle);\r
481 PrivateData->HiiHandle = NULL;\r
482 }\r
483\r
484 //\r
485 // Uninstall HII Config Access Protocol\r
486 //\r
487 if (PrivateData->DriverHandle != NULL) {\r
488 gBS->UninstallMultipleProtocolInterfaces (\r
489 PrivateData->DriverHandle,\r
490 &gEfiDevicePathProtocolGuid,\r
491 &mTcgHiiVendorDevicePath,\r
492 &gEfiHiiConfigAccessProtocolGuid,\r
493 &PrivateData->ConfigAccess,\r
494 NULL\r
495 );\r
496 PrivateData->DriverHandle = NULL;\r
497 }\r
1826b5e6
ZC
498\r
499 if (PrivateData->Configuration != NULL) {\r
500 FreePool(PrivateData->Configuration);\r
501 }\r
0c18794e 502 FreePool (PrivateData);\r
503}\r