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