]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg Tcg2Dxe: Get correct digest list size
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Dxe / Tcg2Dxe.c
1 /** @file
2 This module implements Tcg2 Protocol.
3
4 Copyright (c) 2015 - 2016, 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 };
119
120 EFI_HANDLE mImageHandle;
121
122 /**
123 Measure PE image into TPM log based on the authenticode image hashing in
124 PE/COFF Specification 8.0 Appendix A.
125
126 Caution: This function may receive untrusted input.
127 PE/COFF image is external input, so this function will validate its data structure
128 within this image buffer before use.
129
130 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
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 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
206 Caller is responsible to free LocationBuf.
207
208 @param[out] LocationBuf Returns Processor Location Buffer.
209 @param[out] Num Returns processor number.
210
211 @retval EFI_SUCCESS Operation completed successfully.
212 @retval EFI_UNSUPPORTED MpService protocol not found.
213
214 **/
215 EFI_STATUS
216 GetProcessorsCpuLocation (
217 OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,
218 OUT UINTN *Num
219 )
220 {
221 EFI_STATUS Status;
222 EFI_MP_SERVICES_PROTOCOL *MpProtocol;
223 UINTN ProcessorNum;
224 UINTN EnabledProcessorNum;
225 EFI_PROCESSOR_INFORMATION ProcessorInfo;
226 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
227 UINTN Index;
228
229 Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol);
230 if (EFI_ERROR (Status)) {
231 //
232 // MP protocol is not installed
233 //
234 return EFI_UNSUPPORTED;
235 }
236
237 Status = MpProtocol->GetNumberOfProcessors(
238 MpProtocol,
239 &ProcessorNum,
240 &EnabledProcessorNum
241 );
242 if (EFI_ERROR(Status)){
243 return Status;
244 }
245
246 Status = gBS->AllocatePool(
247 EfiBootServicesData,
248 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
249 (VOID **) &ProcessorLocBuf
250 );
251 if (EFI_ERROR(Status)){
252 return Status;
253 }
254
255 //
256 // Get each processor Location info
257 //
258 for (Index = 0; Index < ProcessorNum; Index++) {
259 Status = MpProtocol->GetProcessorInfo(
260 MpProtocol,
261 Index,
262 &ProcessorInfo
263 );
264 if (EFI_ERROR(Status)){
265 FreePool(ProcessorLocBuf);
266 return Status;
267 }
268
269 //
270 // Get all Processor Location info & measure
271 //
272 CopyMem(
273 &ProcessorLocBuf[Index],
274 &ProcessorInfo.Location,
275 sizeof(EFI_CPU_PHYSICAL_LOCATION)
276 );
277 }
278
279 *LocationBuf = ProcessorLocBuf;
280 *Num = ProcessorNum;
281
282 return Status;
283 }
284
285 /**
286 The EFI_TCG2_PROTOCOL GetCapability function call provides protocol
287 capability information and state information.
288
289 @param[in] This Indicates the calling context
290 @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY
291 structure and sets the size field to the size of the structure allocated.
292 The callee fills in the fields with the EFI protocol capability information
293 and the current EFI TCG2 state information up to the number of fields which
294 fit within the size of the structure passed in.
295
296 @retval EFI_SUCCESS Operation completed successfully.
297 @retval EFI_DEVICE_ERROR The command was unsuccessful.
298 The ProtocolCapability variable will not be populated.
299 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
300 The ProtocolCapability variable will not be populated.
301 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
302 It will be partially populated (required Size field will be set).
303 **/
304 EFI_STATUS
305 EFIAPI
306 Tcg2GetCapability (
307 IN EFI_TCG2_PROTOCOL *This,
308 IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability
309 )
310 {
311 DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability ...\n"));
312
313 if ((This == NULL) || (ProtocolCapability == NULL)) {
314 return EFI_INVALID_PARAMETER;
315 }
316
317 DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));
318 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)));
319
320 if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {
321 //
322 // Handle the case that firmware support 1.1 but OS only support 1.0.
323 //
324 if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) ||
325 ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {
326 if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {
327 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));
328 ProtocolCapability->Size = sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0);
329 ProtocolCapability->StructureVersion.Major = 1;
330 ProtocolCapability->StructureVersion.Minor = 0;
331 ProtocolCapability->ProtocolVersion.Major = 1;
332 ProtocolCapability->ProtocolVersion.Minor = 0;
333 DEBUG ((EFI_D_ERROR, "TreeGetCapability (Compatible) - %r\n", EFI_SUCCESS));
334 return EFI_SUCCESS;
335 }
336 }
337 ProtocolCapability->Size = mTcgDxeData.BsCap.Size;
338 return EFI_BUFFER_TOO_SMALL;
339 }
340
341 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);
342 DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability - %r\n", EFI_SUCCESS));
343 return EFI_SUCCESS;
344 }
345
346 /**
347 This function dump PCR event.
348
349 @param[in] EventHdr TCG PCR event structure.
350 **/
351 VOID
352 DumpEvent (
353 IN TCG_PCR_EVENT_HDR *EventHdr
354 )
355 {
356 UINTN Index;
357
358 DEBUG ((EFI_D_INFO, " Event:\n"));
359 DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", EventHdr->PCRIndex));
360 DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", EventHdr->EventType));
361 DEBUG ((EFI_D_INFO, " Digest - "));
362 for (Index = 0; Index < sizeof(TCG_DIGEST); Index++) {
363 DEBUG ((EFI_D_INFO, "%02x ", EventHdr->Digest.digest[Index]));
364 }
365 DEBUG ((EFI_D_INFO, "\n"));
366 DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize));
367 InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);
368 }
369
370 /**
371 This function dump TCG_EfiSpecIDEventStruct.
372
373 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
374 **/
375 VOID
376 DumpTcgEfiSpecIdEventStruct (
377 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct
378 )
379 {
380 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
381 UINTN Index;
382 UINT8 *VendorInfoSize;
383 UINT8 *VendorInfo;
384 UINT32 NumberOfAlgorithms;
385
386 DEBUG ((EFI_D_INFO, " TCG_EfiSpecIDEventStruct:\n"));
387 DEBUG ((EFI_D_INFO, " signature - '"));
388 for (Index = 0; Index < sizeof(TcgEfiSpecIdEventStruct->signature); Index++) {
389 DEBUG ((EFI_D_INFO, "%c", TcgEfiSpecIdEventStruct->signature[Index]));
390 }
391 DEBUG ((EFI_D_INFO, "'\n"));
392 DEBUG ((EFI_D_INFO, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct->platformClass));
393 DEBUG ((EFI_D_INFO, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct->specVersionMajor, TcgEfiSpecIdEventStruct->specVersionMinor, TcgEfiSpecIdEventStruct->specErrata));
394 DEBUG ((EFI_D_INFO, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct->uintnSize));
395
396 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(NumberOfAlgorithms));
397 DEBUG ((EFI_D_INFO, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms));
398
399 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));
400 for (Index = 0; Index < NumberOfAlgorithms; Index++) {
401 DEBUG ((EFI_D_INFO, " digest(%d)\n", Index));
402 DEBUG ((EFI_D_INFO, " algorithmId - 0x%04x\n", DigestSize[Index].algorithmId));
403 DEBUG ((EFI_D_INFO, " digestSize - 0x%04x\n", DigestSize[Index].digestSize));
404 }
405 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];
406 DEBUG ((EFI_D_INFO, " VendorInfoSize - 0x%02x\n", *VendorInfoSize));
407 VendorInfo = VendorInfoSize + 1;
408 DEBUG ((EFI_D_INFO, " VendorInfo - "));
409 for (Index = 0; Index < *VendorInfoSize; Index++) {
410 DEBUG ((EFI_D_INFO, "%02x ", VendorInfo[Index]));
411 }
412 DEBUG ((EFI_D_INFO, "\n"));
413 }
414
415 /**
416 This function get size of TCG_EfiSpecIDEventStruct.
417
418 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
419 **/
420 UINTN
421 GetTcgEfiSpecIdEventStructSize (
422 IN TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct
423 )
424 {
425 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
426 UINT8 *VendorInfoSize;
427 UINT32 NumberOfAlgorithms;
428
429 CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(NumberOfAlgorithms));
430
431 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));
432 VendorInfoSize = (UINT8 *)&DigestSize[NumberOfAlgorithms];
433 return sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (NumberOfAlgorithms * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8) + (*VendorInfoSize);
434 }
435
436 /**
437 This function dump PCR event 2.
438
439 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.
440 **/
441 VOID
442 DumpEvent2 (
443 IN TCG_PCR_EVENT2 *TcgPcrEvent2
444 )
445 {
446 UINTN Index;
447 UINT32 DigestIndex;
448 UINT32 DigestCount;
449 TPMI_ALG_HASH HashAlgo;
450 UINT32 DigestSize;
451 UINT8 *DigestBuffer;
452 UINT32 EventSize;
453 UINT8 *EventBuffer;
454
455 DEBUG ((EFI_D_INFO, " Event:\n"));
456 DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", TcgPcrEvent2->PCRIndex));
457 DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", TcgPcrEvent2->EventType));
458
459 DEBUG ((EFI_D_INFO, " DigestCount: 0x%08x\n", TcgPcrEvent2->Digest.count));
460
461 DigestCount = TcgPcrEvent2->Digest.count;
462 HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;
463 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;
464 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {
465 DEBUG ((EFI_D_INFO, " HashAlgo : 0x%04x\n", HashAlgo));
466 DEBUG ((EFI_D_INFO, " Digest(%d): ", DigestIndex));
467 DigestSize = GetHashSizeFromAlgo (HashAlgo);
468 for (Index = 0; Index < DigestSize; Index++) {
469 DEBUG ((EFI_D_INFO, "%02x ", DigestBuffer[Index]));
470 }
471 DEBUG ((EFI_D_INFO, "\n"));
472 //
473 // Prepare next
474 //
475 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH));
476 DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH);
477 }
478 DEBUG ((EFI_D_INFO, "\n"));
479 DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH);
480
481 CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize));
482 DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventSize));
483 EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);
484 InternalDumpHex (EventBuffer, EventSize);
485 }
486
487 /**
488 This function returns size of TCG PCR event 2.
489
490 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.
491
492 @return size of TCG PCR event 2.
493 **/
494 UINTN
495 GetPcrEvent2Size (
496 IN TCG_PCR_EVENT2 *TcgPcrEvent2
497 )
498 {
499 UINT32 DigestIndex;
500 UINT32 DigestCount;
501 TPMI_ALG_HASH HashAlgo;
502 UINT32 DigestSize;
503 UINT8 *DigestBuffer;
504 UINT32 EventSize;
505 UINT8 *EventBuffer;
506
507 DigestCount = TcgPcrEvent2->Digest.count;
508 HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;
509 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;
510 for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {
511 DigestSize = GetHashSizeFromAlgo (HashAlgo);
512 //
513 // Prepare next
514 //
515 CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH));
516 DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH);
517 }
518 DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH);
519
520 CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize));
521 EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);
522
523 return (UINTN)EventBuffer + EventSize - (UINTN)TcgPcrEvent2;
524 }
525
526 /**
527 This function dump event log.
528
529 @param[in] EventLogFormat The type of the event log for which the information is requested.
530 @param[in] EventLogLocation A pointer to the memory address of the event log.
531 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
532 address of the start of the last entry in the event log in memory.
533 @param[in] FinalEventsTable A pointer to the memory address of the final event table.
534 **/
535 VOID
536 DumpEventLog (
537 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
538 IN EFI_PHYSICAL_ADDRESS EventLogLocation,
539 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry,
540 IN EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable
541 )
542 {
543 TCG_PCR_EVENT_HDR *EventHdr;
544 TCG_PCR_EVENT2 *TcgPcrEvent2;
545 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
546 UINTN NumberOfEvents;
547
548 DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));
549
550 switch (EventLogFormat) {
551 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
552 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
553 while ((UINTN)EventHdr <= EventLogLastEntry) {
554 DumpEvent (EventHdr);
555 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);
556 }
557 if (FinalEventsTable == NULL) {
558 DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n"));
559 } else {
560 DEBUG ((EFI_D_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));
561 DEBUG ((EFI_D_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));
562 DEBUG ((EFI_D_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));
563
564 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)(FinalEventsTable + 1);
565 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {
566 DumpEvent (EventHdr);
567 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);
568 }
569 }
570 break;
571 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
572 //
573 // Dump first event
574 //
575 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
576 DumpEvent (EventHdr);
577
578 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)(EventHdr + 1);
579 DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct);
580
581 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgEfiSpecIdEventStruct + GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct));
582 while ((UINTN)TcgPcrEvent2 <= EventLogLastEntry) {
583 DumpEvent2 (TcgPcrEvent2);
584 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));
585 }
586
587 if (FinalEventsTable == NULL) {
588 DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n"));
589 } else {
590 DEBUG ((EFI_D_INFO, "FinalEventsTable: (0x%x)\n", FinalEventsTable));
591 DEBUG ((EFI_D_INFO, " Version: (0x%x)\n", FinalEventsTable->Version));
592 DEBUG ((EFI_D_INFO, " NumberOfEvents: (0x%x)\n", FinalEventsTable->NumberOfEvents));
593
594 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)(UINTN)(FinalEventsTable + 1);
595 for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {
596 DumpEvent2 (TcgPcrEvent2);
597 TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));
598 }
599 }
600 break;
601 }
602
603 return ;
604 }
605
606 /**
607 The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to
608 retrieve the address of a given event log and its last entry.
609
610 @param[in] This Indicates the calling context
611 @param[in] EventLogFormat The type of the event log for which the information is requested.
612 @param[out] EventLogLocation A pointer to the memory address of the event log.
613 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
614 address of the start of the last entry in the event log in memory.
615 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
616 have exceeded the area allocated for events, this value is set to TRUE.
617 Otherwise, the value will be FALSE and the Event Log will be complete.
618
619 @retval EFI_SUCCESS Operation completed successfully.
620 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
621 (e.g. asking for an event log whose format is not supported).
622 **/
623 EFI_STATUS
624 EFIAPI
625 Tcg2GetEventLog (
626 IN EFI_TCG2_PROTOCOL *This,
627 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
628 OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
629 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
630 OUT BOOLEAN *EventLogTruncated
631 )
632 {
633 UINTN Index;
634
635 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog ... (0x%x)\n", EventLogFormat));
636
637 if (This == NULL) {
638 return EFI_INVALID_PARAMETER;
639 }
640
641 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
642 if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {
643 break;
644 }
645 }
646
647 if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) {
648 return EFI_INVALID_PARAMETER;
649 }
650
651 if ((mTcg2EventInfo[Index].LogFormat & mTcgDxeData.BsCap.SupportedEventLogs) == 0) {
652 return EFI_INVALID_PARAMETER;
653 }
654
655 if (!mTcgDxeData.BsCap.TPMPresentFlag) {
656 if (EventLogLocation != NULL) {
657 *EventLogLocation = 0;
658 }
659 if (EventLogLastEntry != NULL) {
660 *EventLogLastEntry = 0;
661 }
662 if (EventLogTruncated != NULL) {
663 *EventLogTruncated = FALSE;
664 }
665 return EFI_SUCCESS;
666 }
667
668 if (EventLogLocation != NULL) {
669 *EventLogLocation = mTcgDxeData.EventLogAreaStruct[Index].Lasa;
670 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLocation - %x)\n", *EventLogLocation));
671 }
672
673 if (EventLogLastEntry != NULL) {
674 if (!mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted) {
675 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;
676 } else {
677 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].LastEvent;
678 }
679 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));
680 }
681
682 if (EventLogTruncated != NULL) {
683 *EventLogTruncated = mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated;
684 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));
685 }
686
687 DEBUG ((EFI_D_INFO, "Tcg2GetEventLog - %r\n", EFI_SUCCESS));
688
689 // Dump Event Log for debug purpose
690 if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {
691 DumpEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry, mTcgDxeData.FinalEventsTable[Index]);
692 }
693
694 //
695 // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored
696 // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.
697 //
698 mTcgDxeData.GetEventLogCalled[Index] = TRUE;
699
700 return EFI_SUCCESS;
701 }
702
703 /**
704 Add a new entry to the Event Log.
705
706 @param[in, out] EventLogPtr Pointer to the Event Log data.
707 @param[in, out] LogSize Size of the Event Log.
708 @param[in] MaxSize Maximum size of the Event Log.
709 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
710 @param[in] NewEventHdrSize New event header size.
711 @param[in] NewEventData Pointer to the new event data.
712 @param[in] NewEventSize New event data size.
713
714 @retval EFI_SUCCESS The new event log entry was added.
715 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
716
717 **/
718 EFI_STATUS
719 TcgCommLogEvent (
720 IN OUT UINT8 **EventLogPtr,
721 IN OUT UINTN *LogSize,
722 IN UINTN MaxSize,
723 IN VOID *NewEventHdr,
724 IN UINT32 NewEventHdrSize,
725 IN UINT8 *NewEventData,
726 IN UINT32 NewEventSize
727 )
728 {
729 UINTN NewLogSize;
730
731 if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {
732 return EFI_OUT_OF_RESOURCES;
733 }
734
735 NewLogSize = NewEventHdrSize + NewEventSize;
736
737 if (NewLogSize > MAX_ADDRESS - *LogSize) {
738 return EFI_OUT_OF_RESOURCES;
739 }
740
741 if (NewLogSize + *LogSize > MaxSize) {
742 DEBUG ((EFI_D_INFO, " MaxSize - 0x%x\n", MaxSize));
743 DEBUG ((EFI_D_INFO, " NewLogSize - 0x%x\n", NewLogSize));
744 DEBUG ((EFI_D_INFO, " LogSize - 0x%x\n", *LogSize));
745 DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));
746 return EFI_OUT_OF_RESOURCES;
747 }
748
749 *EventLogPtr += *LogSize;
750 *LogSize += NewLogSize;
751 CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize);
752 CopyMem (
753 *EventLogPtr + NewEventHdrSize,
754 NewEventData,
755 NewEventSize
756 );
757 return EFI_SUCCESS;
758 }
759
760 /**
761 Add a new entry to the Event Log.
762
763 @param[in] EventLogFormat The type of the event log for which the information is requested.
764 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
765 @param[in] NewEventHdrSize New event header size.
766 @param[in] NewEventData Pointer to the new event data.
767 @param[in] NewEventSize New event data size.
768
769 @retval EFI_SUCCESS The new event log entry was added.
770 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
771
772 **/
773 EFI_STATUS
774 TcgDxeLogEvent (
775 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
776 IN VOID *NewEventHdr,
777 IN UINT32 NewEventHdrSize,
778 IN UINT8 *NewEventData,
779 IN UINT32 NewEventSize
780 )
781 {
782 EFI_STATUS Status;
783 UINTN Index;
784 TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;
785
786 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
787 if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {
788 break;
789 }
790 }
791
792 if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) {
793 return EFI_INVALID_PARAMETER;
794 }
795
796 //
797 // Record to normal event log
798 //
799 EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];
800
801 if (EventLogAreaStruct->EventLogTruncated) {
802 return EFI_VOLUME_FULL;
803 }
804
805 EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;
806 Status = TcgCommLogEvent (
807 &EventLogAreaStruct->LastEvent,
808 &EventLogAreaStruct->EventLogSize,
809 (UINTN)EventLogAreaStruct->Laml,
810 NewEventHdr,
811 NewEventHdrSize,
812 NewEventData,
813 NewEventSize
814 );
815
816 if (Status == EFI_OUT_OF_RESOURCES) {
817 EventLogAreaStruct->EventLogTruncated = TRUE;
818 return EFI_VOLUME_FULL;
819 } else if (Status == EFI_SUCCESS) {
820 EventLogAreaStruct->EventLogStarted = TRUE;
821 }
822
823 //
824 // If GetEventLog is called, record to FinalEventsTable, too.
825 //
826 if (mTcgDxeData.GetEventLogCalled[Index]) {
827 if (mTcgDxeData.FinalEventsTable[Index] == NULL) {
828 //
829 // no need for FinalEventsTable
830 //
831 return EFI_SUCCESS;
832 }
833 EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];
834
835 if (EventLogAreaStruct->EventLogTruncated) {
836 return EFI_VOLUME_FULL;
837 }
838
839 EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;
840 Status = TcgCommLogEvent (
841 &EventLogAreaStruct->LastEvent,
842 &EventLogAreaStruct->EventLogSize,
843 (UINTN)EventLogAreaStruct->Laml,
844 NewEventHdr,
845 NewEventHdrSize,
846 NewEventData,
847 NewEventSize
848 );
849 if (Status == EFI_OUT_OF_RESOURCES) {
850 EventLogAreaStruct->EventLogTruncated = TRUE;
851 return EFI_VOLUME_FULL;
852 } else if (Status == EFI_SUCCESS) {
853 EventLogAreaStruct->EventLogStarted = TRUE;
854 //
855 // Increase the NumberOfEvents in FinalEventsTable
856 //
857 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;
858 DEBUG ((EFI_D_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));
859 DEBUG ((EFI_D_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->LastEvent - (UINTN)mTcgDxeData.FinalEventsTable[Index]));
860 }
861 }
862
863 return Status;
864 }
865
866 /**
867 Get TPML_DIGEST_VALUES compact binary buffer size.
868
869 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
870
871 @return TPML_DIGEST_VALUES compact binary buffer size.
872 **/
873 UINT32
874 GetDigestListBinSize (
875 IN VOID *DigestListBin
876 )
877 {
878 UINTN Index;
879 UINT16 DigestSize;
880 UINT32 TotalSize;
881 UINT32 Count;
882 TPMI_ALG_HASH HashAlg;
883
884 Count = ReadUnaligned32 (DigestListBin);
885 TotalSize = sizeof(Count);
886 DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);
887 for (Index = 0; Index < Count; Index++) {
888 HashAlg = ReadUnaligned16 (DigestListBin);
889 TotalSize += sizeof(HashAlg);
890 DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);
891
892 DigestSize = GetHashSizeFromAlgo (HashAlg);
893 TotalSize += DigestSize;
894 DigestListBin = (UINT8 *)DigestListBin + DigestSize;
895 }
896
897 return TotalSize;
898 }
899
900 /**
901 Copy TPML_DIGEST_VALUES compact binary into a buffer
902
903 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
904 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
905 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
906 @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.
907
908 @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
909 **/
910 VOID *
911 CopyDigestListBinToBuffer (
912 IN OUT VOID *Buffer,
913 IN VOID *DigestListBin,
914 IN UINT32 HashAlgorithmMask,
915 OUT UINT32 *HashAlgorithmMaskCopied
916 )
917 {
918 UINTN Index;
919 UINT16 DigestSize;
920 UINT32 Count;
921 TPMI_ALG_HASH HashAlg;
922 UINT32 DigestListCount;
923 UINT32 *DigestListCountPtr;
924
925 DigestListCountPtr = (UINT32 *) Buffer;
926 DigestListCount = 0;
927 (*HashAlgorithmMaskCopied) = 0;
928
929 Count = ReadUnaligned32 (DigestListBin);
930 Buffer = (UINT8 *)Buffer + sizeof(Count);
931 DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);
932 for (Index = 0; Index < Count; Index++) {
933 HashAlg = ReadUnaligned16 (DigestListBin);
934 DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);
935 DigestSize = GetHashSizeFromAlgo (HashAlg);
936
937 if (IsHashAlgSupportedInHashAlgorithmMask(HashAlg, HashAlgorithmMask)) {
938 CopyMem (Buffer, &HashAlg, sizeof(HashAlg));
939 Buffer = (UINT8 *)Buffer + sizeof(HashAlg);
940 CopyMem (Buffer, DigestListBin, DigestSize);
941 Buffer = (UINT8 *)Buffer + DigestSize;
942 DigestListCount++;
943 (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);
944 } else {
945 DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));
946 }
947 DigestListBin = (UINT8 *)DigestListBin + DigestSize;
948 }
949 WriteUnaligned32 (DigestListCountPtr, DigestListCount);
950
951 return Buffer;
952 }
953
954 /**
955 Add a new entry to the Event Log.
956
957 @param[in] DigestList A list of digest.
958 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
959 @param[in] NewEventData Pointer to the new event data.
960
961 @retval EFI_SUCCESS The new event log entry was added.
962 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
963 **/
964 EFI_STATUS
965 TcgDxeLogHashEvent (
966 IN TPML_DIGEST_VALUES *DigestList,
967 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
968 IN UINT8 *NewEventData
969 )
970 {
971 EFI_STATUS Status;
972 EFI_TPL OldTpl;
973 UINTN Index;
974 EFI_STATUS RetStatus;
975 TCG_PCR_EVENT2 TcgPcrEvent2;
976 UINT8 *DigestBuffer;
977 UINT32 *EventSizePtr;
978
979 DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
980
981 RetStatus = EFI_SUCCESS;
982 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
983 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
984 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
985 switch (mTcg2EventInfo[Index].LogFormat) {
986 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
987 Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
988 if (!EFI_ERROR (Status)) {
989 //
990 // Enter critical region
991 //
992 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
993 Status = TcgDxeLogEvent (
994 mTcg2EventInfo[Index].LogFormat,
995 NewEventHdr,
996 sizeof(TCG_PCR_EVENT_HDR),
997 NewEventData,
998 NewEventHdr->EventSize
999 );
1000 if (Status != EFI_SUCCESS) {
1001 RetStatus = Status;
1002 }
1003 gBS->RestoreTPL (OldTpl);
1004 //
1005 // Exit critical region
1006 //
1007 }
1008 break;
1009 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
1010 ZeroMem (&TcgPcrEvent2, sizeof(TcgPcrEvent2));
1011 TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;
1012 TcgPcrEvent2.EventType = NewEventHdr->EventType;
1013 DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;
1014 EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, mTcgDxeData.BsCap.ActivePcrBanks);
1015 CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));
1016
1017 //
1018 // Enter critical region
1019 //
1020 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
1021 Status = TcgDxeLogEvent (
1022 mTcg2EventInfo[Index].LogFormat,
1023 &TcgPcrEvent2,
1024 sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof(TcgPcrEvent2.EventSize),
1025 NewEventData,
1026 NewEventHdr->EventSize
1027 );
1028 if (Status != EFI_SUCCESS) {
1029 RetStatus = Status;
1030 }
1031 gBS->RestoreTPL (OldTpl);
1032 //
1033 // Exit critical region
1034 //
1035 break;
1036 }
1037 }
1038 }
1039
1040 return RetStatus;
1041 }
1042
1043 /**
1044 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
1045 and add an entry to the Event Log.
1046
1047 @param[in] Flags Bitmap providing additional information.
1048 @param[in] HashData Physical address of the start of the data buffer
1049 to be hashed, extended, and logged.
1050 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
1051 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
1052 @param[in] NewEventData Pointer to the new event data.
1053
1054 @retval EFI_SUCCESS Operation completed successfully.
1055 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1056 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1057
1058 **/
1059 EFI_STATUS
1060 TcgDxeHashLogExtendEvent (
1061 IN UINT64 Flags,
1062 IN UINT8 *HashData,
1063 IN UINT64 HashDataLen,
1064 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
1065 IN UINT8 *NewEventData
1066 )
1067 {
1068 EFI_STATUS Status;
1069 TPML_DIGEST_VALUES DigestList;
1070
1071 if (!mTcgDxeData.BsCap.TPMPresentFlag) {
1072 return EFI_DEVICE_ERROR;
1073 }
1074
1075 Status = HashAndExtend (
1076 NewEventHdr->PCRIndex,
1077 HashData,
1078 (UINTN)HashDataLen,
1079 &DigestList
1080 );
1081 if (!EFI_ERROR (Status)) {
1082 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
1083 Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
1084 }
1085 }
1086
1087 if (Status == EFI_DEVICE_ERROR) {
1088 DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));
1089 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;
1090 REPORT_STATUS_CODE (
1091 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1092 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
1093 );
1094 }
1095
1096 return Status;
1097 }
1098
1099 /**
1100 The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with
1101 an opportunity to extend and optionally log events without requiring
1102 knowledge of actual TPM commands.
1103 The extend operation will occur even if this function cannot create an event
1104 log entry (e.g. due to the event log being full).
1105
1106 @param[in] This Indicates the calling context
1107 @param[in] Flags Bitmap providing additional information.
1108 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
1109 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
1110 @param[in] Event Pointer to data buffer containing information about the event.
1111
1112 @retval EFI_SUCCESS Operation completed successfully.
1113 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1114 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
1115 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1116 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
1117 **/
1118 EFI_STATUS
1119 EFIAPI
1120 Tcg2HashLogExtendEvent (
1121 IN EFI_TCG2_PROTOCOL *This,
1122 IN UINT64 Flags,
1123 IN EFI_PHYSICAL_ADDRESS DataToHash,
1124 IN UINT64 DataToHashLen,
1125 IN EFI_TCG2_EVENT *Event
1126 )
1127 {
1128 EFI_STATUS Status;
1129 TCG_PCR_EVENT_HDR NewEventHdr;
1130 TPML_DIGEST_VALUES DigestList;
1131
1132 DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));
1133
1134 if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {
1135 return EFI_INVALID_PARAMETER;
1136 }
1137
1138 if (!mTcgDxeData.BsCap.TPMPresentFlag) {
1139 return EFI_DEVICE_ERROR;
1140 }
1141
1142 if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {
1143 return EFI_INVALID_PARAMETER;
1144 }
1145
1146 if (Event->Header.PCRIndex > MAX_PCR_INDEX) {
1147 return EFI_INVALID_PARAMETER;
1148 }
1149
1150 NewEventHdr.PCRIndex = Event->Header.PCRIndex;
1151 NewEventHdr.EventType = Event->Header.EventType;
1152 NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;
1153 if ((Flags & PE_COFF_IMAGE) != 0) {
1154 Status = MeasurePeImageAndExtend (
1155 NewEventHdr.PCRIndex,
1156 DataToHash,
1157 (UINTN)DataToHashLen,
1158 &DigestList
1159 );
1160 if (!EFI_ERROR (Status)) {
1161 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
1162 Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);
1163 }
1164 }
1165 if (Status == EFI_DEVICE_ERROR) {
1166 DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));
1167 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;
1168 REPORT_STATUS_CODE (
1169 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1170 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
1171 );
1172 }
1173 } else {
1174 Status = TcgDxeHashLogExtendEvent (
1175 Flags,
1176 (UINT8 *) (UINTN) DataToHash,
1177 DataToHashLen,
1178 &NewEventHdr,
1179 Event->Event
1180 );
1181 }
1182 DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent - %r\n", Status));
1183 return Status;
1184 }
1185
1186 /**
1187 This service enables the sending of commands to the TPM.
1188
1189 @param[in] This Indicates the calling context
1190 @param[in] InputParameterBlockSize Size of the TPM input parameter block.
1191 @param[in] InputParameterBlock Pointer to the TPM input parameter block.
1192 @param[in] OutputParameterBlockSize Size of the TPM output parameter block.
1193 @param[in] OutputParameterBlock Pointer to the TPM output parameter block.
1194
1195 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
1196 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
1197 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1198 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
1199 **/
1200 EFI_STATUS
1201 EFIAPI
1202 Tcg2SubmitCommand (
1203 IN EFI_TCG2_PROTOCOL *This,
1204 IN UINT32 InputParameterBlockSize,
1205 IN UINT8 *InputParameterBlock,
1206 IN UINT32 OutputParameterBlockSize,
1207 IN UINT8 *OutputParameterBlock
1208 )
1209 {
1210 EFI_STATUS Status;
1211
1212 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand ...\n"));
1213
1214 if ((This == NULL) ||
1215 (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||
1216 (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {
1217 return EFI_INVALID_PARAMETER;
1218 }
1219
1220 if (!mTcgDxeData.BsCap.TPMPresentFlag) {
1221 return EFI_DEVICE_ERROR;
1222 }
1223
1224 if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {
1225 return EFI_INVALID_PARAMETER;
1226 }
1227 if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {
1228 return EFI_INVALID_PARAMETER;
1229 }
1230
1231 Status = Tpm2SubmitCommand (
1232 InputParameterBlockSize,
1233 InputParameterBlock,
1234 &OutputParameterBlockSize,
1235 OutputParameterBlock
1236 );
1237 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand - %r\n", Status));
1238 return Status;
1239 }
1240
1241 /**
1242 This service returns the currently active PCR banks.
1243
1244 @param[in] This Indicates the calling context
1245 @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.
1246
1247 @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.
1248 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1249 **/
1250 EFI_STATUS
1251 EFIAPI
1252 Tcg2GetActivePCRBanks (
1253 IN EFI_TCG2_PROTOCOL *This,
1254 OUT UINT32 *ActivePcrBanks
1255 )
1256 {
1257 if (ActivePcrBanks == NULL) {
1258 return EFI_INVALID_PARAMETER;
1259 }
1260 *ActivePcrBanks = mTcgDxeData.BsCap.ActivePcrBanks;
1261 return EFI_SUCCESS;
1262 }
1263
1264 /**
1265 This service sets the currently active PCR banks.
1266
1267 @param[in] This Indicates the calling context
1268 @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.
1269
1270 @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.
1271 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1272 **/
1273 EFI_STATUS
1274 EFIAPI
1275 Tcg2SetActivePCRBanks (
1276 IN EFI_TCG2_PROTOCOL *This,
1277 IN UINT32 ActivePcrBanks
1278 )
1279 {
1280 EFI_STATUS Status;
1281 UINT32 ReturnCode;
1282
1283 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks));
1284
1285 if (ActivePcrBanks == 0) {
1286 return EFI_INVALID_PARAMETER;
1287 }
1288 if ((ActivePcrBanks & (~mTcgDxeData.BsCap.HashAlgorithmBitmap)) != 0) {
1289 return EFI_INVALID_PARAMETER;
1290 }
1291 if (ActivePcrBanks == mTcgDxeData.BsCap.ActivePcrBanks) {
1292 //
1293 // Need clear previous SET_PCR_BANKS setting
1294 //
1295 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION, 0);
1296 } else {
1297 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, ActivePcrBanks);
1298 }
1299
1300 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
1301 Status = EFI_SUCCESS;
1302 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
1303 Status = EFI_OUT_OF_RESOURCES;
1304 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
1305 Status = EFI_UNSUPPORTED;
1306 } else {
1307 Status = EFI_DEVICE_ERROR;
1308 }
1309
1310 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks - %r\n", Status));
1311
1312 return Status;
1313 }
1314
1315 /**
1316 This service retrieves the result of a previous invocation of SetActivePcrBanks.
1317
1318 @param[in] This Indicates the calling context
1319 @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.
1320 @param[out] Response The response from the SetActivePcrBank request.
1321
1322 @retval EFI_SUCCESS The result value could be returned.
1323 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1324 **/
1325 EFI_STATUS
1326 EFIAPI
1327 Tcg2GetResultOfSetActivePcrBanks (
1328 IN EFI_TCG2_PROTOCOL *This,
1329 OUT UINT32 *OperationPresent,
1330 OUT UINT32 *Response
1331 )
1332 {
1333 UINT32 ReturnCode;
1334
1335 if ((OperationPresent == NULL) || (Response == NULL)) {
1336 return EFI_INVALID_PARAMETER;
1337 }
1338
1339 ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);
1340 if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {
1341 return EFI_SUCCESS;
1342 } else {
1343 return EFI_UNSUPPORTED;
1344 }
1345 }
1346
1347 EFI_TCG2_PROTOCOL mTcg2Protocol = {
1348 Tcg2GetCapability,
1349 Tcg2GetEventLog,
1350 Tcg2HashLogExtendEvent,
1351 Tcg2SubmitCommand,
1352 Tcg2GetActivePCRBanks,
1353 Tcg2SetActivePCRBanks,
1354 Tcg2GetResultOfSetActivePcrBanks,
1355 };
1356
1357 /**
1358 Initialize the Event Log and log events passed from the PEI phase.
1359
1360 @retval EFI_SUCCESS Operation completed successfully.
1361 @retval EFI_OUT_OF_RESOURCES Out of memory.
1362
1363 **/
1364 EFI_STATUS
1365 SetupEventLog (
1366 VOID
1367 )
1368 {
1369 EFI_STATUS Status;
1370 VOID *TcgEvent;
1371 EFI_PEI_HOB_POINTERS GuidHob;
1372 EFI_PHYSICAL_ADDRESS Lasa;
1373 UINTN Index;
1374 VOID *DigestListBin;
1375 TPML_DIGEST_VALUES TempDigestListBin;
1376 UINT32 DigestListBinSize;
1377 UINT8 *Event;
1378 UINT32 EventSize;
1379 UINT32 *EventSizePtr;
1380 UINT32 HashAlgorithmMaskCopied;
1381 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
1382 UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];
1383 TCG_PCR_EVENT_HDR FirstPcrEvent;
1384 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
1385 TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;
1386 UINT8 *VendorInfoSize;
1387 UINT32 NumberOfAlgorithms;
1388
1389 DEBUG ((EFI_D_INFO, "SetupEventLog\n"));
1390
1391 //
1392 // 1. Create Log Area
1393 //
1394 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
1395 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
1396 mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
1397 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);
1398 Status = gBS->AllocatePages (
1399 AllocateMaxAddress,
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 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);
1500 Status = gBS->AllocatePages (
1501 AllocateMaxAddress,
1502 EfiACPIMemoryNVS,
1503 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),
1504 &Lasa
1505 );
1506 if (EFI_ERROR (Status)) {
1507 return Status;
1508 }
1509 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);
1510
1511 //
1512 // Initialize
1513 //
1514 mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
1515 (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
1516 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
1517
1518 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
1519 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
1520 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
1521 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
1522 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;
1523 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
1524 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
1525
1526 //
1527 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
1528 //
1529 Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);
1530 if (EFI_ERROR (Status)) {
1531 return Status;
1532 }
1533 } else {
1534 //
1535 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
1536 //
1537 mTcgDxeData.FinalEventsTable[Index] = NULL;
1538 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
1539 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;
1540 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;
1541 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
1542 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;
1543 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
1544 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
1545 }
1546 }
1547 }
1548
1549 //
1550 // 3. Sync data from PEI to DXE
1551 //
1552 Status = EFI_SUCCESS;
1553 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
1554 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
1555 GuidHob.Raw = GetHobList ();
1556 Status = EFI_SUCCESS;
1557 while (!EFI_ERROR (Status) &&
1558 (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {
1559 TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));
1560 ASSERT (TcgEvent != NULL);
1561 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
1562 switch (mTcg2EventInfo[Index].LogFormat) {
1563 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
1564 Status = TcgDxeLogEvent (
1565 mTcg2EventInfo[Index].LogFormat,
1566 TcgEvent,
1567 sizeof(TCG_PCR_EVENT_HDR),
1568 ((TCG_PCR_EVENT*)TcgEvent)->Event,
1569 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize
1570 );
1571 break;
1572 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
1573 DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE);
1574 DigestListBinSize = GetDigestListBinSize (DigestListBin);
1575 //
1576 // Save event size.
1577 //
1578 CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32));
1579 Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32);
1580 //
1581 // Filter inactive digest in the event2 log from PEI HOB.
1582 //
1583 CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));
1584 EventSizePtr = CopyDigestListBinToBuffer (
1585 DigestListBin,
1586 &TempDigestListBin,
1587 mTcgDxeData.BsCap.ActivePcrBanks,
1588 &HashAlgorithmMaskCopied
1589 );
1590 if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {
1591 DEBUG ((
1592 DEBUG_ERROR,
1593 "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",
1594 HashAlgorithmMaskCopied,
1595 mTcgDxeData.BsCap.ActivePcrBanks
1596 ));
1597 }
1598 //
1599 // Restore event size.
1600 //
1601 CopyMem (EventSizePtr, &EventSize, sizeof(UINT32));
1602 DigestListBinSize = GetDigestListBinSize (DigestListBin);
1603
1604 Status = TcgDxeLogEvent (
1605 mTcg2EventInfo[Index].LogFormat,
1606 TcgEvent,
1607 sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),
1608 Event,
1609 EventSize
1610 );
1611 break;
1612 }
1613 FreePool (TcgEvent);
1614 }
1615 }
1616 }
1617
1618 return Status;
1619 }
1620
1621 /**
1622 Measure and log an action string, and extend the measurement result into PCR[5].
1623
1624 @param[in] String A specific string that indicates an Action event.
1625
1626 @retval EFI_SUCCESS Operation completed successfully.
1627 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1628
1629 **/
1630 EFI_STATUS
1631 TcgMeasureAction (
1632 IN CHAR8 *String
1633 )
1634 {
1635 TCG_PCR_EVENT_HDR TcgEvent;
1636
1637 TcgEvent.PCRIndex = 5;
1638 TcgEvent.EventType = EV_EFI_ACTION;
1639 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
1640 return TcgDxeHashLogExtendEvent (
1641 0,
1642 (UINT8*)String,
1643 TcgEvent.EventSize,
1644 &TcgEvent,
1645 (UINT8 *) String
1646 );
1647 }
1648
1649 /**
1650 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1651
1652 @retval EFI_SUCCESS Operation completed successfully.
1653 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1654
1655 **/
1656 EFI_STATUS
1657 MeasureHandoffTables (
1658 VOID
1659 )
1660 {
1661 EFI_STATUS Status;
1662 TCG_PCR_EVENT_HDR TcgEvent;
1663 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
1664 UINTN ProcessorNum;
1665 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
1666
1667 ProcessorLocBuf = NULL;
1668 Status = EFI_SUCCESS;
1669
1670 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
1671 //
1672 // Tcg Server spec.
1673 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1674 //
1675 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
1676
1677 if (!EFI_ERROR(Status)){
1678 TcgEvent.PCRIndex = 1;
1679 TcgEvent.EventType = EV_TABLE_OF_DEVICES;
1680 TcgEvent.EventSize = sizeof (HandoffTables);
1681
1682 HandoffTables.NumberOfTables = 1;
1683 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
1684 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
1685
1686 Status = TcgDxeHashLogExtendEvent (
1687 0,
1688 (UINT8*)(UINTN)ProcessorLocBuf,
1689 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
1690 &TcgEvent,
1691 (UINT8*)&HandoffTables
1692 );
1693
1694 FreePool(ProcessorLocBuf);
1695 }
1696 }
1697
1698 return Status;
1699 }
1700
1701 /**
1702 Measure and log Separator event, and extend the measurement result into a specific PCR.
1703
1704 @param[in] PCRIndex PCR index.
1705
1706 @retval EFI_SUCCESS Operation completed successfully.
1707 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1708
1709 **/
1710 EFI_STATUS
1711 MeasureSeparatorEvent (
1712 IN TPM_PCRINDEX PCRIndex
1713 )
1714 {
1715 TCG_PCR_EVENT_HDR TcgEvent;
1716 UINT32 EventData;
1717
1718 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));
1719
1720 EventData = 0;
1721 TcgEvent.PCRIndex = PCRIndex;
1722 TcgEvent.EventType = EV_SEPARATOR;
1723 TcgEvent.EventSize = (UINT32)sizeof (EventData);
1724 return TcgDxeHashLogExtendEvent (
1725 0,
1726 (UINT8 *)&EventData,
1727 sizeof (EventData),
1728 &TcgEvent,
1729 (UINT8 *)&EventData
1730 );
1731 }
1732
1733 /**
1734 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1735
1736 @param[in] PCRIndex PCR Index.
1737 @param[in] EventType Event type.
1738 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1739 @param[in] VendorGuid A unique identifier for the vendor.
1740 @param[in] VarData The content of the variable data.
1741 @param[in] VarSize The size of the variable data.
1742
1743 @retval EFI_SUCCESS Operation completed successfully.
1744 @retval EFI_OUT_OF_RESOURCES Out of memory.
1745 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1746
1747 **/
1748 EFI_STATUS
1749 MeasureVariable (
1750 IN TPM_PCRINDEX PCRIndex,
1751 IN TCG_EVENTTYPE EventType,
1752 IN CHAR16 *VarName,
1753 IN EFI_GUID *VendorGuid,
1754 IN VOID *VarData,
1755 IN UINTN VarSize
1756 )
1757 {
1758 EFI_STATUS Status;
1759 TCG_PCR_EVENT_HDR TcgEvent;
1760 UINTN VarNameLength;
1761 EFI_VARIABLE_DATA_TREE *VarLog;
1762
1763 DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));
1764 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
1765
1766 VarNameLength = StrLen (VarName);
1767 TcgEvent.PCRIndex = PCRIndex;
1768 TcgEvent.EventType = EventType;
1769
1770 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
1771 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
1772
1773 VarLog = (EFI_VARIABLE_DATA_TREE *)AllocatePool (TcgEvent.EventSize);
1774 if (VarLog == NULL) {
1775 return EFI_OUT_OF_RESOURCES;
1776 }
1777
1778 VarLog->VariableName = *VendorGuid;
1779 VarLog->UnicodeNameLength = VarNameLength;
1780 VarLog->VariableDataLength = VarSize;
1781 CopyMem (
1782 VarLog->UnicodeName,
1783 VarName,
1784 VarNameLength * sizeof (*VarName)
1785 );
1786 if (VarSize != 0 && VarData != NULL) {
1787 CopyMem (
1788 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
1789 VarData,
1790 VarSize
1791 );
1792 }
1793
1794 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1795 //
1796 // Digest is the event data (EFI_VARIABLE_DATA)
1797 //
1798 Status = TcgDxeHashLogExtendEvent (
1799 0,
1800 (UINT8*)VarLog,
1801 TcgEvent.EventSize,
1802 &TcgEvent,
1803 (UINT8*)VarLog
1804 );
1805 } else {
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 }