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