]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Dxe / Tcg2Dxe.c
CommitLineData
1abfa4ce
JY
1/** @file\r
2 This module implements Tcg2 Protocol.\r
b3548d32 3\r
930fcd9f 4Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
336dbfd1 5(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
289b714b 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
1abfa4ce
JY
7\r
8**/\r
9\r
10#include <PiDxe.h>\r
11#include <IndustryStandard/Acpi.h>\r
12#include <IndustryStandard/PeImage.h>\r
1abfa4ce
JY
13#include <IndustryStandard/TcpaAcpi.h>\r
14\r
15#include <Guid/GlobalVariable.h>\r
1abfa4ce
JY
16#include <Guid/HobList.h>\r
17#include <Guid/TcgEventHob.h>\r
18#include <Guid/EventGroup.h>\r
19#include <Guid/EventExitBootServiceFailed.h>\r
20#include <Guid/ImageAuthentication.h>\r
21#include <Guid/TpmInstance.h>\r
22\r
23#include <Protocol/DevicePath.h>\r
24#include <Protocol/MpService.h>\r
25#include <Protocol/VariableWrite.h>\r
26#include <Protocol/Tcg2Protocol.h>\r
27#include <Protocol/TrEEProtocol.h>\r
9d5dfe9d 28#include <Protocol/ResetNotification.h>\r
1abfa4ce
JY
29\r
30#include <Library/DebugLib.h>\r
31#include <Library/BaseMemoryLib.h>\r
32#include <Library/UefiRuntimeServicesTableLib.h>\r
33#include <Library/UefiDriverEntryPoint.h>\r
34#include <Library/HobLib.h>\r
35#include <Library/UefiBootServicesTableLib.h>\r
36#include <Library/BaseLib.h>\r
37#include <Library/MemoryAllocationLib.h>\r
38#include <Library/PrintLib.h>\r
39#include <Library/Tpm2CommandLib.h>\r
40#include <Library/PcdLib.h>\r
41#include <Library/UefiLib.h>\r
42#include <Library/Tpm2DeviceLib.h>\r
43#include <Library/HashLib.h>\r
44#include <Library/PerformanceLib.h>\r
45#include <Library/ReportStatusCodeLib.h>\r
46#include <Library/Tcg2PhysicalPresenceLib.h>\r
47\r
48#define PERF_ID_TCG2_DXE 0x3120\r
49\r
50typedef struct {\r
c411b485
MK
51 CHAR16 *VariableName;\r
52 EFI_GUID *VendorGuid;\r
1abfa4ce
JY
53} VARIABLE_TYPE;\r
54\r
c411b485
MK
55#define TCG2_DEFAULT_MAX_COMMAND_SIZE 0x1000\r
56#define TCG2_DEFAULT_MAX_RESPONSE_SIZE 0x1000\r
1abfa4ce
JY
57\r
58typedef struct {\r
c411b485
MK
59 EFI_GUID *EventGuid;\r
60 EFI_TCG2_EVENT_LOG_FORMAT LogFormat;\r
1abfa4ce
JY
61} TCG2_EVENT_INFO_STRUCT;\r
62\r
c411b485
MK
63TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = {\r
64 { &gTcgEventEntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 },\r
65 { &gTcgEvent2EntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 },\r
1abfa4ce
JY
66};\r
67\r
c411b485 68#define TCG_EVENT_LOG_AREA_COUNT_MAX 2\r
1abfa4ce
JY
69\r
70typedef struct {\r
c411b485
MK
71 EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat;\r
72 EFI_PHYSICAL_ADDRESS Lasa;\r
73 UINT64 Laml;\r
74 UINTN EventLogSize;\r
75 UINT8 *LastEvent;\r
76 BOOLEAN EventLogStarted;\r
77 BOOLEAN EventLogTruncated;\r
78 UINTN Next800155EventOffset;\r
1abfa4ce
JY
79} TCG_EVENT_LOG_AREA_STRUCT;\r
80\r
81typedef struct _TCG_DXE_DATA {\r
c411b485
MK
82 EFI_TCG2_BOOT_SERVICE_CAPABILITY BsCap;\r
83 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
84 BOOLEAN GetEventLogCalled[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
85 TCG_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
86 EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
1abfa4ce
JY
87} TCG_DXE_DATA;\r
88\r
c411b485 89TCG_DXE_DATA mTcgDxeData = {\r
1abfa4ce 90 {\r
c411b485
MK
91 sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY), // Size\r
92 { 1, 1 }, // StructureVersion\r
93 { 1, 1 }, // ProtocolVersion\r
94 EFI_TCG2_BOOT_HASH_ALG_SHA1, // HashAlgorithmBitmap\r
95 EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2, // SupportedEventLogs\r
96 TRUE, // TPMPresentFlag\r
97 TCG2_DEFAULT_MAX_COMMAND_SIZE, // MaxCommandSize\r
98 TCG2_DEFAULT_MAX_RESPONSE_SIZE, // MaxResponseSize\r
99 0, // ManufacturerID\r
100 0, // NumberOfPCRBanks\r
101 0, // ActivePcrBanks\r
1abfa4ce
JY
102 },\r
103};\r
104\r
c411b485
MK
105UINTN mBootAttempts = 0;\r
106CHAR16 mBootVarName[] = L"BootOrder";\r
1abfa4ce
JY
107\r
108VARIABLE_TYPE mVariableType[] = {\r
c411b485
MK
109 { EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid },\r
110 { EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid },\r
111 { EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid },\r
112 { EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid },\r
113 { EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid },\r
1abfa4ce
JY
114};\r
115\r
c411b485 116EFI_HANDLE mImageHandle;\r
1abfa4ce
JY
117\r
118/**\r
119 Measure PE image into TPM log based on the authenticode image hashing in\r
120 PE/COFF Specification 8.0 Appendix A.\r
121\r
122 Caution: This function may receive untrusted input.\r
123 PE/COFF image is external input, so this function will validate its data structure\r
124 within this image buffer before use.\r
125\r
5a8eae95
LG
126 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().\r
127\r
1abfa4ce
JY
128 @param[in] PCRIndex TPM PCR index\r
129 @param[in] ImageAddress Start address of image buffer.\r
130 @param[in] ImageSize Image size\r
d6b926e7 131 @param[out] DigestList Digest list of this image.\r
1abfa4ce
JY
132\r
133 @retval EFI_SUCCESS Successfully measure image.\r
134 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.\r
135 @retval other error value\r
136**/\r
137EFI_STATUS\r
138MeasurePeImageAndExtend (\r
c411b485
MK
139 IN UINT32 PCRIndex,\r
140 IN EFI_PHYSICAL_ADDRESS ImageAddress,\r
141 IN UINTN ImageSize,\r
142 OUT TPML_DIGEST_VALUES *DigestList\r
1abfa4ce
JY
143 );\r
144\r
145/**\r
146\r
147 This function dump raw data.\r
148\r
149 @param Data raw data\r
150 @param Size raw data size\r
151\r
152**/\r
153VOID\r
154InternalDumpData (\r
155 IN UINT8 *Data,\r
156 IN UINTN Size\r
157 )\r
158{\r
159 UINTN Index;\r
c411b485 160\r
1abfa4ce 161 for (Index = 0; Index < Size; Index++) {\r
e905fbb0 162 DEBUG ((DEBUG_INFO, "%02x", (UINTN)Data[Index]));\r
1abfa4ce
JY
163 }\r
164}\r
165\r
a2612cf7
ZC
166/**\r
167\r
168 This function initialize TCG_PCR_EVENT2_HDR for EV_NO_ACTION Event Type other than EFI Specification ID event\r
169 The behavior is defined by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types\r
170\r
171 @param[in, out] NoActionEvent Event Header of EV_NO_ACTION Event\r
172 @param[in] EventSize Event Size of the EV_NO_ACTION Event\r
173\r
174**/\r
175VOID\r
176InitNoActionEvent (\r
177 IN OUT TCG_PCR_EVENT2_HDR *NoActionEvent,\r
178 IN UINT32 EventSize\r
c411b485 179 )\r
a2612cf7 180{\r
c411b485
MK
181 UINT32 DigestListCount;\r
182 TPMI_ALG_HASH HashAlgId;\r
183 UINT8 *DigestBuffer;\r
a2612cf7
ZC
184\r
185 DigestBuffer = (UINT8 *)NoActionEvent->Digests.digests;\r
186 DigestListCount = 0;\r
187\r
188 NoActionEvent->PCRIndex = 0;\r
189 NoActionEvent->EventType = EV_NO_ACTION;\r
190\r
191 //\r
192 // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0\r
193 //\r
c411b485 194 ZeroMem (&NoActionEvent->Digests, sizeof (NoActionEvent->Digests));\r
a2612cf7
ZC
195\r
196 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
c411b485
MK
197 HashAlgId = TPM_ALG_SHA1;\r
198 CopyMem (DigestBuffer, &HashAlgId, sizeof (TPMI_ALG_HASH));\r
199 DigestBuffer += sizeof (TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
200 DigestListCount++;\r
a2612cf7
ZC
201 }\r
202\r
203 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
c411b485
MK
204 HashAlgId = TPM_ALG_SHA256;\r
205 CopyMem (DigestBuffer, &HashAlgId, sizeof (TPMI_ALG_HASH));\r
206 DigestBuffer += sizeof (TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
207 DigestListCount++;\r
a2612cf7
ZC
208 }\r
209\r
210 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
211 HashAlgId = TPM_ALG_SHA384;\r
c411b485
MK
212 CopyMem (DigestBuffer, &HashAlgId, sizeof (TPMI_ALG_HASH));\r
213 DigestBuffer += sizeof (TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
a2612cf7
ZC
214 DigestListCount++;\r
215 }\r
216\r
217 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
218 HashAlgId = TPM_ALG_SHA512;\r
c411b485
MK
219 CopyMem (DigestBuffer, &HashAlgId, sizeof (TPMI_ALG_HASH));\r
220 DigestBuffer += sizeof (TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
a2612cf7
ZC
221 DigestListCount++;\r
222 }\r
223\r
224 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
225 HashAlgId = TPM_ALG_SM3_256;\r
c411b485
MK
226 CopyMem (DigestBuffer, &HashAlgId, sizeof (TPMI_ALG_HASH));\r
227 DigestBuffer += sizeof (TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
a2612cf7
ZC
228 DigestListCount++;\r
229 }\r
230\r
231 //\r
232 // Set Digests Count\r
233 //\r
234 WriteUnaligned32 ((UINT32 *)&NoActionEvent->Digests.count, DigestListCount);\r
235\r
236 //\r
237 // Set Event Size\r
238 //\r
c411b485 239 WriteUnaligned32 ((UINT32 *)DigestBuffer, EventSize);\r
a2612cf7
ZC
240}\r
241\r
1abfa4ce
JY
242/**\r
243\r
244 This function dump raw data with colume format.\r
245\r
246 @param Data raw data\r
247 @param Size raw data size\r
248\r
249**/\r
250VOID\r
251InternalDumpHex (\r
252 IN UINT8 *Data,\r
253 IN UINTN Size\r
254 )\r
255{\r
c411b485
MK
256 UINTN Index;\r
257 UINTN Count;\r
258 UINTN Left;\r
1abfa4ce 259\r
c411b485 260 #define COLUME_SIZE (16 * 2)\r
1abfa4ce
JY
261\r
262 Count = Size / COLUME_SIZE;\r
263 Left = Size % COLUME_SIZE;\r
264 for (Index = 0; Index < Count; Index++) {\r
e905fbb0 265 DEBUG ((DEBUG_INFO, "%04x: ", Index * COLUME_SIZE));\r
1abfa4ce 266 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);\r
e905fbb0 267 DEBUG ((DEBUG_INFO, "\n"));\r
1abfa4ce
JY
268 }\r
269\r
270 if (Left != 0) {\r
e905fbb0 271 DEBUG ((DEBUG_INFO, "%04x: ", Index * COLUME_SIZE));\r
1abfa4ce 272 InternalDumpData (Data + Index * COLUME_SIZE, Left);\r
e905fbb0 273 DEBUG ((DEBUG_INFO, "\n"));\r
1abfa4ce
JY
274 }\r
275}\r
276\r
1abfa4ce
JY
277/**\r
278 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function\r
279 Caller is responsible to free LocationBuf.\r
280\r
281 @param[out] LocationBuf Returns Processor Location Buffer.\r
282 @param[out] Num Returns processor number.\r
283\r
284 @retval EFI_SUCCESS Operation completed successfully.\r
285 @retval EFI_UNSUPPORTED MpService protocol not found.\r
286\r
287**/\r
288EFI_STATUS\r
289GetProcessorsCpuLocation (\r
c411b485
MK
290 OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,\r
291 OUT UINTN *Num\r
1abfa4ce
JY
292 )\r
293{\r
c411b485
MK
294 EFI_STATUS Status;\r
295 EFI_MP_SERVICES_PROTOCOL *MpProtocol;\r
296 UINTN ProcessorNum;\r
297 UINTN EnabledProcessorNum;\r
298 EFI_PROCESSOR_INFORMATION ProcessorInfo;\r
299 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
300 UINTN Index;\r
301\r
302 Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpProtocol);\r
1abfa4ce
JY
303 if (EFI_ERROR (Status)) {\r
304 //\r
305 // MP protocol is not installed\r
306 //\r
307 return EFI_UNSUPPORTED;\r
308 }\r
309\r
c411b485 310 Status = MpProtocol->GetNumberOfProcessors (\r
1abfa4ce
JY
311 MpProtocol,\r
312 &ProcessorNum,\r
313 &EnabledProcessorNum\r
314 );\r
c411b485 315 if (EFI_ERROR (Status)) {\r
1abfa4ce
JY
316 return Status;\r
317 }\r
318\r
c411b485 319 Status = gBS->AllocatePool (\r
1abfa4ce 320 EfiBootServicesData,\r
c411b485
MK
321 sizeof (EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
322 (VOID **)&ProcessorLocBuf\r
1abfa4ce 323 );\r
c411b485 324 if (EFI_ERROR (Status)) {\r
1abfa4ce
JY
325 return Status;\r
326 }\r
327\r
328 //\r
329 // Get each processor Location info\r
330 //\r
331 for (Index = 0; Index < ProcessorNum; Index++) {\r
c411b485 332 Status = MpProtocol->GetProcessorInfo (\r
1abfa4ce
JY
333 MpProtocol,\r
334 Index,\r
335 &ProcessorInfo\r
336 );\r
c411b485
MK
337 if (EFI_ERROR (Status)) {\r
338 FreePool (ProcessorLocBuf);\r
1abfa4ce
JY
339 return Status;\r
340 }\r
341\r
342 //\r
343 // Get all Processor Location info & measure\r
344 //\r
c411b485 345 CopyMem (\r
1abfa4ce
JY
346 &ProcessorLocBuf[Index],\r
347 &ProcessorInfo.Location,\r
c411b485 348 sizeof (EFI_CPU_PHYSICAL_LOCATION)\r
1abfa4ce
JY
349 );\r
350 }\r
351\r
352 *LocationBuf = ProcessorLocBuf;\r
c411b485 353 *Num = ProcessorNum;\r
1abfa4ce
JY
354\r
355 return Status;\r
356}\r
357\r
358/**\r
359 The EFI_TCG2_PROTOCOL GetCapability function call provides protocol\r
360 capability information and state information.\r
361\r
362 @param[in] This Indicates the calling context\r
363 @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY\r
364 structure and sets the size field to the size of the structure allocated.\r
365 The callee fills in the fields with the EFI protocol capability information\r
366 and the current EFI TCG2 state information up to the number of fields which\r
367 fit within the size of the structure passed in.\r
368\r
369 @retval EFI_SUCCESS Operation completed successfully.\r
370 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
b3548d32 371 The ProtocolCapability variable will not be populated.\r
1abfa4ce
JY
372 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
373 The ProtocolCapability variable will not be populated.\r
374 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.\r
b3548d32 375 It will be partially populated (required Size field will be set).\r
1abfa4ce
JY
376**/\r
377EFI_STATUS\r
378EFIAPI\r
379Tcg2GetCapability (\r
c411b485
MK
380 IN EFI_TCG2_PROTOCOL *This,\r
381 IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability\r
1abfa4ce
JY
382 )\r
383{\r
336dbfd1 384 DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability ...\n"));\r
1abfa4ce
JY
385\r
386 if ((This == NULL) || (ProtocolCapability == NULL)) {\r
387 return EFI_INVALID_PARAMETER;\r
388 }\r
b3548d32 389\r
336dbfd1 390 DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));\r
c411b485 391 DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0)));\r
1abfa4ce
JY
392\r
393 if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {\r
394 //\r
395 // Handle the case that firmware support 1.1 but OS only support 1.0.\r
396 //\r
b3548d32 397 if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) ||\r
c411b485
MK
398 ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00))))\r
399 {\r
400 if (ProtocolCapability->Size >= sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0)) {\r
401 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0));\r
402 ProtocolCapability->Size = sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0);\r
1abfa4ce
JY
403 ProtocolCapability->StructureVersion.Major = 1;\r
404 ProtocolCapability->StructureVersion.Minor = 0;\r
c411b485
MK
405 ProtocolCapability->ProtocolVersion.Major = 1;\r
406 ProtocolCapability->ProtocolVersion.Minor = 0;\r
e905fbb0 407 DEBUG ((DEBUG_ERROR, "TreeGetCapability (Compatible) - %r\n", EFI_SUCCESS));\r
1abfa4ce
JY
408 return EFI_SUCCESS;\r
409 }\r
410 }\r
c411b485 411\r
1abfa4ce
JY
412 ProtocolCapability->Size = mTcgDxeData.BsCap.Size;\r
413 return EFI_BUFFER_TOO_SMALL;\r
414 }\r
415\r
416 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);\r
336dbfd1 417 DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability - %r\n", EFI_SUCCESS));\r
1abfa4ce
JY
418 return EFI_SUCCESS;\r
419}\r
420\r
421/**\r
422 This function dump PCR event.\r
423\r
424 @param[in] EventHdr TCG PCR event structure.\r
425**/\r
426VOID\r
427DumpEvent (\r
c411b485 428 IN TCG_PCR_EVENT_HDR *EventHdr\r
1abfa4ce
JY
429 )\r
430{\r
c411b485 431 UINTN Index;\r
1abfa4ce 432\r
e905fbb0
MK
433 DEBUG ((DEBUG_INFO, " Event:\n"));\r
434 DEBUG ((DEBUG_INFO, " PCRIndex - %d\n", EventHdr->PCRIndex));\r
435 DEBUG ((DEBUG_INFO, " EventType - 0x%08x\n", EventHdr->EventType));\r
436 DEBUG ((DEBUG_INFO, " Digest - "));\r
c411b485 437 for (Index = 0; Index < sizeof (TCG_DIGEST); Index++) {\r
e905fbb0 438 DEBUG ((DEBUG_INFO, "%02x ", EventHdr->Digest.digest[Index]));\r
1abfa4ce 439 }\r
c411b485 440\r
e905fbb0
MK
441 DEBUG ((DEBUG_INFO, "\n"));\r
442 DEBUG ((DEBUG_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize));\r
1abfa4ce
JY
443 InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);\r
444}\r
445\r
446/**\r
447 This function dump TCG_EfiSpecIDEventStruct.\r
448\r
449 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.\r
450**/\r
451VOID\r
452DumpTcgEfiSpecIdEventStruct (\r
c411b485 453 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct\r
1abfa4ce
JY
454 )\r
455{\r
a9092578 456 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
1abfa4ce 457 UINTN Index;\r
a9092578
QS
458 UINT8 *VendorInfoSize;\r
459 UINT8 *VendorInfo;\r
460 UINT32 NumberOfAlgorithms;\r
1abfa4ce 461\r
e905fbb0
MK
462 DEBUG ((DEBUG_INFO, " TCG_EfiSpecIDEventStruct:\n"));\r
463 DEBUG ((DEBUG_INFO, " signature - '"));\r
c411b485 464 for (Index = 0; Index < sizeof (TcgEfiSpecIdEventStruct->signature); Index++) {\r
e905fbb0 465 DEBUG ((DEBUG_INFO, "%c", TcgEfiSpecIdEventStruct->signature[Index]));\r
1abfa4ce 466 }\r
c411b485 467\r
e905fbb0
MK
468 DEBUG ((DEBUG_INFO, "'\n"));\r
469 DEBUG ((DEBUG_INFO, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct->platformClass));\r
470 DEBUG ((DEBUG_INFO, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct->specVersionMajor, TcgEfiSpecIdEventStruct->specVersionMinor, TcgEfiSpecIdEventStruct->specErrata));\r
471 DEBUG ((DEBUG_INFO, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct->uintnSize));\r
1abfa4ce 472\r
c411b485 473 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof (NumberOfAlgorithms));\r
e905fbb0 474 DEBUG ((DEBUG_INFO, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms));\r
1abfa4ce 475\r
c411b485 476 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof (*TcgEfiSpecIdEventStruct) + sizeof (NumberOfAlgorithms));\r
a9092578 477 for (Index = 0; Index < NumberOfAlgorithms; Index++) {\r
e905fbb0
MK
478 DEBUG ((DEBUG_INFO, " digest(%d)\n", Index));\r
479 DEBUG ((DEBUG_INFO, " algorithmId - 0x%04x\n", DigestSize[Index].algorithmId));\r
480 DEBUG ((DEBUG_INFO, " digestSize - 0x%04x\n", DigestSize[Index].digestSize));\r
1abfa4ce 481 }\r
c411b485 482\r
a9092578 483 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];\r
e905fbb0 484 DEBUG ((DEBUG_INFO, " VendorInfoSize - 0x%02x\n", *VendorInfoSize));\r
a9092578 485 VendorInfo = VendorInfoSize + 1;\r
e905fbb0 486 DEBUG ((DEBUG_INFO, " VendorInfo - "));\r
a9092578 487 for (Index = 0; Index < *VendorInfoSize; Index++) {\r
e905fbb0 488 DEBUG ((DEBUG_INFO, "%02x ", VendorInfo[Index]));\r
1abfa4ce 489 }\r
c411b485 490\r
e905fbb0 491 DEBUG ((DEBUG_INFO, "\n"));\r
1abfa4ce
JY
492}\r
493\r
494/**\r
495 This function get size of TCG_EfiSpecIDEventStruct.\r
496\r
497 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.\r
498**/\r
499UINTN\r
500GetTcgEfiSpecIdEventStructSize (\r
c411b485 501 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct\r
1abfa4ce
JY
502 )\r
503{\r
a9092578
QS
504 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
505 UINT8 *VendorInfoSize;\r
506 UINT32 NumberOfAlgorithms;\r
1abfa4ce 507\r
c411b485 508 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof (NumberOfAlgorithms));\r
1abfa4ce 509\r
c411b485 510 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof (*TcgEfiSpecIdEventStruct) + sizeof (NumberOfAlgorithms));\r
a9092578 511 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];\r
c411b485 512 return sizeof (TCG_EfiSpecIDEventStruct) + sizeof (UINT32) + (NumberOfAlgorithms * sizeof (TCG_EfiSpecIdEventAlgorithmSize)) + sizeof (UINT8) + (*VendorInfoSize);\r
1abfa4ce
JY
513}\r
514\r
515/**\r
516 This function dump PCR event 2.\r
517\r
518 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.\r
519**/\r
520VOID\r
521DumpEvent2 (\r
c411b485 522 IN TCG_PCR_EVENT2 *TcgPcrEvent2\r
1abfa4ce
JY
523 )\r
524{\r
c411b485
MK
525 UINTN Index;\r
526 UINT32 DigestIndex;\r
527 UINT32 DigestCount;\r
528 TPMI_ALG_HASH HashAlgo;\r
529 UINT32 DigestSize;\r
530 UINT8 *DigestBuffer;\r
531 UINT32 EventSize;\r
532 UINT8 *EventBuffer;\r
1abfa4ce 533\r
e905fbb0
MK
534 DEBUG ((DEBUG_INFO, " Event:\n"));\r
535 DEBUG ((DEBUG_INFO, " PCRIndex - %d\n", TcgPcrEvent2->PCRIndex));\r
536 DEBUG ((DEBUG_INFO, " EventType - 0x%08x\n", TcgPcrEvent2->EventType));\r
1abfa4ce 537\r
e905fbb0 538 DEBUG ((DEBUG_INFO, " DigestCount: 0x%08x\n", TcgPcrEvent2->Digest.count));\r
1abfa4ce 539\r
c411b485
MK
540 DigestCount = TcgPcrEvent2->Digest.count;\r
541 HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;\r
1abfa4ce
JY
542 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;\r
543 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {\r
e905fbb0
MK
544 DEBUG ((DEBUG_INFO, " HashAlgo : 0x%04x\n", HashAlgo));\r
545 DEBUG ((DEBUG_INFO, " Digest(%d): ", DigestIndex));\r
1abfa4ce
JY
546 DigestSize = GetHashSizeFromAlgo (HashAlgo);\r
547 for (Index = 0; Index < DigestSize; Index++) {\r
e905fbb0 548 DEBUG ((DEBUG_INFO, "%02x ", DigestBuffer[Index]));\r
1abfa4ce 549 }\r
c411b485 550\r
e905fbb0 551 DEBUG ((DEBUG_INFO, "\n"));\r
1abfa4ce
JY
552 //\r
553 // Prepare next\r
554 //\r
c411b485
MK
555 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof (TPMI_ALG_HASH));\r
556 DigestBuffer = DigestBuffer + DigestSize + sizeof (TPMI_ALG_HASH);\r
1abfa4ce 557 }\r
c411b485 558\r
e905fbb0 559 DEBUG ((DEBUG_INFO, "\n"));\r
c411b485 560 DigestBuffer = DigestBuffer - sizeof (TPMI_ALG_HASH);\r
1abfa4ce 561\r
c411b485 562 CopyMem (&EventSize, DigestBuffer, sizeof (TcgPcrEvent2->EventSize));\r
e905fbb0 563 DEBUG ((DEBUG_INFO, " EventSize - 0x%08x\n", EventSize));\r
c411b485 564 EventBuffer = DigestBuffer + sizeof (TcgPcrEvent2->EventSize);\r
1abfa4ce
JY
565 InternalDumpHex (EventBuffer, EventSize);\r
566}\r
567\r
568/**\r
569 This function returns size of TCG PCR event 2.\r
b3548d32 570\r
1abfa4ce
JY
571 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.\r
572\r
573 @return size of TCG PCR event 2.\r
574**/\r
575UINTN\r
576GetPcrEvent2Size (\r
c411b485 577 IN TCG_PCR_EVENT2 *TcgPcrEvent2\r
1abfa4ce
JY
578 )\r
579{\r
c411b485
MK
580 UINT32 DigestIndex;\r
581 UINT32 DigestCount;\r
582 TPMI_ALG_HASH HashAlgo;\r
583 UINT32 DigestSize;\r
584 UINT8 *DigestBuffer;\r
585 UINT32 EventSize;\r
586 UINT8 *EventBuffer;\r
587\r
588 DigestCount = TcgPcrEvent2->Digest.count;\r
589 HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;\r
1abfa4ce
JY
590 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;\r
591 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {\r
592 DigestSize = GetHashSizeFromAlgo (HashAlgo);\r
593 //\r
594 // Prepare next\r
595 //\r
c411b485
MK
596 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof (TPMI_ALG_HASH));\r
597 DigestBuffer = DigestBuffer + DigestSize + sizeof (TPMI_ALG_HASH);\r
1abfa4ce 598 }\r
1abfa4ce 599\r
c411b485
MK
600 DigestBuffer = DigestBuffer - sizeof (TPMI_ALG_HASH);\r
601\r
602 CopyMem (&EventSize, DigestBuffer, sizeof (TcgPcrEvent2->EventSize));\r
603 EventBuffer = DigestBuffer + sizeof (TcgPcrEvent2->EventSize);\r
1abfa4ce
JY
604\r
605 return (UINTN)EventBuffer + EventSize - (UINTN)TcgPcrEvent2;\r
606}\r
607\r
608/**\r
609 This function dump event log.\r
610\r
611 @param[in] EventLogFormat The type of the event log for which the information is requested.\r
612 @param[in] EventLogLocation A pointer to the memory address of the event log.\r
613 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the\r
614 address of the start of the last entry in the event log in memory.\r
615 @param[in] FinalEventsTable A pointer to the memory address of the final event table.\r
616**/\r
617VOID\r
618DumpEventLog (\r
c411b485
MK
619 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,\r
620 IN EFI_PHYSICAL_ADDRESS EventLogLocation,\r
621 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry,\r
622 IN EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable\r
1abfa4ce
JY
623 )\r
624{\r
625 TCG_PCR_EVENT_HDR *EventHdr;\r
626 TCG_PCR_EVENT2 *TcgPcrEvent2;\r
627 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;\r
628 UINTN NumberOfEvents;\r
629\r
e905fbb0 630 DEBUG ((DEBUG_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));\r
b3548d32 631\r
1abfa4ce 632 switch (EventLogFormat) {\r
c411b485
MK
633 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
634 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
635 while ((UINTN)EventHdr <= EventLogLastEntry) {\r
1abfa4ce 636 DumpEvent (EventHdr);\r
c411b485 637 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof (TCG_PCR_EVENT_HDR) + EventHdr->EventSize);\r
1abfa4ce 638 }\r
1abfa4ce 639\r
c411b485
MK
640 if (FinalEventsTable == NULL) {\r
641 DEBUG ((DEBUG_INFO, "FinalEventsTable: NOT FOUND\n"));\r
642 } else {\r
643 DEBUG ((DEBUG_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));\r
644 DEBUG ((DEBUG_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));\r
645 DEBUG ((DEBUG_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));\r
646\r
647 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)(FinalEventsTable + 1);\r
648 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {\r
649 DumpEvent (EventHdr);\r
650 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof (TCG_PCR_EVENT_HDR) + EventHdr->EventSize);\r
651 }\r
652 }\r
1abfa4ce 653\r
c411b485
MK
654 break;\r
655 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
656 //\r
657 // Dump first event\r
658 //\r
659 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
660 DumpEvent (EventHdr);\r
1abfa4ce 661\r
c411b485
MK
662 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)(EventHdr + 1);\r
663 DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct);\r
1abfa4ce 664\r
c411b485
MK
665 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgEfiSpecIdEventStruct + GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct));\r
666 while ((UINTN)TcgPcrEvent2 <= EventLogLastEntry) {\r
1abfa4ce
JY
667 DumpEvent2 (TcgPcrEvent2);\r
668 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));\r
669 }\r
c411b485
MK
670\r
671 if (FinalEventsTable == NULL) {\r
672 DEBUG ((DEBUG_INFO, "FinalEventsTable: NOT FOUND\n"));\r
673 } else {\r
674 DEBUG ((DEBUG_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));\r
675 DEBUG ((DEBUG_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));\r
676 DEBUG ((DEBUG_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));\r
677\r
678 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)(UINTN)(FinalEventsTable + 1);\r
679 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {\r
680 DumpEvent2 (TcgPcrEvent2);\r
681 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));\r
682 }\r
683 }\r
684\r
685 break;\r
1abfa4ce
JY
686 }\r
687\r
c411b485 688 return;\r
1abfa4ce
JY
689}\r
690\r
691/**\r
692 The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to\r
b3548d32 693 retrieve the address of a given event log and its last entry.\r
1abfa4ce
JY
694\r
695 @param[in] This Indicates the calling context\r
696 @param[in] EventLogFormat The type of the event log for which the information is requested.\r
697 @param[out] EventLogLocation A pointer to the memory address of the event log.\r
698 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the\r
699 address of the start of the last entry in the event log in memory.\r
700 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would\r
701 have exceeded the area allocated for events, this value is set to TRUE.\r
702 Otherwise, the value will be FALSE and the Event Log will be complete.\r
703\r
704 @retval EFI_SUCCESS Operation completed successfully.\r
705 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect\r
706 (e.g. asking for an event log whose format is not supported).\r
707**/\r
708EFI_STATUS\r
709EFIAPI\r
710Tcg2GetEventLog (\r
c411b485
MK
711 IN EFI_TCG2_PROTOCOL *This,\r
712 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,\r
713 OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,\r
714 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,\r
715 OUT BOOLEAN *EventLogTruncated\r
1abfa4ce
JY
716 )\r
717{\r
718 UINTN Index;\r
719\r
e905fbb0 720 DEBUG ((DEBUG_INFO, "Tcg2GetEventLog ... (0x%x)\n", EventLogFormat));\r
1abfa4ce
JY
721\r
722 if (This == NULL) {\r
723 return EFI_INVALID_PARAMETER;\r
724 }\r
725\r
c411b485 726 for (Index = 0; Index < sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0]); Index++) {\r
1abfa4ce
JY
727 if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
728 break;\r
729 }\r
730 }\r
731\r
c411b485 732 if (Index == sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0])) {\r
1abfa4ce
JY
733 return EFI_INVALID_PARAMETER;\r
734 }\r
735\r
736 if ((mTcg2EventInfo[Index].LogFormat & mTcgDxeData.BsCap.SupportedEventLogs) == 0) {\r
737 return EFI_INVALID_PARAMETER;\r
738 }\r
739\r
740 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
741 if (EventLogLocation != NULL) {\r
742 *EventLogLocation = 0;\r
743 }\r
c411b485 744\r
1abfa4ce
JY
745 if (EventLogLastEntry != NULL) {\r
746 *EventLogLastEntry = 0;\r
747 }\r
c411b485 748\r
1abfa4ce
JY
749 if (EventLogTruncated != NULL) {\r
750 *EventLogTruncated = FALSE;\r
751 }\r
c411b485 752\r
1abfa4ce
JY
753 return EFI_SUCCESS;\r
754 }\r
755\r
756 if (EventLogLocation != NULL) {\r
757 *EventLogLocation = mTcgDxeData.EventLogAreaStruct[Index].Lasa;\r
e905fbb0 758 DEBUG ((DEBUG_INFO, "Tcg2GetEventLog (EventLogLocation - %x)\n", *EventLogLocation));\r
1abfa4ce
JY
759 }\r
760\r
761 if (EventLogLastEntry != NULL) {\r
762 if (!mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted) {\r
763 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;\r
764 } else {\r
765 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].LastEvent;\r
766 }\r
c411b485 767\r
e905fbb0 768 DEBUG ((DEBUG_INFO, "Tcg2GetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));\r
1abfa4ce
JY
769 }\r
770\r
771 if (EventLogTruncated != NULL) {\r
772 *EventLogTruncated = mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated;\r
e905fbb0 773 DEBUG ((DEBUG_INFO, "Tcg2GetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));\r
1abfa4ce
JY
774 }\r
775\r
e905fbb0 776 DEBUG ((DEBUG_INFO, "Tcg2GetEventLog - %r\n", EFI_SUCCESS));\r
1abfa4ce
JY
777\r
778 // Dump Event Log for debug purpose\r
779 if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {\r
780 DumpEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry, mTcgDxeData.FinalEventsTable[Index]);\r
781 }\r
782\r
783 //\r
784 // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored\r
785 // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.\r
786 //\r
787 mTcgDxeData.GetEventLogCalled[Index] = TRUE;\r
788\r
789 return EFI_SUCCESS;\r
790}\r
791\r
f9713abe 792/**\r
4fa25853
JY
793 Return if this is a Tcg800155PlatformIdEvent.\r
794\r
795 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
796 @param[in] NewEventHdrSize New event header size.\r
797 @param[in] NewEventData Pointer to the new event data.\r
798 @param[in] NewEventSize New event data size.\r
799\r
800 @retval TRUE This is a Tcg800155PlatformIdEvent.\r
801 @retval FALSE This is NOT a Tcg800155PlatformIdEvent.\r
802\r
f9713abe 803**/\r
4fa25853
JY
804BOOLEAN\r
805Is800155Event (\r
c411b485
MK
806 IN VOID *NewEventHdr,\r
807 IN UINT32 NewEventHdrSize,\r
808 IN UINT8 *NewEventData,\r
809 IN UINT32 NewEventSize\r
4fa25853
JY
810 )\r
811{\r
812 if ((((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType == EV_NO_ACTION) &&\r
c411b485
MK
813 (NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event2)) &&\r
814 (CompareMem (\r
815 NewEventData,\r
816 TCG_Sp800_155_PlatformId_Event2_SIGNATURE,\r
817 sizeof (TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1\r
818 ) == 0))\r
819 {\r
4fa25853
JY
820 return TRUE;\r
821 }\r
c411b485 822\r
4fa25853
JY
823 return FALSE;\r
824}\r
825\r
1abfa4ce
JY
826/**\r
827 Add a new entry to the Event Log.\r
828\r
4fa25853
JY
829 @param[in, out] EventLogAreaStruct The event log area data structure\r
830 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
831 @param[in] NewEventHdrSize New event header size.\r
832 @param[in] NewEventData Pointer to the new event data.\r
833 @param[in] NewEventSize New event data size.\r
b3548d32 834\r
1abfa4ce
JY
835 @retval EFI_SUCCESS The new event log entry was added.\r
836 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
837\r
838**/\r
839EFI_STATUS\r
840TcgCommLogEvent (\r
c411b485
MK
841 IN OUT TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct,\r
842 IN VOID *NewEventHdr,\r
843 IN UINT32 NewEventHdrSize,\r
844 IN UINT8 *NewEventData,\r
845 IN UINT32 NewEventSize\r
1abfa4ce
JY
846 )\r
847{\r
c411b485
MK
848 UINTN NewLogSize;\r
849 BOOLEAN Record800155Event;\r
1abfa4ce
JY
850\r
851 if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {\r
852 return EFI_OUT_OF_RESOURCES;\r
853 }\r
854\r
855 NewLogSize = NewEventHdrSize + NewEventSize;\r
856\r
4fa25853 857 if (NewLogSize > MAX_ADDRESS - EventLogAreaStruct->EventLogSize) {\r
1abfa4ce
JY
858 return EFI_OUT_OF_RESOURCES;\r
859 }\r
860\r
4fa25853
JY
861 if (NewLogSize + EventLogAreaStruct->EventLogSize > EventLogAreaStruct->Laml) {\r
862 DEBUG ((DEBUG_INFO, " Laml - 0x%x\n", EventLogAreaStruct->Laml));\r
863 DEBUG ((DEBUG_INFO, " NewLogSize - 0x%x\n", NewLogSize));\r
864 DEBUG ((DEBUG_INFO, " LogSize - 0x%x\n", EventLogAreaStruct->EventLogSize));\r
865 DEBUG ((DEBUG_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));\r
1abfa4ce
JY
866 return EFI_OUT_OF_RESOURCES;\r
867 }\r
868\r
4fa25853
JY
869 //\r
870 // Check 800-155 event\r
871 // Record to 800-155 event offset only.\r
872 // If the offset is 0, no need to record.\r
873 //\r
874 Record800155Event = Is800155Event (NewEventHdr, NewEventHdrSize, NewEventData, NewEventSize);\r
875 if (Record800155Event) {\r
876 if (EventLogAreaStruct->Next800155EventOffset != 0) {\r
877 CopyMem (\r
878 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewLogSize,\r
879 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,\r
880 EventLogAreaStruct->EventLogSize - EventLogAreaStruct->Next800155EventOffset\r
881 );\r
882\r
883 CopyMem (\r
884 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,\r
885 NewEventHdr,\r
886 NewEventHdrSize\r
887 );\r
888 CopyMem (\r
889 (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewEventHdrSize,\r
890 NewEventData,\r
891 NewEventSize\r
892 );\r
893\r
894 EventLogAreaStruct->Next800155EventOffset += NewLogSize;\r
c411b485
MK
895 EventLogAreaStruct->LastEvent += NewLogSize;\r
896 EventLogAreaStruct->EventLogSize += NewLogSize;\r
4fa25853 897 }\r
c411b485 898\r
4fa25853
JY
899 return EFI_SUCCESS;\r
900 }\r
901\r
c411b485 902 EventLogAreaStruct->LastEvent = (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->EventLogSize;\r
4fa25853
JY
903 EventLogAreaStruct->EventLogSize += NewLogSize;\r
904 CopyMem (EventLogAreaStruct->LastEvent, NewEventHdr, NewEventHdrSize);\r
1abfa4ce 905 CopyMem (\r
4fa25853 906 EventLogAreaStruct->LastEvent + NewEventHdrSize,\r
1abfa4ce
JY
907 NewEventData,\r
908 NewEventSize\r
909 );\r
910 return EFI_SUCCESS;\r
911}\r
912\r
913/**\r
914 Add a new entry to the Event Log.\r
915\r
916 @param[in] EventLogFormat The type of the event log for which the information is requested.\r
b3548d32 917 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
1abfa4ce 918 @param[in] NewEventHdrSize New event header size.\r
b3548d32 919 @param[in] NewEventData Pointer to the new event data.\r
1abfa4ce
JY
920 @param[in] NewEventSize New event data size.\r
921\r
922 @retval EFI_SUCCESS The new event log entry was added.\r
923 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
924\r
925**/\r
926EFI_STATUS\r
927TcgDxeLogEvent (\r
c411b485
MK
928 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,\r
929 IN VOID *NewEventHdr,\r
930 IN UINT32 NewEventHdrSize,\r
931 IN UINT8 *NewEventData,\r
932 IN UINT32 NewEventSize\r
1abfa4ce
JY
933 )\r
934{\r
c411b485
MK
935 EFI_STATUS Status;\r
936 UINTN Index;\r
937 TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;\r
b3548d32 938\r
c411b485 939 for (Index = 0; Index < sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0]); Index++) {\r
1abfa4ce
JY
940 if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
941 break;\r
942 }\r
943 }\r
944\r
c411b485 945 if (Index == sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0])) {\r
1abfa4ce
JY
946 return EFI_INVALID_PARAMETER;\r
947 }\r
948\r
fd46e831
JY
949 //\r
950 // Record to normal event log\r
951 //\r
952 EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];\r
1abfa4ce
JY
953\r
954 if (EventLogAreaStruct->EventLogTruncated) {\r
955 return EFI_VOLUME_FULL;\r
956 }\r
957\r
1abfa4ce 958 Status = TcgCommLogEvent (\r
4fa25853 959 EventLogAreaStruct,\r
1abfa4ce
JY
960 NewEventHdr,\r
961 NewEventHdrSize,\r
962 NewEventData,\r
963 NewEventSize\r
964 );\r
b3548d32 965\r
fd46e831 966 if (Status == EFI_OUT_OF_RESOURCES) {\r
1abfa4ce
JY
967 EventLogAreaStruct->EventLogTruncated = TRUE;\r
968 return EFI_VOLUME_FULL;\r
969 } else if (Status == EFI_SUCCESS) {\r
970 EventLogAreaStruct->EventLogStarted = TRUE;\r
fd46e831
JY
971 }\r
972\r
973 //\r
974 // If GetEventLog is called, record to FinalEventsTable, too.\r
975 //\r
976 if (mTcgDxeData.GetEventLogCalled[Index]) {\r
977 if (mTcgDxeData.FinalEventsTable[Index] == NULL) {\r
978 //\r
979 // no need for FinalEventsTable\r
980 //\r
981 return EFI_SUCCESS;\r
982 }\r
c411b485 983\r
fd46e831
JY
984 EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];\r
985\r
986 if (EventLogAreaStruct->EventLogTruncated) {\r
987 return EFI_VOLUME_FULL;\r
988 }\r
989\r
fd46e831 990 Status = TcgCommLogEvent (\r
4fa25853 991 EventLogAreaStruct,\r
fd46e831
JY
992 NewEventHdr,\r
993 NewEventHdrSize,\r
994 NewEventData,\r
995 NewEventSize\r
996 );\r
997 if (Status == EFI_OUT_OF_RESOURCES) {\r
998 EventLogAreaStruct->EventLogTruncated = TRUE;\r
999 return EFI_VOLUME_FULL;\r
1000 } else if (Status == EFI_SUCCESS) {\r
1001 EventLogAreaStruct->EventLogStarted = TRUE;\r
1002 //\r
1003 // Increase the NumberOfEvents in FinalEventsTable\r
1004 //\r
c411b485 1005 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents++;\r
e905fbb0
MK
1006 DEBUG ((DEBUG_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));\r
1007 DEBUG ((DEBUG_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));\r
1abfa4ce
JY
1008 }\r
1009 }\r
1010\r
1011 return Status;\r
1012}\r
1013\r
1abfa4ce
JY
1014/**\r
1015 Get TPML_DIGEST_VALUES compact binary buffer size.\r
1016\r
1017 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.\r
1018\r
1019 @return TPML_DIGEST_VALUES compact binary buffer size.\r
1020**/\r
1021UINT32\r
1022GetDigestListBinSize (\r
c411b485 1023 IN VOID *DigestListBin\r
1abfa4ce
JY
1024 )\r
1025{\r
c411b485
MK
1026 UINTN Index;\r
1027 UINT16 DigestSize;\r
1028 UINT32 TotalSize;\r
1029 UINT32 Count;\r
1030 TPMI_ALG_HASH HashAlg;\r
1031\r
1032 Count = ReadUnaligned32 (DigestListBin);\r
1033 TotalSize = sizeof (Count);\r
1034 DigestListBin = (UINT8 *)DigestListBin + sizeof (Count);\r
1abfa4ce 1035 for (Index = 0; Index < Count; Index++) {\r
c411b485
MK
1036 HashAlg = ReadUnaligned16 (DigestListBin);\r
1037 TotalSize += sizeof (HashAlg);\r
1038 DigestListBin = (UINT8 *)DigestListBin + sizeof (HashAlg);\r
1abfa4ce 1039\r
c411b485
MK
1040 DigestSize = GetHashSizeFromAlgo (HashAlg);\r
1041 TotalSize += DigestSize;\r
1abfa4ce
JY
1042 DigestListBin = (UINT8 *)DigestListBin + DigestSize;\r
1043 }\r
1044\r
1045 return TotalSize;\r
1046}\r
1047\r
ab5b1f31
SZ
1048/**\r
1049 Copy TPML_DIGEST_VALUES compact binary into a buffer\r
1050\r
1051 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.\r
1052 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.\r
1053 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.\r
1054 @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.\r
1055\r
1056 @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.\r
1057**/\r
1058VOID *\r
1059CopyDigestListBinToBuffer (\r
c411b485
MK
1060 IN OUT VOID *Buffer,\r
1061 IN VOID *DigestListBin,\r
1062 IN UINT32 HashAlgorithmMask,\r
1063 OUT UINT32 *HashAlgorithmMaskCopied\r
ab5b1f31
SZ
1064 )\r
1065{\r
c411b485
MK
1066 UINTN Index;\r
1067 UINT16 DigestSize;\r
1068 UINT32 Count;\r
1069 TPMI_ALG_HASH HashAlg;\r
1070 UINT32 DigestListCount;\r
1071 UINT32 *DigestListCountPtr;\r
1072\r
1073 DigestListCountPtr = (UINT32 *)Buffer;\r
1074 DigestListCount = 0;\r
ab5b1f31
SZ
1075 (*HashAlgorithmMaskCopied) = 0;\r
1076\r
c411b485
MK
1077 Count = ReadUnaligned32 (DigestListBin);\r
1078 Buffer = (UINT8 *)Buffer + sizeof (Count);\r
1079 DigestListBin = (UINT8 *)DigestListBin + sizeof (Count);\r
ab5b1f31 1080 for (Index = 0; Index < Count; Index++) {\r
c411b485
MK
1081 HashAlg = ReadUnaligned16 (DigestListBin);\r
1082 DigestListBin = (UINT8 *)DigestListBin + sizeof (HashAlg);\r
1083 DigestSize = GetHashSizeFromAlgo (HashAlg);\r
ab5b1f31 1084\r
c411b485
MK
1085 if (IsHashAlgSupportedInHashAlgorithmMask (HashAlg, HashAlgorithmMask)) {\r
1086 CopyMem (Buffer, &HashAlg, sizeof (HashAlg));\r
1087 Buffer = (UINT8 *)Buffer + sizeof (HashAlg);\r
ab5b1f31
SZ
1088 CopyMem (Buffer, DigestListBin, DigestSize);\r
1089 Buffer = (UINT8 *)Buffer + DigestSize;\r
1090 DigestListCount++;\r
1091 (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);\r
1092 } else {\r
1093 DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));\r
1094 }\r
c411b485 1095\r
ab5b1f31
SZ
1096 DigestListBin = (UINT8 *)DigestListBin + DigestSize;\r
1097 }\r
c411b485 1098\r
ab5b1f31
SZ
1099 WriteUnaligned32 (DigestListCountPtr, DigestListCount);\r
1100\r
1101 return Buffer;\r
1102}\r
1103\r
1abfa4ce
JY
1104/**\r
1105 Add a new entry to the Event Log.\r
1106\r
1107 @param[in] DigestList A list of digest.\r
1108 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
1109 @param[in] NewEventData Pointer to the new event data.\r
1110\r
1111 @retval EFI_SUCCESS The new event log entry was added.\r
1112 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
1113**/\r
1114EFI_STATUS\r
1115TcgDxeLogHashEvent (\r
c411b485
MK
1116 IN TPML_DIGEST_VALUES *DigestList,\r
1117 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
1118 IN UINT8 *NewEventData\r
1abfa4ce
JY
1119 )\r
1120{\r
c411b485
MK
1121 EFI_STATUS Status;\r
1122 EFI_TPL OldTpl;\r
1123 UINTN Index;\r
1124 EFI_STATUS RetStatus;\r
1125 TCG_PCR_EVENT2 TcgPcrEvent2;\r
1126 UINT8 *DigestBuffer;\r
1127 UINT32 *EventSizePtr;\r
1abfa4ce 1128\r
e905fbb0 1129 DEBUG ((DEBUG_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
1abfa4ce
JY
1130\r
1131 RetStatus = EFI_SUCCESS;\r
c411b485 1132 for (Index = 0; Index < sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0]); Index++) {\r
1abfa4ce 1133 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
e905fbb0 1134 DEBUG ((DEBUG_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));\r
1abfa4ce 1135 switch (mTcg2EventInfo[Index].LogFormat) {\r
c411b485
MK
1136 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
1137 Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
1138 if (!EFI_ERROR (Status)) {\r
1139 //\r
1140 // Enter critical region\r
1141 //\r
1142 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
1143 Status = TcgDxeLogEvent (\r
1144 mTcg2EventInfo[Index].LogFormat,\r
1145 NewEventHdr,\r
1146 sizeof (TCG_PCR_EVENT_HDR),\r
1147 NewEventData,\r
1148 NewEventHdr->EventSize\r
1149 );\r
1150 if (Status != EFI_SUCCESS) {\r
1151 RetStatus = Status;\r
1152 }\r
1153\r
1154 gBS->RestoreTPL (OldTpl);\r
1155 //\r
1156 // Exit critical region\r
1157 //\r
1158 }\r
1159\r
1160 break;\r
1161 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
1162 ZeroMem (&TcgPcrEvent2, sizeof (TcgPcrEvent2));\r
1163 TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;\r
1164 TcgPcrEvent2.EventType = NewEventHdr->EventType;\r
1165 DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;\r
1166 EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, mTcgDxeData.BsCap.ActivePcrBanks);\r
1167 CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof (NewEventHdr->EventSize));\r
1168\r
1abfa4ce
JY
1169 //\r
1170 // Enter critical region\r
1171 //\r
1172 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
1173 Status = TcgDxeLogEvent (\r
1174 mTcg2EventInfo[Index].LogFormat,\r
c411b485
MK
1175 &TcgPcrEvent2,\r
1176 sizeof (TcgPcrEvent2.PCRIndex) + sizeof (TcgPcrEvent2.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof (TcgPcrEvent2.EventSize),\r
1abfa4ce
JY
1177 NewEventData,\r
1178 NewEventHdr->EventSize\r
1179 );\r
1180 if (Status != EFI_SUCCESS) {\r
1181 RetStatus = Status;\r
1182 }\r
c411b485 1183\r
1abfa4ce
JY
1184 gBS->RestoreTPL (OldTpl);\r
1185 //\r
1186 // Exit critical region\r
1187 //\r
c411b485 1188 break;\r
1abfa4ce
JY
1189 }\r
1190 }\r
1191 }\r
1192\r
1193 return RetStatus;\r
1194}\r
1195\r
1196/**\r
1197 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
1198 and add an entry to the Event Log.\r
1199\r
1200 @param[in] Flags Bitmap providing additional information.\r
b3548d32 1201 @param[in] HashData Physical address of the start of the data buffer\r
1abfa4ce
JY
1202 to be hashed, extended, and logged.\r
1203 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
b3548d32
LG
1204 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
1205 @param[in] NewEventData Pointer to the new event data.\r
1abfa4ce
JY
1206\r
1207 @retval EFI_SUCCESS Operation completed successfully.\r
1208 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
1209 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
1210\r
1211**/\r
1212EFI_STATUS\r
1213TcgDxeHashLogExtendEvent (\r
c411b485
MK
1214 IN UINT64 Flags,\r
1215 IN UINT8 *HashData,\r
1216 IN UINT64 HashDataLen,\r
1217 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
1218 IN UINT8 *NewEventData\r
1abfa4ce
JY
1219 )\r
1220{\r
c411b485
MK
1221 EFI_STATUS Status;\r
1222 TPML_DIGEST_VALUES DigestList;\r
1223 TCG_PCR_EVENT2_HDR NoActionEvent;\r
1abfa4ce
JY
1224\r
1225 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1226 return EFI_DEVICE_ERROR;\r
1227 }\r
1228\r
4fa25853
JY
1229 if (NewEventHdr->EventType == EV_NO_ACTION) {\r
1230 //\r
1231 // Do not do TPM extend for EV_NO_ACTION\r
1232 //\r
1233 Status = EFI_SUCCESS;\r
1234 InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);\r
1235 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
1236 Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);\r
1237 }\r
1238\r
1239 return Status;\r
1240 }\r
1241\r
1abfa4ce
JY
1242 Status = HashAndExtend (\r
1243 NewEventHdr->PCRIndex,\r
1244 HashData,\r
1245 (UINTN)HashDataLen,\r
1246 &DigestList\r
1247 );\r
1248 if (!EFI_ERROR (Status)) {\r
1249 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
1250 Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
1251 }\r
1252 }\r
1253\r
1254 if (Status == EFI_DEVICE_ERROR) {\r
e905fbb0 1255 DEBUG ((DEBUG_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));\r
1abfa4ce
JY
1256 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
1257 REPORT_STATUS_CODE (\r
1258 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
1259 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
1260 );\r
1261 }\r
1262\r
1263 return Status;\r
1264}\r
1265\r
1266/**\r
1267 The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with\r
1268 an opportunity to extend and optionally log events without requiring\r
b3548d32 1269 knowledge of actual TPM commands.\r
1abfa4ce 1270 The extend operation will occur even if this function cannot create an event\r
b3548d32 1271 log entry (e.g. due to the event log being full).\r
1abfa4ce
JY
1272\r
1273 @param[in] This Indicates the calling context\r
1274 @param[in] Flags Bitmap providing additional information.\r
b3548d32 1275 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.\r
1abfa4ce
JY
1276 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.\r
1277 @param[in] Event Pointer to data buffer containing information about the event.\r
1278\r
1279 @retval EFI_SUCCESS Operation completed successfully.\r
1280 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
1281 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.\r
1282 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1283 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.\r
1284**/\r
1285EFI_STATUS\r
1286EFIAPI\r
1287Tcg2HashLogExtendEvent (\r
c411b485
MK
1288 IN EFI_TCG2_PROTOCOL *This,\r
1289 IN UINT64 Flags,\r
1290 IN EFI_PHYSICAL_ADDRESS DataToHash,\r
1291 IN UINT64 DataToHashLen,\r
1292 IN EFI_TCG2_EVENT *Event\r
1abfa4ce
JY
1293 )\r
1294{\r
c411b485
MK
1295 EFI_STATUS Status;\r
1296 TCG_PCR_EVENT_HDR NewEventHdr;\r
1297 TPML_DIGEST_VALUES DigestList;\r
1abfa4ce 1298\r
336dbfd1 1299 DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));\r
1abfa4ce 1300\r
4fa25853
JY
1301 if ((This == NULL) || (Event == NULL)) {\r
1302 return EFI_INVALID_PARAMETER;\r
1303 }\r
c411b485 1304\r
4fa25853
JY
1305 //\r
1306 // Do not check hash data size for EV_NO_ACTION event.\r
1307 //\r
1308 if ((Event->Header.EventType != EV_NO_ACTION) && (DataToHash == 0)) {\r
1abfa4ce
JY
1309 return EFI_INVALID_PARAMETER;\r
1310 }\r
1311\r
1312 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1313 return EFI_DEVICE_ERROR;\r
1314 }\r
1315\r
c411b485 1316 if (Event->Size < Event->Header.HeaderSize + sizeof (UINT32)) {\r
1abfa4ce
JY
1317 return EFI_INVALID_PARAMETER;\r
1318 }\r
1319\r
1320 if (Event->Header.PCRIndex > MAX_PCR_INDEX) {\r
1321 return EFI_INVALID_PARAMETER;\r
1322 }\r
1323\r
1324 NewEventHdr.PCRIndex = Event->Header.PCRIndex;\r
1325 NewEventHdr.EventType = Event->Header.EventType;\r
c411b485 1326 NewEventHdr.EventSize = Event->Size - sizeof (UINT32) - Event->Header.HeaderSize;\r
1abfa4ce
JY
1327 if ((Flags & PE_COFF_IMAGE) != 0) {\r
1328 Status = MeasurePeImageAndExtend (\r
1329 NewEventHdr.PCRIndex,\r
1330 DataToHash,\r
1331 (UINTN)DataToHashLen,\r
1332 &DigestList\r
1333 );\r
1334 if (!EFI_ERROR (Status)) {\r
1335 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
1336 Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);\r
1337 }\r
1338 }\r
c411b485 1339\r
1abfa4ce 1340 if (Status == EFI_DEVICE_ERROR) {\r
e905fbb0 1341 DEBUG ((DEBUG_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));\r
1abfa4ce
JY
1342 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
1343 REPORT_STATUS_CODE (\r
1344 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
1345 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
1346 );\r
1347 }\r
1348 } else {\r
1349 Status = TcgDxeHashLogExtendEvent (\r
1350 Flags,\r
c411b485 1351 (UINT8 *)(UINTN)DataToHash,\r
1abfa4ce
JY
1352 DataToHashLen,\r
1353 &NewEventHdr,\r
1354 Event->Event\r
1355 );\r
1356 }\r
c411b485 1357\r
336dbfd1 1358 DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent - %r\n", Status));\r
1abfa4ce
JY
1359 return Status;\r
1360}\r
1361\r
1362/**\r
1363 This service enables the sending of commands to the TPM.\r
1364\r
1365 @param[in] This Indicates the calling context\r
1366 @param[in] InputParameterBlockSize Size of the TPM input parameter block.\r
1367 @param[in] InputParameterBlock Pointer to the TPM input parameter block.\r
1368 @param[in] OutputParameterBlockSize Size of the TPM output parameter block.\r
1369 @param[in] OutputParameterBlock Pointer to the TPM output parameter block.\r
1370\r
1371 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.\r
1372 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.\r
1373 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
b3548d32 1374 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.\r
1abfa4ce
JY
1375**/\r
1376EFI_STATUS\r
1377EFIAPI\r
1378Tcg2SubmitCommand (\r
c411b485
MK
1379 IN EFI_TCG2_PROTOCOL *This,\r
1380 IN UINT32 InputParameterBlockSize,\r
1381 IN UINT8 *InputParameterBlock,\r
1382 IN UINT32 OutputParameterBlockSize,\r
1383 IN UINT8 *OutputParameterBlock\r
1abfa4ce
JY
1384 )\r
1385{\r
c411b485 1386 EFI_STATUS Status;\r
1abfa4ce 1387\r
e905fbb0 1388 DEBUG ((DEBUG_INFO, "Tcg2SubmitCommand ...\n"));\r
1abfa4ce
JY
1389\r
1390 if ((This == NULL) ||\r
1391 (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||\r
c411b485
MK
1392 (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL))\r
1393 {\r
1abfa4ce
JY
1394 return EFI_INVALID_PARAMETER;\r
1395 }\r
1396\r
1397 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1398 return EFI_DEVICE_ERROR;\r
1399 }\r
1400\r
e1f35834 1401 if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {\r
1abfa4ce
JY
1402 return EFI_INVALID_PARAMETER;\r
1403 }\r
c411b485 1404\r
e1f35834 1405 if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {\r
1abfa4ce
JY
1406 return EFI_INVALID_PARAMETER;\r
1407 }\r
1408\r
1409 Status = Tpm2SubmitCommand (\r
1410 InputParameterBlockSize,\r
1411 InputParameterBlock,\r
1412 &OutputParameterBlockSize,\r
1413 OutputParameterBlock\r
1414 );\r
e905fbb0 1415 DEBUG ((DEBUG_INFO, "Tcg2SubmitCommand - %r\n", Status));\r
1abfa4ce
JY
1416 return Status;\r
1417}\r
1418\r
1419/**\r
1420 This service returns the currently active PCR banks.\r
1421\r
1422 @param[in] This Indicates the calling context\r
1423 @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.\r
1424\r
1425 @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.\r
b3548d32 1426 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1abfa4ce
JY
1427**/\r
1428EFI_STATUS\r
1429EFIAPI\r
1430Tcg2GetActivePCRBanks (\r
c411b485
MK
1431 IN EFI_TCG2_PROTOCOL *This,\r
1432 OUT UINT32 *ActivePcrBanks\r
1abfa4ce
JY
1433 )\r
1434{\r
1435 if (ActivePcrBanks == NULL) {\r
1436 return EFI_INVALID_PARAMETER;\r
1437 }\r
c411b485 1438\r
1abfa4ce
JY
1439 *ActivePcrBanks = mTcgDxeData.BsCap.ActivePcrBanks;\r
1440 return EFI_SUCCESS;\r
1441}\r
1442\r
1443/**\r
1444 This service sets the currently active PCR banks.\r
1445\r
1446 @param[in] This Indicates the calling context\r
1447 @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.\r
1448\r
1449 @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.\r
1450 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1451**/\r
1452EFI_STATUS\r
1453EFIAPI\r
1454Tcg2SetActivePCRBanks (\r
c411b485
MK
1455 IN EFI_TCG2_PROTOCOL *This,\r
1456 IN UINT32 ActivePcrBanks\r
1abfa4ce
JY
1457 )\r
1458{\r
1459 EFI_STATUS Status;\r
1460 UINT32 ReturnCode;\r
1461\r
e905fbb0 1462 DEBUG ((DEBUG_INFO, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks));\r
1abfa4ce
JY
1463\r
1464 if (ActivePcrBanks == 0) {\r
1465 return EFI_INVALID_PARAMETER;\r
1466 }\r
c411b485 1467\r
1abfa4ce
JY
1468 if ((ActivePcrBanks & (~mTcgDxeData.BsCap.HashAlgorithmBitmap)) != 0) {\r
1469 return EFI_INVALID_PARAMETER;\r
1470 }\r
c411b485 1471\r
1abfa4ce
JY
1472 if (ActivePcrBanks == mTcgDxeData.BsCap.ActivePcrBanks) {\r
1473 //\r
1474 // Need clear previous SET_PCR_BANKS setting\r
1475 //\r
1476 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION, 0);\r
1477 } else {\r
1478 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, ActivePcrBanks);\r
1479 }\r
1480\r
1481 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
1482 Status = EFI_SUCCESS;\r
1483 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
1484 Status = EFI_OUT_OF_RESOURCES;\r
1485 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
1486 Status = EFI_UNSUPPORTED;\r
1487 } else {\r
1488 Status = EFI_DEVICE_ERROR;\r
1489 }\r
1490\r
e905fbb0 1491 DEBUG ((DEBUG_INFO, "Tcg2SetActivePCRBanks - %r\n", Status));\r
1abfa4ce
JY
1492\r
1493 return Status;\r
1494}\r
1495\r
1496/**\r
1497 This service retrieves the result of a previous invocation of SetActivePcrBanks.\r
1498\r
1499 @param[in] This Indicates the calling context\r
1500 @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.\r
1501 @param[out] Response The response from the SetActivePcrBank request.\r
1502\r
1503 @retval EFI_SUCCESS The result value could be returned.\r
1504 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1505**/\r
1506EFI_STATUS\r
1507EFIAPI\r
1508Tcg2GetResultOfSetActivePcrBanks (\r
1509 IN EFI_TCG2_PROTOCOL *This,\r
1510 OUT UINT32 *OperationPresent,\r
1511 OUT UINT32 *Response\r
1512 )\r
1513{\r
1514 UINT32 ReturnCode;\r
1515\r
1516 if ((OperationPresent == NULL) || (Response == NULL)) {\r
1517 return EFI_INVALID_PARAMETER;\r
1518 }\r
b3548d32 1519\r
1abfa4ce
JY
1520 ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);\r
1521 if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {\r
1522 return EFI_SUCCESS;\r
1523 } else {\r
1524 return EFI_UNSUPPORTED;\r
1525 }\r
1526}\r
1527\r
c411b485
MK
1528EFI_TCG2_PROTOCOL mTcg2Protocol = {\r
1529 Tcg2GetCapability,\r
1530 Tcg2GetEventLog,\r
1531 Tcg2HashLogExtendEvent,\r
1532 Tcg2SubmitCommand,\r
1533 Tcg2GetActivePCRBanks,\r
1534 Tcg2SetActivePCRBanks,\r
1535 Tcg2GetResultOfSetActivePcrBanks,\r
1abfa4ce
JY
1536};\r
1537\r
1538/**\r
1539 Initialize the Event Log and log events passed from the PEI phase.\r
1540\r
1541 @retval EFI_SUCCESS Operation completed successfully.\r
1542 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1543\r
1544**/\r
1545EFI_STATUS\r
1546SetupEventLog (\r
1547 VOID\r
1548 )\r
1549{\r
c411b485
MK
1550 EFI_STATUS Status;\r
1551 VOID *TcgEvent;\r
1552 EFI_PEI_HOB_POINTERS GuidHob;\r
1553 EFI_PHYSICAL_ADDRESS Lasa;\r
1554 UINTN Index;\r
1555 VOID *DigestListBin;\r
1556 TPML_DIGEST_VALUES TempDigestListBin;\r
1557 UINT32 DigestListBinSize;\r
1558 UINT8 *Event;\r
1559 UINT32 EventSize;\r
1560 UINT32 *EventSizePtr;\r
1561 UINT32 HashAlgorithmMaskCopied;\r
1562 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;\r
1563 UINT8 TempBuf[sizeof (TCG_EfiSpecIDEventStruct) + sizeof (UINT32) + (HASH_COUNT * sizeof (TCG_EfiSpecIdEventAlgorithmSize)) + sizeof (UINT8)];\r
1564 TCG_PCR_EVENT_HDR SpecIdEvent;\r
1565 TCG_PCR_EVENT2_HDR NoActionEvent;\r
1566 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
1567 TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
1568 UINT8 *VendorInfoSize;\r
1569 UINT32 NumberOfAlgorithms;\r
1570 TCG_EfiStartupLocalityEvent StartupLocalityEvent;\r
1abfa4ce 1571\r
e905fbb0 1572 DEBUG ((DEBUG_INFO, "SetupEventLog\n"));\r
1abfa4ce
JY
1573\r
1574 //\r
1575 // 1. Create Log Area\r
1576 //\r
c411b485 1577 for (Index = 0; Index < sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0]); Index++) {\r
1abfa4ce
JY
1578 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1579 mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
c411b485 1580 if (PcdGet8 (PcdTpm2AcpiTableRev) >= 4) {\r
a7e2d201
JY
1581 Status = gBS->AllocatePages (\r
1582 AllocateAnyPages,\r
1583 EfiACPIMemoryNVS,\r
1584 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
1585 &Lasa\r
1586 );\r
1587 } else {\r
1588 Status = gBS->AllocatePages (\r
1589 AllocateAnyPages,\r
1590 EfiBootServicesData,\r
1591 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
1592 &Lasa\r
1593 );\r
1594 }\r
c411b485 1595\r
1abfa4ce
JY
1596 if (EFI_ERROR (Status)) {\r
1597 return Status;\r
1598 }\r
c411b485
MK
1599\r
1600 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
1601 mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
4fa25853 1602 mTcgDxeData.EventLogAreaStruct[Index].Next800155EventOffset = 0;\r
a7e2d201 1603\r
c411b485
MK
1604 if ((PcdGet8 (PcdTpm2AcpiTableRev) >= 4) ||\r
1605 (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2))\r
1606 {\r
a7e2d201
JY
1607 //\r
1608 // Report TCG2 event log address and length, so that they can be reported in TPM2 ACPI table.\r
1609 // Ignore the return status, because those fields are optional.\r
1610 //\r
c411b485
MK
1611 PcdSet32S (PcdTpm2AcpiTableLaml, (UINT32)mTcgDxeData.EventLogAreaStruct[Index].Laml);\r
1612 PcdSet64S (PcdTpm2AcpiTableLasa, mTcgDxeData.EventLogAreaStruct[Index].Lasa);\r
a7e2d201
JY
1613 }\r
1614\r
1abfa4ce 1615 //\r
b3548d32 1616 // To initialize them as 0xFF is recommended\r
1abfa4ce
JY
1617 // because the OS can know the last entry for that.\r
1618 //\r
91e914f5 1619 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
1abfa4ce
JY
1620 //\r
1621 // Create first entry for Log Header Entry Data\r
1622 //\r
1623 if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {\r
1624 //\r
1625 // TcgEfiSpecIdEventStruct\r
1626 //\r
1627 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;\r
c411b485
MK
1628 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof (TcgEfiSpecIdEventStruct->signature));\r
1629 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);\r
1abfa4ce
JY
1630 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;\r
1631 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;\r
c411b485
MK
1632 TcgEfiSpecIdEventStruct->specErrata = (UINT8)PcdGet32 (PcdTcgPfpMeasurementRevision);\r
1633 TcgEfiSpecIdEventStruct->uintnSize = sizeof (UINTN)/sizeof (UINT32);\r
1634 NumberOfAlgorithms = 0;\r
1635 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof (*TcgEfiSpecIdEventStruct) + sizeof (NumberOfAlgorithms));\r
1abfa4ce 1636 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
c411b485
MK
1637 TempDigestSize = DigestSize;\r
1638 TempDigestSize += NumberOfAlgorithms;\r
35e00ace 1639 TempDigestSize->algorithmId = TPM_ALG_SHA1;\r
c411b485 1640 TempDigestSize->digestSize = SHA1_DIGEST_SIZE;\r
a9092578 1641 NumberOfAlgorithms++;\r
1abfa4ce 1642 }\r
c411b485 1643\r
1abfa4ce 1644 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
c411b485
MK
1645 TempDigestSize = DigestSize;\r
1646 TempDigestSize += NumberOfAlgorithms;\r
35e00ace 1647 TempDigestSize->algorithmId = TPM_ALG_SHA256;\r
c411b485 1648 TempDigestSize->digestSize = SHA256_DIGEST_SIZE;\r
a9092578 1649 NumberOfAlgorithms++;\r
1abfa4ce 1650 }\r
c411b485 1651\r
1abfa4ce 1652 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
c411b485
MK
1653 TempDigestSize = DigestSize;\r
1654 TempDigestSize += NumberOfAlgorithms;\r
35e00ace 1655 TempDigestSize->algorithmId = TPM_ALG_SHA384;\r
c411b485 1656 TempDigestSize->digestSize = SHA384_DIGEST_SIZE;\r
a9092578 1657 NumberOfAlgorithms++;\r
1abfa4ce 1658 }\r
c411b485 1659\r
1abfa4ce 1660 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
c411b485
MK
1661 TempDigestSize = DigestSize;\r
1662 TempDigestSize += NumberOfAlgorithms;\r
35e00ace 1663 TempDigestSize->algorithmId = TPM_ALG_SHA512;\r
c411b485 1664 TempDigestSize->digestSize = SHA512_DIGEST_SIZE;\r
a9092578 1665 NumberOfAlgorithms++;\r
1abfa4ce 1666 }\r
c411b485 1667\r
1abfa4ce 1668 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
c411b485
MK
1669 TempDigestSize = DigestSize;\r
1670 TempDigestSize += NumberOfAlgorithms;\r
35e00ace 1671 TempDigestSize->algorithmId = TPM_ALG_SM3_256;\r
c411b485 1672 TempDigestSize->digestSize = SM3_256_DIGEST_SIZE;\r
a9092578 1673 NumberOfAlgorithms++;\r
1abfa4ce 1674 }\r
c411b485
MK
1675\r
1676 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof (NumberOfAlgorithms));\r
1677 TempDigestSize = DigestSize;\r
35e00ace 1678 TempDigestSize += NumberOfAlgorithms;\r
c411b485 1679 VendorInfoSize = (UINT8 *)TempDigestSize;\r
a9092578 1680 *VendorInfoSize = 0;\r
1abfa4ce 1681\r
c411b485 1682 SpecIdEvent.PCRIndex = 0;\r
a2612cf7 1683 SpecIdEvent.EventType = EV_NO_ACTION;\r
c411b485 1684 ZeroMem (&SpecIdEvent.Digest, sizeof (SpecIdEvent.Digest));\r
a2612cf7 1685 SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
1abfa4ce
JY
1686\r
1687 //\r
a2612cf7
ZC
1688 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.\r
1689 // TCG EFI Protocol Spec. Section 5.3 Event Log Header\r
18458db1 1690 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log\r
1abfa4ce
JY
1691 //\r
1692 Status = TcgDxeLogEvent (\r
1693 mTcg2EventInfo[Index].LogFormat,\r
a2612cf7 1694 &SpecIdEvent,\r
c411b485 1695 sizeof (SpecIdEvent),\r
1abfa4ce 1696 (UINT8 *)TcgEfiSpecIdEventStruct,\r
a2612cf7 1697 SpecIdEvent.EventSize\r
1abfa4ce 1698 );\r
4fa25853
JY
1699 //\r
1700 // record the offset at the end of 800-155 event.\r
1701 // the future 800-155 event can be inserted here.\r
1702 //\r
1703 mTcgDxeData.EventLogAreaStruct[Index].Next800155EventOffset = \\r
1704 mTcgDxeData.EventLogAreaStruct[Index].EventLogSize;\r
1705\r
1706 //\r
1707 // Tcg800155PlatformIdEvent. Event format is TCG_PCR_EVENT2\r
1708 //\r
1709 GuidHob.Guid = GetFirstGuidHob (&gTcg800155PlatformIdEventHobGuid);\r
1710 while (GuidHob.Guid != NULL) {\r
c411b485 1711 InitNoActionEvent (&NoActionEvent, GET_GUID_HOB_DATA_SIZE (GuidHob.Guid));\r
4fa25853
JY
1712\r
1713 Status = TcgDxeLogEvent (\r
1714 mTcg2EventInfo[Index].LogFormat,\r
1715 &NoActionEvent,\r
c411b485 1716 sizeof (NoActionEvent.PCRIndex) + sizeof (NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof (NoActionEvent.EventSize),\r
4fa25853
JY
1717 GET_GUID_HOB_DATA (GuidHob.Guid),\r
1718 GET_GUID_HOB_DATA_SIZE (GuidHob.Guid)\r
1719 );\r
1720\r
1721 GuidHob.Guid = GET_NEXT_HOB (GuidHob);\r
1722 GuidHob.Guid = GetNextGuidHob (&gTcg800155PlatformIdEventHobGuid, GuidHob.Guid);\r
1723 }\r
18458db1
ZC
1724\r
1725 //\r
a2612cf7 1726 // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2\r
18458db1
ZC
1727 //\r
1728 GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);\r
1729 if (GuidHob.Guid != NULL) {\r
1730 //\r
1731 // Get Locality Indicator from StartupLocality HOB\r
1732 //\r
1733 StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));\r
c411b485 1734 CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof (StartupLocalityEvent.Signature));\r
18458db1
ZC
1735 DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));\r
1736\r
a2612cf7
ZC
1737 //\r
1738 // Initialize StartupLocalityEvent\r
1739 //\r
c411b485 1740 InitNoActionEvent (&NoActionEvent, sizeof (StartupLocalityEvent));\r
a2612cf7 1741\r
18458db1
ZC
1742 //\r
1743 // Log EfiStartupLocalityEvent as the second Event\r
1744 // TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event\r
1745 //\r
1746 Status = TcgDxeLogEvent (\r
1747 mTcg2EventInfo[Index].LogFormat,\r
1748 &NoActionEvent,\r
c411b485 1749 sizeof (NoActionEvent.PCRIndex) + sizeof (NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof (NoActionEvent.EventSize),\r
18458db1 1750 (UINT8 *)&StartupLocalityEvent,\r
c411b485 1751 sizeof (StartupLocalityEvent)\r
18458db1
ZC
1752 );\r
1753 }\r
1abfa4ce
JY
1754 }\r
1755 }\r
1756 }\r
1757\r
1758 //\r
1759 // 2. Create Final Log Area\r
1760 //\r
c411b485 1761 for (Index = 0; Index < sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0]); Index++) {\r
1abfa4ce 1762 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
fd46e831 1763 if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
fd46e831 1764 Status = gBS->AllocatePages (\r
dc756bae 1765 AllocateAnyPages,\r
fd46e831
JY
1766 EfiACPIMemoryNVS,\r
1767 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),\r
1768 &Lasa\r
1769 );\r
1770 if (EFI_ERROR (Status)) {\r
1771 return Status;\r
1772 }\r
c411b485 1773\r
fd46e831 1774 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);\r
1abfa4ce 1775\r
fd46e831
JY
1776 //\r
1777 // Initialize\r
1778 //\r
c411b485
MK
1779 mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;\r
1780 (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;\r
fd46e831
JY
1781 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;\r
1782\r
c411b485
MK
1783 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1784 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof (EFI_TCG2_FINAL_EVENTS_TABLE);\r
1785 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof (EFI_TCG2_FINAL_EVENTS_TABLE);\r
1786 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
1787 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
1788 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
1789 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
4fa25853 1790 mTcgDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;\r
1abfa4ce 1791\r
1abfa4ce 1792 //\r
b3548d32 1793 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2\r
1abfa4ce 1794 //\r
fd46e831 1795 Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
1abfa4ce
JY
1796 if (EFI_ERROR (Status)) {\r
1797 return Status;\r
1798 }\r
fd46e831
JY
1799 } else {\r
1800 //\r
1801 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2\r
1802 //\r
c411b485
MK
1803 mTcgDxeData.FinalEventsTable[Index] = NULL;\r
1804 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1805 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;\r
1806 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;\r
1807 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
1808 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;\r
1809 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
1810 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
4fa25853 1811 mTcgDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;\r
1abfa4ce
JY
1812 }\r
1813 }\r
1814 }\r
b3548d32 1815\r
1abfa4ce
JY
1816 //\r
1817 // 3. Sync data from PEI to DXE\r
1818 //\r
1819 Status = EFI_SUCCESS;\r
c411b485 1820 for (Index = 0; Index < sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0]); Index++) {\r
1abfa4ce
JY
1821 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1822 GuidHob.Raw = GetHobList ();\r
c411b485 1823 Status = EFI_SUCCESS;\r
b3548d32 1824 while (!EFI_ERROR (Status) &&\r
c411b485
MK
1825 (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL)\r
1826 {\r
1827 TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));\r
ab5b1f31 1828 ASSERT (TcgEvent != NULL);\r
1abfa4ce
JY
1829 GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
1830 switch (mTcg2EventInfo[Index].LogFormat) {\r
c411b485
MK
1831 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
1832 Status = TcgDxeLogEvent (\r
1833 mTcg2EventInfo[Index].LogFormat,\r
1834 TcgEvent,\r
1835 sizeof (TCG_PCR_EVENT_HDR),\r
1836 ((TCG_PCR_EVENT *)TcgEvent)->Event,\r
1837 ((TCG_PCR_EVENT_HDR *)TcgEvent)->EventSize\r
1838 );\r
1839 break;\r
1840 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
1841 DigestListBin = (UINT8 *)TcgEvent + sizeof (TCG_PCRINDEX) + sizeof (TCG_EVENTTYPE);\r
1842 DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
1843 //\r
1844 // Save event size.\r
1845 //\r
1846 CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof (UINT32));\r
1847 Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof (UINT32);\r
1848 //\r
1849 // Filter inactive digest in the event2 log from PEI HOB.\r
1850 //\r
1851 CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));\r
1852 EventSizePtr = CopyDigestListBinToBuffer (\r
1853 DigestListBin,\r
1854 &TempDigestListBin,\r
1855 mTcgDxeData.BsCap.ActivePcrBanks,\r
1856 &HashAlgorithmMaskCopied\r
1857 );\r
1858 if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {\r
1859 DEBUG ((\r
1860 DEBUG_ERROR,\r
1861 "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",\r
1862 HashAlgorithmMaskCopied,\r
1863 mTcgDxeData.BsCap.ActivePcrBanks\r
1864 ));\r
1865 }\r
1866\r
1867 //\r
1868 // Restore event size.\r
1869 //\r
1870 CopyMem (EventSizePtr, &EventSize, sizeof (UINT32));\r
1871 DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
1872\r
1873 Status = TcgDxeLogEvent (\r
1874 mTcg2EventInfo[Index].LogFormat,\r
1875 TcgEvent,\r
1876 sizeof (TCG_PCRINDEX) + sizeof (TCG_EVENTTYPE) + DigestListBinSize + sizeof (UINT32),\r
1877 Event,\r
1878 EventSize\r
1879 );\r
1880 break;\r
1abfa4ce 1881 }\r
c411b485 1882\r
ab5b1f31 1883 FreePool (TcgEvent);\r
1abfa4ce
JY
1884 }\r
1885 }\r
1886 }\r
1887\r
1888 return Status;\r
1889}\r
1890\r
1891/**\r
c1b0828b 1892 Measure and log an action string, and extend the measurement result into PCR[PCRIndex].\r
1abfa4ce 1893\r
c1b0828b 1894 @param[in] PCRIndex PCRIndex to extend\r
b3548d32
LG
1895 @param[in] String A specific string that indicates an Action event.\r
1896\r
1abfa4ce
JY
1897 @retval EFI_SUCCESS Operation completed successfully.\r
1898 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1899\r
1900**/\r
1901EFI_STATUS\r
1902TcgMeasureAction (\r
c411b485
MK
1903 IN TPM_PCRINDEX PCRIndex,\r
1904 IN CHAR8 *String\r
1abfa4ce
JY
1905 )\r
1906{\r
c411b485 1907 TCG_PCR_EVENT_HDR TcgEvent;\r
1abfa4ce 1908\r
c1b0828b 1909 TcgEvent.PCRIndex = PCRIndex;\r
1abfa4ce
JY
1910 TcgEvent.EventType = EV_EFI_ACTION;\r
1911 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
1912 return TcgDxeHashLogExtendEvent (\r
1913 0,\r
c411b485 1914 (UINT8 *)String,\r
1abfa4ce
JY
1915 TcgEvent.EventSize,\r
1916 &TcgEvent,\r
c411b485 1917 (UINT8 *)String\r
1abfa4ce
JY
1918 );\r
1919}\r
1920\r
1921/**\r
1922 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].\r
1923\r
1924 @retval EFI_SUCCESS Operation completed successfully.\r
1925 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1926\r
1927**/\r
1928EFI_STATUS\r
1929MeasureHandoffTables (\r
1930 VOID\r
1931 )\r
1932{\r
c411b485
MK
1933 EFI_STATUS Status;\r
1934 TCG_PCR_EVENT_HDR TcgEvent;\r
1935 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
1936 UINTN ProcessorNum;\r
1937 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
1abfa4ce
JY
1938\r
1939 ProcessorLocBuf = NULL;\r
c411b485 1940 Status = EFI_SUCCESS;\r
1abfa4ce
JY
1941\r
1942 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
1943 //\r
b3548d32 1944 // Tcg Server spec.\r
1abfa4ce
JY
1945 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
1946 //\r
c411b485 1947 Status = GetProcessorsCpuLocation (&ProcessorLocBuf, &ProcessorNum);\r
1abfa4ce 1948\r
c411b485 1949 if (!EFI_ERROR (Status)) {\r
1abfa4ce
JY
1950 TcgEvent.PCRIndex = 1;\r
1951 TcgEvent.EventType = EV_TABLE_OF_DEVICES;\r
1952 TcgEvent.EventSize = sizeof (HandoffTables);\r
1953\r
c411b485 1954 HandoffTables.NumberOfTables = 1;\r
1abfa4ce
JY
1955 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;\r
1956 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;\r
1957\r
1958 Status = TcgDxeHashLogExtendEvent (\r
1959 0,\r
c411b485
MK
1960 (UINT8 *)(UINTN)ProcessorLocBuf,\r
1961 sizeof (EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
1abfa4ce 1962 &TcgEvent,\r
c411b485 1963 (UINT8 *)&HandoffTables\r
1abfa4ce
JY
1964 );\r
1965\r
c411b485 1966 FreePool (ProcessorLocBuf);\r
1abfa4ce
JY
1967 }\r
1968 }\r
1969\r
1970 return Status;\r
1971}\r
1972\r
1973/**\r
1974 Measure and log Separator event, and extend the measurement result into a specific PCR.\r
1975\r
b3548d32 1976 @param[in] PCRIndex PCR index.\r
1abfa4ce
JY
1977\r
1978 @retval EFI_SUCCESS Operation completed successfully.\r
1979 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1980\r
1981**/\r
1982EFI_STATUS\r
1983MeasureSeparatorEvent (\r
c411b485 1984 IN TPM_PCRINDEX PCRIndex\r
1abfa4ce
JY
1985 )\r
1986{\r
c411b485
MK
1987 TCG_PCR_EVENT_HDR TcgEvent;\r
1988 UINT32 EventData;\r
1abfa4ce 1989\r
e905fbb0 1990 DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));\r
1abfa4ce 1991\r
c411b485 1992 EventData = 0;\r
1abfa4ce
JY
1993 TcgEvent.PCRIndex = PCRIndex;\r
1994 TcgEvent.EventType = EV_SEPARATOR;\r
1995 TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
1996 return TcgDxeHashLogExtendEvent (\r
1997 0,\r
1998 (UINT8 *)&EventData,\r
1999 sizeof (EventData),\r
2000 &TcgEvent,\r
2001 (UINT8 *)&EventData\r
2002 );\r
2003}\r
2004\r
2005/**\r
2006 Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
2007\r
b3548d32
LG
2008 @param[in] PCRIndex PCR Index.\r
2009 @param[in] EventType Event type.\r
1abfa4ce
JY
2010 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
2011 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
2012 @param[in] VarData The content of the variable data.\r
2013 @param[in] VarSize The size of the variable data.\r
2014\r
1abfa4ce
JY
2015 @retval EFI_SUCCESS Operation completed successfully.\r
2016 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2017 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2018\r
2019**/\r
2020EFI_STATUS\r
2021MeasureVariable (\r
c411b485
MK
2022 IN TPM_PCRINDEX PCRIndex,\r
2023 IN TCG_EVENTTYPE EventType,\r
2024 IN CHAR16 *VarName,\r
2025 IN EFI_GUID *VendorGuid,\r
2026 IN VOID *VarData,\r
2027 IN UINTN VarSize\r
1abfa4ce
JY
2028 )\r
2029{\r
c411b485
MK
2030 EFI_STATUS Status;\r
2031 TCG_PCR_EVENT_HDR TcgEvent;\r
2032 UINTN VarNameLength;\r
2033 UEFI_VARIABLE_DATA *VarLog;\r
1abfa4ce 2034\r
e905fbb0
MK
2035 DEBUG ((DEBUG_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
2036 DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
1abfa4ce
JY
2037\r
2038 VarNameLength = StrLen (VarName);\r
2039 TcgEvent.PCRIndex = PCRIndex;\r
2040 TcgEvent.EventType = EventType;\r
2041\r
2042 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
c411b485 2043 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
1abfa4ce 2044\r
9d77acf1 2045 VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (TcgEvent.EventSize);\r
1abfa4ce
JY
2046 if (VarLog == NULL) {\r
2047 return EFI_OUT_OF_RESOURCES;\r
2048 }\r
2049\r
2050 VarLog->VariableName = *VendorGuid;\r
2051 VarLog->UnicodeNameLength = VarNameLength;\r
2052 VarLog->VariableDataLength = VarSize;\r
2053 CopyMem (\r
c411b485
MK
2054 VarLog->UnicodeName,\r
2055 VarName,\r
2056 VarNameLength * sizeof (*VarName)\r
2057 );\r
2058 if ((VarSize != 0) && (VarData != NULL)) {\r
1abfa4ce 2059 CopyMem (\r
c411b485
MK
2060 (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
2061 VarData,\r
2062 VarSize\r
2063 );\r
1abfa4ce
JY
2064 }\r
2065\r
2066 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
2067 //\r
9d77acf1 2068 // Digest is the event data (UEFI_VARIABLE_DATA)\r
1abfa4ce
JY
2069 //\r
2070 Status = TcgDxeHashLogExtendEvent (\r
2071 0,\r
c411b485 2072 (UINT8 *)VarLog,\r
1abfa4ce
JY
2073 TcgEvent.EventSize,\r
2074 &TcgEvent,\r
c411b485 2075 (UINT8 *)VarLog\r
1abfa4ce
JY
2076 );\r
2077 } else {\r
36e9e3e8 2078 ASSERT (VarData != NULL);\r
1abfa4ce
JY
2079 Status = TcgDxeHashLogExtendEvent (\r
2080 0,\r
c411b485 2081 (UINT8 *)VarData,\r
1abfa4ce
JY
2082 VarSize,\r
2083 &TcgEvent,\r
c411b485 2084 (UINT8 *)VarLog\r
1abfa4ce
JY
2085 );\r
2086 }\r
c411b485 2087\r
1abfa4ce
JY
2088 FreePool (VarLog);\r
2089 return Status;\r
2090}\r
2091\r
2092/**\r
2093 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
2094\r
b3548d32
LG
2095 @param[in] PCRIndex PCR Index.\r
2096 @param[in] EventType Event type.\r
1abfa4ce
JY
2097 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
2098 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
2099 @param[out] VarSize The size of the variable data.\r
2100 @param[out] VarData Pointer to the content of the variable.\r
2101\r
1abfa4ce
JY
2102 @retval EFI_SUCCESS Operation completed successfully.\r
2103 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2104 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2105\r
2106**/\r
2107EFI_STATUS\r
2108ReadAndMeasureVariable (\r
c411b485
MK
2109 IN TPM_PCRINDEX PCRIndex,\r
2110 IN TCG_EVENTTYPE EventType,\r
2111 IN CHAR16 *VarName,\r
2112 IN EFI_GUID *VendorGuid,\r
2113 OUT UINTN *VarSize,\r
2114 OUT VOID **VarData\r
1abfa4ce
JY
2115 )\r
2116{\r
c411b485 2117 EFI_STATUS Status;\r
1abfa4ce
JY
2118\r
2119 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);\r
2120 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
2121 if (EFI_ERROR (Status)) {\r
2122 //\r
2123 // It is valid case, so we need handle it.\r
2124 //\r
2125 *VarData = NULL;\r
2126 *VarSize = 0;\r
2127 }\r
2128 } else {\r
2129 //\r
2130 // if status error, VarData is freed and set NULL by GetVariable2\r
2131 //\r
2132 if (EFI_ERROR (Status)) {\r
2133 return EFI_NOT_FOUND;\r
2134 }\r
2135 }\r
2136\r
2137 Status = MeasureVariable (\r
2138 PCRIndex,\r
2139 EventType,\r
2140 VarName,\r
2141 VendorGuid,\r
2142 *VarData,\r
2143 *VarSize\r
2144 );\r
2145 return Status;\r
2146}\r
2147\r
2148/**\r
fe13f92b
ZC
2149 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].\r
2150according to TCG PC Client PFP spec 0021 Section 2.4.4.2\r
1abfa4ce
JY
2151\r
2152 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
2153 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
2154 @param[out] VarSize The size of the variable data.\r
2155 @param[out] VarData Pointer to the content of the variable.\r
2156\r
1abfa4ce
JY
2157 @retval EFI_SUCCESS Operation completed successfully.\r
2158 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2159 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2160\r
2161**/\r
2162EFI_STATUS\r
2163ReadAndMeasureBootVariable (\r
c411b485
MK
2164 IN CHAR16 *VarName,\r
2165 IN EFI_GUID *VendorGuid,\r
2166 OUT UINTN *VarSize,\r
2167 OUT VOID **VarData\r
1abfa4ce
JY
2168 )\r
2169{\r
2170 return ReadAndMeasureVariable (\r
fe13f92b 2171 1,\r
1abfa4ce
JY
2172 EV_EFI_VARIABLE_BOOT,\r
2173 VarName,\r
2174 VendorGuid,\r
2175 VarSize,\r
2176 VarData\r
2177 );\r
2178}\r
2179\r
2180/**\r
2181 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].\r
2182\r
2183 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
2184 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
2185 @param[out] VarSize The size of the variable data.\r
2186 @param[out] VarData Pointer to the content of the variable.\r
2187\r
1abfa4ce
JY
2188 @retval EFI_SUCCESS Operation completed successfully.\r
2189 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2190 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2191\r
2192**/\r
2193EFI_STATUS\r
2194ReadAndMeasureSecureVariable (\r
c411b485
MK
2195 IN CHAR16 *VarName,\r
2196 IN EFI_GUID *VendorGuid,\r
2197 OUT UINTN *VarSize,\r
2198 OUT VOID **VarData\r
1abfa4ce
JY
2199 )\r
2200{\r
2201 return ReadAndMeasureVariable (\r
2202 7,\r
2203 EV_EFI_VARIABLE_DRIVER_CONFIG,\r
2204 VarName,\r
2205 VendorGuid,\r
2206 VarSize,\r
2207 VarData\r
2208 );\r
2209}\r
2210\r
2211/**\r
2212 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.\r
2213\r
2214 The EFI boot variables are BootOrder and Boot#### variables.\r
2215\r
2216 @retval EFI_SUCCESS Operation completed successfully.\r
2217 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2218 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2219\r
2220**/\r
2221EFI_STATUS\r
2222MeasureAllBootVariables (\r
2223 VOID\r
2224 )\r
2225{\r
c411b485
MK
2226 EFI_STATUS Status;\r
2227 UINT16 *BootOrder;\r
2228 UINTN BootCount;\r
2229 UINTN Index;\r
2230 VOID *BootVarData;\r
2231 UINTN Size;\r
1abfa4ce
JY
2232\r
2233 Status = ReadAndMeasureBootVariable (\r
2234 mBootVarName,\r
2235 &gEfiGlobalVariableGuid,\r
2236 &BootCount,\r
c411b485 2237 (VOID **)&BootOrder\r
1abfa4ce 2238 );\r
c411b485 2239 if ((Status == EFI_NOT_FOUND) || (BootOrder == NULL)) {\r
1abfa4ce
JY
2240 return EFI_SUCCESS;\r
2241 }\r
2242\r
2243 if (EFI_ERROR (Status)) {\r
2244 //\r
2245 // BootOrder can't be NULL if status is not EFI_NOT_FOUND\r
2246 //\r
2247 FreePool (BootOrder);\r
2248 return Status;\r
2249 }\r
2250\r
2251 BootCount /= sizeof (*BootOrder);\r
2252 for (Index = 0; Index < BootCount; Index++) {\r
2253 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);\r
2254 Status = ReadAndMeasureBootVariable (\r
2255 mBootVarName,\r
2256 &gEfiGlobalVariableGuid,\r
2257 &Size,\r
2258 &BootVarData\r
2259 );\r
2260 if (!EFI_ERROR (Status)) {\r
2261 FreePool (BootVarData);\r
2262 }\r
2263 }\r
2264\r
2265 FreePool (BootOrder);\r
2266 return EFI_SUCCESS;\r
2267}\r
2268\r
2269/**\r
2270 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.\r
2271\r
2272 The EFI boot variables are BootOrder and Boot#### variables.\r
2273\r
2274 @retval EFI_SUCCESS Operation completed successfully.\r
2275 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2276 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2277\r
2278**/\r
2279EFI_STATUS\r
2280MeasureAllSecureVariables (\r
2281 VOID\r
2282 )\r
2283{\r
c411b485
MK
2284 EFI_STATUS Status;\r
2285 VOID *Data;\r
2286 UINTN DataSize;\r
2287 UINTN Index;\r
1abfa4ce
JY
2288\r
2289 Status = EFI_NOT_FOUND;\r
c411b485 2290 for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {\r
1abfa4ce
JY
2291 Status = ReadAndMeasureSecureVariable (\r
2292 mVariableType[Index].VariableName,\r
2293 mVariableType[Index].VendorGuid,\r
2294 &DataSize,\r
2295 &Data\r
2296 );\r
2297 if (!EFI_ERROR (Status)) {\r
2298 if (Data != NULL) {\r
2299 FreePool (Data);\r
2300 }\r
2301 }\r
2302 }\r
2303\r
400b0940
ZC
2304 //\r
2305 // Measure DBT if present and not empty\r
2306 //\r
2307 Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);\r
c411b485 2308 if (!EFI_ERROR (Status)) {\r
400b0940
ZC
2309 Status = MeasureVariable (\r
2310 7,\r
2311 EV_EFI_VARIABLE_DRIVER_CONFIG,\r
2312 EFI_IMAGE_SECURITY_DATABASE2,\r
2313 &gEfiImageSecurityDatabaseGuid,\r
2314 Data,\r
2315 DataSize\r
2316 );\r
c411b485 2317 FreePool (Data);\r
400b0940 2318 } else {\r
c411b485 2319 DEBUG ((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));\r
400b0940
ZC
2320 }\r
2321\r
1abfa4ce
JY
2322 return EFI_SUCCESS;\r
2323}\r
2324\r
2325/**\r
2326 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.\r
2327\r
2328 @retval EFI_SUCCESS Operation completed successfully.\r
2329 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2330 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2331\r
2332**/\r
2333EFI_STATUS\r
2334MeasureLaunchOfFirmwareDebugger (\r
2335 VOID\r
2336 )\r
2337{\r
c411b485 2338 TCG_PCR_EVENT_HDR TcgEvent;\r
1abfa4ce
JY
2339\r
2340 TcgEvent.PCRIndex = 7;\r
2341 TcgEvent.EventType = EV_EFI_ACTION;\r
c411b485 2342 TcgEvent.EventSize = sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1;\r
1abfa4ce
JY
2343 return TcgDxeHashLogExtendEvent (\r
2344 0,\r
2345 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,\r
c411b485 2346 sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1,\r
1abfa4ce
JY
2347 &TcgEvent,\r
2348 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING\r
2349 );\r
2350}\r
2351\r
2352/**\r
2353 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.\r
2354\r
2355 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)\r
2356 - The contents of the SecureBoot variable\r
2357 - The contents of the PK variable\r
2358 - The contents of the KEK variable\r
2359 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable\r
2360 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable\r
2361 - Separator\r
2362 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path\r
2363\r
2364 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,\r
2365 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].\r
2366\r
2367 @param[in] Event Event whose notification function is being invoked\r
2368 @param[in] Context Pointer to the notification function's context\r
2369**/\r
2370VOID\r
2371EFIAPI\r
2372MeasureSecureBootPolicy (\r
c411b485
MK
2373 IN EFI_EVENT Event,\r
2374 IN VOID *Context\r
1abfa4ce
JY
2375 )\r
2376{\r
2377 EFI_STATUS Status;\r
2378 VOID *Protocol;\r
2379\r
2380 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);\r
2381 if (EFI_ERROR (Status)) {\r
2382 return;\r
2383 }\r
2384\r
2385 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {\r
2386 Status = MeasureLaunchOfFirmwareDebugger ();\r
e905fbb0 2387 DEBUG ((DEBUG_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));\r
1abfa4ce
JY
2388 }\r
2389\r
2390 Status = MeasureAllSecureVariables ();\r
e905fbb0 2391 DEBUG ((DEBUG_INFO, "MeasureAllSecureVariables - %r\n", Status));\r
1abfa4ce
JY
2392\r
2393 //\r
2394 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)\r
2395 // and ImageVerification (Authority)\r
2396 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So\r
2397 // the Authority measurement happen before ReadToBoot event.\r
2398 //\r
2399 Status = MeasureSeparatorEvent (7);\r
e905fbb0 2400 DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent - %r\n", Status));\r
c411b485 2401 return;\r
1abfa4ce
JY
2402}\r
2403\r
2404/**\r
2405 Ready to Boot Event notification handler.\r
2406\r
2407 Sequence of OS boot events is measured in this event notification handler.\r
2408\r
2409 @param[in] Event Event whose notification function is being invoked\r
2410 @param[in] Context Pointer to the notification function's context\r
2411\r
2412**/\r
2413VOID\r
2414EFIAPI\r
2415OnReadyToBoot (\r
c411b485
MK
2416 IN EFI_EVENT Event,\r
2417 IN VOID *Context\r
1abfa4ce
JY
2418 )\r
2419{\r
c411b485
MK
2420 EFI_STATUS Status;\r
2421 TPM_PCRINDEX PcrIndex;\r
1abfa4ce
JY
2422\r
2423 PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE);\r
2424 if (mBootAttempts == 0) {\r
1abfa4ce
JY
2425 //\r
2426 // Measure handoff tables.\r
2427 //\r
2428 Status = MeasureHandoffTables ();\r
2429 if (EFI_ERROR (Status)) {\r
e905fbb0 2430 DEBUG ((DEBUG_ERROR, "HOBs not Measured. Error!\n"));\r
1abfa4ce
JY
2431 }\r
2432\r
2433 //\r
2434 // Measure BootOrder & Boot#### variables.\r
2435 //\r
2436 Status = MeasureAllBootVariables ();\r
2437 if (EFI_ERROR (Status)) {\r
e905fbb0 2438 DEBUG ((DEBUG_ERROR, "Boot Variables not Measured. Error!\n"));\r
1abfa4ce
JY
2439 }\r
2440\r
2441 //\r
2442 // 1. This is the first boot attempt.\r
2443 //\r
2444 Status = TcgMeasureAction (\r
c1b0828b 2445 4,\r
1abfa4ce
JY
2446 EFI_CALLING_EFI_APPLICATION\r
2447 );\r
2448 if (EFI_ERROR (Status)) {\r
e905fbb0 2449 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
1abfa4ce
JY
2450 }\r
2451\r
2452 //\r
2453 // 2. Draw a line between pre-boot env and entering post-boot env.\r
2454 // PCR[7] is already done.\r
2455 //\r
2456 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
2457 Status = MeasureSeparatorEvent (PcrIndex);\r
2458 if (EFI_ERROR (Status)) {\r
0ab475c9 2459 DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));\r
1abfa4ce
JY
2460 }\r
2461 }\r
2462\r
2463 //\r
2464 // 3. Measure GPT. It would be done in SAP driver.\r
2465 //\r
2466\r
2467 //\r
2468 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.\r
2469 //\r
2470\r
2471 //\r
2472 // 5. Read & Measure variable. BootOrder already measured.\r
2473 //\r
2474 } else {\r
2475 //\r
2476 // 6. Not first attempt, meaning a return from last attempt\r
2477 //\r
2478 Status = TcgMeasureAction (\r
c1b0828b 2479 4,\r
5f3b0250 2480 EFI_RETURNING_FROM_EFI_APPLICATION\r
1abfa4ce
JY
2481 );\r
2482 if (EFI_ERROR (Status)) {\r
e905fbb0 2483 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));\r
1abfa4ce 2484 }\r
c1b0828b
ZC
2485\r
2486 //\r
2487 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again\r
2488 // TCG PC Client PFP spec Section 2.4.4.5 Step 4\r
2489 //\r
2490 Status = TcgMeasureAction (\r
2491 4,\r
2492 EFI_CALLING_EFI_APPLICATION\r
2493 );\r
2494 if (EFI_ERROR (Status)) {\r
e905fbb0 2495 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
c1b0828b 2496 }\r
1abfa4ce
JY
2497 }\r
2498\r
e905fbb0 2499 DEBUG ((DEBUG_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));\r
1abfa4ce
JY
2500 //\r
2501 // Increase boot attempt counter.\r
2502 //\r
2503 mBootAttempts++;\r
2504 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1);\r
2505}\r
2506\r
2507/**\r
2508 Exit Boot Services Event notification handler.\r
2509\r
2510 Measure invocation and success of ExitBootServices.\r
2511\r
2512 @param[in] Event Event whose notification function is being invoked\r
2513 @param[in] Context Pointer to the notification function's context\r
2514\r
2515**/\r
2516VOID\r
2517EFIAPI\r
2518OnExitBootServices (\r
c411b485
MK
2519 IN EFI_EVENT Event,\r
2520 IN VOID *Context\r
1abfa4ce
JY
2521 )\r
2522{\r
c411b485 2523 EFI_STATUS Status;\r
1abfa4ce
JY
2524\r
2525 //\r
2526 // Measure invocation of ExitBootServices,\r
2527 //\r
2528 Status = TcgMeasureAction (\r
c1b0828b 2529 5,\r
1abfa4ce
JY
2530 EFI_EXIT_BOOT_SERVICES_INVOCATION\r
2531 );\r
2532 if (EFI_ERROR (Status)) {\r
e905fbb0 2533 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));\r
1abfa4ce
JY
2534 }\r
2535\r
2536 //\r
2537 // Measure success of ExitBootServices\r
2538 //\r
2539 Status = TcgMeasureAction (\r
c1b0828b 2540 5,\r
1abfa4ce
JY
2541 EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
2542 );\r
2543 if (EFI_ERROR (Status)) {\r
e905fbb0 2544 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));\r
1abfa4ce
JY
2545 }\r
2546}\r
2547\r
2548/**\r
2549 Exit Boot Services Failed Event notification handler.\r
2550\r
2551 Measure Failure of ExitBootServices.\r
2552\r
2553 @param[in] Event Event whose notification function is being invoked\r
2554 @param[in] Context Pointer to the notification function's context\r
2555\r
2556**/\r
2557VOID\r
2558EFIAPI\r
2559OnExitBootServicesFailed (\r
c411b485
MK
2560 IN EFI_EVENT Event,\r
2561 IN VOID *Context\r
1abfa4ce
JY
2562 )\r
2563{\r
c411b485 2564 EFI_STATUS Status;\r
1abfa4ce
JY
2565\r
2566 //\r
2567 // Measure Failure of ExitBootServices,\r
2568 //\r
2569 Status = TcgMeasureAction (\r
c1b0828b 2570 5,\r
1abfa4ce
JY
2571 EFI_EXIT_BOOT_SERVICES_FAILED\r
2572 );\r
2573 if (EFI_ERROR (Status)) {\r
e905fbb0 2574 DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));\r
1abfa4ce 2575 }\r
1abfa4ce
JY
2576}\r
2577\r
9d5dfe9d
RN
2578/**\r
2579 This routine is called to properly shutdown the TPM before system reset.\r
2580 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
2581 Part 1: Architecture, Revision 01.16.\r
2582\r
2583 @param[in] ResetType The type of reset to perform.\r
2584 @param[in] ResetStatus The status code for the reset.\r
2585 @param[in] DataSize The size, in bytes, of ResetData.\r
2586 @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or\r
2587 EfiResetShutdown the data buffer starts with a Null-terminated\r
2588 string, optionally followed by additional binary data.\r
2589 The string is a description that the caller may use to further\r
930fcd9f 2590 indicate the reason for the system reset.\r
9d5dfe9d
RN
2591 For a ResetType of EfiResetPlatformSpecific the data buffer\r
2592 also starts with a Null-terminated string that is followed\r
2593 by an EFI_GUID that describes the specific type of reset to perform.\r
2594**/\r
2595VOID\r
2596EFIAPI\r
2597ShutdownTpmOnReset (\r
c411b485
MK
2598 IN EFI_RESET_TYPE ResetType,\r
2599 IN EFI_STATUS ResetStatus,\r
2600 IN UINTN DataSize,\r
2601 IN VOID *ResetData OPTIONAL\r
9d5dfe9d
RN
2602 )\r
2603{\r
c411b485
MK
2604 EFI_STATUS Status;\r
2605\r
9d5dfe9d
RN
2606 Status = Tpm2Shutdown (TPM_SU_CLEAR);\r
2607 DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));\r
2608}\r
2609\r
2610/**\r
2611 Hook the system reset to properly shutdown TPM.\r
2612 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
2613 Part 1: Architecture, Revision 01.16.\r
2614\r
2615 @param[in] Event Event whose notification function is being invoked\r
2616 @param[in] Context Pointer to the notification function's context\r
2617**/\r
2618VOID\r
2619EFIAPI\r
2620OnResetNotificationInstall (\r
c411b485
MK
2621 IN EFI_EVENT Event,\r
2622 IN VOID *Context\r
9d5dfe9d
RN
2623 )\r
2624{\r
c411b485
MK
2625 EFI_STATUS Status;\r
2626 EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;\r
9d5dfe9d 2627\r
c411b485 2628 Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **)&ResetNotify);\r
9d5dfe9d
RN
2629 if (!EFI_ERROR (Status)) {\r
2630 Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);\r
2631 ASSERT_EFI_ERROR (Status);\r
2632 DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));\r
2633\r
2634 gBS->CloseEvent (Event);\r
2635 }\r
2636}\r
2637\r
1abfa4ce
JY
2638/**\r
2639 The function install Tcg2 protocol.\r
b3548d32 2640\r
1abfa4ce
JY
2641 @retval EFI_SUCCESS Tcg2 protocol is installed.\r
2642 @retval other Some error occurs.\r
2643**/\r
2644EFI_STATUS\r
2645InstallTcg2 (\r
2646 VOID\r
2647 )\r
2648{\r
c411b485
MK
2649 EFI_STATUS Status;\r
2650 EFI_HANDLE Handle;\r
1abfa4ce
JY
2651\r
2652 Handle = NULL;\r
2653 Status = gBS->InstallMultipleProtocolInterfaces (\r
2654 &Handle,\r
2655 &gEfiTcg2ProtocolGuid,\r
2656 &mTcg2Protocol,\r
2657 NULL\r
2658 );\r
2659 return Status;\r
2660}\r
2661\r
2662/**\r
2663 The driver's entry point. It publishes EFI Tcg2 Protocol.\r
2664\r
b3548d32 2665 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
1abfa4ce 2666 @param[in] SystemTable A pointer to the EFI System Table.\r
b3548d32 2667\r
1abfa4ce
JY
2668 @retval EFI_SUCCESS The entry point is executed successfully.\r
2669 @retval other Some error occurs when executing this entry point.\r
2670**/\r
2671EFI_STATUS\r
2672EFIAPI\r
2673DriverEntry (\r
c411b485
MK
2674 IN EFI_HANDLE ImageHandle,\r
2675 IN EFI_SYSTEM_TABLE *SystemTable\r
1abfa4ce
JY
2676 )\r
2677{\r
c411b485
MK
2678 EFI_STATUS Status;\r
2679 EFI_EVENT Event;\r
2680 VOID *Registration;\r
2681 UINT32 MaxCommandSize;\r
2682 UINT32 MaxResponseSize;\r
2683 UINTN Index;\r
2684 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;\r
2685 UINT32 ActivePCRBanks;\r
2686 UINT32 NumberOfPCRBanks;\r
1abfa4ce
JY
2687\r
2688 mImageHandle = ImageHandle;\r
2689\r
c411b485
MK
2690 if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
2691 CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid))\r
2692 {\r
f0f1a3cb 2693 DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
1abfa4ce
JY
2694 return EFI_UNSUPPORTED;\r
2695 }\r
2696\r
2697 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
e905fbb0 2698 DEBUG ((DEBUG_ERROR, "TPM2 error!\n"));\r
1abfa4ce
JY
2699 return EFI_DEVICE_ERROR;\r
2700 }\r
b3548d32 2701\r
1abfa4ce
JY
2702 Status = Tpm2RequestUseTpm ();\r
2703 if (EFI_ERROR (Status)) {\r
e905fbb0 2704 DEBUG ((DEBUG_ERROR, "TPM2 not detected!\n"));\r
1abfa4ce
JY
2705 return Status;\r
2706 }\r
b3548d32 2707\r
1abfa4ce
JY
2708 //\r
2709 // Fill information\r
2710 //\r
c411b485 2711 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof (mTcg2EventInfo)/sizeof (mTcg2EventInfo[0]));\r
b3548d32 2712\r
c411b485
MK
2713 mTcgDxeData.BsCap.Size = sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
2714 mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
2715 mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
1abfa4ce
JY
2716 mTcgDxeData.BsCap.StructureVersion.Major = 1;\r
2717 mTcgDxeData.BsCap.StructureVersion.Minor = 1;\r
2718\r
e905fbb0
MK
2719 DEBUG ((DEBUG_INFO, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));\r
2720 DEBUG ((DEBUG_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));\r
1abfa4ce
JY
2721\r
2722 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);\r
2723 if (EFI_ERROR (Status)) {\r
e905fbb0 2724 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));\r
1abfa4ce 2725 } else {\r
e905fbb0 2726 DEBUG ((DEBUG_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));\r
1abfa4ce
JY
2727 }\r
2728\r
f9f4fb23 2729 DEBUG_CODE_BEGIN ();\r
c411b485
MK
2730 UINT32 FirmwareVersion1;\r
2731 UINT32 FirmwareVersion2;\r
2732\r
2733 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);\r
2734 if (EFI_ERROR (Status)) {\r
2735 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));\r
2736 } else {\r
2737 DEBUG ((DEBUG_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));\r
2738 }\r
1abfa4ce 2739\r
f9f4fb23 2740 DEBUG_CODE_END ();\r
1abfa4ce
JY
2741\r
2742 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);\r
2743 if (EFI_ERROR (Status)) {\r
e905fbb0 2744 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));\r
1abfa4ce
JY
2745 } else {\r
2746 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;\r
2747 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;\r
e905fbb0 2748 DEBUG ((DEBUG_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));\r
1abfa4ce
JY
2749 }\r
2750\r
2751 //\r
2752 // Get supported PCR and current Active PCRs\r
2753 //\r
07cdba18
JY
2754 Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks);\r
2755 ASSERT_EFI_ERROR (Status);\r
2756\r
1abfa4ce 2757 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
c411b485 2758 mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
1abfa4ce 2759\r
a3cad6f8
JY
2760 //\r
2761 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.\r
2762 //\r
2763 NumberOfPCRBanks = 0;\r
2764 for (Index = 0; Index < 32; Index++) {\r
2765 if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {\r
2766 NumberOfPCRBanks++;\r
2767 }\r
2768 }\r
2769\r
1abfa4ce
JY
2770 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {\r
2771 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
2772 } else {\r
2773 mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks);\r
2774 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) {\r
e905fbb0 2775 DEBUG ((DEBUG_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks));\r
1abfa4ce
JY
2776 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
2777 }\r
2778 }\r
2779\r
2780 mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;\r
87361c6a 2781 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {\r
1abfa4ce
JY
2782 //\r
2783 // No need to expose TCG1.2 event log if SHA1 bank does not exist.\r
2784 //\r
87361c6a 2785 mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;\r
1abfa4ce
JY
2786 }\r
2787\r
e905fbb0
MK
2788 DEBUG ((DEBUG_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
2789 DEBUG ((DEBUG_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));\r
2790 DEBUG ((DEBUG_INFO, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks));\r
2791 DEBUG ((DEBUG_INFO, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks));\r
1abfa4ce
JY
2792\r
2793 if (mTcgDxeData.BsCap.TPMPresentFlag) {\r
2794 //\r
2795 // Setup the log area and copy event log from hob list to it\r
2796 //\r
2797 Status = SetupEventLog ();\r
2798 ASSERT_EFI_ERROR (Status);\r
2799\r
2800 //\r
2801 // Measure handoff tables, Boot#### variables etc.\r
2802 //\r
2803 Status = EfiCreateEventReadyToBootEx (\r
2804 TPL_CALLBACK,\r
2805 OnReadyToBoot,\r
2806 NULL,\r
2807 &Event\r
2808 );\r
2809\r
2810 Status = gBS->CreateEventEx (\r
2811 EVT_NOTIFY_SIGNAL,\r
2812 TPL_NOTIFY,\r
2813 OnExitBootServices,\r
2814 NULL,\r
2815 &gEfiEventExitBootServicesGuid,\r
2816 &Event\r
2817 );\r
2818\r
2819 //\r
b3548d32 2820 // Measure Exit Boot Service failed\r
1abfa4ce
JY
2821 //\r
2822 Status = gBS->CreateEventEx (\r
2823 EVT_NOTIFY_SIGNAL,\r
2824 TPL_NOTIFY,\r
2825 OnExitBootServicesFailed,\r
2826 NULL,\r
2827 &gEventExitBootServicesFailedGuid,\r
2828 &Event\r
2829 );\r
2830\r
2831 //\r
2832 // Create event callback, because we need access variable on SecureBootPolicyVariable\r
2833 // We should use VariableWriteArch instead of VariableArch, because Variable driver\r
2834 // may update SecureBoot value based on last setting.\r
2835 //\r
2836 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
9d5dfe9d
RN
2837\r
2838 //\r
2839 // Hook the system reset to properly shutdown TPM.\r
2840 //\r
2841 EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);\r
1abfa4ce
JY
2842 }\r
2843\r
2844 //\r
2845 // Install Tcg2Protocol\r
2846 //\r
2847 Status = InstallTcg2 ();\r
e905fbb0 2848 DEBUG ((DEBUG_INFO, "InstallTcg2 - %r\n", Status));\r
1abfa4ce
JY
2849\r
2850 return Status;\r
2851}\r