]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg: Fix spelling errors
[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 Digest 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 if (PcdGet8(PcdTpm2AcpiTableRev) >= 4) {
1471 Status = gBS->AllocatePages (
1472 AllocateAnyPages,
1473 EfiACPIMemoryNVS,
1474 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
1475 &Lasa
1476 );
1477 } else {
1478 Status = gBS->AllocatePages (
1479 AllocateAnyPages,
1480 EfiBootServicesData,
1481 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
1482 &Lasa
1483 );
1484 }
1485 if (EFI_ERROR (Status)) {
1486 return Status;
1487 }
1488 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
1489 mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);
1490
1491 if ((PcdGet8(PcdTpm2AcpiTableRev) >= 4) ||
1492 (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)) {
1493 //
1494 // Report TCG2 event log address and length, so that they can be reported in TPM2 ACPI table.
1495 // Ignore the return status, because those fields are optional.
1496 //
1497 PcdSet32S(PcdTpm2AcpiTableLaml, (UINT32)mTcgDxeData.EventLogAreaStruct[Index].Laml);
1498 PcdSet64S(PcdTpm2AcpiTableLasa, mTcgDxeData.EventLogAreaStruct[Index].Lasa);
1499 }
1500
1501 //
1502 // To initialize them as 0xFF is recommended
1503 // because the OS can know the last entry for that.
1504 //
1505 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
1506 //
1507 // Create first entry for Log Header Entry Data
1508 //
1509 if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {
1510 //
1511 // TcgEfiSpecIdEventStruct
1512 //
1513 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;
1514 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof(TcgEfiSpecIdEventStruct->signature));
1515 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);
1516 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;
1517 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;
1518 TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;
1519 TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);
1520 NumberOfAlgorithms = 0;
1521 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));
1522 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
1523 TempDigestSize = DigestSize;
1524 TempDigestSize += NumberOfAlgorithms;
1525 TempDigestSize->algorithmId = TPM_ALG_SHA1;
1526 TempDigestSize->digestSize = SHA1_DIGEST_SIZE;
1527 NumberOfAlgorithms++;
1528 }
1529 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
1530 TempDigestSize = DigestSize;
1531 TempDigestSize += NumberOfAlgorithms;
1532 TempDigestSize->algorithmId = TPM_ALG_SHA256;
1533 TempDigestSize->digestSize = SHA256_DIGEST_SIZE;
1534 NumberOfAlgorithms++;
1535 }
1536 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
1537 TempDigestSize = DigestSize;
1538 TempDigestSize += NumberOfAlgorithms;
1539 TempDigestSize->algorithmId = TPM_ALG_SHA384;
1540 TempDigestSize->digestSize = SHA384_DIGEST_SIZE;
1541 NumberOfAlgorithms++;
1542 }
1543 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
1544 TempDigestSize = DigestSize;
1545 TempDigestSize += NumberOfAlgorithms;
1546 TempDigestSize->algorithmId = TPM_ALG_SHA512;
1547 TempDigestSize->digestSize = SHA512_DIGEST_SIZE;
1548 NumberOfAlgorithms++;
1549 }
1550 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
1551 TempDigestSize = DigestSize;
1552 TempDigestSize += NumberOfAlgorithms;
1553 TempDigestSize->algorithmId = TPM_ALG_SM3_256;
1554 TempDigestSize->digestSize = SM3_256_DIGEST_SIZE;
1555 NumberOfAlgorithms++;
1556 }
1557 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof(NumberOfAlgorithms));
1558 TempDigestSize = DigestSize;
1559 TempDigestSize += NumberOfAlgorithms;
1560 VendorInfoSize = (UINT8 *)TempDigestSize;
1561 *VendorInfoSize = 0;
1562
1563 SpecIdEvent.PCRIndex = 0;
1564 SpecIdEvent.EventType = EV_NO_ACTION;
1565 ZeroMem (&SpecIdEvent.Digest, sizeof(SpecIdEvent.Digest));
1566 SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);
1567
1568 //
1569 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.
1570 // TCG EFI Protocol Spec. Section 5.3 Event Log Header
1571 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log
1572 //
1573 Status = TcgDxeLogEvent (
1574 mTcg2EventInfo[Index].LogFormat,
1575 &SpecIdEvent,
1576 sizeof(SpecIdEvent),
1577 (UINT8 *)TcgEfiSpecIdEventStruct,
1578 SpecIdEvent.EventSize
1579 );
1580
1581 //
1582 // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2
1583 //
1584 GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);
1585 if (GuidHob.Guid != NULL) {
1586 //
1587 // Get Locality Indicator from StartupLocality HOB
1588 //
1589 StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));
1590 CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));
1591 DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));
1592
1593 //
1594 // Initialize StartupLocalityEvent
1595 //
1596 InitNoActionEvent(&NoActionEvent, sizeof(StartupLocalityEvent));
1597
1598 //
1599 // Log EfiStartupLocalityEvent as the second Event
1600 // TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event
1601 //
1602 Status = TcgDxeLogEvent (
1603 mTcg2EventInfo[Index].LogFormat,
1604 &NoActionEvent,
1605 sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),
1606 (UINT8 *)&StartupLocalityEvent,
1607 sizeof(StartupLocalityEvent)
1608 );
1609
1610 }
1611 }
1612 }
1613 }
1614
1615 //
1616 // 2. Create Final Log Area
1617 //
1618 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
1619 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
1620 if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
1621 Status = gBS->AllocatePages (
1622 AllocateAnyPages,
1623 EfiACPIMemoryNVS,
1624 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),
1625 &Lasa
1626 );
1627 if (EFI_ERROR (Status)) {
1628 return Status;
1629 }
1630 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);
1631
1632 //
1633 // Initialize
1634 //
1635 mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
1636 (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
1637 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
1638
1639 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
1640 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
1641 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
1642 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
1643 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;
1644 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
1645 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
1646
1647 //
1648 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
1649 //
1650 Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);
1651 if (EFI_ERROR (Status)) {
1652 return Status;
1653 }
1654 } else {
1655 //
1656 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
1657 //
1658 mTcgDxeData.FinalEventsTable[Index] = NULL;
1659 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
1660 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;
1661 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;
1662 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
1663 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;
1664 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
1665 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
1666 }
1667 }
1668 }
1669
1670 //
1671 // 3. Sync data from PEI to DXE
1672 //
1673 Status = EFI_SUCCESS;
1674 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
1675 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
1676 GuidHob.Raw = GetHobList ();
1677 Status = EFI_SUCCESS;
1678 while (!EFI_ERROR (Status) &&
1679 (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {
1680 TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));
1681 ASSERT (TcgEvent != NULL);
1682 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
1683 switch (mTcg2EventInfo[Index].LogFormat) {
1684 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
1685 Status = TcgDxeLogEvent (
1686 mTcg2EventInfo[Index].LogFormat,
1687 TcgEvent,
1688 sizeof(TCG_PCR_EVENT_HDR),
1689 ((TCG_PCR_EVENT*)TcgEvent)->Event,
1690 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize
1691 );
1692 break;
1693 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
1694 DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE);
1695 DigestListBinSize = GetDigestListBinSize (DigestListBin);
1696 //
1697 // Save event size.
1698 //
1699 CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32));
1700 Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32);
1701 //
1702 // Filter inactive digest in the event2 log from PEI HOB.
1703 //
1704 CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));
1705 EventSizePtr = CopyDigestListBinToBuffer (
1706 DigestListBin,
1707 &TempDigestListBin,
1708 mTcgDxeData.BsCap.ActivePcrBanks,
1709 &HashAlgorithmMaskCopied
1710 );
1711 if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {
1712 DEBUG ((
1713 DEBUG_ERROR,
1714 "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",
1715 HashAlgorithmMaskCopied,
1716 mTcgDxeData.BsCap.ActivePcrBanks
1717 ));
1718 }
1719 //
1720 // Restore event size.
1721 //
1722 CopyMem (EventSizePtr, &EventSize, sizeof(UINT32));
1723 DigestListBinSize = GetDigestListBinSize (DigestListBin);
1724
1725 Status = TcgDxeLogEvent (
1726 mTcg2EventInfo[Index].LogFormat,
1727 TcgEvent,
1728 sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),
1729 Event,
1730 EventSize
1731 );
1732 break;
1733 }
1734 FreePool (TcgEvent);
1735 }
1736 }
1737 }
1738
1739 return Status;
1740 }
1741
1742 /**
1743 Measure and log an action string, and extend the measurement result into PCR[PCRIndex].
1744
1745 @param[in] PCRIndex PCRIndex to extend
1746 @param[in] String A specific string that indicates an Action event.
1747
1748 @retval EFI_SUCCESS Operation completed successfully.
1749 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1750
1751 **/
1752 EFI_STATUS
1753 TcgMeasureAction (
1754 IN TPM_PCRINDEX PCRIndex,
1755 IN CHAR8 *String
1756 )
1757 {
1758 TCG_PCR_EVENT_HDR TcgEvent;
1759
1760 TcgEvent.PCRIndex = PCRIndex;
1761 TcgEvent.EventType = EV_EFI_ACTION;
1762 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
1763 return TcgDxeHashLogExtendEvent (
1764 0,
1765 (UINT8*)String,
1766 TcgEvent.EventSize,
1767 &TcgEvent,
1768 (UINT8 *) String
1769 );
1770 }
1771
1772 /**
1773 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1774
1775 @retval EFI_SUCCESS Operation completed successfully.
1776 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1777
1778 **/
1779 EFI_STATUS
1780 MeasureHandoffTables (
1781 VOID
1782 )
1783 {
1784 EFI_STATUS Status;
1785 TCG_PCR_EVENT_HDR TcgEvent;
1786 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
1787 UINTN ProcessorNum;
1788 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
1789
1790 ProcessorLocBuf = NULL;
1791 Status = EFI_SUCCESS;
1792
1793 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
1794 //
1795 // Tcg Server spec.
1796 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1797 //
1798 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
1799
1800 if (!EFI_ERROR(Status)){
1801 TcgEvent.PCRIndex = 1;
1802 TcgEvent.EventType = EV_TABLE_OF_DEVICES;
1803 TcgEvent.EventSize = sizeof (HandoffTables);
1804
1805 HandoffTables.NumberOfTables = 1;
1806 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
1807 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
1808
1809 Status = TcgDxeHashLogExtendEvent (
1810 0,
1811 (UINT8*)(UINTN)ProcessorLocBuf,
1812 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
1813 &TcgEvent,
1814 (UINT8*)&HandoffTables
1815 );
1816
1817 FreePool(ProcessorLocBuf);
1818 }
1819 }
1820
1821 return Status;
1822 }
1823
1824 /**
1825 Measure and log Separator event, and extend the measurement result into a specific PCR.
1826
1827 @param[in] PCRIndex PCR index.
1828
1829 @retval EFI_SUCCESS Operation completed successfully.
1830 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1831
1832 **/
1833 EFI_STATUS
1834 MeasureSeparatorEvent (
1835 IN TPM_PCRINDEX PCRIndex
1836 )
1837 {
1838 TCG_PCR_EVENT_HDR TcgEvent;
1839 UINT32 EventData;
1840
1841 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));
1842
1843 EventData = 0;
1844 TcgEvent.PCRIndex = PCRIndex;
1845 TcgEvent.EventType = EV_SEPARATOR;
1846 TcgEvent.EventSize = (UINT32)sizeof (EventData);
1847 return TcgDxeHashLogExtendEvent (
1848 0,
1849 (UINT8 *)&EventData,
1850 sizeof (EventData),
1851 &TcgEvent,
1852 (UINT8 *)&EventData
1853 );
1854 }
1855
1856 /**
1857 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1858
1859 @param[in] PCRIndex PCR Index.
1860 @param[in] EventType Event type.
1861 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1862 @param[in] VendorGuid A unique identifier for the vendor.
1863 @param[in] VarData The content of the variable data.
1864 @param[in] VarSize The size of the variable data.
1865
1866 @retval EFI_SUCCESS Operation completed successfully.
1867 @retval EFI_OUT_OF_RESOURCES Out of memory.
1868 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1869
1870 **/
1871 EFI_STATUS
1872 MeasureVariable (
1873 IN TPM_PCRINDEX PCRIndex,
1874 IN TCG_EVENTTYPE EventType,
1875 IN CHAR16 *VarName,
1876 IN EFI_GUID *VendorGuid,
1877 IN VOID *VarData,
1878 IN UINTN VarSize
1879 )
1880 {
1881 EFI_STATUS Status;
1882 TCG_PCR_EVENT_HDR TcgEvent;
1883 UINTN VarNameLength;
1884 UEFI_VARIABLE_DATA *VarLog;
1885
1886 DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));
1887 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
1888
1889 VarNameLength = StrLen (VarName);
1890 TcgEvent.PCRIndex = PCRIndex;
1891 TcgEvent.EventType = EventType;
1892
1893 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
1894 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
1895
1896 VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (TcgEvent.EventSize);
1897 if (VarLog == NULL) {
1898 return EFI_OUT_OF_RESOURCES;
1899 }
1900
1901 VarLog->VariableName = *VendorGuid;
1902 VarLog->UnicodeNameLength = VarNameLength;
1903 VarLog->VariableDataLength = VarSize;
1904 CopyMem (
1905 VarLog->UnicodeName,
1906 VarName,
1907 VarNameLength * sizeof (*VarName)
1908 );
1909 if (VarSize != 0 && VarData != NULL) {
1910 CopyMem (
1911 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
1912 VarData,
1913 VarSize
1914 );
1915 }
1916
1917 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1918 //
1919 // Digest is the event data (UEFI_VARIABLE_DATA)
1920 //
1921 Status = TcgDxeHashLogExtendEvent (
1922 0,
1923 (UINT8*)VarLog,
1924 TcgEvent.EventSize,
1925 &TcgEvent,
1926 (UINT8*)VarLog
1927 );
1928 } else {
1929 ASSERT (VarData != NULL);
1930 Status = TcgDxeHashLogExtendEvent (
1931 0,
1932 (UINT8*)VarData,
1933 VarSize,
1934 &TcgEvent,
1935 (UINT8*)VarLog
1936 );
1937 }
1938 FreePool (VarLog);
1939 return Status;
1940 }
1941
1942 /**
1943 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1944
1945 @param[in] PCRIndex PCR Index.
1946 @param[in] EventType Event type.
1947 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1948 @param[in] VendorGuid A unique identifier for the vendor.
1949 @param[out] VarSize The size of the variable data.
1950 @param[out] VarData Pointer to the content of the variable.
1951
1952 @retval EFI_SUCCESS Operation completed successfully.
1953 @retval EFI_OUT_OF_RESOURCES Out of memory.
1954 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1955
1956 **/
1957 EFI_STATUS
1958 ReadAndMeasureVariable (
1959 IN TPM_PCRINDEX PCRIndex,
1960 IN TCG_EVENTTYPE EventType,
1961 IN CHAR16 *VarName,
1962 IN EFI_GUID *VendorGuid,
1963 OUT UINTN *VarSize,
1964 OUT VOID **VarData
1965 )
1966 {
1967 EFI_STATUS Status;
1968
1969 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);
1970 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1971 if (EFI_ERROR (Status)) {
1972 //
1973 // It is valid case, so we need handle it.
1974 //
1975 *VarData = NULL;
1976 *VarSize = 0;
1977 }
1978 } else {
1979 //
1980 // if status error, VarData is freed and set NULL by GetVariable2
1981 //
1982 if (EFI_ERROR (Status)) {
1983 return EFI_NOT_FOUND;
1984 }
1985 }
1986
1987 Status = MeasureVariable (
1988 PCRIndex,
1989 EventType,
1990 VarName,
1991 VendorGuid,
1992 *VarData,
1993 *VarSize
1994 );
1995 return Status;
1996 }
1997
1998 /**
1999 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].
2000 according to TCG PC Client PFP spec 0021 Section 2.4.4.2
2001
2002 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
2003 @param[in] VendorGuid A unique identifier for the vendor.
2004 @param[out] VarSize The size of the variable data.
2005 @param[out] VarData Pointer to the content of the variable.
2006
2007 @retval EFI_SUCCESS Operation completed successfully.
2008 @retval EFI_OUT_OF_RESOURCES Out of memory.
2009 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2010
2011 **/
2012 EFI_STATUS
2013 ReadAndMeasureBootVariable (
2014 IN CHAR16 *VarName,
2015 IN EFI_GUID *VendorGuid,
2016 OUT UINTN *VarSize,
2017 OUT VOID **VarData
2018 )
2019 {
2020 return ReadAndMeasureVariable (
2021 1,
2022 EV_EFI_VARIABLE_BOOT,
2023 VarName,
2024 VendorGuid,
2025 VarSize,
2026 VarData
2027 );
2028 }
2029
2030 /**
2031 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
2032
2033 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
2034 @param[in] VendorGuid A unique identifier for the vendor.
2035 @param[out] VarSize The size of the variable data.
2036 @param[out] VarData Pointer to the content of the variable.
2037
2038 @retval EFI_SUCCESS Operation completed successfully.
2039 @retval EFI_OUT_OF_RESOURCES Out of memory.
2040 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2041
2042 **/
2043 EFI_STATUS
2044 ReadAndMeasureSecureVariable (
2045 IN CHAR16 *VarName,
2046 IN EFI_GUID *VendorGuid,
2047 OUT UINTN *VarSize,
2048 OUT VOID **VarData
2049 )
2050 {
2051 return ReadAndMeasureVariable (
2052 7,
2053 EV_EFI_VARIABLE_DRIVER_CONFIG,
2054 VarName,
2055 VendorGuid,
2056 VarSize,
2057 VarData
2058 );
2059 }
2060
2061 /**
2062 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
2063
2064 The EFI boot variables are BootOrder and Boot#### variables.
2065
2066 @retval EFI_SUCCESS Operation completed successfully.
2067 @retval EFI_OUT_OF_RESOURCES Out of memory.
2068 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2069
2070 **/
2071 EFI_STATUS
2072 MeasureAllBootVariables (
2073 VOID
2074 )
2075 {
2076 EFI_STATUS Status;
2077 UINT16 *BootOrder;
2078 UINTN BootCount;
2079 UINTN Index;
2080 VOID *BootVarData;
2081 UINTN Size;
2082
2083 Status = ReadAndMeasureBootVariable (
2084 mBootVarName,
2085 &gEfiGlobalVariableGuid,
2086 &BootCount,
2087 (VOID **) &BootOrder
2088 );
2089 if (Status == EFI_NOT_FOUND || BootOrder == NULL) {
2090 return EFI_SUCCESS;
2091 }
2092
2093 if (EFI_ERROR (Status)) {
2094 //
2095 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
2096 //
2097 FreePool (BootOrder);
2098 return Status;
2099 }
2100
2101 BootCount /= sizeof (*BootOrder);
2102 for (Index = 0; Index < BootCount; Index++) {
2103 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
2104 Status = ReadAndMeasureBootVariable (
2105 mBootVarName,
2106 &gEfiGlobalVariableGuid,
2107 &Size,
2108 &BootVarData
2109 );
2110 if (!EFI_ERROR (Status)) {
2111 FreePool (BootVarData);
2112 }
2113 }
2114
2115 FreePool (BootOrder);
2116 return EFI_SUCCESS;
2117 }
2118
2119 /**
2120 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
2121
2122 The EFI boot variables are BootOrder and Boot#### variables.
2123
2124 @retval EFI_SUCCESS Operation completed successfully.
2125 @retval EFI_OUT_OF_RESOURCES Out of memory.
2126 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2127
2128 **/
2129 EFI_STATUS
2130 MeasureAllSecureVariables (
2131 VOID
2132 )
2133 {
2134 EFI_STATUS Status;
2135 VOID *Data;
2136 UINTN DataSize;
2137 UINTN Index;
2138
2139 Status = EFI_NOT_FOUND;
2140 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
2141 Status = ReadAndMeasureSecureVariable (
2142 mVariableType[Index].VariableName,
2143 mVariableType[Index].VendorGuid,
2144 &DataSize,
2145 &Data
2146 );
2147 if (!EFI_ERROR (Status)) {
2148 if (Data != NULL) {
2149 FreePool (Data);
2150 }
2151 }
2152 }
2153
2154 //
2155 // Measure DBT if present and not empty
2156 //
2157 Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);
2158 if (!EFI_ERROR(Status)) {
2159 Status = MeasureVariable (
2160 7,
2161 EV_EFI_VARIABLE_DRIVER_CONFIG,
2162 EFI_IMAGE_SECURITY_DATABASE2,
2163 &gEfiImageSecurityDatabaseGuid,
2164 Data,
2165 DataSize
2166 );
2167 FreePool(Data);
2168 } else {
2169 DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));
2170 }
2171
2172 return EFI_SUCCESS;
2173 }
2174
2175 /**
2176 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
2177
2178 @retval EFI_SUCCESS Operation completed successfully.
2179 @retval EFI_OUT_OF_RESOURCES Out of memory.
2180 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2181
2182 **/
2183 EFI_STATUS
2184 MeasureLaunchOfFirmwareDebugger (
2185 VOID
2186 )
2187 {
2188 TCG_PCR_EVENT_HDR TcgEvent;
2189
2190 TcgEvent.PCRIndex = 7;
2191 TcgEvent.EventType = EV_EFI_ACTION;
2192 TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;
2193 return TcgDxeHashLogExtendEvent (
2194 0,
2195 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,
2196 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,
2197 &TcgEvent,
2198 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING
2199 );
2200 }
2201
2202 /**
2203 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
2204
2205 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
2206 - The contents of the SecureBoot variable
2207 - The contents of the PK variable
2208 - The contents of the KEK variable
2209 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
2210 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
2211 - Separator
2212 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
2213
2214 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
2215 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
2216
2217 @param[in] Event Event whose notification function is being invoked
2218 @param[in] Context Pointer to the notification function's context
2219 **/
2220 VOID
2221 EFIAPI
2222 MeasureSecureBootPolicy (
2223 IN EFI_EVENT Event,
2224 IN VOID *Context
2225 )
2226 {
2227 EFI_STATUS Status;
2228 VOID *Protocol;
2229
2230 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
2231 if (EFI_ERROR (Status)) {
2232 return;
2233 }
2234
2235 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {
2236 Status = MeasureLaunchOfFirmwareDebugger ();
2237 DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));
2238 }
2239
2240 Status = MeasureAllSecureVariables ();
2241 DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));
2242
2243 //
2244 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
2245 // and ImageVerification (Authority)
2246 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
2247 // the Authority measurement happen before ReadToBoot event.
2248 //
2249 Status = MeasureSeparatorEvent (7);
2250 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));
2251 return ;
2252 }
2253
2254 /**
2255 Ready to Boot Event notification handler.
2256
2257 Sequence of OS boot events is measured in this event notification handler.
2258
2259 @param[in] Event Event whose notification function is being invoked
2260 @param[in] Context Pointer to the notification function's context
2261
2262 **/
2263 VOID
2264 EFIAPI
2265 OnReadyToBoot (
2266 IN EFI_EVENT Event,
2267 IN VOID *Context
2268 )
2269 {
2270 EFI_STATUS Status;
2271 TPM_PCRINDEX PcrIndex;
2272
2273 PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE);
2274 if (mBootAttempts == 0) {
2275
2276 //
2277 // Measure handoff tables.
2278 //
2279 Status = MeasureHandoffTables ();
2280 if (EFI_ERROR (Status)) {
2281 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));
2282 }
2283
2284 //
2285 // Measure BootOrder & Boot#### variables.
2286 //
2287 Status = MeasureAllBootVariables ();
2288 if (EFI_ERROR (Status)) {
2289 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));
2290 }
2291
2292 //
2293 // 1. This is the first boot attempt.
2294 //
2295 Status = TcgMeasureAction (
2296 4,
2297 EFI_CALLING_EFI_APPLICATION
2298 );
2299 if (EFI_ERROR (Status)) {
2300 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
2301 }
2302
2303 //
2304 // 2. Draw a line between pre-boot env and entering post-boot env.
2305 // PCR[7] is already done.
2306 //
2307 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {
2308 Status = MeasureSeparatorEvent (PcrIndex);
2309 if (EFI_ERROR (Status)) {
2310 DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));
2311 }
2312 }
2313
2314 //
2315 // 3. Measure GPT. It would be done in SAP driver.
2316 //
2317
2318 //
2319 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
2320 //
2321
2322 //
2323 // 5. Read & Measure variable. BootOrder already measured.
2324 //
2325 } else {
2326 //
2327 // 6. Not first attempt, meaning a return from last attempt
2328 //
2329 Status = TcgMeasureAction (
2330 4,
2331 EFI_RETURNING_FROM_EFI_APPLICATION
2332 );
2333 if (EFI_ERROR (Status)) {
2334 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));
2335 }
2336
2337 //
2338 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
2339 // TCG PC Client PFP spec Section 2.4.4.5 Step 4
2340 //
2341 Status = TcgMeasureAction (
2342 4,
2343 EFI_CALLING_EFI_APPLICATION
2344 );
2345 if (EFI_ERROR (Status)) {
2346 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
2347 }
2348 }
2349
2350 DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));
2351 //
2352 // Increase boot attempt counter.
2353 //
2354 mBootAttempts++;
2355 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1);
2356 }
2357
2358 /**
2359 Exit Boot Services Event notification handler.
2360
2361 Measure invocation and success of ExitBootServices.
2362
2363 @param[in] Event Event whose notification function is being invoked
2364 @param[in] Context Pointer to the notification function's context
2365
2366 **/
2367 VOID
2368 EFIAPI
2369 OnExitBootServices (
2370 IN EFI_EVENT Event,
2371 IN VOID *Context
2372 )
2373 {
2374 EFI_STATUS Status;
2375
2376 //
2377 // Measure invocation of ExitBootServices,
2378 //
2379 Status = TcgMeasureAction (
2380 5,
2381 EFI_EXIT_BOOT_SERVICES_INVOCATION
2382 );
2383 if (EFI_ERROR (Status)) {
2384 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
2385 }
2386
2387 //
2388 // Measure success of ExitBootServices
2389 //
2390 Status = TcgMeasureAction (
2391 5,
2392 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
2393 );
2394 if (EFI_ERROR (Status)) {
2395 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
2396 }
2397 }
2398
2399 /**
2400 Exit Boot Services Failed Event notification handler.
2401
2402 Measure Failure of ExitBootServices.
2403
2404 @param[in] Event Event whose notification function is being invoked
2405 @param[in] Context Pointer to the notification function's context
2406
2407 **/
2408 VOID
2409 EFIAPI
2410 OnExitBootServicesFailed (
2411 IN EFI_EVENT Event,
2412 IN VOID *Context
2413 )
2414 {
2415 EFI_STATUS Status;
2416
2417 //
2418 // Measure Failure of ExitBootServices,
2419 //
2420 Status = TcgMeasureAction (
2421 5,
2422 EFI_EXIT_BOOT_SERVICES_FAILED
2423 );
2424 if (EFI_ERROR (Status)) {
2425 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
2426 }
2427
2428 }
2429
2430 /**
2431 This routine is called to properly shutdown the TPM before system reset.
2432 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
2433 Part 1: Architecture, Revision 01.16.
2434
2435 @param[in] ResetType The type of reset to perform.
2436 @param[in] ResetStatus The status code for the reset.
2437 @param[in] DataSize The size, in bytes, of ResetData.
2438 @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
2439 EfiResetShutdown the data buffer starts with a Null-terminated
2440 string, optionally followed by additional binary data.
2441 The string is a description that the caller may use to further
2442 indicate the reason for the system reset.
2443 For a ResetType of EfiResetPlatformSpecific the data buffer
2444 also starts with a Null-terminated string that is followed
2445 by an EFI_GUID that describes the specific type of reset to perform.
2446 **/
2447 VOID
2448 EFIAPI
2449 ShutdownTpmOnReset (
2450 IN EFI_RESET_TYPE ResetType,
2451 IN EFI_STATUS ResetStatus,
2452 IN UINTN DataSize,
2453 IN VOID *ResetData OPTIONAL
2454 )
2455 {
2456 EFI_STATUS Status;
2457 Status = Tpm2Shutdown (TPM_SU_CLEAR);
2458 DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));
2459 }
2460
2461 /**
2462 Hook the system reset to properly shutdown TPM.
2463 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
2464 Part 1: Architecture, Revision 01.16.
2465
2466 @param[in] Event Event whose notification function is being invoked
2467 @param[in] Context Pointer to the notification function's context
2468 **/
2469 VOID
2470 EFIAPI
2471 OnResetNotificationInstall (
2472 IN EFI_EVENT Event,
2473 IN VOID *Context
2474 )
2475 {
2476 EFI_STATUS Status;
2477 EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;
2478
2479 Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);
2480 if (!EFI_ERROR (Status)) {
2481 Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);
2482 ASSERT_EFI_ERROR (Status);
2483 DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));
2484
2485 gBS->CloseEvent (Event);
2486 }
2487 }
2488
2489 /**
2490 The function install Tcg2 protocol.
2491
2492 @retval EFI_SUCCESS Tcg2 protocol is installed.
2493 @retval other Some error occurs.
2494 **/
2495 EFI_STATUS
2496 InstallTcg2 (
2497 VOID
2498 )
2499 {
2500 EFI_STATUS Status;
2501 EFI_HANDLE Handle;
2502
2503 Handle = NULL;
2504 Status = gBS->InstallMultipleProtocolInterfaces (
2505 &Handle,
2506 &gEfiTcg2ProtocolGuid,
2507 &mTcg2Protocol,
2508 NULL
2509 );
2510 return Status;
2511 }
2512
2513 /**
2514 The driver's entry point. It publishes EFI Tcg2 Protocol.
2515
2516 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2517 @param[in] SystemTable A pointer to the EFI System Table.
2518
2519 @retval EFI_SUCCESS The entry point is executed successfully.
2520 @retval other Some error occurs when executing this entry point.
2521 **/
2522 EFI_STATUS
2523 EFIAPI
2524 DriverEntry (
2525 IN EFI_HANDLE ImageHandle,
2526 IN EFI_SYSTEM_TABLE *SystemTable
2527 )
2528 {
2529 EFI_STATUS Status;
2530 EFI_EVENT Event;
2531 VOID *Registration;
2532 UINT32 MaxCommandSize;
2533 UINT32 MaxResponseSize;
2534 UINTN Index;
2535 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
2536 UINT32 ActivePCRBanks;
2537 UINT32 NumberOfPCRBanks;
2538
2539 mImageHandle = ImageHandle;
2540
2541 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
2542 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
2543 DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));
2544 return EFI_UNSUPPORTED;
2545 }
2546
2547 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
2548 DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
2549 return EFI_DEVICE_ERROR;
2550 }
2551
2552 Status = Tpm2RequestUseTpm ();
2553 if (EFI_ERROR (Status)) {
2554 DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));
2555 return Status;
2556 }
2557
2558 //
2559 // Fill information
2560 //
2561 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));
2562
2563 mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);
2564 mTcgDxeData.BsCap.ProtocolVersion.Major = 1;
2565 mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;
2566 mTcgDxeData.BsCap.StructureVersion.Major = 1;
2567 mTcgDxeData.BsCap.StructureVersion.Minor = 1;
2568
2569 DEBUG ((EFI_D_INFO, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));
2570 DEBUG ((EFI_D_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));
2571
2572 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);
2573 if (EFI_ERROR (Status)) {
2574 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));
2575 } else {
2576 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));
2577 }
2578
2579 DEBUG_CODE (
2580 UINT32 FirmwareVersion1;
2581 UINT32 FirmwareVersion2;
2582
2583 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);
2584 if (EFI_ERROR (Status)) {
2585 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
2586 } else {
2587 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));
2588 }
2589 );
2590
2591 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);
2592 if (EFI_ERROR (Status)) {
2593 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
2594 } else {
2595 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;
2596 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;
2597 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));
2598 }
2599
2600 //
2601 // Get supported PCR and current Active PCRs
2602 //
2603 Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks);
2604 ASSERT_EFI_ERROR (Status);
2605
2606 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);
2607 mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);
2608
2609 //
2610 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.
2611 //
2612 NumberOfPCRBanks = 0;
2613 for (Index = 0; Index < 32; Index++) {
2614 if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {
2615 NumberOfPCRBanks++;
2616 }
2617 }
2618
2619 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {
2620 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;
2621 } else {
2622 mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks);
2623 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) {
2624 DEBUG ((EFI_D_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks));
2625 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;
2626 }
2627 }
2628
2629 mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
2630 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {
2631 //
2632 // No need to expose TCG1.2 event log if SHA1 bank does not exist.
2633 //
2634 mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
2635 }
2636
2637 DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
2638 DEBUG ((EFI_D_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));
2639 DEBUG ((EFI_D_INFO, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks));
2640 DEBUG ((EFI_D_INFO, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks));
2641
2642 if (mTcgDxeData.BsCap.TPMPresentFlag) {
2643 //
2644 // Setup the log area and copy event log from hob list to it
2645 //
2646 Status = SetupEventLog ();
2647 ASSERT_EFI_ERROR (Status);
2648
2649 //
2650 // Measure handoff tables, Boot#### variables etc.
2651 //
2652 Status = EfiCreateEventReadyToBootEx (
2653 TPL_CALLBACK,
2654 OnReadyToBoot,
2655 NULL,
2656 &Event
2657 );
2658
2659 Status = gBS->CreateEventEx (
2660 EVT_NOTIFY_SIGNAL,
2661 TPL_NOTIFY,
2662 OnExitBootServices,
2663 NULL,
2664 &gEfiEventExitBootServicesGuid,
2665 &Event
2666 );
2667
2668 //
2669 // Measure Exit Boot Service failed
2670 //
2671 Status = gBS->CreateEventEx (
2672 EVT_NOTIFY_SIGNAL,
2673 TPL_NOTIFY,
2674 OnExitBootServicesFailed,
2675 NULL,
2676 &gEventExitBootServicesFailedGuid,
2677 &Event
2678 );
2679
2680 //
2681 // Create event callback, because we need access variable on SecureBootPolicyVariable
2682 // We should use VariableWriteArch instead of VariableArch, because Variable driver
2683 // may update SecureBoot value based on last setting.
2684 //
2685 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
2686
2687 //
2688 // Hook the system reset to properly shutdown TPM.
2689 //
2690 EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);
2691 }
2692
2693 //
2694 // Install Tcg2Protocol
2695 //
2696 Status = InstallTcg2 ();
2697 DEBUG ((EFI_D_INFO, "InstallTcg2 - %r\n", Status));
2698
2699 return Status;
2700 }