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