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