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