]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c
SecurityPkg: Add default value for TPM action question
[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
2bc36371 4Copyright (c) 2011 - 2014, 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
152 UINTN BufferSize;\r
153 TCG_CONFIGURATION Configuration;\r
154 TCG_CONFIG_PRIVATE_DATA *PrivateData;\r
155 EFI_STRING ConfigRequestHdr;\r
156 EFI_STRING ConfigRequest;\r
157 BOOLEAN AllocatedRequest;\r
158 UINTN Size;\r
159 BOOLEAN TpmEnable;\r
160 BOOLEAN TpmActivate;\r
161 CHAR16 State[32];\r
162\r
163 if (Progress == NULL || Results == NULL) {\r
164 return EFI_INVALID_PARAMETER;\r
165 }\r
166\r
167 *Progress = Request;\r
a0c56a82 168 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTcgConfigFormSetGuid, mTcgStorageName)) {\r
0c18794e 169 return EFI_NOT_FOUND;\r
170 }\r
171\r
172 ConfigRequestHdr = NULL;\r
173 ConfigRequest = NULL;\r
174 AllocatedRequest = FALSE;\r
175 Size = 0;\r
176\r
177 PrivateData = TCG_CONFIG_PRIVATE_DATA_FROM_THIS (This);\r
178\r
179 //\r
180 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
181 // \r
182 ZeroMem (&Configuration, sizeof (TCG_CONFIGURATION));\r
183\r
607599bf 184 Configuration.TpmOperation = PHYSICAL_PRESENCE_ENABLE;\r
0c18794e 185\r
186 //\r
187 // Display current TPM state.\r
188 //\r
189 if (PrivateData->TcgProtocol != NULL) {\r
190 Status = GetTpmState (PrivateData->TcgProtocol, &TpmEnable, &TpmActivate);\r
191 if (EFI_ERROR (Status)) {\r
192 return Status;\r
193 }\r
194\r
195 UnicodeSPrint (\r
196 State,\r
197 sizeof (State),\r
198 L"%s, and %s",\r
199 TpmEnable ? L"Enabled" : L"Disabled",\r
200 TpmActivate ? L"Activated" : L"Deactivated"\r
201 );\r
202 Configuration.TpmEnable = TpmEnable;\r
203 Configuration.TpmActivate = TpmActivate;\r
204\r
205 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM_STATE_CONTENT), State, NULL);\r
206 }\r
207\r
208 BufferSize = sizeof (Configuration);\r
209 ConfigRequest = Request;\r
210 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
211 //\r
212 // Request has no request element, construct full request string.\r
213 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
214 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
215 //\r
a0c56a82 216 ConfigRequestHdr = HiiConstructConfigHdr (&gTcgConfigFormSetGuid, mTcgStorageName, PrivateData->DriverHandle);\r
0c18794e 217 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
218 ConfigRequest = AllocateZeroPool (Size);\r
219 ASSERT (ConfigRequest != NULL);\r
220 AllocatedRequest = TRUE;\r
221 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);\r
222 FreePool (ConfigRequestHdr);\r
223 }\r
224\r
225 Status = gHiiConfigRouting->BlockToConfig (\r
226 gHiiConfigRouting,\r
227 ConfigRequest,\r
228 (UINT8 *) &Configuration,\r
229 BufferSize,\r
230 Results,\r
231 Progress\r
232 );\r
233 //\r
234 // Free the allocated config request string.\r
235 //\r
236 if (AllocatedRequest) {\r
237 FreePool (ConfigRequest);\r
238 }\r
239 //\r
240 // Set Progress string to the original request string.\r
241 //\r
242 if (Request == NULL) {\r
243 *Progress = NULL;\r
244 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
245 *Progress = Request + StrLen (Request);\r
246 }\r
247\r
248 return Status;\r
249}\r
250\r
251/**\r
252 This function processes the results of changes in configuration.\r
253\r
254 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
255 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
256 format.\r
257 @param[out] Progress A pointer to a string filled in with the offset of\r
258 the most recent '&' before the first failing\r
259 name/value pair (or the beginning of the string if\r
260 the failure is in the first name/value pair) or\r
261 the terminating NULL if all was successful.\r
262\r
263 @retval EFI_SUCCESS The Results is processed successfully.\r
264 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
265 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
266 driver.\r
267\r
268**/\r
269EFI_STATUS\r
270EFIAPI\r
271TcgRouteConfig (\r
272 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
273 IN CONST EFI_STRING Configuration,\r
274 OUT EFI_STRING *Progress\r
275 )\r
276{\r
277 EFI_STATUS Status;\r
278 UINTN BufferSize;\r
279 TCG_CONFIGURATION TcgConfiguration;\r
280\r
281 if (Configuration == NULL || Progress == NULL) {\r
282 return EFI_INVALID_PARAMETER;\r
283 }\r
284\r
285 *Progress = Configuration;\r
a0c56a82 286 if (!HiiIsConfigHdrMatch (Configuration, &gTcgConfigFormSetGuid, mTcgStorageName)) {\r
0c18794e 287 return EFI_NOT_FOUND;\r
288 }\r
289\r
290 //\r
291 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
292 //\r
293 BufferSize = sizeof (TCG_CONFIGURATION);\r
294 Status = gHiiConfigRouting->ConfigToBlock (\r
295 gHiiConfigRouting,\r
296 Configuration,\r
297 (UINT8 *) &TcgConfiguration,\r
298 &BufferSize,\r
299 Progress\r
300 );\r
301 if (EFI_ERROR (Status)) {\r
302 return Status;\r
303 }\r
304\r
0c18794e 305 return EFI_SUCCESS;\r
306}\r
307\r
308/**\r
309 Save TPM request to variable space.\r
310\r
311 @param[in] PpRequest Physical Presence request command.\r
312\r
313 @retval EFI_SUCCESS The operation is finished successfully.\r
314 @retval Others Other errors as indicated.\r
315\r
316**/\r
317EFI_STATUS\r
318SavePpRequest (\r
319 IN UINT8 PpRequest\r
320 )\r
321{\r
322 EFI_STATUS Status;\r
323 UINTN DataSize;\r
324 EFI_PHYSICAL_PRESENCE PpData;\r
325\r
326 //\r
327 // Save TPM command to variable.\r
328 //\r
329 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
330 Status = gRT->GetVariable (\r
331 PHYSICAL_PRESENCE_VARIABLE,\r
332 &gEfiPhysicalPresenceGuid,\r
333 NULL,\r
334 &DataSize,\r
335 &PpData\r
336 );\r
337 if (EFI_ERROR (Status)) {\r
338 return Status;\r
339 } \r
340 \r
341 PpData.PPRequest = PpRequest;\r
342 Status = gRT->SetVariable (\r
343 PHYSICAL_PRESENCE_VARIABLE,\r
344 &gEfiPhysicalPresenceGuid,\r
345 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
346 DataSize,\r
347 &PpData\r
348 );\r
349 if (EFI_ERROR(Status)) {\r
350 return Status;\r
351 }\r
352\r
0c18794e 353 return EFI_SUCCESS;\r
354}\r
355\r
356/**\r
357 This function processes the results of changes in configuration.\r
358\r
359 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
360 @param[in] Action Specifies the type of action taken by the browser.\r
361 @param[in] QuestionId A unique value which is sent to the original\r
362 exporting driver so that it can identify the type\r
363 of data to expect.\r
364 @param[in] Type The type of value for the question.\r
365 @param[in] Value A pointer to the data being sent to the original\r
366 exporting driver.\r
367 @param[out] ActionRequest On return, points to the action requested by the\r
368 callback function.\r
369\r
370 @retval EFI_SUCCESS The callback successfully handled the action.\r
371 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
372 variable and its data.\r
373 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
374 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
375 callback.\r
376\r
377**/\r
378EFI_STATUS\r
379EFIAPI\r
380TcgCallback (\r
381 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
382 IN EFI_BROWSER_ACTION Action,\r
383 IN EFI_QUESTION_ID QuestionId,\r
384 IN UINT8 Type,\r
385 IN EFI_IFR_TYPE_VALUE *Value,\r
386 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
387 )\r
388{\r
389 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
390 return EFI_INVALID_PARAMETER;\r
391 }\r
392\r
fab10465 393 if ((Action != EFI_BROWSER_ACTION_CHANGED) || (QuestionId != KEY_TPM_ACTION)) {\r
0c18794e 394 return EFI_UNSUPPORTED;\r
395 }\r
396\r
397 SavePpRequest (Value->u8);\r
54a26282 398 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
399 \r
0c18794e 400 return EFI_SUCCESS;\r
401}\r
402\r
403/**\r
404 This function publish the TCG configuration Form for TPM device.\r
405\r
406 @param[in, out] PrivateData Points to TCG configuration private data.\r
407\r
408 @retval EFI_SUCCESS HII Form is installed for this network device.\r
409 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
410 @retval Others Other errors as indicated.\r
411\r
412**/\r
413EFI_STATUS\r
414InstallTcgConfigForm (\r
415 IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData\r
416 )\r
417{\r
418 EFI_STATUS Status;\r
419 EFI_HII_HANDLE HiiHandle;\r
420 EFI_HANDLE DriverHandle;\r
0c18794e 421 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
422\r
423 DriverHandle = NULL;\r
424 ConfigAccess = &PrivateData->ConfigAccess;\r
425 Status = gBS->InstallMultipleProtocolInterfaces (\r
426 &DriverHandle,\r
427 &gEfiDevicePathProtocolGuid,\r
428 &mTcgHiiVendorDevicePath,\r
429 &gEfiHiiConfigAccessProtocolGuid,\r
430 ConfigAccess,\r
431 NULL\r
432 );\r
433 if (EFI_ERROR (Status)) {\r
434 return Status;\r
435 }\r
436\r
437 PrivateData->DriverHandle = DriverHandle;\r
438\r
439 //\r
440 // Publish the HII package list\r
441 //\r
442 HiiHandle = HiiAddPackages (\r
a0c56a82 443 &gTcgConfigFormSetGuid,\r
0c18794e 444 DriverHandle,\r
445 TcgConfigDxeStrings,\r
446 TcgConfigBin,\r
447 NULL\r
448 );\r
449 if (HiiHandle == NULL) {\r
450 gBS->UninstallMultipleProtocolInterfaces (\r
451 DriverHandle,\r
452 &gEfiDevicePathProtocolGuid,\r
453 &mTcgHiiVendorDevicePath,\r
454 &gEfiHiiConfigAccessProtocolGuid,\r
455 ConfigAccess,\r
456 NULL\r
457 ); \r
458\r
459 return EFI_OUT_OF_RESOURCES;\r
460 }\r
461 \r
462 PrivateData->HiiHandle = HiiHandle;\r
463\r
0c18794e 464 return EFI_SUCCESS; \r
465}\r
466\r
467/**\r
468 This function removes TCG configuration Form.\r
469\r
470 @param[in, out] PrivateData Points to TCG configuration private data.\r
471\r
472**/\r
473VOID\r
474UninstallTcgConfigForm (\r
475 IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData\r
476 )\r
477{\r
478 //\r
479 // Uninstall HII package list\r
480 //\r
481 if (PrivateData->HiiHandle != NULL) {\r
482 HiiRemovePackages (PrivateData->HiiHandle);\r
483 PrivateData->HiiHandle = NULL;\r
484 }\r
485\r
486 //\r
487 // Uninstall HII Config Access Protocol\r
488 //\r
489 if (PrivateData->DriverHandle != NULL) {\r
490 gBS->UninstallMultipleProtocolInterfaces (\r
491 PrivateData->DriverHandle,\r
492 &gEfiDevicePathProtocolGuid,\r
493 &mTcgHiiVendorDevicePath,\r
494 &gEfiHiiConfigAccessProtocolGuid,\r
495 &PrivateData->ConfigAccess,\r
496 NULL\r
497 );\r
498 PrivateData->DriverHandle = NULL;\r
499 }\r
500 \r
501 FreePool (PrivateData);\r
502}\r