TianoCore EDK2 master
Loading...
Searching...
No Matches
TcgSmm.c
Go to the documentation of this file.
1
16#include "TcgSmm.h"
17
18EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;
19TCG_NVS *mTcgNvs;
20
39EFIAPI
41 IN EFI_HANDLE DispatchHandle,
42 IN CONST VOID *Context,
43 IN OUT VOID *CommBuffer,
44 IN OUT UINTN *CommBufferSize
45 )
46{
47 EFI_STATUS Status;
48 UINTN DataSize;
51 BOOLEAN RequestConfirmed;
52
53 //
54 // Get the Physical Presence variable
55 //
56 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
57 Status = mSmmVariable->SmmGetVariable (
58 PHYSICAL_PRESENCE_VARIABLE,
59 &gEfiPhysicalPresenceGuid,
60 NULL,
61 &DataSize,
62 &PpData
63 );
64
65 DEBUG ((DEBUG_INFO, "[TPM] PP callback, Parameter = %x\n", mTcgNvs->PhysicalPresence.Parameter));
66 if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {
67 if (EFI_ERROR (Status)) {
68 mTcgNvs->PhysicalPresence.ReturnCode = PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
69 mTcgNvs->PhysicalPresence.LastRequest = 0;
70 mTcgNvs->PhysicalPresence.Response = 0;
71 DEBUG ((DEBUG_ERROR, "[TPM] Get PP variable failure! Status = %r\n", Status));
72 return EFI_SUCCESS;
73 }
74
75 mTcgNvs->PhysicalPresence.ReturnCode = PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
76 mTcgNvs->PhysicalPresence.LastRequest = PpData.LastPPRequest;
77 mTcgNvs->PhysicalPresence.Response = PpData.PPResponse;
78 } else if ( (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS)
79 || (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2))
80 {
81 if (EFI_ERROR (Status)) {
82 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
83 DEBUG ((DEBUG_ERROR, "[TPM] Get PP variable failure! Status = %r\n", Status));
84 return EFI_SUCCESS;
85 }
86
87 if (mTcgNvs->PhysicalPresence.Request == PHYSICAL_PRESENCE_SET_OPERATOR_AUTH) {
88 //
89 // This command requires UI to prompt user for Auth data.
90 //
91 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
92 return EFI_SUCCESS;
93 }
94
95 if (PpData.PPRequest != mTcgNvs->PhysicalPresence.Request) {
96 PpData.PPRequest = (UINT8)mTcgNvs->PhysicalPresence.Request;
97 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
98 Status = mSmmVariable->SmmSetVariable (
99 PHYSICAL_PRESENCE_VARIABLE,
100 &gEfiPhysicalPresenceGuid,
101 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
102 DataSize,
103 &PpData
104 );
105 }
106
107 if (EFI_ERROR (Status)) {
108 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
109 return EFI_SUCCESS;
110 }
111
112 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
113
114 if (mTcgNvs->PhysicalPresence.Request >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
115 DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS);
116 Status = mSmmVariable->SmmGetVariable (
117 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
118 &gEfiPhysicalPresenceGuid,
119 NULL,
120 &DataSize,
121 &Flags
122 );
123 if (EFI_ERROR (Status)) {
124 Flags.PPFlags = TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION;
125 }
126
127 mTcgNvs->PhysicalPresence.ReturnCode = TcgPpVendorLibSubmitRequestToPreOSFunction (mTcgNvs->PhysicalPresence.Request, Flags.PPFlags);
128 }
129 } else if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {
130 if (EFI_ERROR (Status)) {
131 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
132 DEBUG ((DEBUG_ERROR, "[TPM] Get PP variable failure! Status = %r\n", Status));
133 return EFI_SUCCESS;
134 }
135
136 //
137 // Get the Physical Presence flags
138 //
139 DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS);
140 Status = mSmmVariable->SmmGetVariable (
141 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
142 &gEfiPhysicalPresenceGuid,
143 NULL,
144 &DataSize,
145 &Flags
146 );
147 if (EFI_ERROR (Status)) {
148 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
149 DEBUG ((DEBUG_ERROR, "[TPM] Get PP flags failure! Status = %r\n", Status));
150 return EFI_SUCCESS;
151 }
152
153 RequestConfirmed = FALSE;
154
155 switch (mTcgNvs->PPRequestUserConfirm) {
156 case PHYSICAL_PRESENCE_ENABLE:
157 case PHYSICAL_PRESENCE_DISABLE:
158 case PHYSICAL_PRESENCE_ACTIVATE:
159 case PHYSICAL_PRESENCE_DEACTIVATE:
160 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
161 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
162 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:
163 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:
164 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
165 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
166 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0) {
167 RequestConfirmed = TRUE;
168 }
169
170 break;
171
172 case PHYSICAL_PRESENCE_CLEAR:
173 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
174 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) {
175 RequestConfirmed = TRUE;
176 }
177
178 break;
179
180 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
181 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE) != 0) {
182 RequestConfirmed = TRUE;
183 }
184
185 break;
186
187 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
188 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
189 if (((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) && ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0)) {
190 RequestConfirmed = TRUE;
191 }
192
193 break;
194
195 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE:
196 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:
197 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:
198 case PHYSICAL_PRESENCE_NO_ACTION:
199 RequestConfirmed = TRUE;
200 break;
201
202 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
203 //
204 // This command requires UI to prompt user for Auth data
205 //
206 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
207 return EFI_SUCCESS;
208 default:
209 break;
210 }
211
212 if (RequestConfirmed) {
213 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;
214 } else {
215 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;
216 }
217
218 if (mTcgNvs->PhysicalPresence.Request >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
219 mTcgNvs->PhysicalPresence.ReturnCode = TcgPpVendorLibGetUserConfirmationStatusFunction (mTcgNvs->PhysicalPresence.Request, Flags.PPFlags);
220 }
221 }
222
223 return EFI_SUCCESS;
224}
225
244EFIAPI
246 IN EFI_HANDLE DispatchHandle,
247 IN CONST VOID *Context,
248 IN OUT VOID *CommBuffer,
249 IN OUT UINTN *CommBufferSize
250 )
251{
252 EFI_STATUS Status;
253 UINTN DataSize;
254 UINT8 MorControl;
255
256 mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS;
257 if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) {
258 MorControl = (UINT8)mTcgNvs->MemoryClear.Request;
259 } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) {
260 DataSize = sizeof (UINT8);
261 Status = mSmmVariable->SmmGetVariable (
263 &gEfiMemoryOverwriteControlDataGuid,
264 NULL,
265 &DataSize,
266 &MorControl
267 );
268 if (EFI_ERROR (Status)) {
269 mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
270 DEBUG ((DEBUG_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", Status));
271 return EFI_SUCCESS;
272 }
273
274 if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {
275 return EFI_SUCCESS;
276 }
277
278 MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;
279 } else {
280 mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
281 DEBUG ((DEBUG_ERROR, "[TPM] MOR Parameter error! Parameter = %x\n", mTcgNvs->MemoryClear.Parameter));
282 return EFI_SUCCESS;
283 }
284
285 DataSize = sizeof (UINT8);
286 Status = mSmmVariable->SmmSetVariable (
288 &gEfiMemoryOverwriteControlDataGuid,
289 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
290 DataSize,
291 &MorControl
292 );
293 if (EFI_ERROR (Status)) {
294 mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
295 DEBUG ((DEBUG_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status));
296 }
297
298 return EFI_SUCCESS;
299}
300
312VOID *
315 UINT32 Name,
316 UINT16 Size
317 )
318{
319 EFI_STATUS Status;
320 AML_OP_REGION_32_8 *OpRegion;
321 EFI_PHYSICAL_ADDRESS MemoryAddress;
322
323 MemoryAddress = SIZE_4GB - 1;
324
325 //
326 // Patch some pointers for the ASL code before loading the SSDT.
327 //
328 for (OpRegion = (AML_OP_REGION_32_8 *)(Table + 1);
329 OpRegion <= (AML_OP_REGION_32_8 *)((UINT8 *)Table + Table->Length);
330 OpRegion = (AML_OP_REGION_32_8 *)((UINT8 *)OpRegion + 1))
331 {
332 if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) &&
333 (OpRegion->NameString == Name) &&
334 (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&
335 (OpRegion->BytePrefix == AML_BYTE_PREFIX))
336 {
337 Status = gBS->AllocatePages (AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);
338 ASSERT_EFI_ERROR (Status);
339 ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);
340 OpRegion->RegionOffset = (UINT32)(UINTN)MemoryAddress;
341 OpRegion->RegionLen = (UINT8)Size;
342 break;
343 }
344 }
345
346 return (VOID *)(UINTN)MemoryAddress;
347}
348
358 VOID
359 )
360{
361 EFI_STATUS Status;
362 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
363 UINTN TableKey;
365 UINTN TableSize;
366
367 Status = GetSectionFromFv (
368 &gEfiCallerIdGuid,
369 EFI_SECTION_RAW,
370 0,
371 (VOID **)&Table,
372 &TableSize
373 );
374 ASSERT_EFI_ERROR (Status);
375
376 //
377 // Measure to PCR[0] with event EV_POST_CODE ACPI DATA
378 //
380 0,
381 EV_POST_CODE,
382 EV_POSTCODE_INFO_ACPI_DATA,
383 ACPI_DATA_LEN,
384 Table,
385 TableSize
386 );
387
388 ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'c', 'g', 'T', 'a', 'b', 'l', 'e'));
389 CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId));
390 mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16)sizeof (TCG_NVS));
391 ASSERT (mTcgNvs != NULL);
392
393 //
394 // Publish the TPM ACPI table
395 //
396 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
397 ASSERT_EFI_ERROR (Status);
398
399 TableKey = 0;
400 Status = AcpiTable->InstallAcpiTable (
401 AcpiTable,
402 Table,
403 TableSize,
404 &TableKey
405 );
406 ASSERT_EFI_ERROR (Status);
407
408 return Status;
409}
410
425EFIAPI
427 IN EFI_HANDLE ImageHandle,
428 IN EFI_SYSTEM_TABLE *SystemTable
429 )
430{
431 EFI_STATUS Status;
434 EFI_HANDLE SwHandle;
435
436 if (!CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
437 DEBUG ((DEBUG_ERROR, "No TPM12 instance required!\n"));
438 return EFI_UNSUPPORTED;
439 }
440
441 Status = PublishAcpiTable ();
442 ASSERT_EFI_ERROR (Status);
443
444 //
445 // Get the Sw dispatch protocol and register SMI callback functions.
446 //
447 Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID **)&SwDispatch);
448 ASSERT_EFI_ERROR (Status);
449 SwContext.SwSmiInputValue = (UINTN)-1;
450 Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);
451 ASSERT_EFI_ERROR (Status);
452 if (EFI_ERROR (Status)) {
453 return Status;
454 }
455
456 mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8)SwContext.SwSmiInputValue;
457
458 SwContext.SwSmiInputValue = (UINTN)-1;
459 Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);
460 ASSERT_EFI_ERROR (Status);
461 if (EFI_ERROR (Status)) {
462 return Status;
463 }
464
465 mTcgNvs->MemoryClear.SoftwareSmi = (UINT8)SwContext.SwSmiInputValue;
466
467 //
468 // Locate SmmVariableProtocol.
469 //
470 Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);
471 ASSERT_EFI_ERROR (Status);
472
473 return EFI_SUCCESS;
474}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI GetSectionFromFv(IN CONST EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, OUT VOID **Buffer, OUT UINTN *Size)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define SIGNATURE_64(A, B, C, D, E, F, G, H)
Definition: Base.h:1331
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define SIGNATURE_32(A, B, C, D)
Definition: Base.h:1310
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define MOR_CLEAR_MEMORY_VALUE(mor)
#define MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
EFI_SMM_SYSTEM_TABLE2 * gSmst
UINT32 EFIAPI TcgPpVendorLibGetUserConfirmationStatusFunction(IN UINT32 OperationRequest, IN UINT32 ManagementFlags)
UINT32 EFIAPI TcgPpVendorLibSubmitRequestToPreOSFunction(IN UINT32 OperationRequest, IN UINT32 ManagementFlags)
EFI_STATUS EFIAPI MemoryClearCallback(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context, IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize)
Definition: TcgSmm.c:245
VOID * AssignOpRegion(EFI_ACPI_DESCRIPTION_HEADER *Table, UINT32 Name, UINT16 Size)
Definition: TcgSmm.c:313
EFI_STATUS PublishAcpiTable(VOID)
Definition: TcgSmm.c:357
EFI_STATUS EFIAPI PhysicalPresenceCallback(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context, IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize)
Definition: TcgSmm.c:40
EFI_STATUS EFIAPI InitializeTcgSmm(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: TcgSmm.c:426
EFI_STATUS EFIAPI TpmMeasureAndLogData(IN UINT32 PcrIndex, IN UINT32 EventType, IN VOID *EventLog, IN UINT32 LogLen, IN VOID *HashData, IN UINT64 HashDataLen)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiACPIMemoryNVS
#define EFI_VARIABLE_NON_VOLATILE
@ AllocateMaxAddress
Definition: UefiSpec.h:38
UINT8 PPRequest
Physical Presence request command.