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