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