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