]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg/Tcg2: Add Support Laml, Lasa for TPM2 ACPI.
[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
a7e2d201
JY
1470 if (PcdGet8(PcdTpm2AcpiTableRev) >= 4) {\r
1471 Status = gBS->AllocatePages (\r
1472 AllocateAnyPages,\r
1473 EfiACPIMemoryNVS,\r
1474 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
1475 &Lasa\r
1476 );\r
1477 } else {\r
1478 Status = gBS->AllocatePages (\r
1479 AllocateAnyPages,\r
1480 EfiBootServicesData,\r
1481 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
1482 &Lasa\r
1483 );\r
1484 }\r
1abfa4ce
JY
1485 if (EFI_ERROR (Status)) {\r
1486 return Status;\r
1487 }\r
1488 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
91e914f5 1489 mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
a7e2d201
JY
1490\r
1491 if ((PcdGet8(PcdTpm2AcpiTableRev) >= 4) ||\r
1492 (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)) {\r
1493 //\r
1494 // Report TCG2 event log address and length, so that they can be reported in TPM2 ACPI table.\r
1495 // Ignore the return status, because those fields are optional.\r
1496 //\r
1497 PcdSet32S(PcdTpm2AcpiTableLaml, (UINT32)mTcgDxeData.EventLogAreaStruct[Index].Laml);\r
1498 PcdSet64S(PcdTpm2AcpiTableLasa, mTcgDxeData.EventLogAreaStruct[Index].Lasa);\r
1499 }\r
1500\r
1abfa4ce 1501 //\r
b3548d32 1502 // To initialize them as 0xFF is recommended\r
1abfa4ce
JY
1503 // because the OS can know the last entry for that.\r
1504 //\r
91e914f5 1505 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
1abfa4ce
JY
1506 //\r
1507 // Create first entry for Log Header Entry Data\r
1508 //\r
1509 if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {\r
1510 //\r
1511 // TcgEfiSpecIdEventStruct\r
1512 //\r
1513 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;\r
1514 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof(TcgEfiSpecIdEventStruct->signature));\r
1515 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);\r
1516 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;\r
1517 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;\r
1518 TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;\r
1519 TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);\r
a9092578
QS
1520 NumberOfAlgorithms = 0;\r
1521 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));\r
1abfa4ce 1522 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
35e00ace
QS
1523 TempDigestSize = DigestSize;\r
1524 TempDigestSize += NumberOfAlgorithms;\r
1525 TempDigestSize->algorithmId = TPM_ALG_SHA1;\r
1526 TempDigestSize->digestSize = SHA1_DIGEST_SIZE;\r
a9092578 1527 NumberOfAlgorithms++;\r
1abfa4ce
JY
1528 }\r
1529 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
35e00ace
QS
1530 TempDigestSize = DigestSize;\r
1531 TempDigestSize += NumberOfAlgorithms;\r
1532 TempDigestSize->algorithmId = TPM_ALG_SHA256;\r
1533 TempDigestSize->digestSize = SHA256_DIGEST_SIZE;\r
a9092578 1534 NumberOfAlgorithms++;\r
1abfa4ce
JY
1535 }\r
1536 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
35e00ace
QS
1537 TempDigestSize = DigestSize;\r
1538 TempDigestSize += NumberOfAlgorithms;\r
1539 TempDigestSize->algorithmId = TPM_ALG_SHA384;\r
1540 TempDigestSize->digestSize = SHA384_DIGEST_SIZE;\r
a9092578 1541 NumberOfAlgorithms++;\r
1abfa4ce
JY
1542 }\r
1543 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
35e00ace
QS
1544 TempDigestSize = DigestSize;\r
1545 TempDigestSize += NumberOfAlgorithms;\r
1546 TempDigestSize->algorithmId = TPM_ALG_SHA512;\r
1547 TempDigestSize->digestSize = SHA512_DIGEST_SIZE;\r
a9092578 1548 NumberOfAlgorithms++;\r
1abfa4ce
JY
1549 }\r
1550 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
35e00ace
QS
1551 TempDigestSize = DigestSize;\r
1552 TempDigestSize += NumberOfAlgorithms;\r
1553 TempDigestSize->algorithmId = TPM_ALG_SM3_256;\r
1554 TempDigestSize->digestSize = SM3_256_DIGEST_SIZE;\r
a9092578 1555 NumberOfAlgorithms++;\r
1abfa4ce 1556 }\r
a9092578 1557 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof(NumberOfAlgorithms));\r
35e00ace
QS
1558 TempDigestSize = DigestSize;\r
1559 TempDigestSize += NumberOfAlgorithms;\r
1560 VendorInfoSize = (UINT8 *)TempDigestSize;\r
a9092578 1561 *VendorInfoSize = 0;\r
1abfa4ce 1562\r
a2612cf7
ZC
1563 SpecIdEvent.PCRIndex = 0;\r
1564 SpecIdEvent.EventType = EV_NO_ACTION;\r
1565 ZeroMem (&SpecIdEvent.Digest, sizeof(SpecIdEvent.Digest));\r
1566 SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
1abfa4ce
JY
1567\r
1568 //\r
a2612cf7
ZC
1569 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.\r
1570 // TCG EFI Protocol Spec. Section 5.3 Event Log Header\r
18458db1 1571 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log\r
1abfa4ce
JY
1572 //\r
1573 Status = TcgDxeLogEvent (\r
1574 mTcg2EventInfo[Index].LogFormat,\r
a2612cf7
ZC
1575 &SpecIdEvent,\r
1576 sizeof(SpecIdEvent),\r
1abfa4ce 1577 (UINT8 *)TcgEfiSpecIdEventStruct,\r
a2612cf7 1578 SpecIdEvent.EventSize\r
1abfa4ce 1579 );\r
18458db1
ZC
1580\r
1581 //\r
a2612cf7 1582 // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2\r
18458db1
ZC
1583 //\r
1584 GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);\r
1585 if (GuidHob.Guid != NULL) {\r
1586 //\r
1587 // Get Locality Indicator from StartupLocality HOB\r
1588 //\r
1589 StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));\r
1590 CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));\r
18458db1
ZC
1591 DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));\r
1592\r
a2612cf7
ZC
1593 //\r
1594 // Initialize StartupLocalityEvent\r
1595 //\r
1596 InitNoActionEvent(&NoActionEvent, sizeof(StartupLocalityEvent));\r
1597\r
18458db1
ZC
1598 //\r
1599 // Log EfiStartupLocalityEvent as the second Event\r
1600 // TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event\r
1601 //\r
1602 Status = TcgDxeLogEvent (\r
1603 mTcg2EventInfo[Index].LogFormat,\r
1604 &NoActionEvent,\r
a2612cf7 1605 sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),\r
18458db1 1606 (UINT8 *)&StartupLocalityEvent,\r
a2612cf7 1607 sizeof(StartupLocalityEvent)\r
18458db1 1608 );\r
a2612cf7 1609\r
18458db1 1610 }\r
1abfa4ce
JY
1611 }\r
1612 }\r
1613 }\r
1614\r
1615 //\r
1616 // 2. Create Final Log Area\r
1617 //\r
1618 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1619 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
fd46e831 1620 if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
fd46e831 1621 Status = gBS->AllocatePages (\r
dc756bae 1622 AllocateAnyPages,\r
fd46e831
JY
1623 EfiACPIMemoryNVS,\r
1624 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),\r
1625 &Lasa\r
1626 );\r
1627 if (EFI_ERROR (Status)) {\r
1628 return Status;\r
1629 }\r
1630 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);\r
1abfa4ce 1631\r
fd46e831
JY
1632 //\r
1633 // Initialize\r
1634 //\r
1635 mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;\r
1636 (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;\r
1637 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;\r
1638\r
1639 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1640 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
1641 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
1642 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
1643 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
1644 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
1645 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
1abfa4ce 1646\r
1abfa4ce 1647 //\r
b3548d32 1648 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2\r
1abfa4ce 1649 //\r
fd46e831 1650 Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
1abfa4ce
JY
1651 if (EFI_ERROR (Status)) {\r
1652 return Status;\r
1653 }\r
fd46e831
JY
1654 } else {\r
1655 //\r
1656 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2\r
1657 //\r
1658 mTcgDxeData.FinalEventsTable[Index] = NULL;\r
1659 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1660 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;\r
1661 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;\r
1662 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
1663 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;\r
1664 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
1665 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
1abfa4ce
JY
1666 }\r
1667 }\r
1668 }\r
b3548d32 1669\r
1abfa4ce
JY
1670 //\r
1671 // 3. Sync data from PEI to DXE\r
1672 //\r
1673 Status = EFI_SUCCESS;\r
1674 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1675 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1676 GuidHob.Raw = GetHobList ();\r
1677 Status = EFI_SUCCESS;\r
b3548d32 1678 while (!EFI_ERROR (Status) &&\r
1abfa4ce 1679 (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
ab5b1f31
SZ
1680 TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));\r
1681 ASSERT (TcgEvent != NULL);\r
1abfa4ce
JY
1682 GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
1683 switch (mTcg2EventInfo[Index].LogFormat) {\r
1684 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
1685 Status = TcgDxeLogEvent (\r
1686 mTcg2EventInfo[Index].LogFormat,\r
1687 TcgEvent,\r
1688 sizeof(TCG_PCR_EVENT_HDR),\r
1689 ((TCG_PCR_EVENT*)TcgEvent)->Event,\r
1690 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize\r
1691 );\r
1692 break;\r
1693 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
ab5b1f31
SZ
1694 DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE);\r
1695 DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
1696 //\r
1697 // Save event size.\r
1698 //\r
1699 CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32));\r
1700 Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32);\r
1701 //\r
1702 // Filter inactive digest in the event2 log from PEI HOB.\r
1703 //\r
1704 CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));\r
1705 EventSizePtr = CopyDigestListBinToBuffer (\r
1706 DigestListBin,\r
1707 &TempDigestListBin,\r
1708 mTcgDxeData.BsCap.ActivePcrBanks,\r
1709 &HashAlgorithmMaskCopied\r
1710 );\r
1711 if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {\r
1712 DEBUG ((\r
1713 DEBUG_ERROR,\r
1714 "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",\r
1715 HashAlgorithmMaskCopied,\r
1716 mTcgDxeData.BsCap.ActivePcrBanks\r
1717 ));\r
1718 }\r
1719 //\r
1720 // Restore event size.\r
1721 //\r
1722 CopyMem (EventSizePtr, &EventSize, sizeof(UINT32));\r
1723 DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
1724\r
1abfa4ce
JY
1725 Status = TcgDxeLogEvent (\r
1726 mTcg2EventInfo[Index].LogFormat,\r
1727 TcgEvent,\r
1728 sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
ab5b1f31 1729 Event,\r
1abfa4ce
JY
1730 EventSize\r
1731 );\r
1732 break;\r
1733 }\r
ab5b1f31 1734 FreePool (TcgEvent);\r
1abfa4ce
JY
1735 }\r
1736 }\r
1737 }\r
1738\r
1739 return Status;\r
1740}\r
1741\r
1742/**\r
c1b0828b 1743 Measure and log an action string, and extend the measurement result into PCR[PCRIndex].\r
1abfa4ce 1744\r
c1b0828b 1745 @param[in] PCRIndex PCRIndex to extend\r
b3548d32
LG
1746 @param[in] String A specific string that indicates an Action event.\r
1747\r
1abfa4ce
JY
1748 @retval EFI_SUCCESS Operation completed successfully.\r
1749 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1750\r
1751**/\r
1752EFI_STATUS\r
1753TcgMeasureAction (\r
c1b0828b
ZC
1754 IN TPM_PCRINDEX PCRIndex,\r
1755 IN CHAR8 *String\r
1abfa4ce
JY
1756 )\r
1757{\r
1758 TCG_PCR_EVENT_HDR TcgEvent;\r
1759\r
c1b0828b 1760 TcgEvent.PCRIndex = PCRIndex;\r
1abfa4ce
JY
1761 TcgEvent.EventType = EV_EFI_ACTION;\r
1762 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
1763 return TcgDxeHashLogExtendEvent (\r
1764 0,\r
1765 (UINT8*)String,\r
1766 TcgEvent.EventSize,\r
1767 &TcgEvent,\r
1768 (UINT8 *) String\r
1769 );\r
1770}\r
1771\r
1772/**\r
1773 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].\r
1774\r
1775 @retval EFI_SUCCESS Operation completed successfully.\r
1776 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1777\r
1778**/\r
1779EFI_STATUS\r
1780MeasureHandoffTables (\r
1781 VOID\r
1782 )\r
1783{\r
1784 EFI_STATUS Status;\r
1abfa4ce
JY
1785 TCG_PCR_EVENT_HDR TcgEvent;\r
1786 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
1787 UINTN ProcessorNum;\r
1788 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
1789\r
1790 ProcessorLocBuf = NULL;\r
d2de4483 1791 Status = EFI_SUCCESS;\r
1abfa4ce
JY
1792\r
1793 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
1794 //\r
b3548d32 1795 // Tcg Server spec.\r
1abfa4ce
JY
1796 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
1797 //\r
1798 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
1799\r
1800 if (!EFI_ERROR(Status)){\r
1801 TcgEvent.PCRIndex = 1;\r
1802 TcgEvent.EventType = EV_TABLE_OF_DEVICES;\r
1803 TcgEvent.EventSize = sizeof (HandoffTables);\r
1804\r
1805 HandoffTables.NumberOfTables = 1;\r
1806 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;\r
1807 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;\r
1808\r
1809 Status = TcgDxeHashLogExtendEvent (\r
1810 0,\r
1811 (UINT8*)(UINTN)ProcessorLocBuf,\r
1812 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
1813 &TcgEvent,\r
1814 (UINT8*)&HandoffTables\r
1815 );\r
1816\r
1817 FreePool(ProcessorLocBuf);\r
1818 }\r
1819 }\r
1820\r
1821 return Status;\r
1822}\r
1823\r
1824/**\r
1825 Measure and log Separator event, and extend the measurement result into a specific PCR.\r
1826\r
b3548d32 1827 @param[in] PCRIndex PCR index.\r
1abfa4ce
JY
1828\r
1829 @retval EFI_SUCCESS Operation completed successfully.\r
1830 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1831\r
1832**/\r
1833EFI_STATUS\r
1834MeasureSeparatorEvent (\r
1835 IN TPM_PCRINDEX PCRIndex\r
1836 )\r
1837{\r
1838 TCG_PCR_EVENT_HDR TcgEvent;\r
1839 UINT32 EventData;\r
1840\r
1841 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));\r
1842\r
1843 EventData = 0;\r
1844 TcgEvent.PCRIndex = PCRIndex;\r
1845 TcgEvent.EventType = EV_SEPARATOR;\r
1846 TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
1847 return TcgDxeHashLogExtendEvent (\r
1848 0,\r
1849 (UINT8 *)&EventData,\r
1850 sizeof (EventData),\r
1851 &TcgEvent,\r
1852 (UINT8 *)&EventData\r
1853 );\r
1854}\r
1855\r
1856/**\r
1857 Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
1858\r
b3548d32
LG
1859 @param[in] PCRIndex PCR Index.\r
1860 @param[in] EventType Event type.\r
1abfa4ce
JY
1861 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1862 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
1863 @param[in] VarData The content of the variable data.\r
1864 @param[in] VarSize The size of the variable data.\r
1865\r
1abfa4ce
JY
1866 @retval EFI_SUCCESS Operation completed successfully.\r
1867 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1868 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1869\r
1870**/\r
1871EFI_STATUS\r
1872MeasureVariable (\r
1873 IN TPM_PCRINDEX PCRIndex,\r
1874 IN TCG_EVENTTYPE EventType,\r
1875 IN CHAR16 *VarName,\r
1876 IN EFI_GUID *VendorGuid,\r
1877 IN VOID *VarData,\r
1878 IN UINTN VarSize\r
1879 )\r
1880{\r
1881 EFI_STATUS Status;\r
1882 TCG_PCR_EVENT_HDR TcgEvent;\r
1883 UINTN VarNameLength;\r
9d77acf1 1884 UEFI_VARIABLE_DATA *VarLog;\r
1abfa4ce
JY
1885\r
1886 DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
1887 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
1888\r
1889 VarNameLength = StrLen (VarName);\r
1890 TcgEvent.PCRIndex = PCRIndex;\r
1891 TcgEvent.EventType = EventType;\r
1892\r
1893 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
1894 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
1895\r
9d77acf1 1896 VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (TcgEvent.EventSize);\r
1abfa4ce
JY
1897 if (VarLog == NULL) {\r
1898 return EFI_OUT_OF_RESOURCES;\r
1899 }\r
1900\r
1901 VarLog->VariableName = *VendorGuid;\r
1902 VarLog->UnicodeNameLength = VarNameLength;\r
1903 VarLog->VariableDataLength = VarSize;\r
1904 CopyMem (\r
1905 VarLog->UnicodeName,\r
1906 VarName,\r
1907 VarNameLength * sizeof (*VarName)\r
1908 );\r
1909 if (VarSize != 0 && VarData != NULL) {\r
1910 CopyMem (\r
1911 (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
1912 VarData,\r
1913 VarSize\r
1914 );\r
1915 }\r
1916\r
1917 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
1918 //\r
9d77acf1 1919 // Digest is the event data (UEFI_VARIABLE_DATA)\r
1abfa4ce
JY
1920 //\r
1921 Status = TcgDxeHashLogExtendEvent (\r
1922 0,\r
1923 (UINT8*)VarLog,\r
1924 TcgEvent.EventSize,\r
1925 &TcgEvent,\r
1926 (UINT8*)VarLog\r
1927 );\r
1928 } else {\r
36e9e3e8 1929 ASSERT (VarData != NULL);\r
1abfa4ce
JY
1930 Status = TcgDxeHashLogExtendEvent (\r
1931 0,\r
1932 (UINT8*)VarData,\r
1933 VarSize,\r
1934 &TcgEvent,\r
1935 (UINT8*)VarLog\r
1936 );\r
1937 }\r
1938 FreePool (VarLog);\r
1939 return Status;\r
1940}\r
1941\r
1942/**\r
1943 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
1944\r
b3548d32
LG
1945 @param[in] PCRIndex PCR Index.\r
1946 @param[in] EventType Event type.\r
1abfa4ce
JY
1947 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1948 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
1949 @param[out] VarSize The size of the variable data.\r
1950 @param[out] VarData Pointer to the content of the variable.\r
1951\r
1abfa4ce
JY
1952 @retval EFI_SUCCESS Operation completed successfully.\r
1953 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1954 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1955\r
1956**/\r
1957EFI_STATUS\r
1958ReadAndMeasureVariable (\r
1959 IN TPM_PCRINDEX PCRIndex,\r
1960 IN TCG_EVENTTYPE EventType,\r
1961 IN CHAR16 *VarName,\r
1962 IN EFI_GUID *VendorGuid,\r
1963 OUT UINTN *VarSize,\r
1964 OUT VOID **VarData\r
1965 )\r
1966{\r
1967 EFI_STATUS Status;\r
1968\r
1969 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);\r
1970 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
1971 if (EFI_ERROR (Status)) {\r
1972 //\r
1973 // It is valid case, so we need handle it.\r
1974 //\r
1975 *VarData = NULL;\r
1976 *VarSize = 0;\r
1977 }\r
1978 } else {\r
1979 //\r
1980 // if status error, VarData is freed and set NULL by GetVariable2\r
1981 //\r
1982 if (EFI_ERROR (Status)) {\r
1983 return EFI_NOT_FOUND;\r
1984 }\r
1985 }\r
1986\r
1987 Status = MeasureVariable (\r
1988 PCRIndex,\r
1989 EventType,\r
1990 VarName,\r
1991 VendorGuid,\r
1992 *VarData,\r
1993 *VarSize\r
1994 );\r
1995 return Status;\r
1996}\r
1997\r
1998/**\r
fe13f92b
ZC
1999 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].\r
2000according to TCG PC Client PFP spec 0021 Section 2.4.4.2\r
1abfa4ce
JY
2001\r
2002 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
2003 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
2004 @param[out] VarSize The size of the variable data.\r
2005 @param[out] VarData Pointer to the content of the variable.\r
2006\r
1abfa4ce
JY
2007 @retval EFI_SUCCESS Operation completed successfully.\r
2008 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2009 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2010\r
2011**/\r
2012EFI_STATUS\r
2013ReadAndMeasureBootVariable (\r
2014 IN CHAR16 *VarName,\r
2015 IN EFI_GUID *VendorGuid,\r
2016 OUT UINTN *VarSize,\r
2017 OUT VOID **VarData\r
2018 )\r
2019{\r
2020 return ReadAndMeasureVariable (\r
fe13f92b 2021 1,\r
1abfa4ce
JY
2022 EV_EFI_VARIABLE_BOOT,\r
2023 VarName,\r
2024 VendorGuid,\r
2025 VarSize,\r
2026 VarData\r
2027 );\r
2028}\r
2029\r
2030/**\r
2031 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].\r
2032\r
2033 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
2034 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
2035 @param[out] VarSize The size of the variable data.\r
2036 @param[out] VarData Pointer to the content of the variable.\r
2037\r
1abfa4ce
JY
2038 @retval EFI_SUCCESS Operation completed successfully.\r
2039 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2040 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2041\r
2042**/\r
2043EFI_STATUS\r
2044ReadAndMeasureSecureVariable (\r
2045 IN CHAR16 *VarName,\r
2046 IN EFI_GUID *VendorGuid,\r
2047 OUT UINTN *VarSize,\r
2048 OUT VOID **VarData\r
2049 )\r
2050{\r
2051 return ReadAndMeasureVariable (\r
2052 7,\r
2053 EV_EFI_VARIABLE_DRIVER_CONFIG,\r
2054 VarName,\r
2055 VendorGuid,\r
2056 VarSize,\r
2057 VarData\r
2058 );\r
2059}\r
2060\r
2061/**\r
2062 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.\r
2063\r
2064 The EFI boot variables are BootOrder and Boot#### variables.\r
2065\r
2066 @retval EFI_SUCCESS Operation completed successfully.\r
2067 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2068 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2069\r
2070**/\r
2071EFI_STATUS\r
2072MeasureAllBootVariables (\r
2073 VOID\r
2074 )\r
2075{\r
2076 EFI_STATUS Status;\r
2077 UINT16 *BootOrder;\r
2078 UINTN BootCount;\r
2079 UINTN Index;\r
2080 VOID *BootVarData;\r
2081 UINTN Size;\r
2082\r
2083 Status = ReadAndMeasureBootVariable (\r
2084 mBootVarName,\r
2085 &gEfiGlobalVariableGuid,\r
2086 &BootCount,\r
2087 (VOID **) &BootOrder\r
2088 );\r
2089 if (Status == EFI_NOT_FOUND || BootOrder == NULL) {\r
2090 return EFI_SUCCESS;\r
2091 }\r
2092\r
2093 if (EFI_ERROR (Status)) {\r
2094 //\r
2095 // BootOrder can't be NULL if status is not EFI_NOT_FOUND\r
2096 //\r
2097 FreePool (BootOrder);\r
2098 return Status;\r
2099 }\r
2100\r
2101 BootCount /= sizeof (*BootOrder);\r
2102 for (Index = 0; Index < BootCount; Index++) {\r
2103 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);\r
2104 Status = ReadAndMeasureBootVariable (\r
2105 mBootVarName,\r
2106 &gEfiGlobalVariableGuid,\r
2107 &Size,\r
2108 &BootVarData\r
2109 );\r
2110 if (!EFI_ERROR (Status)) {\r
2111 FreePool (BootVarData);\r
2112 }\r
2113 }\r
2114\r
2115 FreePool (BootOrder);\r
2116 return EFI_SUCCESS;\r
2117}\r
2118\r
2119/**\r
2120 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.\r
2121\r
2122 The EFI boot variables are BootOrder and Boot#### variables.\r
2123\r
2124 @retval EFI_SUCCESS Operation completed successfully.\r
2125 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2126 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2127\r
2128**/\r
2129EFI_STATUS\r
2130MeasureAllSecureVariables (\r
2131 VOID\r
2132 )\r
2133{\r
2134 EFI_STATUS Status;\r
2135 VOID *Data;\r
2136 UINTN DataSize;\r
2137 UINTN Index;\r
2138\r
2139 Status = EFI_NOT_FOUND;\r
2140 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
2141 Status = ReadAndMeasureSecureVariable (\r
2142 mVariableType[Index].VariableName,\r
2143 mVariableType[Index].VendorGuid,\r
2144 &DataSize,\r
2145 &Data\r
2146 );\r
2147 if (!EFI_ERROR (Status)) {\r
2148 if (Data != NULL) {\r
2149 FreePool (Data);\r
2150 }\r
2151 }\r
2152 }\r
2153\r
400b0940
ZC
2154 //\r
2155 // Measure DBT if present and not empty\r
2156 //\r
2157 Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);\r
2158 if (!EFI_ERROR(Status)) {\r
2159 Status = MeasureVariable (\r
2160 7,\r
2161 EV_EFI_VARIABLE_DRIVER_CONFIG,\r
2162 EFI_IMAGE_SECURITY_DATABASE2,\r
2163 &gEfiImageSecurityDatabaseGuid,\r
2164 Data,\r
2165 DataSize\r
2166 );\r
2167 FreePool(Data);\r
2168 } else {\r
2169 DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));\r
2170 }\r
2171\r
1abfa4ce
JY
2172 return EFI_SUCCESS;\r
2173}\r
2174\r
2175/**\r
2176 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.\r
2177\r
2178 @retval EFI_SUCCESS Operation completed successfully.\r
2179 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2180 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2181\r
2182**/\r
2183EFI_STATUS\r
2184MeasureLaunchOfFirmwareDebugger (\r
2185 VOID\r
2186 )\r
2187{\r
2188 TCG_PCR_EVENT_HDR TcgEvent;\r
2189\r
2190 TcgEvent.PCRIndex = 7;\r
2191 TcgEvent.EventType = EV_EFI_ACTION;\r
2192 TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;\r
2193 return TcgDxeHashLogExtendEvent (\r
2194 0,\r
2195 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,\r
2196 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,\r
2197 &TcgEvent,\r
2198 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING\r
2199 );\r
2200}\r
2201\r
2202/**\r
2203 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.\r
2204\r
2205 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)\r
2206 - The contents of the SecureBoot variable\r
2207 - The contents of the PK variable\r
2208 - The contents of the KEK variable\r
2209 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable\r
2210 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable\r
2211 - Separator\r
2212 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path\r
2213\r
2214 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,\r
2215 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].\r
2216\r
2217 @param[in] Event Event whose notification function is being invoked\r
2218 @param[in] Context Pointer to the notification function's context\r
2219**/\r
2220VOID\r
2221EFIAPI\r
2222MeasureSecureBootPolicy (\r
2223 IN EFI_EVENT Event,\r
2224 IN VOID *Context\r
2225 )\r
2226{\r
2227 EFI_STATUS Status;\r
2228 VOID *Protocol;\r
2229\r
2230 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);\r
2231 if (EFI_ERROR (Status)) {\r
2232 return;\r
2233 }\r
2234\r
2235 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {\r
2236 Status = MeasureLaunchOfFirmwareDebugger ();\r
2237 DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));\r
2238 }\r
2239\r
2240 Status = MeasureAllSecureVariables ();\r
2241 DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));\r
2242\r
2243 //\r
2244 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)\r
2245 // and ImageVerification (Authority)\r
2246 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So\r
2247 // the Authority measurement happen before ReadToBoot event.\r
2248 //\r
2249 Status = MeasureSeparatorEvent (7);\r
2250 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));\r
2251 return ;\r
2252}\r
2253\r
2254/**\r
2255 Ready to Boot Event notification handler.\r
2256\r
2257 Sequence of OS boot events is measured in this event notification handler.\r
2258\r
2259 @param[in] Event Event whose notification function is being invoked\r
2260 @param[in] Context Pointer to the notification function's context\r
2261\r
2262**/\r
2263VOID\r
2264EFIAPI\r
2265OnReadyToBoot (\r
2266 IN EFI_EVENT Event,\r
2267 IN VOID *Context\r
2268 )\r
2269{\r
2270 EFI_STATUS Status;\r
2271 TPM_PCRINDEX PcrIndex;\r
2272\r
2273 PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE);\r
2274 if (mBootAttempts == 0) {\r
2275\r
2276 //\r
2277 // Measure handoff tables.\r
2278 //\r
2279 Status = MeasureHandoffTables ();\r
2280 if (EFI_ERROR (Status)) {\r
2281 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));\r
2282 }\r
2283\r
2284 //\r
2285 // Measure BootOrder & Boot#### variables.\r
2286 //\r
2287 Status = MeasureAllBootVariables ();\r
2288 if (EFI_ERROR (Status)) {\r
2289 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));\r
2290 }\r
2291\r
2292 //\r
2293 // 1. This is the first boot attempt.\r
2294 //\r
2295 Status = TcgMeasureAction (\r
c1b0828b 2296 4,\r
1abfa4ce
JY
2297 EFI_CALLING_EFI_APPLICATION\r
2298 );\r
2299 if (EFI_ERROR (Status)) {\r
655dabe3 2300 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
1abfa4ce
JY
2301 }\r
2302\r
2303 //\r
2304 // 2. Draw a line between pre-boot env and entering post-boot env.\r
2305 // PCR[7] is already done.\r
2306 //\r
2307 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
2308 Status = MeasureSeparatorEvent (PcrIndex);\r
2309 if (EFI_ERROR (Status)) {\r
0ab475c9 2310 DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));\r
1abfa4ce
JY
2311 }\r
2312 }\r
2313\r
2314 //\r
2315 // 3. Measure GPT. It would be done in SAP driver.\r
2316 //\r
2317\r
2318 //\r
2319 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.\r
2320 //\r
2321\r
2322 //\r
2323 // 5. Read & Measure variable. BootOrder already measured.\r
2324 //\r
2325 } else {\r
2326 //\r
2327 // 6. Not first attempt, meaning a return from last attempt\r
2328 //\r
2329 Status = TcgMeasureAction (\r
c1b0828b 2330 4,\r
5f3b0250 2331 EFI_RETURNING_FROM_EFI_APPLICATION\r
1abfa4ce
JY
2332 );\r
2333 if (EFI_ERROR (Status)) {\r
5f3b0250 2334 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));\r
1abfa4ce 2335 }\r
c1b0828b
ZC
2336\r
2337 //\r
2338 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again\r
2339 // TCG PC Client PFP spec Section 2.4.4.5 Step 4\r
2340 //\r
2341 Status = TcgMeasureAction (\r
2342 4,\r
2343 EFI_CALLING_EFI_APPLICATION\r
2344 );\r
2345 if (EFI_ERROR (Status)) {\r
2346 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
2347 }\r
1abfa4ce
JY
2348 }\r
2349\r
2350 DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));\r
2351 //\r
2352 // Increase boot attempt counter.\r
2353 //\r
2354 mBootAttempts++;\r
2355 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1);\r
2356}\r
2357\r
2358/**\r
2359 Exit Boot Services Event notification handler.\r
2360\r
2361 Measure invocation and success of ExitBootServices.\r
2362\r
2363 @param[in] Event Event whose notification function is being invoked\r
2364 @param[in] Context Pointer to the notification function's context\r
2365\r
2366**/\r
2367VOID\r
2368EFIAPI\r
2369OnExitBootServices (\r
2370 IN EFI_EVENT Event,\r
2371 IN VOID *Context\r
2372 )\r
2373{\r
2374 EFI_STATUS Status;\r
2375\r
2376 //\r
2377 // Measure invocation of ExitBootServices,\r
2378 //\r
2379 Status = TcgMeasureAction (\r
c1b0828b 2380 5,\r
1abfa4ce
JY
2381 EFI_EXIT_BOOT_SERVICES_INVOCATION\r
2382 );\r
2383 if (EFI_ERROR (Status)) {\r
655dabe3 2384 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));\r
1abfa4ce
JY
2385 }\r
2386\r
2387 //\r
2388 // Measure success of ExitBootServices\r
2389 //\r
2390 Status = TcgMeasureAction (\r
c1b0828b 2391 5,\r
1abfa4ce
JY
2392 EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
2393 );\r
2394 if (EFI_ERROR (Status)) {\r
655dabe3 2395 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));\r
1abfa4ce
JY
2396 }\r
2397}\r
2398\r
2399/**\r
2400 Exit Boot Services Failed Event notification handler.\r
2401\r
2402 Measure Failure of ExitBootServices.\r
2403\r
2404 @param[in] Event Event whose notification function is being invoked\r
2405 @param[in] Context Pointer to the notification function's context\r
2406\r
2407**/\r
2408VOID\r
2409EFIAPI\r
2410OnExitBootServicesFailed (\r
2411 IN EFI_EVENT Event,\r
2412 IN VOID *Context\r
2413 )\r
2414{\r
2415 EFI_STATUS Status;\r
2416\r
2417 //\r
2418 // Measure Failure of ExitBootServices,\r
2419 //\r
2420 Status = TcgMeasureAction (\r
c1b0828b 2421 5,\r
1abfa4ce
JY
2422 EFI_EXIT_BOOT_SERVICES_FAILED\r
2423 );\r
2424 if (EFI_ERROR (Status)) {\r
655dabe3 2425 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));\r
1abfa4ce
JY
2426 }\r
2427\r
2428}\r
2429\r
9d5dfe9d
RN
2430/**\r
2431 This routine is called to properly shutdown the TPM before system reset.\r
2432 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
2433 Part 1: Architecture, Revision 01.16.\r
2434\r
2435 @param[in] ResetType The type of reset to perform.\r
2436 @param[in] ResetStatus The status code for the reset.\r
2437 @param[in] DataSize The size, in bytes, of ResetData.\r
2438 @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or\r
2439 EfiResetShutdown the data buffer starts with a Null-terminated\r
2440 string, optionally followed by additional binary data.\r
2441 The string is a description that the caller may use to further\r
930fcd9f 2442 indicate the reason for the system reset.\r
9d5dfe9d
RN
2443 For a ResetType of EfiResetPlatformSpecific the data buffer\r
2444 also starts with a Null-terminated string that is followed\r
2445 by an EFI_GUID that describes the specific type of reset to perform.\r
2446**/\r
2447VOID\r
2448EFIAPI\r
2449ShutdownTpmOnReset (\r
2450 IN EFI_RESET_TYPE ResetType,\r
2451 IN EFI_STATUS ResetStatus,\r
2452 IN UINTN DataSize,\r
2453 IN VOID *ResetData OPTIONAL\r
2454 )\r
2455{\r
2456 EFI_STATUS Status;\r
2457 Status = Tpm2Shutdown (TPM_SU_CLEAR);\r
2458 DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));\r
2459}\r
2460\r
2461/**\r
2462 Hook the system reset to properly shutdown TPM.\r
2463 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
2464 Part 1: Architecture, Revision 01.16.\r
2465\r
2466 @param[in] Event Event whose notification function is being invoked\r
2467 @param[in] Context Pointer to the notification function's context\r
2468**/\r
2469VOID\r
2470EFIAPI\r
2471OnResetNotificationInstall (\r
2472 IN EFI_EVENT Event,\r
2473 IN VOID *Context\r
2474 )\r
2475{\r
2476 EFI_STATUS Status;\r
2477 EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;\r
2478\r
2479 Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);\r
2480 if (!EFI_ERROR (Status)) {\r
2481 Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);\r
2482 ASSERT_EFI_ERROR (Status);\r
2483 DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));\r
2484\r
2485 gBS->CloseEvent (Event);\r
2486 }\r
2487}\r
2488\r
1abfa4ce
JY
2489/**\r
2490 The function install Tcg2 protocol.\r
b3548d32 2491\r
1abfa4ce
JY
2492 @retval EFI_SUCCESS Tcg2 protocol is installed.\r
2493 @retval other Some error occurs.\r
2494**/\r
2495EFI_STATUS\r
2496InstallTcg2 (\r
2497 VOID\r
2498 )\r
2499{\r
2500 EFI_STATUS Status;\r
2501 EFI_HANDLE Handle;\r
2502\r
2503 Handle = NULL;\r
2504 Status = gBS->InstallMultipleProtocolInterfaces (\r
2505 &Handle,\r
2506 &gEfiTcg2ProtocolGuid,\r
2507 &mTcg2Protocol,\r
2508 NULL\r
2509 );\r
2510 return Status;\r
2511}\r
2512\r
2513/**\r
2514 The driver's entry point. It publishes EFI Tcg2 Protocol.\r
2515\r
b3548d32 2516 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
1abfa4ce 2517 @param[in] SystemTable A pointer to the EFI System Table.\r
b3548d32 2518\r
1abfa4ce
JY
2519 @retval EFI_SUCCESS The entry point is executed successfully.\r
2520 @retval other Some error occurs when executing this entry point.\r
2521**/\r
2522EFI_STATUS\r
2523EFIAPI\r
2524DriverEntry (\r
2525 IN EFI_HANDLE ImageHandle,\r
2526 IN EFI_SYSTEM_TABLE *SystemTable\r
2527 )\r
2528{\r
2529 EFI_STATUS Status;\r
2530 EFI_EVENT Event;\r
2531 VOID *Registration;\r
2532 UINT32 MaxCommandSize;\r
2533 UINT32 MaxResponseSize;\r
1abfa4ce
JY
2534 UINTN Index;\r
2535 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;\r
2536 UINT32 ActivePCRBanks;\r
2537 UINT32 NumberOfPCRBanks;\r
2538\r
2539 mImageHandle = ImageHandle;\r
2540\r
2541 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
2542 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
f0f1a3cb 2543 DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
1abfa4ce
JY
2544 return EFI_UNSUPPORTED;\r
2545 }\r
2546\r
2547 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
2548 DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
2549 return EFI_DEVICE_ERROR;\r
2550 }\r
b3548d32 2551\r
1abfa4ce
JY
2552 Status = Tpm2RequestUseTpm ();\r
2553 if (EFI_ERROR (Status)) {\r
2554 DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
2555 return Status;\r
2556 }\r
b3548d32 2557\r
1abfa4ce
JY
2558 //\r
2559 // Fill information\r
2560 //\r
2561 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));\r
b3548d32 2562\r
1abfa4ce
JY
2563 mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
2564 mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
2565 mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
2566 mTcgDxeData.BsCap.StructureVersion.Major = 1;\r
2567 mTcgDxeData.BsCap.StructureVersion.Minor = 1;\r
2568\r
2569 DEBUG ((EFI_D_INFO, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));\r
2570 DEBUG ((EFI_D_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));\r
2571\r
2572 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);\r
2573 if (EFI_ERROR (Status)) {\r
2574 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));\r
2575 } else {\r
2576 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));\r
2577 }\r
2578\r
2579 DEBUG_CODE (\r
2580 UINT32 FirmwareVersion1;\r
2581 UINT32 FirmwareVersion2;\r
2582\r
2583 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);\r
2584 if (EFI_ERROR (Status)) {\r
2585 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));\r
2586 } else {\r
2587 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));\r
2588 }\r
2589 );\r
2590\r
2591 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);\r
2592 if (EFI_ERROR (Status)) {\r
2593 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));\r
2594 } else {\r
2595 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;\r
2596 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;\r
2597 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));\r
2598 }\r
2599\r
2600 //\r
2601 // Get supported PCR and current Active PCRs\r
2602 //\r
07cdba18
JY
2603 Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks);\r
2604 ASSERT_EFI_ERROR (Status);\r
2605\r
1abfa4ce
JY
2606 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
2607 mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
2608\r
a3cad6f8
JY
2609 //\r
2610 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.\r
2611 //\r
2612 NumberOfPCRBanks = 0;\r
2613 for (Index = 0; Index < 32; Index++) {\r
2614 if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {\r
2615 NumberOfPCRBanks++;\r
2616 }\r
2617 }\r
2618\r
1abfa4ce
JY
2619 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {\r
2620 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
2621 } else {\r
2622 mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks);\r
2623 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) {\r
2624 DEBUG ((EFI_D_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks));\r
2625 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
2626 }\r
2627 }\r
2628\r
2629 mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;\r
87361c6a 2630 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {\r
1abfa4ce
JY
2631 //\r
2632 // No need to expose TCG1.2 event log if SHA1 bank does not exist.\r
2633 //\r
87361c6a 2634 mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;\r
1abfa4ce
JY
2635 }\r
2636\r
2637 DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
2638 DEBUG ((EFI_D_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));\r
2639 DEBUG ((EFI_D_INFO, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks));\r
2640 DEBUG ((EFI_D_INFO, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks));\r
2641\r
2642 if (mTcgDxeData.BsCap.TPMPresentFlag) {\r
2643 //\r
2644 // Setup the log area and copy event log from hob list to it\r
2645 //\r
2646 Status = SetupEventLog ();\r
2647 ASSERT_EFI_ERROR (Status);\r
2648\r
2649 //\r
2650 // Measure handoff tables, Boot#### variables etc.\r
2651 //\r
2652 Status = EfiCreateEventReadyToBootEx (\r
2653 TPL_CALLBACK,\r
2654 OnReadyToBoot,\r
2655 NULL,\r
2656 &Event\r
2657 );\r
2658\r
2659 Status = gBS->CreateEventEx (\r
2660 EVT_NOTIFY_SIGNAL,\r
2661 TPL_NOTIFY,\r
2662 OnExitBootServices,\r
2663 NULL,\r
2664 &gEfiEventExitBootServicesGuid,\r
2665 &Event\r
2666 );\r
2667\r
2668 //\r
b3548d32 2669 // Measure Exit Boot Service failed\r
1abfa4ce
JY
2670 //\r
2671 Status = gBS->CreateEventEx (\r
2672 EVT_NOTIFY_SIGNAL,\r
2673 TPL_NOTIFY,\r
2674 OnExitBootServicesFailed,\r
2675 NULL,\r
2676 &gEventExitBootServicesFailedGuid,\r
2677 &Event\r
2678 );\r
2679\r
2680 //\r
2681 // Create event callback, because we need access variable on SecureBootPolicyVariable\r
2682 // We should use VariableWriteArch instead of VariableArch, because Variable driver\r
2683 // may update SecureBoot value based on last setting.\r
2684 //\r
2685 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
9d5dfe9d
RN
2686\r
2687 //\r
2688 // Hook the system reset to properly shutdown TPM.\r
2689 //\r
2690 EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);\r
1abfa4ce
JY
2691 }\r
2692\r
2693 //\r
2694 // Install Tcg2Protocol\r
2695 //\r
2696 Status = InstallTcg2 ();\r
2697 DEBUG ((EFI_D_INFO, "InstallTcg2 - %r\n", Status));\r
2698\r
2699 return Status;\r
2700}\r