2 Handle TPM 2.0 physical presence requests from OS.
4 This library will handle TPM 2.0 physical presence request from OS.
6 Caution: This module requires additional review when modified.
7 This driver will have external input - variable.
8 This external input must be validated carefully to avoid security issue.
10 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction()
11 will receive untrusted input and do validation.
13 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
14 SPDX-License-Identifier: BSD-2-Clause-Patent
20 #include <Guid/Tcg2PhysicalPresenceData.h>
22 #include <Protocol/SmmVariable.h>
24 #include <Library/BaseLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/Tcg2PpVendorLib.h>
28 #include <Library/SmmServicesTableLib.h>
30 #define PP_INF_VERSION_1_2 "1.2"
32 EFI_SMM_VARIABLE_PROTOCOL
*mTcg2PpSmmVariable
;
33 BOOLEAN mIsTcg2PPVerLowerThan_1_3
= FALSE
;
36 The handler for TPM physical presence function:
37 Return TPM Operation Response to OS Environment.
39 This API should be invoked in OS runtime phase to interface with ACPI method.
41 @param[out] MostRecentRequest Most recent operation request.
42 @param[out] Response Response to the most recent operation request.
44 @return Return Code for Return TPM Operation Response to OS Environment.
48 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
49 OUT UINT32
*MostRecentRequest
,
55 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
57 DEBUG ((EFI_D_INFO
, "[TPM2] ReturnOperationResponseToOsFunction\n"));
60 // Get the Physical Presence variable
62 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
63 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
64 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
65 &gEfiTcg2PhysicalPresenceGuid
,
70 if (EFI_ERROR (Status
)) {
71 *MostRecentRequest
= 0;
73 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
74 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
77 *MostRecentRequest
= PpData
.LastPPRequest
;
78 *Response
= PpData
.PPResponse
;
80 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
84 The handler for TPM physical presence function:
85 Submit TPM Operation Request to Pre-OS Environment and
86 Submit TPM Operation Request to Pre-OS Environment 2.
88 This API should be invoked in OS runtime phase to interface with ACPI method.
90 Caution: This function may receive untrusted input.
92 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.
93 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.
95 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
96 Submit TPM Operation Request to Pre-OS Environment 2.
99 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
100 IN OUT UINT32
*OperationRequest
,
101 IN OUT UINT32
*RequestParameter
107 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
108 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
110 DEBUG ((EFI_D_INFO
, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest
, *RequestParameter
));
111 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;
114 // Get the Physical Presence variable
116 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
117 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
118 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
119 &gEfiTcg2PhysicalPresenceGuid
,
124 if (EFI_ERROR (Status
)) {
125 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
126 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
130 if ((*OperationRequest
> TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) &&
131 (*OperationRequest
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) ) {
132 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
;
136 if ((PpData
.PPRequest
!= *OperationRequest
) ||
137 (PpData
.PPRequestParameter
!= *RequestParameter
)) {
138 PpData
.PPRequest
= (UINT8
)*OperationRequest
;
139 PpData
.PPRequestParameter
= *RequestParameter
;
140 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
141 Status
= mTcg2PpSmmVariable
->SmmSetVariable (
142 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
143 &gEfiTcg2PhysicalPresenceGuid
,
144 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
148 if (EFI_ERROR (Status
)) {
149 DEBUG ((EFI_D_ERROR
, "[TPM2] Set PP variable failure! Status = %r\n", Status
));
150 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
155 if (*OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
156 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
157 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
158 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
159 &gEfiTcg2PhysicalPresenceGuid
,
164 if (EFI_ERROR (Status
)) {
165 Flags
.PPFlags
= TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT
| TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT
;
167 ReturnCode
= Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest
, Flags
.PPFlags
, *RequestParameter
);
172 // Sync PPRQ/PPRM from PP Variable if PP submission fails
174 if (ReturnCode
!= TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
) {
175 DEBUG ((EFI_D_ERROR
, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status
));
176 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
177 ZeroMem(&PpData
, DataSize
);
178 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
179 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
180 &gEfiTcg2PhysicalPresenceGuid
,
185 *OperationRequest
= (UINT32
)PpData
.PPRequest
;
186 *RequestParameter
= PpData
.PPRequestParameter
;
193 The handler for TPM physical presence function:
194 Submit TPM Operation Request to Pre-OS Environment and
195 Submit TPM Operation Request to Pre-OS Environment 2.
197 This API should be invoked in OS runtime phase to interface with ACPI method.
199 Caution: This function may receive untrusted input.
201 @param[in] OperationRequest TPM physical presence operation request.
202 @param[in] RequestParameter TPM physical presence operation request parameter.
204 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
205 Submit TPM Operation Request to Pre-OS Environment 2.
209 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
210 IN UINT32 OperationRequest
,
211 IN UINT32 RequestParameter
214 UINT32 TempOperationRequest
;
215 UINT32 TempRequestParameter
;
217 TempOperationRequest
= OperationRequest
;
218 TempRequestParameter
= RequestParameter
;
220 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest
, &TempRequestParameter
);
224 The handler for TPM physical presence function:
225 Get User Confirmation Status for Operation.
227 This API should be invoked in OS runtime phase to interface with ACPI method.
229 Caution: This function may receive untrusted input.
231 @param[in] OperationRequest TPM physical presence operation request.
233 @return Return Code for Get User Confirmation Status for Operation.
237 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
238 IN UINT32 OperationRequest
243 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
244 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
245 BOOLEAN RequestConfirmed
;
247 DEBUG ((EFI_D_INFO
, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest
));
250 // Get the Physical Presence variable
252 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
253 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
254 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
255 &gEfiTcg2PhysicalPresenceGuid
,
260 if (EFI_ERROR (Status
)) {
261 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
262 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION
;
265 // Get the Physical Presence flags
267 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
268 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
269 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
270 &gEfiTcg2PhysicalPresenceGuid
,
275 if (EFI_ERROR (Status
)) {
276 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP flags failure! Status = %r\n", Status
));
277 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION
;
280 RequestConfirmed
= FALSE
;
282 switch (OperationRequest
) {
283 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
284 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
285 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
286 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
287 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
) == 0) {
288 RequestConfirmed
= TRUE
;
292 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
293 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE
:
294 RequestConfirmed
= TRUE
;
297 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
300 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
301 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS
) == 0) {
302 RequestConfirmed
= TRUE
;
306 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
307 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS
) == 0) {
308 RequestConfirmed
= TRUE
;
312 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
313 RequestConfirmed
= TRUE
;
316 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
317 if ((Flags
.PPFlags
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID
) == 0) {
318 RequestConfirmed
= TRUE
;
322 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
323 if ((Flags
.PPFlags
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID
) == 0) {
324 RequestConfirmed
= TRUE
;
328 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE
:
329 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE
:
330 RequestConfirmed
= TRUE
;
333 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE
:
334 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE
:
338 if (!mIsTcg2PPVerLowerThan_1_3
) {
339 if (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
341 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented
343 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED
;
347 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)
349 if (OperationRequest
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
350 RequestConfirmed
= TRUE
;
351 } else if (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
352 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED
;
358 if (OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
359 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest
, Flags
.PPFlags
);
362 if (RequestConfirmed
) {
363 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED
;
365 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED
;
370 The constructor function locates SmmVariable protocol.
372 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
374 @param ImageHandle The firmware allocated handle for the EFI image.
375 @param SystemTable A pointer to the EFI System Table.
377 @retval EFI_SUCCESS The constructor successfully added string package.
378 @retval Other value The constructor can't add string package.
382 Tcg2PhysicalPresenceLibConstructor (
383 IN EFI_HANDLE ImageHandle
,
384 IN EFI_SYSTEM_TABLE
*SystemTable
389 if (AsciiStrnCmp(PP_INF_VERSION_1_2
, (CHAR8
*)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer
), sizeof(PP_INF_VERSION_1_2
) - 1) <= 0) {
390 mIsTcg2PPVerLowerThan_1_3
= TRUE
;
394 // Locate SmmVariableProtocol.
396 Status
= gSmst
->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid
, NULL
, (VOID
**)&mTcg2PpSmmVariable
);
397 ASSERT_EFI_ERROR (Status
);