]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
SecurityPkg: Change default value source
[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 - 2020, Intel Corporation. All rights reserved.<BR>
14 SPDX-License-Identifier: BSD-2-Clause-Patent
15
16 **/
17
18 #include <PiSmm.h>
19
20 #include <Guid/Tcg2PhysicalPresenceData.h>
21
22 #include <Protocol/SmmVariable.h>
23
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>
29
30 #define PP_INF_VERSION_1_2 "1.2"
31
32 EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable;
33 BOOLEAN mIsTcg2PPVerLowerThan_1_3 = FALSE;
34 UINT32 mTcg2PhysicalPresenceFlags;
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, out] Pointer to OperationRequest TPM physical presence operation request.
94 @param[in, out] Pointer to 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 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
101 IN OUT UINT32 *OperationRequest,
102 IN OUT UINT32 *RequestParameter
103 )
104 {
105 EFI_STATUS Status;
106 UINT32 ReturnCode;
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 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
113
114 //
115 // Get the Physical Presence variable
116 //
117 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
118 Status = mTcg2PpSmmVariable->SmmGetVariable (
119 TCG2_PHYSICAL_PRESENCE_VARIABLE,
120 &gEfiTcg2PhysicalPresenceGuid,
121 NULL,
122 &DataSize,
123 &PpData
124 );
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;
128 goto EXIT;
129 }
130
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;
134 goto EXIT;
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 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;
152 goto EXIT;
153 }
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 = mTcg2PhysicalPresenceFlags;
167 }
168 ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);
169 }
170
171 EXIT:
172 //
173 // Sync PPRQ/PPRM from PP Variable if PP submission fails
174 //
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,
182 NULL,
183 &DataSize,
184 &PpData
185 );
186 *OperationRequest = (UINT32)PpData.PPRequest;
187 *RequestParameter = PpData.PPRequestParameter;
188 }
189
190 return ReturnCode;
191 }
192
193 /**
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.
197
198 This API should be invoked in OS runtime phase to interface with ACPI method.
199
200 Caution: This function may receive untrusted input.
201
202 @param[in] OperationRequest TPM physical presence operation request.
203 @param[in] RequestParameter TPM physical presence operation request parameter.
204
205 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
206 Submit TPM Operation Request to Pre-OS Environment 2.
207 **/
208 UINT32
209 EFIAPI
210 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
211 IN UINT32 OperationRequest,
212 IN UINT32 RequestParameter
213 )
214 {
215 UINT32 TempOperationRequest;
216 UINT32 TempRequestParameter;
217
218 TempOperationRequest = OperationRequest;
219 TempRequestParameter = RequestParameter;
220
221 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest, &TempRequestParameter);
222 }
223
224 /**
225 The handler for TPM physical presence function:
226 Get User Confirmation Status for Operation.
227
228 This API should be invoked in OS runtime phase to interface with ACPI method.
229
230 Caution: This function may receive untrusted input.
231
232 @param[in] OperationRequest TPM physical presence operation request.
233
234 @return Return Code for Get User Confirmation Status for Operation.
235 **/
236 UINT32
237 EFIAPI
238 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
239 IN UINT32 OperationRequest
240 )
241 {
242 EFI_STATUS Status;
243 UINTN DataSize;
244 EFI_TCG2_PHYSICAL_PRESENCE PpData;
245 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
246 BOOLEAN RequestConfirmed;
247
248 DEBUG ((EFI_D_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));
249
250 //
251 // Get the Physical Presence variable
252 //
253 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
254 Status = mTcg2PpSmmVariable->SmmGetVariable (
255 TCG2_PHYSICAL_PRESENCE_VARIABLE,
256 &gEfiTcg2PhysicalPresenceGuid,
257 NULL,
258 &DataSize,
259 &PpData
260 );
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;
264 }
265 //
266 // Get the Physical Presence flags
267 //
268 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
269 Status = mTcg2PpSmmVariable->SmmGetVariable (
270 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
271 &gEfiTcg2PhysicalPresenceGuid,
272 NULL,
273 &DataSize,
274 &Flags
275 );
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;
279 }
280
281 RequestConfirmed = FALSE;
282
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;
290 }
291 break;
292
293 case TCG2_PHYSICAL_PRESENCE_NO_ACTION:
294 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
295 RequestConfirmed = TRUE;
296 break;
297
298 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
299 break;
300
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;
304 }
305 break;
306
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;
310 }
311 break;
312
313 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
314 RequestConfirmed = TRUE;
315 break;
316
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;
320 }
321 break;
322
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;
326 }
327 break;
328
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;
332 break;
333
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:
336 break;
337
338 default:
339 if (!mIsTcg2PPVerLowerThan_1_3) {
340 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
341 //
342 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented
343 //
344 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
345 }
346 } else {
347 //
348 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)
349 //
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;
354 }
355 }
356 break;
357 }
358
359 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
360 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);
361 }
362
363 if (RequestConfirmed) {
364 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;
365 } else {
366 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;
367 }
368 }
369
370 /**
371 The constructor function locates SmmVariable protocol.
372
373 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
374
375 @param ImageHandle The firmware allocated handle for the EFI image.
376 @param SystemTable A pointer to the EFI System Table.
377
378 @retval EFI_SUCCESS The constructor successfully added string package.
379 @retval Other value The constructor can't add string package.
380 **/
381 EFI_STATUS
382 EFIAPI
383 Tcg2PhysicalPresenceLibConstructor (
384 IN EFI_HANDLE ImageHandle,
385 IN EFI_SYSTEM_TABLE *SystemTable
386 )
387 {
388 EFI_STATUS Status;
389
390 if (AsciiStrnCmp(PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer), sizeof(PP_INF_VERSION_1_2) - 1) <= 0) {
391 mIsTcg2PPVerLowerThan_1_3 = TRUE;
392 }
393
394 //
395 // Locate SmmVariableProtocol.
396 //
397 Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mTcg2PpSmmVariable);
398 ASSERT_EFI_ERROR (Status);
399
400 mTcg2PhysicalPresenceFlags = PcdGet32(PcdTcg2PhysicalPresenceFlags);
401
402 return EFI_SUCCESS;
403 }