]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Library / SmmTcg2PhysicalPresenceLib / MmTcg2PhysicalPresenceLibCommon.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 <PiMm.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/MmServicesTableLib.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 ((DEBUG_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 ((DEBUG_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 ((DEBUG_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 ((DEBUG_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 {
134 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
135 goto EXIT;
136 }
137
138 if ((PpData.PPRequest != *OperationRequest) ||
139 (PpData.PPRequestParameter != *RequestParameter))
140 {
141 PpData.PPRequest = (UINT8)*OperationRequest;
142 PpData.PPRequestParameter = *RequestParameter;
143 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
144 Status = mTcg2PpSmmVariable->SmmSetVariable (
145 TCG2_PHYSICAL_PRESENCE_VARIABLE,
146 &gEfiTcg2PhysicalPresenceGuid,
147 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
148 DataSize,
149 &PpData
150 );
151 if (EFI_ERROR (Status)) {
152 DEBUG ((DEBUG_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
153 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
154 goto EXIT;
155 }
156 }
157
158 if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
159 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
160 Status = mTcg2PpSmmVariable->SmmGetVariable (
161 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
162 &gEfiTcg2PhysicalPresenceGuid,
163 NULL,
164 &DataSize,
165 &Flags
166 );
167 if (EFI_ERROR (Status)) {
168 Flags.PPFlags = mTcg2PhysicalPresenceFlags;
169 }
170
171 ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);
172 }
173
174 EXIT:
175 //
176 // Sync PPRQ/PPRM from PP Variable if PP submission fails
177 //
178 if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
179 DEBUG ((DEBUG_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));
180 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
181 ZeroMem (&PpData, DataSize);
182 Status = mTcg2PpSmmVariable->SmmGetVariable (
183 TCG2_PHYSICAL_PRESENCE_VARIABLE,
184 &gEfiTcg2PhysicalPresenceGuid,
185 NULL,
186 &DataSize,
187 &PpData
188 );
189 *OperationRequest = (UINT32)PpData.PPRequest;
190 *RequestParameter = PpData.PPRequestParameter;
191 }
192
193 return ReturnCode;
194 }
195
196 /**
197 The handler for TPM physical presence function:
198 Submit TPM Operation Request to Pre-OS Environment and
199 Submit TPM Operation Request to Pre-OS Environment 2.
200
201 This API should be invoked in OS runtime phase to interface with ACPI method.
202
203 Caution: This function may receive untrusted input.
204
205 @param[in] OperationRequest TPM physical presence operation request.
206 @param[in] RequestParameter TPM physical presence operation request parameter.
207
208 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
209 Submit TPM Operation Request to Pre-OS Environment 2.
210 **/
211 UINT32
212 EFIAPI
213 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
214 IN UINT32 OperationRequest,
215 IN UINT32 RequestParameter
216 )
217 {
218 UINT32 TempOperationRequest;
219 UINT32 TempRequestParameter;
220
221 TempOperationRequest = OperationRequest;
222 TempRequestParameter = RequestParameter;
223
224 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (&TempOperationRequest, &TempRequestParameter);
225 }
226
227 /**
228 The handler for TPM physical presence function:
229 Get User Confirmation Status for Operation.
230
231 This API should be invoked in OS runtime phase to interface with ACPI method.
232
233 Caution: This function may receive untrusted input.
234
235 @param[in] OperationRequest TPM physical presence operation request.
236
237 @return Return Code for Get User Confirmation Status for Operation.
238 **/
239 UINT32
240 EFIAPI
241 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
242 IN UINT32 OperationRequest
243 )
244 {
245 EFI_STATUS Status;
246 UINTN DataSize;
247 EFI_TCG2_PHYSICAL_PRESENCE PpData;
248 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
249 BOOLEAN RequestConfirmed;
250
251 DEBUG ((DEBUG_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));
252
253 //
254 // Get the Physical Presence variable
255 //
256 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
257 Status = mTcg2PpSmmVariable->SmmGetVariable (
258 TCG2_PHYSICAL_PRESENCE_VARIABLE,
259 &gEfiTcg2PhysicalPresenceGuid,
260 NULL,
261 &DataSize,
262 &PpData
263 );
264 if (EFI_ERROR (Status)) {
265 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
266 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
267 }
268
269 //
270 // Get the Physical Presence flags
271 //
272 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
273 Status = mTcg2PpSmmVariable->SmmGetVariable (
274 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
275 &gEfiTcg2PhysicalPresenceGuid,
276 NULL,
277 &DataSize,
278 &Flags
279 );
280 if (EFI_ERROR (Status)) {
281 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));
282 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
283 }
284
285 RequestConfirmed = FALSE;
286
287 switch (OperationRequest) {
288 case TCG2_PHYSICAL_PRESENCE_CLEAR:
289 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
290 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
291 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
292 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {
293 RequestConfirmed = TRUE;
294 }
295
296 break;
297
298 case TCG2_PHYSICAL_PRESENCE_NO_ACTION:
299 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
300 RequestConfirmed = TRUE;
301 break;
302
303 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
304 break;
305
306 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
307 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {
308 RequestConfirmed = TRUE;
309 }
310
311 break;
312
313 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
314 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {
315 RequestConfirmed = TRUE;
316 }
317
318 break;
319
320 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
321 RequestConfirmed = TRUE;
322 break;
323
324 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
325 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {
326 RequestConfirmed = TRUE;
327 }
328
329 break;
330
331 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
332 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {
333 RequestConfirmed = TRUE;
334 }
335
336 break;
337
338 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
339 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
340 RequestConfirmed = TRUE;
341 break;
342
343 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
344 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
345 break;
346
347 default:
348 if (!mIsTcg2PPVerLowerThan_1_3) {
349 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
350 //
351 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented
352 //
353 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
354 }
355 } else {
356 //
357 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)
358 //
359 if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
360 RequestConfirmed = TRUE;
361 } else if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
362 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
363 }
364 }
365
366 break;
367 }
368
369 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
370 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);
371 }
372
373 if (RequestConfirmed) {
374 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;
375 } else {
376 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;
377 }
378 }
379
380 /**
381 The constructor function locates SmmVariable protocol.
382
383 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
384
385 @retval EFI_SUCCESS The constructor successfully added string package.
386 @retval Other value The constructor can't add string package.
387 **/
388 EFI_STATUS
389 Tcg2PhysicalPresenceLibCommonConstructor (
390 VOID
391 )
392 {
393 EFI_STATUS Status;
394
395 if (AsciiStrnCmp (PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer), sizeof (PP_INF_VERSION_1_2) - 1) >= 0) {
396 mIsTcg2PPVerLowerThan_1_3 = TRUE;
397 }
398
399 //
400 // Locate SmmVariableProtocol.
401 //
402 Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mTcg2PpSmmVariable);
403 ASSERT_EFI_ERROR (Status);
404
405 mTcg2PhysicalPresenceFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
406
407 return EFI_SUCCESS;
408 }