]> 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 // Set Progress string to the original request string.
220 //
221 if (Request == NULL) {
222 *Progress = NULL;
223 } else if (StrStr (Request, L"OFFSET") == NULL) {
224 *Progress = Request + StrLen (Request);
225 }
226
227 return Status;
228 }
229
230 /**
231 This function processes the results of changes in configuration.
232
233 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
234 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
235 format.
236 @param[out] Progress A pointer to a string filled in with the offset of
237 the most recent '&' before the first failing
238 name/value pair (or the beginning of the string if
239 the failure is in the first name/value pair) or
240 the terminating NULL if all was successful.
241
242 @retval EFI_SUCCESS The Results is processed successfully.
243 @retval EFI_INVALID_PARAMETER Configuration is NULL.
244 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
245 driver.
246
247 **/
248 EFI_STATUS
249 EFIAPI
250 TcgRouteConfig (
251 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
252 IN CONST EFI_STRING Configuration,
253 OUT EFI_STRING *Progress
254 )
255 {
256 EFI_STATUS Status;
257 UINTN BufferSize;
258 TCG_CONFIGURATION TcgConfiguration;
259
260 if (Configuration == NULL || Progress == NULL) {
261 return EFI_INVALID_PARAMETER;
262 }
263
264 *Progress = Configuration;
265 if (!HiiIsConfigHdrMatch (Configuration, &gTcgConfigFormSetGuid, mTcgStorageName)) {
266 return EFI_NOT_FOUND;
267 }
268
269 //
270 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
271 //
272 BufferSize = sizeof (TCG_CONFIGURATION);
273 Status = gHiiConfigRouting->ConfigToBlock (
274 gHiiConfigRouting,
275 Configuration,
276 (UINT8 *) &TcgConfiguration,
277 &BufferSize,
278 Progress
279 );
280 if (EFI_ERROR (Status)) {
281 return Status;
282 }
283
284 return EFI_SUCCESS;
285 }
286
287 /**
288 Save TPM request to variable space.
289
290 @param[in] PpRequest Physical Presence request command.
291
292 @retval EFI_SUCCESS The operation is finished successfully.
293 @retval Others Other errors as indicated.
294
295 **/
296 EFI_STATUS
297 SavePpRequest (
298 IN UINT8 PpRequest
299 )
300 {
301 EFI_STATUS Status;
302 UINTN DataSize;
303 EFI_PHYSICAL_PRESENCE PpData;
304
305 //
306 // Save TPM command to variable.
307 //
308 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
309 Status = gRT->GetVariable (
310 PHYSICAL_PRESENCE_VARIABLE,
311 &gEfiPhysicalPresenceGuid,
312 NULL,
313 &DataSize,
314 &PpData
315 );
316 if (EFI_ERROR (Status)) {
317 return Status;
318 }
319
320 PpData.PPRequest = PpRequest;
321 Status = gRT->SetVariable (
322 PHYSICAL_PRESENCE_VARIABLE,
323 &gEfiPhysicalPresenceGuid,
324 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
325 DataSize,
326 &PpData
327 );
328 if (EFI_ERROR(Status)) {
329 return Status;
330 }
331
332 return EFI_SUCCESS;
333 }
334
335 /**
336 This function processes the results of changes in configuration.
337
338 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
339 @param[in] Action Specifies the type of action taken by the browser.
340 @param[in] QuestionId A unique value which is sent to the original
341 exporting driver so that it can identify the type
342 of data to expect.
343 @param[in] Type The type of value for the question.
344 @param[in] Value A pointer to the data being sent to the original
345 exporting driver.
346 @param[out] ActionRequest On return, points to the action requested by the
347 callback function.
348
349 @retval EFI_SUCCESS The callback successfully handled the action.
350 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
351 variable and its data.
352 @retval EFI_DEVICE_ERROR The variable could not be saved.
353 @retval EFI_UNSUPPORTED The specified Action is not supported by the
354 callback.
355
356 **/
357 EFI_STATUS
358 EFIAPI
359 TcgCallback (
360 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
361 IN EFI_BROWSER_ACTION Action,
362 IN EFI_QUESTION_ID QuestionId,
363 IN UINT8 Type,
364 IN EFI_IFR_TYPE_VALUE *Value,
365 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
366 )
367 {
368 TCG_CONFIG_PRIVATE_DATA *PrivateData;
369 CHAR16 State[32];
370
371 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
372 return EFI_INVALID_PARAMETER;
373 }
374
375 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
376 if (QuestionId == KEY_TPM_ACTION) {
377
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 return EFI_SUCCESS;
389 }
390
391 if ((Action != EFI_BROWSER_ACTION_CHANGED) || (QuestionId != KEY_TPM_ACTION)) {
392 return EFI_UNSUPPORTED;
393 }
394
395 SavePpRequest (Value->u8);
396 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
397
398 return EFI_SUCCESS;
399 }
400
401 /**
402 This function publish the TCG configuration Form for TPM device.
403
404 @param[in, out] PrivateData Points to TCG configuration private data.
405
406 @retval EFI_SUCCESS HII Form is installed for this network device.
407 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
408 @retval Others Other errors as indicated.
409
410 **/
411 EFI_STATUS
412 InstallTcgConfigForm (
413 IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData
414 )
415 {
416 EFI_STATUS Status;
417 EFI_HII_HANDLE HiiHandle;
418 EFI_HANDLE DriverHandle;
419 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
420
421 DriverHandle = NULL;
422 ConfigAccess = &PrivateData->ConfigAccess;
423 Status = gBS->InstallMultipleProtocolInterfaces (
424 &DriverHandle,
425 &gEfiDevicePathProtocolGuid,
426 &mTcgHiiVendorDevicePath,
427 &gEfiHiiConfigAccessProtocolGuid,
428 ConfigAccess,
429 NULL
430 );
431 if (EFI_ERROR (Status)) {
432 return Status;
433 }
434
435 PrivateData->DriverHandle = DriverHandle;
436
437 //
438 // Publish the HII package list
439 //
440 HiiHandle = HiiAddPackages (
441 &gTcgConfigFormSetGuid,
442 DriverHandle,
443 TcgConfigDxeStrings,
444 TcgConfigBin,
445 NULL
446 );
447 if (HiiHandle == NULL) {
448 gBS->UninstallMultipleProtocolInterfaces (
449 DriverHandle,
450 &gEfiDevicePathProtocolGuid,
451 &mTcgHiiVendorDevicePath,
452 &gEfiHiiConfigAccessProtocolGuid,
453 ConfigAccess,
454 NULL
455 );
456
457 return EFI_OUT_OF_RESOURCES;
458 }
459
460 PrivateData->HiiHandle = HiiHandle;
461
462 return EFI_SUCCESS;
463 }
464
465 /**
466 This function removes TCG configuration Form.
467
468 @param[in, out] PrivateData Points to TCG configuration private data.
469
470 **/
471 VOID
472 UninstallTcgConfigForm (
473 IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData
474 )
475 {
476 //
477 // Uninstall HII package list
478 //
479 if (PrivateData->HiiHandle != NULL) {
480 HiiRemovePackages (PrivateData->HiiHandle);
481 PrivateData->HiiHandle = NULL;
482 }
483
484 //
485 // Uninstall HII Config Access Protocol
486 //
487 if (PrivateData->DriverHandle != NULL) {
488 gBS->UninstallMultipleProtocolInterfaces (
489 PrivateData->DriverHandle,
490 &gEfiDevicePathProtocolGuid,
491 &mTcgHiiVendorDevicePath,
492 &gEfiHiiConfigAccessProtocolGuid,
493 &PrivateData->ConfigAccess,
494 NULL
495 );
496 PrivateData->DriverHandle = NULL;
497 }
498
499 if (PrivateData->Configuration != NULL) {
500 FreePool(PrivateData->Configuration);
501 }
502 FreePool (PrivateData);
503 }