]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg/TPM2: Move GetDigestFromDigestList() to Tpm2CommandLib
[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 data size.\r
868\r
869 @param[in] DigestList TPML_DIGEST_VALUES data.\r
870\r
871 @return TPML_DIGEST_VALUES data size.\r
872**/\r
873UINT32\r
874GetDigestListSize (\r
875 IN TPML_DIGEST_VALUES *DigestList\r
876 )\r
877{\r
878 UINTN Index;\r
879 UINT16 DigestSize;\r
880 UINT32 TotalSize;\r
881\r
882 TotalSize = sizeof(DigestList->count);\r
883 for (Index = 0; Index < DigestList->count; Index++) {\r
884 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
885 TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize;\r
886 }\r
887\r
888 return TotalSize;\r
889}\r
890\r
891/**\r
892 Get TPML_DIGEST_VALUES compact binary buffer size.\r
893\r
894 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.\r
895\r
896 @return TPML_DIGEST_VALUES compact binary buffer size.\r
897**/\r
898UINT32\r
899GetDigestListBinSize (\r
900 IN VOID *DigestListBin\r
901 )\r
902{\r
903 UINTN Index;\r
904 UINT16 DigestSize;\r
905 UINT32 TotalSize;\r
906 UINT32 Count;\r
907 TPMI_ALG_HASH HashAlg;\r
908\r
909 Count = ReadUnaligned32 (DigestListBin);\r
910 TotalSize = sizeof(Count);\r
911 DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);\r
912 for (Index = 0; Index < Count; Index++) {\r
913 HashAlg = ReadUnaligned16 (DigestListBin);\r
914 TotalSize += sizeof(HashAlg);\r
915 DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);\r
916\r
917 DigestSize = GetHashSizeFromAlgo (HashAlg);\r
918 TotalSize += DigestSize;\r
919 DigestListBin = (UINT8 *)DigestListBin + DigestSize;\r
920 }\r
921\r
922 return TotalSize;\r
923}\r
924\r
925/**\r
926 Return if hash alg is supported in TPM PCR bank.\r
927\r
928 @param HashAlg Hash algorithm to be checked.\r
929\r
930 @retval TRUE Hash algorithm is supported.\r
931 @retval FALSE Hash algorithm is not supported.\r
932**/\r
933BOOLEAN\r
934IsHashAlgSupportedInPcrBank (\r
935 IN TPMI_ALG_HASH HashAlg\r
936 )\r
937{\r
938 switch (HashAlg) {\r
939 case TPM_ALG_SHA1:\r
940 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
941 return TRUE;\r
942 }\r
943 break;\r
944 case TPM_ALG_SHA256:\r
945 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
946 return TRUE;\r
947 }\r
948 break;\r
949 case TPM_ALG_SHA384:\r
950 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
951 return TRUE;\r
952 }\r
953 break;\r
954 case TPM_ALG_SHA512:\r
955 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
956 return TRUE;\r
957 }\r
958 break;\r
959 case TPM_ALG_SM3_256:\r
960 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
961 return TRUE;\r
962 }\r
963 break;\r
964 }\r
965\r
966 return FALSE;\r
967}\r
968\r
969/**\r
970 Copy TPML_DIGEST_VALUES into a buffer\r
971\r
972 @param[in,out] Buffer Buffer to hold TPML_DIGEST_VALUES.\r
973 @param[in] DigestList TPML_DIGEST_VALUES to be copied.\r
974\r
975 @return The end of buffer to hold TPML_DIGEST_VALUES.\r
976**/\r
977VOID *\r
978CopyDigestListToBuffer (\r
979 IN OUT VOID *Buffer,\r
980 IN TPML_DIGEST_VALUES *DigestList\r
981 )\r
982{\r
983 UINTN Index;\r
984 UINT16 DigestSize;\r
985\r
986 CopyMem (Buffer, &DigestList->count, sizeof(DigestList->count));\r
987 Buffer = (UINT8 *)Buffer + sizeof(DigestList->count);\r
988 for (Index = 0; Index < DigestList->count; Index++) {\r
989 if (!IsHashAlgSupportedInPcrBank (DigestList->digests[Index].hashAlg)) {\r
990 DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));\r
991 continue;\r
992 }\r
993 CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg));\r
994 Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg);\r
995 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
996 CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);\r
997 Buffer = (UINT8 *)Buffer + DigestSize;\r
998 }\r
999\r
1000 return Buffer;\r
1001}\r
1002\r
1003/**\r
1004 Add a new entry to the Event Log.\r
1005\r
1006 @param[in] DigestList A list of digest.\r
1007 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
1008 @param[in] NewEventData Pointer to the new event data.\r
1009\r
1010 @retval EFI_SUCCESS The new event log entry was added.\r
1011 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
1012**/\r
1013EFI_STATUS\r
1014TcgDxeLogHashEvent (\r
1015 IN TPML_DIGEST_VALUES *DigestList,\r
1016 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
1017 IN UINT8 *NewEventData\r
1018 )\r
1019{\r
1020 EFI_STATUS Status;\r
1021 EFI_TPL OldTpl;\r
1022 UINTN Index;\r
1023 EFI_STATUS RetStatus;\r
1024 TCG_PCR_EVENT2 TcgPcrEvent2;\r
1025 UINT8 *DigestBuffer;\r
1026\r
1027 DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
1028\r
1029 RetStatus = EFI_SUCCESS;\r
1030 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1031 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1032 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));\r
1033 switch (mTcg2EventInfo[Index].LogFormat) {\r
1034 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
d4b9b2c3 1035 Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
1abfa4ce
JY
1036 if (!EFI_ERROR (Status)) {\r
1037 //\r
1038 // Enter critical region\r
1039 //\r
1040 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
1041 Status = TcgDxeLogEvent (\r
1042 mTcg2EventInfo[Index].LogFormat,\r
1043 NewEventHdr,\r
1044 sizeof(TCG_PCR_EVENT_HDR),\r
1045 NewEventData,\r
1046 NewEventHdr->EventSize\r
1047 );\r
1048 if (Status != EFI_SUCCESS) {\r
1049 RetStatus = Status;\r
1050 }\r
1051 gBS->RestoreTPL (OldTpl);\r
1052 //\r
1053 // Exit critical region\r
1054 //\r
1055 }\r
1056 break;\r
1057 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
1058 ZeroMem (&TcgPcrEvent2, sizeof(TcgPcrEvent2));\r
1059 TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;\r
1060 TcgPcrEvent2.EventType = NewEventHdr->EventType;\r
1061 DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;\r
1062 DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList);\r
1063 CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));\r
1064 DigestBuffer = DigestBuffer + sizeof(NewEventHdr->EventSize);\r
1065\r
1066 //\r
1067 // Enter critical region\r
1068 //\r
1069 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
1070 Status = TcgDxeLogEvent (\r
1071 mTcg2EventInfo[Index].LogFormat,\r
1072 &TcgPcrEvent2,\r
1073 sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2.EventSize),\r
1074 NewEventData,\r
1075 NewEventHdr->EventSize\r
1076 );\r
1077 if (Status != EFI_SUCCESS) {\r
1078 RetStatus = Status;\r
1079 }\r
1080 gBS->RestoreTPL (OldTpl);\r
1081 //\r
1082 // Exit critical region\r
1083 //\r
1084 break;\r
1085 }\r
1086 }\r
1087 }\r
1088\r
1089 return RetStatus;\r
1090}\r
1091\r
1092/**\r
1093 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
1094 and add an entry to the Event Log.\r
1095\r
1096 @param[in] Flags Bitmap providing additional information.\r
1097 @param[in] HashData Physical address of the start of the data buffer \r
1098 to be hashed, extended, and logged.\r
1099 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
1100 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
1101 @param[in] NewEventData Pointer to the new event data. \r
1102\r
1103 @retval EFI_SUCCESS Operation completed successfully.\r
1104 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
1105 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
1106\r
1107**/\r
1108EFI_STATUS\r
1109TcgDxeHashLogExtendEvent (\r
1110 IN UINT64 Flags,\r
1111 IN UINT8 *HashData,\r
1112 IN UINT64 HashDataLen,\r
1113 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
1114 IN UINT8 *NewEventData\r
1115 )\r
1116{\r
1117 EFI_STATUS Status;\r
1118 TPML_DIGEST_VALUES DigestList;\r
1119\r
1120 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1121 return EFI_DEVICE_ERROR;\r
1122 }\r
1123\r
1124 Status = HashAndExtend (\r
1125 NewEventHdr->PCRIndex,\r
1126 HashData,\r
1127 (UINTN)HashDataLen,\r
1128 &DigestList\r
1129 );\r
1130 if (!EFI_ERROR (Status)) {\r
1131 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
1132 Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
1133 }\r
1134 }\r
1135\r
1136 if (Status == EFI_DEVICE_ERROR) {\r
1137 DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));\r
1138 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
1139 REPORT_STATUS_CODE (\r
1140 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
1141 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
1142 );\r
1143 }\r
1144\r
1145 return Status;\r
1146}\r
1147\r
1148/**\r
1149 The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with\r
1150 an opportunity to extend and optionally log events without requiring\r
1151 knowledge of actual TPM commands. \r
1152 The extend operation will occur even if this function cannot create an event\r
1153 log entry (e.g. due to the event log being full). \r
1154\r
1155 @param[in] This Indicates the calling context\r
1156 @param[in] Flags Bitmap providing additional information.\r
1157 @param[in] DataToHash Physical address of the start of the data buffer to be hashed. \r
1158 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.\r
1159 @param[in] Event Pointer to data buffer containing information about the event.\r
1160\r
1161 @retval EFI_SUCCESS Operation completed successfully.\r
1162 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
1163 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.\r
1164 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1165 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.\r
1166**/\r
1167EFI_STATUS\r
1168EFIAPI\r
1169Tcg2HashLogExtendEvent (\r
1170 IN EFI_TCG2_PROTOCOL *This,\r
1171 IN UINT64 Flags,\r
1172 IN EFI_PHYSICAL_ADDRESS DataToHash,\r
1173 IN UINT64 DataToHashLen,\r
1174 IN EFI_TCG2_EVENT *Event\r
1175 )\r
1176{\r
1177 EFI_STATUS Status;\r
1178 TCG_PCR_EVENT_HDR NewEventHdr;\r
1179 TPML_DIGEST_VALUES DigestList;\r
1180\r
336dbfd1 1181 DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));\r
1abfa4ce
JY
1182\r
1183 if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {\r
1184 return EFI_INVALID_PARAMETER;\r
1185 }\r
1186\r
1187 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1188 return EFI_DEVICE_ERROR;\r
1189 }\r
1190\r
1191 if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {\r
1192 return EFI_INVALID_PARAMETER;\r
1193 }\r
1194\r
1195 if (Event->Header.PCRIndex > MAX_PCR_INDEX) {\r
1196 return EFI_INVALID_PARAMETER;\r
1197 }\r
1198\r
1199 NewEventHdr.PCRIndex = Event->Header.PCRIndex;\r
1200 NewEventHdr.EventType = Event->Header.EventType;\r
1201 NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;\r
1202 if ((Flags & PE_COFF_IMAGE) != 0) {\r
1203 Status = MeasurePeImageAndExtend (\r
1204 NewEventHdr.PCRIndex,\r
1205 DataToHash,\r
1206 (UINTN)DataToHashLen,\r
1207 &DigestList\r
1208 );\r
1209 if (!EFI_ERROR (Status)) {\r
1210 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
1211 Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);\r
1212 }\r
1213 }\r
1214 if (Status == EFI_DEVICE_ERROR) {\r
1215 DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));\r
1216 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
1217 REPORT_STATUS_CODE (\r
1218 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
1219 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
1220 );\r
1221 }\r
1222 } else {\r
1223 Status = TcgDxeHashLogExtendEvent (\r
1224 Flags,\r
1225 (UINT8 *) (UINTN) DataToHash,\r
1226 DataToHashLen,\r
1227 &NewEventHdr,\r
1228 Event->Event\r
1229 );\r
1230 }\r
336dbfd1 1231 DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent - %r\n", Status));\r
1abfa4ce
JY
1232 return Status;\r
1233}\r
1234\r
1235/**\r
1236 This service enables the sending of commands to the TPM.\r
1237\r
1238 @param[in] This Indicates the calling context\r
1239 @param[in] InputParameterBlockSize Size of the TPM input parameter block.\r
1240 @param[in] InputParameterBlock Pointer to the TPM input parameter block.\r
1241 @param[in] OutputParameterBlockSize Size of the TPM output parameter block.\r
1242 @param[in] OutputParameterBlock Pointer to the TPM output parameter block.\r
1243\r
1244 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.\r
1245 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.\r
1246 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1247 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. \r
1248**/\r
1249EFI_STATUS\r
1250EFIAPI\r
1251Tcg2SubmitCommand (\r
1252 IN EFI_TCG2_PROTOCOL *This,\r
1253 IN UINT32 InputParameterBlockSize,\r
1254 IN UINT8 *InputParameterBlock,\r
1255 IN UINT32 OutputParameterBlockSize,\r
1256 IN UINT8 *OutputParameterBlock\r
1257 )\r
1258{\r
1259 EFI_STATUS Status;\r
1260\r
1261 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand ...\n"));\r
1262\r
1263 if ((This == NULL) ||\r
1264 (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||\r
1265 (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {\r
1266 return EFI_INVALID_PARAMETER;\r
1267 }\r
1268\r
1269 if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
1270 return EFI_DEVICE_ERROR;\r
1271 }\r
1272\r
e1f35834 1273 if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {\r
1abfa4ce
JY
1274 return EFI_INVALID_PARAMETER;\r
1275 }\r
e1f35834 1276 if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {\r
1abfa4ce
JY
1277 return EFI_INVALID_PARAMETER;\r
1278 }\r
1279\r
1280 Status = Tpm2SubmitCommand (\r
1281 InputParameterBlockSize,\r
1282 InputParameterBlock,\r
1283 &OutputParameterBlockSize,\r
1284 OutputParameterBlock\r
1285 );\r
1286 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand - %r\n", Status));\r
1287 return Status;\r
1288}\r
1289\r
1290/**\r
1291 This service returns the currently active PCR banks.\r
1292\r
1293 @param[in] This Indicates the calling context\r
1294 @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.\r
1295\r
1296 @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.\r
1297 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. \r
1298**/\r
1299EFI_STATUS\r
1300EFIAPI\r
1301Tcg2GetActivePCRBanks (\r
1302 IN EFI_TCG2_PROTOCOL *This,\r
1303 OUT UINT32 *ActivePcrBanks\r
1304 )\r
1305{\r
1306 if (ActivePcrBanks == NULL) {\r
1307 return EFI_INVALID_PARAMETER;\r
1308 }\r
1309 *ActivePcrBanks = mTcgDxeData.BsCap.ActivePcrBanks;\r
1310 return EFI_SUCCESS;\r
1311}\r
1312\r
1313/**\r
1314 This service sets the currently active PCR banks.\r
1315\r
1316 @param[in] This Indicates the calling context\r
1317 @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.\r
1318\r
1319 @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.\r
1320 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1321**/\r
1322EFI_STATUS\r
1323EFIAPI\r
1324Tcg2SetActivePCRBanks (\r
1325 IN EFI_TCG2_PROTOCOL *This,\r
1326 IN UINT32 ActivePcrBanks\r
1327 )\r
1328{\r
1329 EFI_STATUS Status;\r
1330 UINT32 ReturnCode;\r
1331\r
1332 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks));\r
1333\r
1334 if (ActivePcrBanks == 0) {\r
1335 return EFI_INVALID_PARAMETER;\r
1336 }\r
1337 if ((ActivePcrBanks & (~mTcgDxeData.BsCap.HashAlgorithmBitmap)) != 0) {\r
1338 return EFI_INVALID_PARAMETER;\r
1339 }\r
1340 if (ActivePcrBanks == mTcgDxeData.BsCap.ActivePcrBanks) {\r
1341 //\r
1342 // Need clear previous SET_PCR_BANKS setting\r
1343 //\r
1344 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION, 0);\r
1345 } else {\r
1346 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, ActivePcrBanks);\r
1347 }\r
1348\r
1349 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
1350 Status = EFI_SUCCESS;\r
1351 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
1352 Status = EFI_OUT_OF_RESOURCES;\r
1353 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
1354 Status = EFI_UNSUPPORTED;\r
1355 } else {\r
1356 Status = EFI_DEVICE_ERROR;\r
1357 }\r
1358\r
1359 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks - %r\n", Status));\r
1360\r
1361 return Status;\r
1362}\r
1363\r
1364/**\r
1365 This service retrieves the result of a previous invocation of SetActivePcrBanks.\r
1366\r
1367 @param[in] This Indicates the calling context\r
1368 @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.\r
1369 @param[out] Response The response from the SetActivePcrBank request.\r
1370\r
1371 @retval EFI_SUCCESS The result value could be returned.\r
1372 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
1373**/\r
1374EFI_STATUS\r
1375EFIAPI\r
1376Tcg2GetResultOfSetActivePcrBanks (\r
1377 IN EFI_TCG2_PROTOCOL *This,\r
1378 OUT UINT32 *OperationPresent,\r
1379 OUT UINT32 *Response\r
1380 )\r
1381{\r
1382 UINT32 ReturnCode;\r
1383\r
1384 if ((OperationPresent == NULL) || (Response == NULL)) {\r
1385 return EFI_INVALID_PARAMETER;\r
1386 }\r
1387 \r
1388 ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);\r
1389 if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {\r
1390 return EFI_SUCCESS;\r
1391 } else {\r
1392 return EFI_UNSUPPORTED;\r
1393 }\r
1394}\r
1395\r
1396EFI_TCG2_PROTOCOL mTcg2Protocol = {\r
1397 Tcg2GetCapability,\r
1398 Tcg2GetEventLog,\r
1399 Tcg2HashLogExtendEvent,\r
1400 Tcg2SubmitCommand,\r
1401 Tcg2GetActivePCRBanks,\r
1402 Tcg2SetActivePCRBanks,\r
1403 Tcg2GetResultOfSetActivePcrBanks,\r
1404};\r
1405\r
1406/**\r
1407 Initialize the Event Log and log events passed from the PEI phase.\r
1408\r
1409 @retval EFI_SUCCESS Operation completed successfully.\r
1410 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1411\r
1412**/\r
1413EFI_STATUS\r
1414SetupEventLog (\r
1415 VOID\r
1416 )\r
1417{\r
1418 EFI_STATUS Status;\r
1419 VOID *TcgEvent;\r
1420 EFI_PEI_HOB_POINTERS GuidHob;\r
1421 EFI_PHYSICAL_ADDRESS Lasa;\r
1422 UINTN Index;\r
1423 UINT32 DigestListBinSize;\r
1424 UINT32 EventSize;\r
1425 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;\r
9381e149 1426 UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
1abfa4ce 1427 TCG_PCR_EVENT_HDR FirstPcrEvent;\r
a9092578 1428 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
35e00ace 1429 TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
a9092578
QS
1430 UINT8 *VendorInfoSize;\r
1431 UINT32 NumberOfAlgorithms;\r
1abfa4ce
JY
1432\r
1433 DEBUG ((EFI_D_INFO, "SetupEventLog\n"));\r
1434\r
1435 //\r
1436 // 1. Create Log Area\r
1437 //\r
1438 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1439 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1440 mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1441 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
1442 Status = gBS->AllocatePages (\r
1443 AllocateMaxAddress,\r
fd46e831 1444 EfiBootServicesData,\r
91e914f5 1445 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
1abfa4ce
JY
1446 &Lasa\r
1447 );\r
1448 if (EFI_ERROR (Status)) {\r
1449 return Status;\r
1450 }\r
1451 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
91e914f5 1452 mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
1abfa4ce
JY
1453 //\r
1454 // To initialize them as 0xFF is recommended \r
1455 // because the OS can know the last entry for that.\r
1456 //\r
91e914f5 1457 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
1abfa4ce
JY
1458 //\r
1459 // Create first entry for Log Header Entry Data\r
1460 //\r
1461 if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {\r
1462 //\r
1463 // TcgEfiSpecIdEventStruct\r
1464 //\r
1465 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;\r
1466 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof(TcgEfiSpecIdEventStruct->signature));\r
1467 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);\r
1468 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;\r
1469 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;\r
1470 TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;\r
1471 TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);\r
a9092578
QS
1472 NumberOfAlgorithms = 0;\r
1473 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));\r
1abfa4ce 1474 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
35e00ace
QS
1475 TempDigestSize = DigestSize;\r
1476 TempDigestSize += NumberOfAlgorithms;\r
1477 TempDigestSize->algorithmId = TPM_ALG_SHA1;\r
1478 TempDigestSize->digestSize = SHA1_DIGEST_SIZE;\r
a9092578 1479 NumberOfAlgorithms++;\r
1abfa4ce
JY
1480 }\r
1481 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
35e00ace
QS
1482 TempDigestSize = DigestSize;\r
1483 TempDigestSize += NumberOfAlgorithms;\r
1484 TempDigestSize->algorithmId = TPM_ALG_SHA256;\r
1485 TempDigestSize->digestSize = SHA256_DIGEST_SIZE;\r
a9092578 1486 NumberOfAlgorithms++;\r
1abfa4ce
JY
1487 }\r
1488 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
35e00ace
QS
1489 TempDigestSize = DigestSize;\r
1490 TempDigestSize += NumberOfAlgorithms;\r
1491 TempDigestSize->algorithmId = TPM_ALG_SHA384;\r
1492 TempDigestSize->digestSize = SHA384_DIGEST_SIZE;\r
a9092578 1493 NumberOfAlgorithms++;\r
1abfa4ce
JY
1494 }\r
1495 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
35e00ace
QS
1496 TempDigestSize = DigestSize;\r
1497 TempDigestSize += NumberOfAlgorithms;\r
1498 TempDigestSize->algorithmId = TPM_ALG_SHA512;\r
1499 TempDigestSize->digestSize = SHA512_DIGEST_SIZE;\r
a9092578 1500 NumberOfAlgorithms++;\r
1abfa4ce
JY
1501 }\r
1502 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
35e00ace
QS
1503 TempDigestSize = DigestSize;\r
1504 TempDigestSize += NumberOfAlgorithms;\r
1505 TempDigestSize->algorithmId = TPM_ALG_SM3_256;\r
1506 TempDigestSize->digestSize = SM3_256_DIGEST_SIZE;\r
a9092578 1507 NumberOfAlgorithms++;\r
1abfa4ce 1508 }\r
a9092578 1509 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof(NumberOfAlgorithms));\r
35e00ace
QS
1510 TempDigestSize = DigestSize;\r
1511 TempDigestSize += NumberOfAlgorithms;\r
1512 VendorInfoSize = (UINT8 *)TempDigestSize;\r
a9092578 1513 *VendorInfoSize = 0;\r
1abfa4ce
JY
1514\r
1515 //\r
1516 // FirstPcrEvent\r
1517 //\r
1518 FirstPcrEvent.PCRIndex = 0;\r
1519 FirstPcrEvent.EventType = EV_NO_ACTION;\r
1520 ZeroMem (&FirstPcrEvent.Digest, sizeof(FirstPcrEvent.Digest));\r
1521 FirstPcrEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
1522\r
1523 //\r
1524 // Record\r
1525 //\r
1526 Status = TcgDxeLogEvent (\r
1527 mTcg2EventInfo[Index].LogFormat,\r
1528 &FirstPcrEvent,\r
1529 sizeof(FirstPcrEvent),\r
1530 (UINT8 *)TcgEfiSpecIdEventStruct,\r
1531 FirstPcrEvent.EventSize\r
1532 );\r
1533 }\r
1534 }\r
1535 }\r
1536\r
1537 //\r
1538 // 2. Create Final Log Area\r
1539 //\r
1540 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1541 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
fd46e831
JY
1542 if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
1543 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
1544 Status = gBS->AllocatePages (\r
1545 AllocateMaxAddress,\r
1546 EfiACPIMemoryNVS,\r
1547 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),\r
1548 &Lasa\r
1549 );\r
1550 if (EFI_ERROR (Status)) {\r
1551 return Status;\r
1552 }\r
1553 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);\r
1abfa4ce 1554\r
fd46e831
JY
1555 //\r
1556 // Initialize\r
1557 //\r
1558 mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;\r
1559 (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;\r
1560 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;\r
1561\r
1562 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1563 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
1564 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
1565 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
1566 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
1567 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
1568 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
1abfa4ce 1569\r
1abfa4ce 1570 //\r
fd46e831 1571 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 \r
1abfa4ce 1572 //\r
fd46e831 1573 Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
1abfa4ce
JY
1574 if (EFI_ERROR (Status)) {\r
1575 return Status;\r
1576 }\r
fd46e831
JY
1577 } else {\r
1578 //\r
1579 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2\r
1580 //\r
1581 mTcgDxeData.FinalEventsTable[Index] = NULL;\r
1582 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
1583 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;\r
1584 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;\r
1585 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
1586 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;\r
1587 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
1588 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
1abfa4ce
JY
1589 }\r
1590 }\r
1591 }\r
1592 \r
1593 //\r
1594 // 3. Sync data from PEI to DXE\r
1595 //\r
1596 Status = EFI_SUCCESS;\r
1597 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
1598 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
1599 GuidHob.Raw = GetHobList ();\r
1600 Status = EFI_SUCCESS;\r
1601 while (!EFI_ERROR (Status) && \r
1602 (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
1603 TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);\r
1604 GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
1605 switch (mTcg2EventInfo[Index].LogFormat) {\r
1606 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
1607 Status = TcgDxeLogEvent (\r
1608 mTcg2EventInfo[Index].LogFormat,\r
1609 TcgEvent,\r
1610 sizeof(TCG_PCR_EVENT_HDR),\r
1611 ((TCG_PCR_EVENT*)TcgEvent)->Event,\r
1612 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize\r
1613 );\r
1614 break;\r
1615 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
1616 DigestListBinSize = GetDigestListBinSize ((UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE));\r
1617 CopyMem (&EventSize, (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize, sizeof(UINT32));\r
1618 Status = TcgDxeLogEvent (\r
1619 mTcg2EventInfo[Index].LogFormat,\r
1620 TcgEvent,\r
1621 sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
1622 (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
1623 EventSize\r
1624 );\r
1625 break;\r
1626 }\r
1627 }\r
1628 }\r
1629 }\r
1630\r
1631 return Status;\r
1632}\r
1633\r
1634/**\r
1635 Measure and log an action string, and extend the measurement result into PCR[5].\r
1636\r
1637 @param[in] String A specific string that indicates an Action event. \r
1638 \r
1639 @retval EFI_SUCCESS Operation completed successfully.\r
1640 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1641\r
1642**/\r
1643EFI_STATUS\r
1644TcgMeasureAction (\r
1645 IN CHAR8 *String\r
1646 )\r
1647{\r
1648 TCG_PCR_EVENT_HDR TcgEvent;\r
1649\r
1650 TcgEvent.PCRIndex = 5;\r
1651 TcgEvent.EventType = EV_EFI_ACTION;\r
1652 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
1653 return TcgDxeHashLogExtendEvent (\r
1654 0,\r
1655 (UINT8*)String,\r
1656 TcgEvent.EventSize,\r
1657 &TcgEvent,\r
1658 (UINT8 *) String\r
1659 );\r
1660}\r
1661\r
1662/**\r
1663 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].\r
1664\r
1665 @retval EFI_SUCCESS Operation completed successfully.\r
1666 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1667\r
1668**/\r
1669EFI_STATUS\r
1670MeasureHandoffTables (\r
1671 VOID\r
1672 )\r
1673{\r
1674 EFI_STATUS Status;\r
1abfa4ce
JY
1675 TCG_PCR_EVENT_HDR TcgEvent;\r
1676 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
1677 UINTN ProcessorNum;\r
1678 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
1679\r
1680 ProcessorLocBuf = NULL;\r
d2de4483 1681 Status = EFI_SUCCESS;\r
1abfa4ce
JY
1682\r
1683 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
1684 //\r
1685 // Tcg Server spec. \r
1686 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
1687 //\r
1688 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
1689\r
1690 if (!EFI_ERROR(Status)){\r
1691 TcgEvent.PCRIndex = 1;\r
1692 TcgEvent.EventType = EV_TABLE_OF_DEVICES;\r
1693 TcgEvent.EventSize = sizeof (HandoffTables);\r
1694\r
1695 HandoffTables.NumberOfTables = 1;\r
1696 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;\r
1697 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;\r
1698\r
1699 Status = TcgDxeHashLogExtendEvent (\r
1700 0,\r
1701 (UINT8*)(UINTN)ProcessorLocBuf,\r
1702 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
1703 &TcgEvent,\r
1704 (UINT8*)&HandoffTables\r
1705 );\r
1706\r
1707 FreePool(ProcessorLocBuf);\r
1708 }\r
1709 }\r
1710\r
1711 return Status;\r
1712}\r
1713\r
1714/**\r
1715 Measure and log Separator event, and extend the measurement result into a specific PCR.\r
1716\r
1717 @param[in] PCRIndex PCR index. \r
1718\r
1719 @retval EFI_SUCCESS Operation completed successfully.\r
1720 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1721\r
1722**/\r
1723EFI_STATUS\r
1724MeasureSeparatorEvent (\r
1725 IN TPM_PCRINDEX PCRIndex\r
1726 )\r
1727{\r
1728 TCG_PCR_EVENT_HDR TcgEvent;\r
1729 UINT32 EventData;\r
1730\r
1731 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));\r
1732\r
1733 EventData = 0;\r
1734 TcgEvent.PCRIndex = PCRIndex;\r
1735 TcgEvent.EventType = EV_SEPARATOR;\r
1736 TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
1737 return TcgDxeHashLogExtendEvent (\r
1738 0,\r
1739 (UINT8 *)&EventData,\r
1740 sizeof (EventData),\r
1741 &TcgEvent,\r
1742 (UINT8 *)&EventData\r
1743 );\r
1744}\r
1745\r
1746/**\r
1747 Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
1748\r
1749 @param[in] PCRIndex PCR Index. \r
1750 @param[in] EventType Event type. \r
1751 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1752 @param[in] VendorGuid A unique identifier for the vendor.\r
1753 @param[in] VarData The content of the variable data. \r
1754 @param[in] VarSize The size of the variable data. \r
1755 \r
1756 @retval EFI_SUCCESS Operation completed successfully.\r
1757 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1758 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1759\r
1760**/\r
1761EFI_STATUS\r
1762MeasureVariable (\r
1763 IN TPM_PCRINDEX PCRIndex,\r
1764 IN TCG_EVENTTYPE EventType,\r
1765 IN CHAR16 *VarName,\r
1766 IN EFI_GUID *VendorGuid,\r
1767 IN VOID *VarData,\r
1768 IN UINTN VarSize\r
1769 )\r
1770{\r
1771 EFI_STATUS Status;\r
1772 TCG_PCR_EVENT_HDR TcgEvent;\r
1773 UINTN VarNameLength;\r
1774 EFI_VARIABLE_DATA_TREE *VarLog;\r
1775\r
1776 DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
1777 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
1778\r
1779 VarNameLength = StrLen (VarName);\r
1780 TcgEvent.PCRIndex = PCRIndex;\r
1781 TcgEvent.EventType = EventType;\r
1782\r
1783 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
1784 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
1785\r
1786 VarLog = (EFI_VARIABLE_DATA_TREE *)AllocatePool (TcgEvent.EventSize);\r
1787 if (VarLog == NULL) {\r
1788 return EFI_OUT_OF_RESOURCES;\r
1789 }\r
1790\r
1791 VarLog->VariableName = *VendorGuid;\r
1792 VarLog->UnicodeNameLength = VarNameLength;\r
1793 VarLog->VariableDataLength = VarSize;\r
1794 CopyMem (\r
1795 VarLog->UnicodeName,\r
1796 VarName,\r
1797 VarNameLength * sizeof (*VarName)\r
1798 );\r
1799 if (VarSize != 0 && VarData != NULL) {\r
1800 CopyMem (\r
1801 (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
1802 VarData,\r
1803 VarSize\r
1804 );\r
1805 }\r
1806\r
1807 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
1808 //\r
1809 // Digest is the event data (EFI_VARIABLE_DATA)\r
1810 //\r
1811 Status = TcgDxeHashLogExtendEvent (\r
1812 0,\r
1813 (UINT8*)VarLog,\r
1814 TcgEvent.EventSize,\r
1815 &TcgEvent,\r
1816 (UINT8*)VarLog\r
1817 );\r
1818 } else {\r
1819 Status = TcgDxeHashLogExtendEvent (\r
1820 0,\r
1821 (UINT8*)VarData,\r
1822 VarSize,\r
1823 &TcgEvent,\r
1824 (UINT8*)VarLog\r
1825 );\r
1826 }\r
1827 FreePool (VarLog);\r
1828 return Status;\r
1829}\r
1830\r
1831/**\r
1832 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
1833\r
1834 @param[in] PCRIndex PCR Index. \r
1835 @param[in] EventType Event type. \r
1836 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1837 @param[in] VendorGuid A unique identifier for the vendor.\r
1838 @param[out] VarSize The size of the variable data. \r
1839 @param[out] VarData Pointer to the content of the variable. \r
1840 \r
1841 @retval EFI_SUCCESS Operation completed successfully.\r
1842 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1843 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1844\r
1845**/\r
1846EFI_STATUS\r
1847ReadAndMeasureVariable (\r
1848 IN TPM_PCRINDEX PCRIndex,\r
1849 IN TCG_EVENTTYPE EventType,\r
1850 IN CHAR16 *VarName,\r
1851 IN EFI_GUID *VendorGuid,\r
1852 OUT UINTN *VarSize,\r
1853 OUT VOID **VarData\r
1854 )\r
1855{\r
1856 EFI_STATUS Status;\r
1857\r
1858 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);\r
1859 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
1860 if (EFI_ERROR (Status)) {\r
1861 //\r
1862 // It is valid case, so we need handle it.\r
1863 //\r
1864 *VarData = NULL;\r
1865 *VarSize = 0;\r
1866 }\r
1867 } else {\r
1868 //\r
1869 // if status error, VarData is freed and set NULL by GetVariable2\r
1870 //\r
1871 if (EFI_ERROR (Status)) {\r
1872 return EFI_NOT_FOUND;\r
1873 }\r
1874 }\r
1875\r
1876 Status = MeasureVariable (\r
1877 PCRIndex,\r
1878 EventType,\r
1879 VarName,\r
1880 VendorGuid,\r
1881 *VarData,\r
1882 *VarSize\r
1883 );\r
1884 return Status;\r
1885}\r
1886\r
1887/**\r
1888 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].\r
1889\r
1890 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1891 @param[in] VendorGuid A unique identifier for the vendor.\r
1892 @param[out] VarSize The size of the variable data. \r
1893 @param[out] VarData Pointer to the content of the variable. \r
1894 \r
1895 @retval EFI_SUCCESS Operation completed successfully.\r
1896 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1897 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1898\r
1899**/\r
1900EFI_STATUS\r
1901ReadAndMeasureBootVariable (\r
1902 IN CHAR16 *VarName,\r
1903 IN EFI_GUID *VendorGuid,\r
1904 OUT UINTN *VarSize,\r
1905 OUT VOID **VarData\r
1906 )\r
1907{\r
1908 return ReadAndMeasureVariable (\r
1909 5,\r
1910 EV_EFI_VARIABLE_BOOT,\r
1911 VarName,\r
1912 VendorGuid,\r
1913 VarSize,\r
1914 VarData\r
1915 );\r
1916}\r
1917\r
1918/**\r
1919 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].\r
1920\r
1921 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
1922 @param[in] VendorGuid A unique identifier for the vendor.\r
1923 @param[out] VarSize The size of the variable data. \r
1924 @param[out] VarData Pointer to the content of the variable. \r
1925 \r
1926 @retval EFI_SUCCESS Operation completed successfully.\r
1927 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1928 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1929\r
1930**/\r
1931EFI_STATUS\r
1932ReadAndMeasureSecureVariable (\r
1933 IN CHAR16 *VarName,\r
1934 IN EFI_GUID *VendorGuid,\r
1935 OUT UINTN *VarSize,\r
1936 OUT VOID **VarData\r
1937 )\r
1938{\r
1939 return ReadAndMeasureVariable (\r
1940 7,\r
1941 EV_EFI_VARIABLE_DRIVER_CONFIG,\r
1942 VarName,\r
1943 VendorGuid,\r
1944 VarSize,\r
1945 VarData\r
1946 );\r
1947}\r
1948\r
1949/**\r
1950 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.\r
1951\r
1952 The EFI boot variables are BootOrder and Boot#### variables.\r
1953\r
1954 @retval EFI_SUCCESS Operation completed successfully.\r
1955 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
1956 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1957\r
1958**/\r
1959EFI_STATUS\r
1960MeasureAllBootVariables (\r
1961 VOID\r
1962 )\r
1963{\r
1964 EFI_STATUS Status;\r
1965 UINT16 *BootOrder;\r
1966 UINTN BootCount;\r
1967 UINTN Index;\r
1968 VOID *BootVarData;\r
1969 UINTN Size;\r
1970\r
1971 Status = ReadAndMeasureBootVariable (\r
1972 mBootVarName,\r
1973 &gEfiGlobalVariableGuid,\r
1974 &BootCount,\r
1975 (VOID **) &BootOrder\r
1976 );\r
1977 if (Status == EFI_NOT_FOUND || BootOrder == NULL) {\r
1978 return EFI_SUCCESS;\r
1979 }\r
1980\r
1981 if (EFI_ERROR (Status)) {\r
1982 //\r
1983 // BootOrder can't be NULL if status is not EFI_NOT_FOUND\r
1984 //\r
1985 FreePool (BootOrder);\r
1986 return Status;\r
1987 }\r
1988\r
1989 BootCount /= sizeof (*BootOrder);\r
1990 for (Index = 0; Index < BootCount; Index++) {\r
1991 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);\r
1992 Status = ReadAndMeasureBootVariable (\r
1993 mBootVarName,\r
1994 &gEfiGlobalVariableGuid,\r
1995 &Size,\r
1996 &BootVarData\r
1997 );\r
1998 if (!EFI_ERROR (Status)) {\r
1999 FreePool (BootVarData);\r
2000 }\r
2001 }\r
2002\r
2003 FreePool (BootOrder);\r
2004 return EFI_SUCCESS;\r
2005}\r
2006\r
2007/**\r
2008 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.\r
2009\r
2010 The EFI boot variables are BootOrder and Boot#### variables.\r
2011\r
2012 @retval EFI_SUCCESS Operation completed successfully.\r
2013 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2014 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2015\r
2016**/\r
2017EFI_STATUS\r
2018MeasureAllSecureVariables (\r
2019 VOID\r
2020 )\r
2021{\r
2022 EFI_STATUS Status;\r
2023 VOID *Data;\r
2024 UINTN DataSize;\r
2025 UINTN Index;\r
2026\r
2027 Status = EFI_NOT_FOUND;\r
2028 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
2029 Status = ReadAndMeasureSecureVariable (\r
2030 mVariableType[Index].VariableName,\r
2031 mVariableType[Index].VendorGuid,\r
2032 &DataSize,\r
2033 &Data\r
2034 );\r
2035 if (!EFI_ERROR (Status)) {\r
2036 if (Data != NULL) {\r
2037 FreePool (Data);\r
2038 }\r
2039 }\r
2040 }\r
2041\r
2042 return EFI_SUCCESS;\r
2043}\r
2044\r
2045/**\r
2046 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.\r
2047\r
2048 @retval EFI_SUCCESS Operation completed successfully.\r
2049 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
2050 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
2051\r
2052**/\r
2053EFI_STATUS\r
2054MeasureLaunchOfFirmwareDebugger (\r
2055 VOID\r
2056 )\r
2057{\r
2058 TCG_PCR_EVENT_HDR TcgEvent;\r
2059\r
2060 TcgEvent.PCRIndex = 7;\r
2061 TcgEvent.EventType = EV_EFI_ACTION;\r
2062 TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;\r
2063 return TcgDxeHashLogExtendEvent (\r
2064 0,\r
2065 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,\r
2066 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,\r
2067 &TcgEvent,\r
2068 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING\r
2069 );\r
2070}\r
2071\r
2072/**\r
2073 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.\r
2074\r
2075 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)\r
2076 - The contents of the SecureBoot variable\r
2077 - The contents of the PK variable\r
2078 - The contents of the KEK variable\r
2079 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable\r
2080 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable\r
2081 - Separator\r
2082 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path\r
2083\r
2084 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,\r
2085 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].\r
2086\r
2087 @param[in] Event Event whose notification function is being invoked\r
2088 @param[in] Context Pointer to the notification function's context\r
2089**/\r
2090VOID\r
2091EFIAPI\r
2092MeasureSecureBootPolicy (\r
2093 IN EFI_EVENT Event,\r
2094 IN VOID *Context\r
2095 )\r
2096{\r
2097 EFI_STATUS Status;\r
2098 VOID *Protocol;\r
2099\r
2100 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);\r
2101 if (EFI_ERROR (Status)) {\r
2102 return;\r
2103 }\r
2104\r
2105 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {\r
2106 Status = MeasureLaunchOfFirmwareDebugger ();\r
2107 DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));\r
2108 }\r
2109\r
2110 Status = MeasureAllSecureVariables ();\r
2111 DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));\r
2112\r
2113 //\r
2114 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)\r
2115 // and ImageVerification (Authority)\r
2116 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So\r
2117 // the Authority measurement happen before ReadToBoot event.\r
2118 //\r
2119 Status = MeasureSeparatorEvent (7);\r
2120 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));\r
2121 return ;\r
2122}\r
2123\r
2124/**\r
2125 Ready to Boot Event notification handler.\r
2126\r
2127 Sequence of OS boot events is measured in this event notification handler.\r
2128\r
2129 @param[in] Event Event whose notification function is being invoked\r
2130 @param[in] Context Pointer to the notification function's context\r
2131\r
2132**/\r
2133VOID\r
2134EFIAPI\r
2135OnReadyToBoot (\r
2136 IN EFI_EVENT Event,\r
2137 IN VOID *Context\r
2138 )\r
2139{\r
2140 EFI_STATUS Status;\r
2141 TPM_PCRINDEX PcrIndex;\r
2142\r
2143 PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE);\r
2144 if (mBootAttempts == 0) {\r
2145\r
2146 //\r
2147 // Measure handoff tables.\r
2148 //\r
2149 Status = MeasureHandoffTables ();\r
2150 if (EFI_ERROR (Status)) {\r
2151 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));\r
2152 }\r
2153\r
2154 //\r
2155 // Measure BootOrder & Boot#### variables.\r
2156 //\r
2157 Status = MeasureAllBootVariables ();\r
2158 if (EFI_ERROR (Status)) {\r
2159 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));\r
2160 }\r
2161\r
2162 //\r
2163 // 1. This is the first boot attempt.\r
2164 //\r
2165 Status = TcgMeasureAction (\r
2166 EFI_CALLING_EFI_APPLICATION\r
2167 );\r
2168 if (EFI_ERROR (Status)) {\r
655dabe3 2169 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
1abfa4ce
JY
2170 }\r
2171\r
2172 //\r
2173 // 2. Draw a line between pre-boot env and entering post-boot env.\r
2174 // PCR[7] is already done.\r
2175 //\r
2176 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
2177 Status = MeasureSeparatorEvent (PcrIndex);\r
2178 if (EFI_ERROR (Status)) {\r
2179 DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));\r
2180 }\r
2181 }\r
2182\r
2183 //\r
2184 // 3. Measure GPT. It would be done in SAP driver.\r
2185 //\r
2186\r
2187 //\r
2188 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.\r
2189 //\r
2190\r
2191 //\r
2192 // 5. Read & Measure variable. BootOrder already measured.\r
2193 //\r
2194 } else {\r
2195 //\r
2196 // 6. Not first attempt, meaning a return from last attempt\r
2197 //\r
2198 Status = TcgMeasureAction (\r
2199 EFI_RETURNING_FROM_EFI_APPLICATOIN\r
2200 );\r
2201 if (EFI_ERROR (Status)) {\r
655dabe3 2202 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
1abfa4ce
JY
2203 }\r
2204 }\r
2205\r
2206 DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));\r
2207 //\r
2208 // Increase boot attempt counter.\r
2209 //\r
2210 mBootAttempts++;\r
2211 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1);\r
2212}\r
2213\r
2214/**\r
2215 Exit Boot Services Event notification handler.\r
2216\r
2217 Measure invocation and success of ExitBootServices.\r
2218\r
2219 @param[in] Event Event whose notification function is being invoked\r
2220 @param[in] Context Pointer to the notification function's context\r
2221\r
2222**/\r
2223VOID\r
2224EFIAPI\r
2225OnExitBootServices (\r
2226 IN EFI_EVENT Event,\r
2227 IN VOID *Context\r
2228 )\r
2229{\r
2230 EFI_STATUS Status;\r
2231\r
2232 //\r
2233 // Measure invocation of ExitBootServices,\r
2234 //\r
2235 Status = TcgMeasureAction (\r
2236 EFI_EXIT_BOOT_SERVICES_INVOCATION\r
2237 );\r
2238 if (EFI_ERROR (Status)) {\r
655dabe3 2239 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));\r
1abfa4ce
JY
2240 }\r
2241\r
2242 //\r
2243 // Measure success of ExitBootServices\r
2244 //\r
2245 Status = TcgMeasureAction (\r
2246 EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
2247 );\r
2248 if (EFI_ERROR (Status)) {\r
655dabe3 2249 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));\r
1abfa4ce
JY
2250 }\r
2251}\r
2252\r
2253/**\r
2254 Exit Boot Services Failed Event notification handler.\r
2255\r
2256 Measure Failure of ExitBootServices.\r
2257\r
2258 @param[in] Event Event whose notification function is being invoked\r
2259 @param[in] Context Pointer to the notification function's context\r
2260\r
2261**/\r
2262VOID\r
2263EFIAPI\r
2264OnExitBootServicesFailed (\r
2265 IN EFI_EVENT Event,\r
2266 IN VOID *Context\r
2267 )\r
2268{\r
2269 EFI_STATUS Status;\r
2270\r
2271 //\r
2272 // Measure Failure of ExitBootServices,\r
2273 //\r
2274 Status = TcgMeasureAction (\r
2275 EFI_EXIT_BOOT_SERVICES_FAILED\r
2276 );\r
2277 if (EFI_ERROR (Status)) {\r
655dabe3 2278 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));\r
1abfa4ce
JY
2279 }\r
2280\r
2281}\r
2282\r
2283/**\r
2284 The function install Tcg2 protocol.\r
2285 \r
2286 @retval EFI_SUCCESS Tcg2 protocol is installed.\r
2287 @retval other Some error occurs.\r
2288**/\r
2289EFI_STATUS\r
2290InstallTcg2 (\r
2291 VOID\r
2292 )\r
2293{\r
2294 EFI_STATUS Status;\r
2295 EFI_HANDLE Handle;\r
2296\r
2297 Handle = NULL;\r
2298 Status = gBS->InstallMultipleProtocolInterfaces (\r
2299 &Handle,\r
2300 &gEfiTcg2ProtocolGuid,\r
2301 &mTcg2Protocol,\r
2302 NULL\r
2303 );\r
2304 return Status;\r
2305}\r
2306\r
2307/**\r
2308 The driver's entry point. It publishes EFI Tcg2 Protocol.\r
2309\r
2310 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
2311 @param[in] SystemTable A pointer to the EFI System Table.\r
2312 \r
2313 @retval EFI_SUCCESS The entry point is executed successfully.\r
2314 @retval other Some error occurs when executing this entry point.\r
2315**/\r
2316EFI_STATUS\r
2317EFIAPI\r
2318DriverEntry (\r
2319 IN EFI_HANDLE ImageHandle,\r
2320 IN EFI_SYSTEM_TABLE *SystemTable\r
2321 )\r
2322{\r
2323 EFI_STATUS Status;\r
2324 EFI_EVENT Event;\r
2325 VOID *Registration;\r
2326 UINT32 MaxCommandSize;\r
2327 UINT32 MaxResponseSize;\r
2328 TPML_PCR_SELECTION Pcrs;\r
2329 UINTN Index;\r
2330 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;\r
2331 UINT32 ActivePCRBanks;\r
2332 UINT32 NumberOfPCRBanks;\r
2333\r
2334 mImageHandle = ImageHandle;\r
2335\r
2336 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
2337 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
2338 DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));\r
2339 return EFI_UNSUPPORTED;\r
2340 }\r
2341\r
2342 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
2343 DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
2344 return EFI_DEVICE_ERROR;\r
2345 }\r
2346 \r
2347 Status = Tpm2RequestUseTpm ();\r
2348 if (EFI_ERROR (Status)) {\r
2349 DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
2350 return Status;\r
2351 }\r
2352 \r
2353 //\r
2354 // Fill information\r
2355 //\r
2356 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));\r
2357 \r
2358 mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
2359 mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
2360 mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
2361 mTcgDxeData.BsCap.StructureVersion.Major = 1;\r
2362 mTcgDxeData.BsCap.StructureVersion.Minor = 1;\r
2363\r
2364 DEBUG ((EFI_D_INFO, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));\r
2365 DEBUG ((EFI_D_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));\r
2366\r
2367 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);\r
2368 if (EFI_ERROR (Status)) {\r
2369 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));\r
2370 } else {\r
2371 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));\r
2372 }\r
2373\r
2374 DEBUG_CODE (\r
2375 UINT32 FirmwareVersion1;\r
2376 UINT32 FirmwareVersion2;\r
2377\r
2378 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);\r
2379 if (EFI_ERROR (Status)) {\r
2380 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));\r
2381 } else {\r
2382 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));\r
2383 }\r
2384 );\r
2385\r
2386 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);\r
2387 if (EFI_ERROR (Status)) {\r
2388 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));\r
2389 } else {\r
2390 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;\r
2391 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;\r
2392 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));\r
2393 }\r
2394\r
2395 //\r
2396 // Get supported PCR and current Active PCRs\r
2397 //\r
2398 Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
2399 if (EFI_ERROR (Status)) {\r
2400 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));\r
2401 TpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
1abfa4ce
JY
2402 ActivePCRBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
2403 } else {\r
2404 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));\r
1abfa4ce
JY
2405 TpmHashAlgorithmBitmap = 0;\r
2406 ActivePCRBanks = 0;\r
2407 for (Index = 0; Index < Pcrs.count; Index++) {\r
2408 DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));\r
2409 switch (Pcrs.pcrSelections[Index].hash) {\r
2410 case TPM_ALG_SHA1:\r
2411 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
72388f9c 2412 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
1abfa4ce
JY
2413 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
2414 } \r
2415 break;\r
2416 case TPM_ALG_SHA256:\r
2417 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
72388f9c 2418 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
1abfa4ce
JY
2419 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
2420 }\r
2421 break;\r
2422 case TPM_ALG_SHA384:\r
2423 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
72388f9c 2424 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
1abfa4ce
JY
2425 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
2426 }\r
2427 break;\r
2428 case TPM_ALG_SHA512:\r
2429 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
72388f9c 2430 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
1abfa4ce
JY
2431 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
2432 }\r
2433 break;\r
2434 case TPM_ALG_SM3_256:\r
2435 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
72388f9c 2436 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
1abfa4ce
JY
2437 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
2438 }\r
2439 break;\r
2440 }\r
2441 }\r
2442 }\r
2443 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
2444 mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
2445\r
a3cad6f8
JY
2446 //\r
2447 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.\r
2448 //\r
2449 NumberOfPCRBanks = 0;\r
2450 for (Index = 0; Index < 32; Index++) {\r
2451 if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {\r
2452 NumberOfPCRBanks++;\r
2453 }\r
2454 }\r
2455\r
1abfa4ce
JY
2456 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {\r
2457 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
2458 } else {\r
2459 mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks);\r
2460 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) {\r
2461 DEBUG ((EFI_D_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks));\r
2462 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
2463 }\r
2464 }\r
2465\r
2466 mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;\r
87361c6a 2467 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {\r
1abfa4ce
JY
2468 //\r
2469 // No need to expose TCG1.2 event log if SHA1 bank does not exist.\r
2470 //\r
87361c6a 2471 mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;\r
1abfa4ce
JY
2472 }\r
2473\r
2474 DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
2475 DEBUG ((EFI_D_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));\r
2476 DEBUG ((EFI_D_INFO, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks));\r
2477 DEBUG ((EFI_D_INFO, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks));\r
2478\r
2479 if (mTcgDxeData.BsCap.TPMPresentFlag) {\r
2480 //\r
2481 // Setup the log area and copy event log from hob list to it\r
2482 //\r
2483 Status = SetupEventLog ();\r
2484 ASSERT_EFI_ERROR (Status);\r
2485\r
2486 //\r
2487 // Measure handoff tables, Boot#### variables etc.\r
2488 //\r
2489 Status = EfiCreateEventReadyToBootEx (\r
2490 TPL_CALLBACK,\r
2491 OnReadyToBoot,\r
2492 NULL,\r
2493 &Event\r
2494 );\r
2495\r
2496 Status = gBS->CreateEventEx (\r
2497 EVT_NOTIFY_SIGNAL,\r
2498 TPL_NOTIFY,\r
2499 OnExitBootServices,\r
2500 NULL,\r
2501 &gEfiEventExitBootServicesGuid,\r
2502 &Event\r
2503 );\r
2504\r
2505 //\r
2506 // Measure Exit Boot Service failed \r
2507 //\r
2508 Status = gBS->CreateEventEx (\r
2509 EVT_NOTIFY_SIGNAL,\r
2510 TPL_NOTIFY,\r
2511 OnExitBootServicesFailed,\r
2512 NULL,\r
2513 &gEventExitBootServicesFailedGuid,\r
2514 &Event\r
2515 );\r
2516\r
2517 //\r
2518 // Create event callback, because we need access variable on SecureBootPolicyVariable\r
2519 // We should use VariableWriteArch instead of VariableArch, because Variable driver\r
2520 // may update SecureBoot value based on last setting.\r
2521 //\r
2522 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
2523 }\r
2524\r
2525 //\r
2526 // Install Tcg2Protocol\r
2527 //\r
2528 Status = InstallTcg2 ();\r
2529 DEBUG ((EFI_D_INFO, "InstallTcg2 - %r\n", Status));\r
2530\r
2531 return Status;\r
2532}\r