2 HII Config Access protocol implementation of TCG configuration module.
4 Copyright (c) 2011 - 2012, 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
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.
15 #include "TcgConfigImpl.h"
17 CHAR16 mTcgStorageName
[] = L
"TCG_CONFIGURATION";
19 TCG_CONFIG_PRIVATE_DATA mTcgConfigPrivateDateTemplate
= {
20 TCG_CONFIG_PRIVATE_DATA_SIGNATURE
,
28 HII_VENDOR_DEVICE_PATH mTcgHiiVendorDevicePath
= {
34 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
35 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
38 TCG_CONFIG_FORM_SET_GUID
42 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
44 (UINT8
) (END_DEVICE_PATH_LENGTH
),
45 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
51 Get current state of TPM device.
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.
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.
64 IN EFI_TCG_PROTOCOL
*TcgProtocol
,
65 OUT BOOLEAN
*TpmEnable
, OPTIONAL
66 OUT BOOLEAN
*TpmActivate OPTIONAL
70 TPM_RSP_COMMAND_HDR
*TpmRsp
;
72 TPM_PERMANENT_FLAGS
*TpmPermanentFlags
;
75 ASSERT (TcgProtocol
!= NULL
);
78 // Get TPM Permanent flags (TpmEnable, TpmActivate)
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
);
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
);
90 Status
= TcgProtocol
->PassThroughToTpm (
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
;
102 TpmPermanentFlags
= (TPM_PERMANENT_FLAGS
*) &CmdBuf
[sizeof (TPM_RSP_COMMAND_HDR
) + sizeof (UINT32
)];
104 if (TpmEnable
!= NULL
) {
105 *TpmEnable
= (BOOLEAN
) !TpmPermanentFlags
->disable
;
108 if (TpmActivate
!= NULL
) {
109 *TpmActivate
= (BOOLEAN
) !TpmPermanentFlags
->deactivated
;
117 This function allows a caller to extract the current configuration for one
118 or more named elements from the target driver.
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
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.
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
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
153 TCG_CONFIGURATION Configuration
;
154 TCG_CONFIG_PRIVATE_DATA
*PrivateData
;
155 EFI_STRING ConfigRequestHdr
;
156 EFI_STRING ConfigRequest
;
157 BOOLEAN AllocatedRequest
;
163 if (Progress
== NULL
|| Results
== NULL
) {
164 return EFI_INVALID_PARAMETER
;
168 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gTcgConfigFormSetGuid
, mTcgStorageName
)) {
169 return EFI_NOT_FOUND
;
172 ConfigRequestHdr
= NULL
;
173 ConfigRequest
= NULL
;
174 AllocatedRequest
= FALSE
;
177 PrivateData
= TCG_CONFIG_PRIVATE_DATA_FROM_THIS (This
);
180 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
182 ZeroMem (&Configuration
, sizeof (TCG_CONFIGURATION
));
184 Configuration
.MorState
= PcdGetBool (PcdMorEnable
);
185 Configuration
.TpmOperation
= PHYSICAL_PRESENCE_ENABLE
;
186 Configuration
.HideTpm
= (BOOLEAN
) (PcdGetBool (PcdHideTpmSupport
) && PcdGetBool (PcdHideTpm
));
188 // Read the original value of HideTpm from PrivateData which won't be changed by Setup in this boot.
190 Configuration
.OriginalHideTpm
= PrivateData
->HideTpm
;
193 // Display current TPM state.
195 if (PrivateData
->TcgProtocol
!= NULL
) {
196 Status
= GetTpmState (PrivateData
->TcgProtocol
, &TpmEnable
, &TpmActivate
);
197 if (EFI_ERROR (Status
)) {
205 TpmEnable
? L
"Enabled" : L
"Disabled",
206 TpmActivate
? L
"Activated" : L
"Deactivated"
208 Configuration
.TpmEnable
= TpmEnable
;
209 Configuration
.TpmActivate
= TpmActivate
;
211 HiiSetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_TPM_STATE_CONTENT
), State
, NULL
);
214 BufferSize
= sizeof (Configuration
);
215 ConfigRequest
= Request
;
216 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
218 // Request has no request element, construct full request string.
219 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
220 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
222 ConfigRequestHdr
= HiiConstructConfigHdr (&gTcgConfigFormSetGuid
, mTcgStorageName
, PrivateData
->DriverHandle
);
223 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
224 ConfigRequest
= AllocateZeroPool (Size
);
225 ASSERT (ConfigRequest
!= NULL
);
226 AllocatedRequest
= TRUE
;
227 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
) BufferSize
);
228 FreePool (ConfigRequestHdr
);
231 Status
= gHiiConfigRouting
->BlockToConfig (
234 (UINT8
*) &Configuration
,
240 // Free the allocated config request string.
242 if (AllocatedRequest
) {
243 FreePool (ConfigRequest
);
246 // Set Progress string to the original request string.
248 if (Request
== NULL
) {
250 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
251 *Progress
= Request
+ StrLen (Request
);
258 This function processes the results of changes in configuration.
260 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
261 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
263 @param[out] Progress A pointer to a string filled in with the offset of
264 the most recent '&' before the first failing
265 name/value pair (or the beginning of the string if
266 the failure is in the first name/value pair) or
267 the terminating NULL if all was successful.
269 @retval EFI_SUCCESS The Results is processed successfully.
270 @retval EFI_INVALID_PARAMETER Configuration is NULL.
271 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
278 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
279 IN CONST EFI_STRING Configuration
,
280 OUT EFI_STRING
*Progress
285 TCG_CONFIGURATION TcgConfiguration
;
287 if (Configuration
== NULL
|| Progress
== NULL
) {
288 return EFI_INVALID_PARAMETER
;
291 *Progress
= Configuration
;
292 if (!HiiIsConfigHdrMatch (Configuration
, &gTcgConfigFormSetGuid
, mTcgStorageName
)) {
293 return EFI_NOT_FOUND
;
297 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
299 BufferSize
= sizeof (TCG_CONFIGURATION
);
300 Status
= gHiiConfigRouting
->ConfigToBlock (
303 (UINT8
*) &TcgConfiguration
,
307 if (EFI_ERROR (Status
)) {
311 PcdSetBool (PcdMorEnable
, TcgConfiguration
.MorState
);
312 PcdSetBool (PcdHideTpm
, TcgConfiguration
.HideTpm
);
318 Save TPM request to variable space.
320 @param[in] PpRequest Physical Presence request command.
322 @retval EFI_SUCCESS The operation is finished successfully.
323 @retval Others Other errors as indicated.
333 EFI_PHYSICAL_PRESENCE PpData
;
336 // Save TPM command to variable.
338 DataSize
= sizeof (EFI_PHYSICAL_PRESENCE
);
339 Status
= gRT
->GetVariable (
340 PHYSICAL_PRESENCE_VARIABLE
,
341 &gEfiPhysicalPresenceGuid
,
346 if (EFI_ERROR (Status
)) {
350 PpData
.PPRequest
= PpRequest
;
351 Status
= gRT
->SetVariable (
352 PHYSICAL_PRESENCE_VARIABLE
,
353 &gEfiPhysicalPresenceGuid
,
354 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
358 if (EFI_ERROR(Status
)) {
366 This function processes the results of changes in configuration.
368 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
369 @param[in] Action Specifies the type of action taken by the browser.
370 @param[in] QuestionId A unique value which is sent to the original
371 exporting driver so that it can identify the type
373 @param[in] Type The type of value for the question.
374 @param[in] Value A pointer to the data being sent to the original
376 @param[out] ActionRequest On return, points to the action requested by the
379 @retval EFI_SUCCESS The callback successfully handled the action.
380 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
381 variable and its data.
382 @retval EFI_DEVICE_ERROR The variable could not be saved.
383 @retval EFI_UNSUPPORTED The specified Action is not supported by the
390 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
391 IN EFI_BROWSER_ACTION Action
,
392 IN EFI_QUESTION_ID QuestionId
,
394 IN EFI_IFR_TYPE_VALUE
*Value
,
395 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
398 if ((This
== NULL
) || (Value
== NULL
) || (ActionRequest
== NULL
)) {
399 return EFI_INVALID_PARAMETER
;
402 if ((Action
!= EFI_BROWSER_ACTION_CHANGED
) || (QuestionId
!= KEY_TPM_ACTION
)) {
403 return EFI_UNSUPPORTED
;
406 SavePpRequest (Value
->u8
);
407 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
413 This function publish the TCG configuration Form for TPM device.
415 @param[in, out] PrivateData Points to TCG configuration private data.
417 @retval EFI_SUCCESS HII Form is installed for this network device.
418 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
419 @retval Others Other errors as indicated.
423 InstallTcgConfigForm (
424 IN OUT TCG_CONFIG_PRIVATE_DATA
*PrivateData
428 EFI_HII_HANDLE HiiHandle
;
429 EFI_HANDLE DriverHandle
;
430 VOID
*StartOpCodeHandle
;
431 VOID
*EndOpCodeHandle
;
432 EFI_IFR_GUID_LABEL
*StartLabel
;
433 EFI_IFR_GUID_LABEL
*EndLabel
;
435 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
438 ConfigAccess
= &PrivateData
->ConfigAccess
;
439 Status
= gBS
->InstallMultipleProtocolInterfaces (
441 &gEfiDevicePathProtocolGuid
,
442 &mTcgHiiVendorDevicePath
,
443 &gEfiHiiConfigAccessProtocolGuid
,
447 if (EFI_ERROR (Status
)) {
451 PrivateData
->DriverHandle
= DriverHandle
;
454 // Publish the HII package list
456 HiiHandle
= HiiAddPackages (
457 &gTcgConfigFormSetGuid
,
463 if (HiiHandle
== NULL
) {
464 gBS
->UninstallMultipleProtocolInterfaces (
466 &gEfiDevicePathProtocolGuid
,
467 &mTcgHiiVendorDevicePath
,
468 &gEfiHiiConfigAccessProtocolGuid
,
473 return EFI_OUT_OF_RESOURCES
;
476 PrivateData
->HiiHandle
= HiiHandle
;
479 // Remove the Hide TPM question from the IFR
481 if (!PcdGetBool (PcdHideTpmSupport
)) {
483 // Allocate space for creation of UpdateData Buffer
485 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
486 ASSERT (StartOpCodeHandle
!= NULL
);
488 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
489 ASSERT (EndOpCodeHandle
!= NULL
);
492 // Create Hii Extend Label OpCode as the start opcode
494 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
495 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
496 StartLabel
->Number
= LABEL_TCG_CONFIGURATION_HIDETPM
;
499 // Create Hii Extend Label OpCode as the end opcode
501 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
502 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
503 EndLabel
->Number
= LABEL_END
;
505 HiiUpdateForm (HiiHandle
, NULL
, TCG_CONFIGURATION_FORM_ID
, StartOpCodeHandle
, EndOpCodeHandle
);
507 HiiFreeOpCodeHandle (StartOpCodeHandle
);
508 HiiFreeOpCodeHandle (EndOpCodeHandle
);
515 This function removes TCG configuration Form.
517 @param[in, out] PrivateData Points to TCG configuration private data.
521 UninstallTcgConfigForm (
522 IN OUT TCG_CONFIG_PRIVATE_DATA
*PrivateData
526 // Uninstall HII package list
528 if (PrivateData
->HiiHandle
!= NULL
) {
529 HiiRemovePackages (PrivateData
->HiiHandle
);
530 PrivateData
->HiiHandle
= NULL
;
534 // Uninstall HII Config Access Protocol
536 if (PrivateData
->DriverHandle
!= NULL
) {
537 gBS
->UninstallMultipleProtocolInterfaces (
538 PrivateData
->DriverHandle
,
539 &gEfiDevicePathProtocolGuid
,
540 &mTcgHiiVendorDevicePath
,
541 &gEfiHiiConfigAccessProtocolGuid
,
542 &PrivateData
->ConfigAccess
,
545 PrivateData
->DriverHandle
= NULL
;
548 FreePool (PrivateData
);