]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
SecurityPkg SmmTcg2PhysicalPresenceLib: Enable Storage actions.
[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/BaseMemoryLib.h>
32 #include <Library/Tcg2PpVendorLib.h>
33 #include <Library/SmmServicesTableLib.h>
34 #include <Library/TcgPhysicalPresenceStorageLib.h>
35
36 EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable;
37
38 /**
39 The handler for TPM physical presence function:
40 Return TPM Operation Response to OS Environment.
41
42 This API should be invoked in OS runtime phase to interface with ACPI method.
43
44 @param[out] MostRecentRequest Most recent operation request.
45 @param[out] Response Response to the most recent operation request.
46
47 @return Return Code for Return TPM Operation Response to OS Environment.
48 **/
49 UINT32
50 EFIAPI
51 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
52 OUT UINT32 *MostRecentRequest,
53 OUT UINT32 *Response
54 )
55 {
56 EFI_STATUS Status;
57 UINTN DataSize;
58 EFI_TCG2_PHYSICAL_PRESENCE PpData;
59
60 DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));
61
62 //
63 // Get the Physical Presence variable
64 //
65 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
66 Status = mTcg2PpSmmVariable->SmmGetVariable (
67 TCG2_PHYSICAL_PRESENCE_VARIABLE,
68 &gEfiTcg2PhysicalPresenceGuid,
69 NULL,
70 &DataSize,
71 &PpData
72 );
73 if (EFI_ERROR (Status)) {
74 *MostRecentRequest = 0;
75 *Response = 0;
76 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
77 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
78 }
79
80 *MostRecentRequest = PpData.LastPPRequest;
81 *Response = PpData.PPResponse;
82
83 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
84 }
85
86 /**
87 The handler for TPM physical presence function:
88 Submit TPM Operation Request to Pre-OS Environment and
89 Submit TPM Operation Request to Pre-OS Environment 2.
90
91 This API should be invoked in OS runtime phase to interface with ACPI method.
92
93 Caution: This function may receive untrusted input.
94
95 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.
96 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.
97
98 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
99 Submit TPM Operation Request to Pre-OS Environment 2.
100 **/
101 UINT32
102 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
103 IN OUT UINT32 *OperationRequest,
104 IN OUT UINT32 *RequestParameter
105 )
106 {
107 EFI_STATUS Status;
108 UINT32 ReturnCode;
109 UINTN DataSize;
110 EFI_TCG2_PHYSICAL_PRESENCE PpData;
111 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
112
113 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));
114 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
115
116 //
117 // Get the Physical Presence variable
118 //
119 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
120 Status = mTcg2PpSmmVariable->SmmGetVariable (
121 TCG2_PHYSICAL_PRESENCE_VARIABLE,
122 &gEfiTcg2PhysicalPresenceGuid,
123 NULL,
124 &DataSize,
125 &PpData
126 );
127 if (EFI_ERROR (Status)) {
128 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
129 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
130 goto EXIT;
131 }
132
133 if (((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
134 (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN))||
135 ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE) &&
136 (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN))) {
137 //
138 // This command requires UI to prompt user for Auth data.
139 //
140 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
141 goto EXIT;
142 }
143
144 if ((PpData.PPRequest != *OperationRequest) ||
145 (PpData.PPRequestParameter != *RequestParameter)) {
146 PpData.PPRequest = (UINT8)*OperationRequest;
147 PpData.PPRequestParameter = *RequestParameter;
148 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
149 Status = mTcg2PpSmmVariable->SmmSetVariable (
150 TCG2_PHYSICAL_PRESENCE_VARIABLE,
151 &gEfiTcg2PhysicalPresenceGuid,
152 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
153 DataSize,
154 &PpData
155 );
156 }
157
158 if (EFI_ERROR (Status)) {
159 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
160 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
161 goto EXIT;
162 }
163
164 if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
165 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
166 Status = mTcg2PpSmmVariable->SmmGetVariable (
167 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
168 &gEfiTcg2PhysicalPresenceGuid,
169 NULL,
170 &DataSize,
171 &Flags
172 );
173 if (EFI_ERROR (Status)) {
174 Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;
175 }
176 ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);
177 }
178
179 EXIT:
180 //
181 // Sync PPRQ/PPRM from PP Variable if PP submission fails
182 //
183 if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
184 DEBUG ((EFI_D_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));
185 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
186 ZeroMem(&PpData, DataSize);
187 Status = mTcg2PpSmmVariable->SmmGetVariable (
188 TCG2_PHYSICAL_PRESENCE_VARIABLE,
189 &gEfiTcg2PhysicalPresenceGuid,
190 NULL,
191 &DataSize,
192 &PpData
193 );
194 *OperationRequest = (UINT32)PpData.PPRequest;
195 *RequestParameter = PpData.PPRequestParameter;
196 }
197
198 return ReturnCode;
199 }
200
201 /**
202 The handler for TPM physical presence function:
203 Submit TPM Operation Request to Pre-OS Environment and
204 Submit TPM Operation Request to Pre-OS Environment 2.
205
206 This API should be invoked in OS runtime phase to interface with ACPI method.
207
208 Caution: This function may receive untrusted input.
209
210 @param[in] OperationRequest TPM physical presence operation request.
211 @param[in] RequestParameter TPM physical presence operation request parameter.
212
213 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
214 Submit TPM Operation Request to Pre-OS Environment 2.
215 **/
216 UINT32
217 EFIAPI
218 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
219 IN UINT32 OperationRequest,
220 IN UINT32 RequestParameter
221 )
222 {
223 UINT32 TempOperationRequest;
224 UINT32 TempRequestParameter;
225
226 TempOperationRequest = OperationRequest;
227 TempRequestParameter = RequestParameter;
228
229 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest, &TempRequestParameter);
230 }
231
232 /**
233 The handler for TPM physical presence function:
234 Get User Confirmation Status for Operation.
235
236 This API should be invoked in OS runtime phase to interface with ACPI method.
237
238 Caution: This function may receive untrusted input.
239
240 @param[in] OperationRequest TPM physical presence operation request.
241
242 @return Return Code for Get User Confirmation Status for Operation.
243 **/
244 UINT32
245 EFIAPI
246 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
247 IN UINT32 OperationRequest
248 )
249 {
250 EFI_STATUS Status;
251 UINTN DataSize;
252 EFI_TCG2_PHYSICAL_PRESENCE PpData;
253 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
254 UINT32 StorageFlags;
255 BOOLEAN RequestConfirmed;
256
257 DEBUG ((EFI_D_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));
258
259 //
260 // Get the Physical Presence variable
261 //
262 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
263 Status = mTcg2PpSmmVariable->SmmGetVariable (
264 TCG2_PHYSICAL_PRESENCE_VARIABLE,
265 &gEfiTcg2PhysicalPresenceGuid,
266 NULL,
267 &DataSize,
268 &PpData
269 );
270 if (EFI_ERROR (Status)) {
271 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
272 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
273 }
274 //
275 // Get the Physical Presence flags
276 //
277 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
278 Status = mTcg2PpSmmVariable->SmmGetVariable (
279 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
280 &gEfiTcg2PhysicalPresenceGuid,
281 NULL,
282 &DataSize,
283 &Flags
284 );
285 if (EFI_ERROR (Status)) {
286 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));
287 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
288 }
289
290 //
291 // Get the Physical Presence storage flags
292 //
293 StorageFlags = TcgPhysicalPresenceStorageLibReturnStorageFlags();
294
295 RequestConfirmed = FALSE;
296
297 switch (OperationRequest) {
298 case TCG2_PHYSICAL_PRESENCE_CLEAR:
299 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
300 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
301 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
302 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {
303 RequestConfirmed = TRUE;
304 }
305 break;
306
307 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
308 RequestConfirmed = TRUE;
309 break;
310
311 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
312 break;
313
314 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
315 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {
316 RequestConfirmed = TRUE;
317 }
318 break;
319
320 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
321 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {
322 RequestConfirmed = TRUE;
323 }
324 break;
325
326 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
327 RequestConfirmed = TRUE;
328 break;
329
330 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
331 if ((StorageFlags & TCG_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {
332 RequestConfirmed = TRUE;
333 }
334 break;
335
336 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
337 if ((StorageFlags & TCG_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {
338 RequestConfirmed = TRUE;
339 }
340 break;
341
342 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
343 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
344 break;
345
346 default:
347 if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
348 RequestConfirmed = TRUE;
349 } else {
350 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
351 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
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 register UNI strings into imageHandle.
370
371 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
372
373 @param ImageHandle The firmware allocated handle for the EFI image.
374 @param SystemTable A pointer to the EFI System Table.
375
376 @retval EFI_SUCCESS The constructor successfully added string package.
377 @retval Other value The constructor can't add string package.
378 **/
379 EFI_STATUS
380 EFIAPI
381 Tcg2PhysicalPresenceLibConstructor (
382 IN EFI_HANDLE ImageHandle,
383 IN EFI_SYSTEM_TABLE *SystemTable
384 )
385 {
386 EFI_STATUS Status;
387
388 //
389 // Locate SmmVariableProtocol.
390 //
391 Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mTcg2PpSmmVariable);
392 ASSERT_EFI_ERROR (Status);
393
394 return EFI_SUCCESS;
395 }