VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.c

Last change on this file was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 13.6 KB
Line 
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
13Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
14SPDX-License-Identifier: BSD-2-Clause-Patent
15
16**/
17
18#include "MmTcg2PhysicalPresenceLibCommon.h"
19
20EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable;
21BOOLEAN mIsTcg2PPVerLowerThan_1_3 = FALSE;
22UINT32 mTcg2PhysicalPresenceFlags;
23
24/**
25 The handler for TPM physical presence function:
26 Return TPM Operation Response to OS Environment.
27
28 This API should be invoked in OS runtime phase to interface with ACPI method.
29
30 @param[out] MostRecentRequest Most recent operation request.
31 @param[out] Response Response to the most recent operation request.
32
33 @return Return Code for Return TPM Operation Response to OS Environment.
34**/
35UINT32
36EFIAPI
37Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
38 OUT UINT32 *MostRecentRequest,
39 OUT UINT32 *Response
40 )
41{
42 EFI_STATUS Status;
43 UINTN DataSize;
44 EFI_TCG2_PHYSICAL_PRESENCE PpData;
45
46 DEBUG ((DEBUG_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));
47
48 //
49 // Get the Physical Presence variable
50 //
51 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
52 Status = mTcg2PpSmmVariable->SmmGetVariable (
53 TCG2_PHYSICAL_PRESENCE_VARIABLE,
54 &gEfiTcg2PhysicalPresenceGuid,
55 NULL,
56 &DataSize,
57 &PpData
58 );
59 if (EFI_ERROR (Status)) {
60 *MostRecentRequest = 0;
61 *Response = 0;
62 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
63 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
64 }
65
66 *MostRecentRequest = PpData.LastPPRequest;
67 *Response = PpData.PPResponse;
68
69 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
70}
71
72/**
73 The handler for TPM physical presence function:
74 Submit TPM Operation Request to Pre-OS Environment and
75 Submit TPM Operation Request to Pre-OS Environment 2.
76
77 This API should be invoked in OS runtime phase to interface with ACPI method.
78
79 Caution: This function may receive untrusted input.
80
81 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.
82 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.
83
84 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
85 Submit TPM Operation Request to Pre-OS Environment 2.
86 **/
87UINT32
88Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
89 IN OUT UINT32 *OperationRequest,
90 IN OUT UINT32 *RequestParameter
91 )
92{
93 EFI_STATUS Status;
94 UINT32 ReturnCode;
95 UINTN DataSize;
96 EFI_TCG2_PHYSICAL_PRESENCE PpData;
97 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
98
99 DEBUG ((DEBUG_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));
100 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
101
102 //
103 // Get the Physical Presence variable
104 //
105 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
106 Status = mTcg2PpSmmVariable->SmmGetVariable (
107 TCG2_PHYSICAL_PRESENCE_VARIABLE,
108 &gEfiTcg2PhysicalPresenceGuid,
109 NULL,
110 &DataSize,
111 &PpData
112 );
113 if (EFI_ERROR (Status)) {
114 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
115 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
116 goto EXIT;
117 }
118
119 if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
120 (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN))
121 {
122 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
123 goto EXIT;
124 }
125
126 if ((PpData.PPRequest != *OperationRequest) ||
127 (PpData.PPRequestParameter != *RequestParameter))
128 {
129 PpData.PPRequest = (UINT8)*OperationRequest;
130 PpData.PPRequestParameter = *RequestParameter;
131 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
132 Status = mTcg2PpSmmVariable->SmmSetVariable (
133 TCG2_PHYSICAL_PRESENCE_VARIABLE,
134 &gEfiTcg2PhysicalPresenceGuid,
135 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
136 DataSize,
137 &PpData
138 );
139 if (EFI_ERROR (Status)) {
140 DEBUG ((DEBUG_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
141 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
142 goto EXIT;
143 }
144 }
145
146 if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
147 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
148 Status = mTcg2PpSmmVariable->SmmGetVariable (
149 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
150 &gEfiTcg2PhysicalPresenceGuid,
151 NULL,
152 &DataSize,
153 &Flags
154 );
155 if (EFI_ERROR (Status)) {
156 Flags.PPFlags = mTcg2PhysicalPresenceFlags;
157 }
158
159 ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);
160 }
161
162EXIT:
163 //
164 // Sync PPRQ/PPRM from PP Variable if PP submission fails
165 //
166 if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
167 DEBUG ((DEBUG_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable. Status = %r\n", Status));
168 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
169 ZeroMem (&PpData, DataSize);
170 Status = mTcg2PpSmmVariable->SmmGetVariable (
171 TCG2_PHYSICAL_PRESENCE_VARIABLE,
172 &gEfiTcg2PhysicalPresenceGuid,
173 NULL,
174 &DataSize,
175 &PpData
176 );
177 *OperationRequest = (UINT32)PpData.PPRequest;
178 *RequestParameter = PpData.PPRequestParameter;
179 }
180
181 return ReturnCode;
182}
183
184/**
185 The handler for TPM physical presence function:
186 Submit TPM Operation Request to Pre-OS Environment and
187 Submit TPM Operation Request to Pre-OS Environment 2.
188
189 This API should be invoked in OS runtime phase to interface with ACPI method.
190
191 Caution: This function may receive untrusted input.
192
193 @param[in] OperationRequest TPM physical presence operation request.
194 @param[in] RequestParameter TPM physical presence operation request parameter.
195
196 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
197 Submit TPM Operation Request to Pre-OS Environment 2.
198**/
199UINT32
200EFIAPI
201Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
202 IN UINT32 OperationRequest,
203 IN UINT32 RequestParameter
204 )
205{
206 UINT32 TempOperationRequest;
207 UINT32 TempRequestParameter;
208
209 TempOperationRequest = OperationRequest;
210 TempRequestParameter = RequestParameter;
211
212 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (&TempOperationRequest, &TempRequestParameter);
213}
214
215/**
216 The handler for TPM physical presence function:
217 Get User Confirmation Status for Operation.
218
219 This API should be invoked in OS runtime phase to interface with ACPI method.
220
221 Caution: This function may receive untrusted input.
222
223 @param[in] OperationRequest TPM physical presence operation request.
224
225 @return Return Code for Get User Confirmation Status for Operation.
226**/
227UINT32
228EFIAPI
229Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
230 IN UINT32 OperationRequest
231 )
232{
233 EFI_STATUS Status;
234 UINTN DataSize;
235 EFI_TCG2_PHYSICAL_PRESENCE PpData;
236 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
237 BOOLEAN RequestConfirmed;
238
239 DEBUG ((DEBUG_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));
240
241 //
242 // Get the Physical Presence variable
243 //
244 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
245 Status = mTcg2PpSmmVariable->SmmGetVariable (
246 TCG2_PHYSICAL_PRESENCE_VARIABLE,
247 &gEfiTcg2PhysicalPresenceGuid,
248 NULL,
249 &DataSize,
250 &PpData
251 );
252 if (EFI_ERROR (Status)) {
253 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
254 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
255 }
256
257 //
258 // Get the Physical Presence flags
259 //
260 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
261 Status = mTcg2PpSmmVariable->SmmGetVariable (
262 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
263 &gEfiTcg2PhysicalPresenceGuid,
264 NULL,
265 &DataSize,
266 &Flags
267 );
268 if (EFI_ERROR (Status)) {
269 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));
270 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
271 }
272
273 RequestConfirmed = FALSE;
274
275 switch (OperationRequest) {
276 case TCG2_PHYSICAL_PRESENCE_CLEAR:
277 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
278 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
279 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
280 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {
281 RequestConfirmed = TRUE;
282 }
283
284 break;
285
286 case TCG2_PHYSICAL_PRESENCE_NO_ACTION:
287 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
288 RequestConfirmed = TRUE;
289 break;
290
291 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
292 break;
293
294 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
295 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {
296 RequestConfirmed = TRUE;
297 }
298
299 break;
300
301 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
302 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {
303 RequestConfirmed = TRUE;
304 }
305
306 break;
307
308 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
309 RequestConfirmed = TRUE;
310 break;
311
312 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
313 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {
314 RequestConfirmed = TRUE;
315 }
316
317 break;
318
319 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
320 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {
321 RequestConfirmed = TRUE;
322 }
323
324 break;
325
326 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
327 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
328 RequestConfirmed = TRUE;
329 break;
330
331 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
332 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
333 break;
334
335 default:
336 if (!mIsTcg2PPVerLowerThan_1_3) {
337 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
338 //
339 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented
340 //
341 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
342 }
343 } else {
344 //
345 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)
346 //
347 if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
348 RequestConfirmed = TRUE;
349 } else if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
350 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
351 }
352 }
353
354 break;
355 }
356
357 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
358 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);
359 }
360
361 if (RequestConfirmed) {
362 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;
363 } else {
364 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;
365 }
366}
367
368/**
369 The constructor function locates SmmVariable protocol.
370
371 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
372
373 @retval EFI_SUCCESS The constructor successfully added string package.
374 @retval Other value The constructor can't add string package.
375**/
376EFI_STATUS
377Tcg2PhysicalPresenceLibCommonConstructor (
378 VOID
379 )
380{
381 EFI_STATUS Status;
382
383 mIsTcg2PPVerLowerThan_1_3 = IsTcg2PPVerLowerThan_1_3 ();
384
385 //
386 // Locate SmmVariableProtocol.
387 //
388 Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mTcg2PpSmmVariable);
389 ASSERT_EFI_ERROR (Status);
390
391 mTcg2PhysicalPresenceFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
392
393 return EFI_SUCCESS;
394}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette