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 - 2020, 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
;
34 UINT32 mTcg2PhysicalPresenceFlags
;
37 The handler for TPM physical presence function:
38 Return TPM Operation Response to OS Environment.
40 This API should be invoked in OS runtime phase to interface with ACPI method.
42 @param[out] MostRecentRequest Most recent operation request.
43 @param[out] Response Response to the most recent operation request.
45 @return Return Code for Return TPM Operation Response to OS Environment.
49 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
50 OUT UINT32
*MostRecentRequest
,
56 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
58 DEBUG ((EFI_D_INFO
, "[TPM2] ReturnOperationResponseToOsFunction\n"));
61 // Get the Physical Presence variable
63 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
64 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
65 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
66 &gEfiTcg2PhysicalPresenceGuid
,
71 if (EFI_ERROR (Status
)) {
72 *MostRecentRequest
= 0;
74 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
75 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
78 *MostRecentRequest
= PpData
.LastPPRequest
;
79 *Response
= PpData
.PPResponse
;
81 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
85 The handler for TPM physical presence function:
86 Submit TPM Operation Request to Pre-OS Environment and
87 Submit TPM Operation Request to Pre-OS Environment 2.
89 This API should be invoked in OS runtime phase to interface with ACPI method.
91 Caution: This function may receive untrusted input.
93 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.
94 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.
96 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
97 Submit TPM Operation Request to Pre-OS Environment 2.
100 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
101 IN OUT UINT32
*OperationRequest
,
102 IN OUT UINT32
*RequestParameter
108 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
109 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
111 DEBUG ((EFI_D_INFO
, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest
, *RequestParameter
));
112 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;
115 // Get the Physical Presence variable
117 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
118 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
119 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
120 &gEfiTcg2PhysicalPresenceGuid
,
125 if (EFI_ERROR (Status
)) {
126 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
127 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
131 if ((*OperationRequest
> TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) &&
132 (*OperationRequest
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) ) {
133 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
;
137 if ((PpData
.PPRequest
!= *OperationRequest
) ||
138 (PpData
.PPRequestParameter
!= *RequestParameter
)) {
139 PpData
.PPRequest
= (UINT8
)*OperationRequest
;
140 PpData
.PPRequestParameter
= *RequestParameter
;
141 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
142 Status
= mTcg2PpSmmVariable
->SmmSetVariable (
143 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
144 &gEfiTcg2PhysicalPresenceGuid
,
145 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
149 if (EFI_ERROR (Status
)) {
150 DEBUG ((EFI_D_ERROR
, "[TPM2] Set PP variable failure! Status = %r\n", Status
));
151 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
156 if (*OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
157 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
158 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
159 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
160 &gEfiTcg2PhysicalPresenceGuid
,
165 if (EFI_ERROR (Status
)) {
166 Flags
.PPFlags
= mTcg2PhysicalPresenceFlags
;
168 ReturnCode
= Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest
, Flags
.PPFlags
, *RequestParameter
);
173 // Sync PPRQ/PPRM from PP Variable if PP submission fails
175 if (ReturnCode
!= TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
) {
176 DEBUG ((EFI_D_ERROR
, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status
));
177 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
178 ZeroMem(&PpData
, DataSize
);
179 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
180 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
181 &gEfiTcg2PhysicalPresenceGuid
,
186 *OperationRequest
= (UINT32
)PpData
.PPRequest
;
187 *RequestParameter
= PpData
.PPRequestParameter
;
194 The handler for TPM physical presence function:
195 Submit TPM Operation Request to Pre-OS Environment and
196 Submit TPM Operation Request to Pre-OS Environment 2.
198 This API should be invoked in OS runtime phase to interface with ACPI method.
200 Caution: This function may receive untrusted input.
202 @param[in] OperationRequest TPM physical presence operation request.
203 @param[in] RequestParameter TPM physical presence operation request parameter.
205 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
206 Submit TPM Operation Request to Pre-OS Environment 2.
210 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
211 IN UINT32 OperationRequest
,
212 IN UINT32 RequestParameter
215 UINT32 TempOperationRequest
;
216 UINT32 TempRequestParameter
;
218 TempOperationRequest
= OperationRequest
;
219 TempRequestParameter
= RequestParameter
;
221 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest
, &TempRequestParameter
);
225 The handler for TPM physical presence function:
226 Get User Confirmation Status for Operation.
228 This API should be invoked in OS runtime phase to interface with ACPI method.
230 Caution: This function may receive untrusted input.
232 @param[in] OperationRequest TPM physical presence operation request.
234 @return Return Code for Get User Confirmation Status for Operation.
238 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
239 IN UINT32 OperationRequest
244 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
245 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
246 BOOLEAN RequestConfirmed
;
248 DEBUG ((EFI_D_INFO
, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest
));
251 // Get the Physical Presence variable
253 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
254 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
255 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
256 &gEfiTcg2PhysicalPresenceGuid
,
261 if (EFI_ERROR (Status
)) {
262 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
263 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION
;
266 // Get the Physical Presence flags
268 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
269 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
270 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
271 &gEfiTcg2PhysicalPresenceGuid
,
276 if (EFI_ERROR (Status
)) {
277 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP flags failure! Status = %r\n", Status
));
278 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION
;
281 RequestConfirmed
= FALSE
;
283 switch (OperationRequest
) {
284 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
285 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
286 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
287 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
288 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
) == 0) {
289 RequestConfirmed
= TRUE
;
293 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
294 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE
:
295 RequestConfirmed
= TRUE
;
298 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
301 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
302 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS
) == 0) {
303 RequestConfirmed
= TRUE
;
307 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
308 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS
) == 0) {
309 RequestConfirmed
= TRUE
;
313 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
314 RequestConfirmed
= TRUE
;
317 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
318 if ((Flags
.PPFlags
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID
) == 0) {
319 RequestConfirmed
= TRUE
;
323 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
324 if ((Flags
.PPFlags
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID
) == 0) {
325 RequestConfirmed
= TRUE
;
329 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE
:
330 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE
:
331 RequestConfirmed
= TRUE
;
334 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE
:
335 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE
:
339 if (!mIsTcg2PPVerLowerThan_1_3
) {
340 if (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
342 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented
344 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED
;
348 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)
350 if (OperationRequest
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
351 RequestConfirmed
= TRUE
;
352 } else if (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
353 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED
;
359 if (OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
360 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest
, Flags
.PPFlags
);
363 if (RequestConfirmed
) {
364 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED
;
366 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED
;
371 The constructor function locates SmmVariable protocol.
373 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
375 @param ImageHandle The firmware allocated handle for the EFI image.
376 @param SystemTable A pointer to the EFI System Table.
378 @retval EFI_SUCCESS The constructor successfully added string package.
379 @retval Other value The constructor can't add string package.
383 Tcg2PhysicalPresenceLibConstructor (
384 IN EFI_HANDLE ImageHandle
,
385 IN EFI_SYSTEM_TABLE
*SystemTable
390 if (AsciiStrnCmp(PP_INF_VERSION_1_2
, (CHAR8
*)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer
), sizeof(PP_INF_VERSION_1_2
) - 1) <= 0) {
391 mIsTcg2PPVerLowerThan_1_3
= TRUE
;
395 // Locate SmmVariableProtocol.
397 Status
= gSmst
->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid
, NULL
, (VOID
**)&mTcg2PpSmmVariable
);
398 ASSERT_EFI_ERROR (Status
);
400 mTcg2PhysicalPresenceFlags
= PcdGet32(PcdTcg2PhysicalPresenceFlags
);