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