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