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