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