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