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