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