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