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