]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
SecurityPkg: Fix Tcg2 SubmitRequestToPreOSFunction() fail in second times.
[mirror_edk2.git] / SecurityPkg / Library / SmmTcg2PhysicalPresenceLib / SmmTcg2PhysicalPresenceLib.c
1 /** @file
2 Handle TPM 2.0 physical presence requests from OS.
3
4 This library will handle TPM 2.0 physical presence request from OS.
5
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.
9
10 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction()
11 will receive untrusted input and do validation.
12
13 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
14 This program and the accompanying materials
15 are licensed and made available under the terms and conditions of the BSD License
16 which accompanies this distribution. The full text of the license may be found at
17 http://opensource.org/licenses/bsd-license.php
18
19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21
22 **/
23
24 #include <PiSmm.h>
25
26 #include <Guid/Tcg2PhysicalPresenceData.h>
27
28 #include <Protocol/SmmVariable.h>
29
30 #include <Library/DebugLib.h>
31 #include <Library/Tcg2PpVendorLib.h>
32 #include <Library/SmmServicesTableLib.h>
33
34 EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable;
35
36 /**
37 The handler for TPM physical presence function:
38 Return TPM Operation Response to OS Environment.
39
40 This API should be invoked in OS runtime phase to interface with ACPI method.
41
42 @param[out] MostRecentRequest Most recent operation request.
43 @param[out] Response Response to the most recent operation request.
44
45 @return Return Code for Return TPM Operation Response to OS Environment.
46 **/
47 UINT32
48 EFIAPI
49 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
50 OUT UINT32 *MostRecentRequest,
51 OUT UINT32 *Response
52 )
53 {
54 EFI_STATUS Status;
55 UINTN DataSize;
56 EFI_TCG2_PHYSICAL_PRESENCE PpData;
57
58 DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));
59
60 //
61 // Get the Physical Presence variable
62 //
63 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
64 Status = mTcg2PpSmmVariable->SmmGetVariable (
65 TCG2_PHYSICAL_PRESENCE_VARIABLE,
66 &gEfiTcg2PhysicalPresenceGuid,
67 NULL,
68 &DataSize,
69 &PpData
70 );
71 if (EFI_ERROR (Status)) {
72 *MostRecentRequest = 0;
73 *Response = 0;
74 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
75 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
76 }
77
78 *MostRecentRequest = PpData.LastPPRequest;
79 *Response = PpData.PPResponse;
80
81 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
82 }
83
84 /**
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.
88
89 This API should be invoked in OS runtime phase to interface with ACPI method.
90
91 Caution: This function may receive untrusted input.
92
93 @param[in] OperationRequest TPM physical presence operation request.
94 @param[in] RequestParameter TPM physical presence operation request parameter.
95
96 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
97 Submit TPM Operation Request to Pre-OS Environment 2.
98 **/
99 UINT32
100 EFIAPI
101 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
102 IN UINT32 OperationRequest,
103 IN UINT32 RequestParameter
104 )
105 {
106 EFI_STATUS Status;
107 UINTN DataSize;
108 EFI_TCG2_PHYSICAL_PRESENCE PpData;
109 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
110
111 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));
112
113 //
114 // Get the Physical Presence variable
115 //
116 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
117 Status = mTcg2PpSmmVariable->SmmGetVariable (
118 TCG2_PHYSICAL_PRESENCE_VARIABLE,
119 &gEfiTcg2PhysicalPresenceGuid,
120 NULL,
121 &DataSize,
122 &PpData
123 );
124 if (EFI_ERROR (Status)) {
125 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
126 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
127 }
128
129 if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
130 (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {
131 //
132 // This command requires UI to prompt user for Auth data.
133 //
134 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
135 }
136
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,
146 DataSize,
147 &PpData
148 );
149 }
150
151 if (EFI_ERROR (Status)) {
152 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
153 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
154 }
155
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,
161 NULL,
162 &DataSize,
163 &Flags
164 );
165 if (EFI_ERROR (Status)) {
166 Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;
167 }
168 return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);
169 }
170
171 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
172 }
173
174 /**
175 The handler for TPM physical presence function:
176 Get User Confirmation Status for Operation.
177
178 This API should be invoked in OS runtime phase to interface with ACPI method.
179
180 Caution: This function may receive untrusted input.
181
182 @param[in] OperationRequest TPM physical presence operation request.
183
184 @return Return Code for Get User Confirmation Status for Operation.
185 **/
186 UINT32
187 EFIAPI
188 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
189 IN UINT32 OperationRequest
190 )
191 {
192 EFI_STATUS Status;
193 UINTN DataSize;
194 EFI_TCG2_PHYSICAL_PRESENCE PpData;
195 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
196 BOOLEAN RequestConfirmed;
197
198 DEBUG ((EFI_D_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));
199
200 //
201 // Get the Physical Presence variable
202 //
203 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
204 Status = mTcg2PpSmmVariable->SmmGetVariable (
205 TCG2_PHYSICAL_PRESENCE_VARIABLE,
206 &gEfiTcg2PhysicalPresenceGuid,
207 NULL,
208 &DataSize,
209 &PpData
210 );
211 if (EFI_ERROR (Status)) {
212 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
213 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
214 }
215 //
216 // Get the Physical Presence flags
217 //
218 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
219 Status = mTcg2PpSmmVariable->SmmGetVariable (
220 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
221 &gEfiTcg2PhysicalPresenceGuid,
222 NULL,
223 &DataSize,
224 &Flags
225 );
226 if (EFI_ERROR (Status)) {
227 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));
228 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
229 }
230
231 RequestConfirmed = FALSE;
232
233 switch (OperationRequest) {
234 case TCG2_PHYSICAL_PRESENCE_CLEAR:
235 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
236 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
237 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
238 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {
239 RequestConfirmed = TRUE;
240 }
241 break;
242
243 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
244 RequestConfirmed = TRUE;
245 break;
246
247 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
248 break;
249
250 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
251 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {
252 RequestConfirmed = TRUE;
253 }
254 break;
255
256 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
257 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {
258 RequestConfirmed = TRUE;
259 }
260 break;
261
262 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
263 RequestConfirmed = TRUE;
264 break;
265
266 default:
267 if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
268 RequestConfirmed = TRUE;
269 } else {
270 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
271 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
272 }
273 }
274 break;
275 }
276
277 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
278 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);
279 }
280
281 if (RequestConfirmed) {
282 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;
283 } else {
284 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;
285 }
286 }
287
288 /**
289 The constructor function register UNI strings into imageHandle.
290
291 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
292
293 @param ImageHandle The firmware allocated handle for the EFI image.
294 @param SystemTable A pointer to the EFI System Table.
295
296 @retval EFI_SUCCESS The constructor successfully added string package.
297 @retval Other value The constructor can't add string package.
298 **/
299 EFI_STATUS
300 EFIAPI
301 Tcg2PhysicalPresenceLibConstructor (
302 IN EFI_HANDLE ImageHandle,
303 IN EFI_SYSTEM_TABLE *SystemTable
304 )
305 {
306 EFI_STATUS Status;
307
308 //
309 // Locate SmmVariableProtocol.
310 //
311 Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mTcg2PpSmmVariable);
312 ASSERT_EFI_ERROR (Status);
313
314 return EFI_SUCCESS;
315 }