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