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