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