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