]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
c411b485 11CHAR16 mTcgStorageName[] = L"TCG_CONFIGURATION";\r
0c18794e 12\r
c411b485 13TCG_CONFIG_PRIVATE_DATA mTcgConfigPrivateDateTemplate = {\r
0c18794e 14 TCG_CONFIG_PRIVATE_DATA_SIGNATURE,\r
15 {\r
16 TcgExtractConfig,\r
17 TcgRouteConfig,\r
18 TcgCallback\r
19 }\r
20};\r
21\r
c411b485 22HII_VENDOR_DEVICE_PATH mTcgHiiVendorDevicePath = {\r
0c18794e 23 {\r
24 {\r
25 HARDWARE_DEVICE_PATH,\r
26 HW_VENDOR_DP,\r
27 {\r
c411b485
MK
28 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),\r
29 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
0c18794e 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
c411b485
MK
38 (UINT8)(END_DEVICE_PATH_LENGTH),\r
39 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)\r
0c18794e 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
c411b485
MK
58 IN EFI_TCG_PROTOCOL *TcgProtocol,\r
59 OUT BOOLEAN *TpmEnable OPTIONAL,\r
60 OUT BOOLEAN *TpmActivate OPTIONAL\r
0c18794e 61 )\r
62{\r
c411b485
MK
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
0c18794e 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
c411b485
MK
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
c411b485
MK
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
c411b485 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
c411b485 96 TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&CmdBuf[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];\r
0c18794e 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
c411b485
MK
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
0c18794e 143 )\r
144{\r
c411b485
MK
145 EFI_STATUS Status;\r
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
153\r
154 if ((Progress == NULL) || (Results == NULL)) {\r
0c18794e 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
c411b485
MK
196 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
197 ConfigRequest = AllocateZeroPool (Size);\r
0c18794e 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
c411b485 207 (UINT8 *)PrivateData->Configuration,\r
1826b5e6 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
c411b485 218\r
0c18794e 219 //\r
220 // Set Progress string to the original request string.\r
221 //\r
222 if (Request == NULL) {\r
223 *Progress = NULL;\r
224 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
225 *Progress = Request + StrLen (Request);\r
226 }\r
227\r
228 return Status;\r
229}\r
230\r
231/**\r
232 This function processes the results of changes in configuration.\r
233\r
234 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
235 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
236 format.\r
237 @param[out] Progress A pointer to a string filled in with the offset of\r
238 the most recent '&' before the first failing\r
239 name/value pair (or the beginning of the string if\r
240 the failure is in the first name/value pair) or\r
241 the terminating NULL if all was successful.\r
242\r
243 @retval EFI_SUCCESS The Results is processed successfully.\r
244 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
245 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
246 driver.\r
247\r
248**/\r
249EFI_STATUS\r
250EFIAPI\r
251TcgRouteConfig (\r
c411b485
MK
252 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
253 IN CONST EFI_STRING Configuration,\r
254 OUT EFI_STRING *Progress\r
0c18794e 255 )\r
256{\r
c411b485
MK
257 EFI_STATUS Status;\r
258 UINTN BufferSize;\r
259 TCG_CONFIGURATION TcgConfiguration;\r
0c18794e 260\r
c411b485 261 if ((Configuration == NULL) || (Progress == NULL)) {\r
0c18794e 262 return EFI_INVALID_PARAMETER;\r
263 }\r
264\r
265 *Progress = Configuration;\r
a0c56a82 266 if (!HiiIsConfigHdrMatch (Configuration, &gTcgConfigFormSetGuid, mTcgStorageName)) {\r
0c18794e 267 return EFI_NOT_FOUND;\r
268 }\r
269\r
270 //\r
271 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
272 //\r
273 BufferSize = sizeof (TCG_CONFIGURATION);\r
c411b485
MK
274 Status = gHiiConfigRouting->ConfigToBlock (\r
275 gHiiConfigRouting,\r
276 Configuration,\r
277 (UINT8 *)&TcgConfiguration,\r
278 &BufferSize,\r
279 Progress\r
280 );\r
0c18794e 281 if (EFI_ERROR (Status)) {\r
282 return Status;\r
283 }\r
284\r
0c18794e 285 return EFI_SUCCESS;\r
286}\r
287\r
288/**\r
289 Save TPM request to variable space.\r
290\r
291 @param[in] PpRequest Physical Presence request command.\r
292\r
293 @retval EFI_SUCCESS The operation is finished successfully.\r
294 @retval Others Other errors as indicated.\r
295\r
296**/\r
297EFI_STATUS\r
298SavePpRequest (\r
c411b485 299 IN UINT8 PpRequest\r
0c18794e 300 )\r
301{\r
c411b485
MK
302 EFI_STATUS Status;\r
303 UINTN DataSize;\r
304 EFI_PHYSICAL_PRESENCE PpData;\r
0c18794e 305\r
306 //\r
307 // Save TPM command to variable.\r
308 //\r
309 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
c411b485
MK
310 Status = gRT->GetVariable (\r
311 PHYSICAL_PRESENCE_VARIABLE,\r
312 &gEfiPhysicalPresenceGuid,\r
313 NULL,\r
314 &DataSize,\r
315 &PpData\r
316 );\r
0c18794e 317 if (EFI_ERROR (Status)) {\r
318 return Status;\r
b3548d32
LG
319 }\r
320\r
0c18794e 321 PpData.PPRequest = PpRequest;\r
c411b485
MK
322 Status = gRT->SetVariable (\r
323 PHYSICAL_PRESENCE_VARIABLE,\r
324 &gEfiPhysicalPresenceGuid,\r
325 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
326 DataSize,\r
327 &PpData\r
328 );\r
329 if (EFI_ERROR (Status)) {\r
0c18794e 330 return Status;\r
331 }\r
332\r
0c18794e 333 return EFI_SUCCESS;\r
334}\r
335\r
336/**\r
337 This function processes the results of changes in configuration.\r
338\r
339 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
340 @param[in] Action Specifies the type of action taken by the browser.\r
341 @param[in] QuestionId A unique value which is sent to the original\r
342 exporting driver so that it can identify the type\r
343 of data to expect.\r
344 @param[in] Type The type of value for the question.\r
345 @param[in] Value A pointer to the data being sent to the original\r
346 exporting driver.\r
347 @param[out] ActionRequest On return, points to the action requested by the\r
348 callback function.\r
349\r
350 @retval EFI_SUCCESS The callback successfully handled the action.\r
351 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
352 variable and its data.\r
353 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
354 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
355 callback.\r
356\r
357**/\r
358EFI_STATUS\r
359EFIAPI\r
360TcgCallback (\r
c411b485
MK
361 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
362 IN EFI_BROWSER_ACTION Action,\r
363 IN EFI_QUESTION_ID QuestionId,\r
364 IN UINT8 Type,\r
365 IN EFI_IFR_TYPE_VALUE *Value,\r
366 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
0c18794e 367 )\r
368{\r
c411b485
MK
369 TCG_CONFIG_PRIVATE_DATA *PrivateData;\r
370 CHAR16 State[32];\r
1826b5e6 371\r
0c18794e 372 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
373 return EFI_INVALID_PARAMETER;\r
374 }\r
375\r
1826b5e6
ZC
376 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
377 if (QuestionId == KEY_TPM_ACTION) {\r
1826b5e6
ZC
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
c411b485 388\r
1826b5e6
ZC
389 return EFI_SUCCESS;\r
390 }\r
391\r
fab10465 392 if ((Action != EFI_BROWSER_ACTION_CHANGED) || (QuestionId != KEY_TPM_ACTION)) {\r
0c18794e 393 return EFI_UNSUPPORTED;\r
394 }\r
395\r
396 SavePpRequest (Value->u8);\r
54a26282 397 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
b3548d32 398\r
0c18794e 399 return EFI_SUCCESS;\r
400}\r
401\r
402/**\r
403 This function publish the TCG configuration Form for TPM device.\r
404\r
405 @param[in, out] PrivateData Points to TCG configuration private data.\r
406\r
407 @retval EFI_SUCCESS HII Form is installed for this network device.\r
408 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
409 @retval Others Other errors as indicated.\r
410\r
411**/\r
412EFI_STATUS\r
413InstallTcgConfigForm (\r
414 IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData\r
415 )\r
416{\r
417 EFI_STATUS Status;\r
418 EFI_HII_HANDLE HiiHandle;\r
419 EFI_HANDLE DriverHandle;\r
0c18794e 420 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
421\r
422 DriverHandle = NULL;\r
423 ConfigAccess = &PrivateData->ConfigAccess;\r
c411b485
MK
424 Status = gBS->InstallMultipleProtocolInterfaces (\r
425 &DriverHandle,\r
426 &gEfiDevicePathProtocolGuid,\r
427 &mTcgHiiVendorDevicePath,\r
428 &gEfiHiiConfigAccessProtocolGuid,\r
429 ConfigAccess,\r
430 NULL\r
431 );\r
0c18794e 432 if (EFI_ERROR (Status)) {\r
433 return Status;\r
434 }\r
435\r
436 PrivateData->DriverHandle = DriverHandle;\r
437\r
438 //\r
439 // Publish the HII package list\r
440 //\r
441 HiiHandle = HiiAddPackages (\r
a0c56a82 442 &gTcgConfigFormSetGuid,\r
0c18794e 443 DriverHandle,\r
444 TcgConfigDxeStrings,\r
445 TcgConfigBin,\r
446 NULL\r
447 );\r
448 if (HiiHandle == NULL) {\r
449 gBS->UninstallMultipleProtocolInterfaces (\r
450 DriverHandle,\r
451 &gEfiDevicePathProtocolGuid,\r
452 &mTcgHiiVendorDevicePath,\r
453 &gEfiHiiConfigAccessProtocolGuid,\r
454 ConfigAccess,\r
455 NULL\r
b3548d32 456 );\r
0c18794e 457\r
458 return EFI_OUT_OF_RESOURCES;\r
459 }\r
b3548d32 460\r
0c18794e 461 PrivateData->HiiHandle = HiiHandle;\r
462\r
b3548d32 463 return EFI_SUCCESS;\r
0c18794e 464}\r
465\r
466/**\r
467 This function removes TCG configuration Form.\r
468\r
469 @param[in, out] PrivateData Points to TCG configuration private data.\r
470\r
471**/\r
472VOID\r
473UninstallTcgConfigForm (\r
c411b485 474 IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData\r
0c18794e 475 )\r
476{\r
477 //\r
478 // Uninstall HII package list\r
479 //\r
480 if (PrivateData->HiiHandle != NULL) {\r
481 HiiRemovePackages (PrivateData->HiiHandle);\r
482 PrivateData->HiiHandle = NULL;\r
483 }\r
484\r
485 //\r
486 // Uninstall HII Config Access Protocol\r
487 //\r
488 if (PrivateData->DriverHandle != NULL) {\r
489 gBS->UninstallMultipleProtocolInterfaces (\r
490 PrivateData->DriverHandle,\r
491 &gEfiDevicePathProtocolGuid,\r
492 &mTcgHiiVendorDevicePath,\r
493 &gEfiHiiConfigAccessProtocolGuid,\r
494 &PrivateData->ConfigAccess,\r
495 NULL\r
496 );\r
497 PrivateData->DriverHandle = NULL;\r
498 }\r
1826b5e6
ZC
499\r
500 if (PrivateData->Configuration != NULL) {\r
c411b485 501 FreePool (PrivateData->Configuration);\r
1826b5e6 502 }\r
c411b485 503\r
0c18794e 504 FreePool (PrivateData);\r
505}\r