]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
b1c885e407bc17beb12b0cac6883e7eddbd8f917
[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 //
821 // Record to normal event log
822 //
823 EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];
824
825 if (EventLogAreaStruct->EventLogTruncated) {
826 return EFI_VOLUME_FULL;
827 }
828
829 EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;
830 Status = TcgCommLogEvent (
831 &EventLogAreaStruct->LastEvent,
832 &EventLogAreaStruct->EventLogSize,
833 (UINTN)EventLogAreaStruct->Laml,
834 NewEventHdr,
835 NewEventHdrSize,
836 NewEventData,
837 NewEventSize
838 );
839
840 if (Status == EFI_OUT_OF_RESOURCES) {
841 EventLogAreaStruct->EventLogTruncated = TRUE;
842 return EFI_VOLUME_FULL;
843 } else if (Status == EFI_SUCCESS) {
844 EventLogAreaStruct->EventLogStarted = TRUE;
845 }
846
847 //
848 // If GetEventLog is called, record to FinalEventsTable, too.
849 //
850 if (mTcgDxeData.GetEventLogCalled[Index]) {
851 if (mTcgDxeData.FinalEventsTable[Index] == NULL) {
852 //
853 // no need for FinalEventsTable
854 //
855 return EFI_SUCCESS;
856 }
857 EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];
858
859 if (EventLogAreaStruct->EventLogTruncated) {
860 return EFI_VOLUME_FULL;
861 }
862
863 EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;
864 Status = TcgCommLogEvent (
865 &EventLogAreaStruct->LastEvent,
866 &EventLogAreaStruct->EventLogSize,
867 (UINTN)EventLogAreaStruct->Laml,
868 NewEventHdr,
869 NewEventHdrSize,
870 NewEventData,
871 NewEventSize
872 );
873 if (Status == EFI_OUT_OF_RESOURCES) {
874 EventLogAreaStruct->EventLogTruncated = TRUE;
875 return EFI_VOLUME_FULL;
876 } else if (Status == EFI_SUCCESS) {
877 EventLogAreaStruct->EventLogStarted = TRUE;
878 //
879 // Increase the NumberOfEvents in FinalEventsTable
880 //
881 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;
882 DEBUG ((EFI_D_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));
883 DEBUG ((EFI_D_INFO, " Size - 0x%x\n", (UINTN)EventLogAreaStruct->LastEvent - (UINTN)mTcgDxeData.FinalEventsTable[Index]));
884 }
885 }
886
887 return Status;
888 }
889
890 /**
891 This function get digest from digest list.
892
893 @param HashAlg digest algorithm
894 @param DigestList digest list
895 @param Digest digest
896
897 @retval EFI_SUCCESS Sha1Digest is found and returned.
898 @retval EFI_NOT_FOUND Sha1Digest is not found.
899 **/
900 EFI_STATUS
901 Tpm2GetDigestFromDigestList (
902 IN TPMI_ALG_HASH HashAlg,
903 IN TPML_DIGEST_VALUES *DigestList,
904 IN VOID *Digest
905 )
906 {
907 UINTN Index;
908 UINT16 DigestSize;
909
910 DigestSize = GetHashSizeFromAlgo (HashAlg);
911 for (Index = 0; Index < DigestList->count; Index++) {
912 if (DigestList->digests[Index].hashAlg == HashAlg) {
913 CopyMem (
914 Digest,
915 &DigestList->digests[Index].digest,
916 DigestSize
917 );
918 return EFI_SUCCESS;
919 }
920 }
921
922 return EFI_NOT_FOUND;
923 }
924
925 /**
926 Get TPML_DIGEST_VALUES data size.
927
928 @param[in] DigestList TPML_DIGEST_VALUES data.
929
930 @return TPML_DIGEST_VALUES data size.
931 **/
932 UINT32
933 GetDigestListSize (
934 IN TPML_DIGEST_VALUES *DigestList
935 )
936 {
937 UINTN Index;
938 UINT16 DigestSize;
939 UINT32 TotalSize;
940
941 TotalSize = sizeof(DigestList->count);
942 for (Index = 0; Index < DigestList->count; Index++) {
943 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
944 TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize;
945 }
946
947 return TotalSize;
948 }
949
950 /**
951 Get TPML_DIGEST_VALUES compact binary buffer size.
952
953 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
954
955 @return TPML_DIGEST_VALUES compact binary buffer size.
956 **/
957 UINT32
958 GetDigestListBinSize (
959 IN VOID *DigestListBin
960 )
961 {
962 UINTN Index;
963 UINT16 DigestSize;
964 UINT32 TotalSize;
965 UINT32 Count;
966 TPMI_ALG_HASH HashAlg;
967
968 Count = ReadUnaligned32 (DigestListBin);
969 TotalSize = sizeof(Count);
970 DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);
971 for (Index = 0; Index < Count; Index++) {
972 HashAlg = ReadUnaligned16 (DigestListBin);
973 TotalSize += sizeof(HashAlg);
974 DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);
975
976 DigestSize = GetHashSizeFromAlgo (HashAlg);
977 TotalSize += DigestSize;
978 DigestListBin = (UINT8 *)DigestListBin + DigestSize;
979 }
980
981 return TotalSize;
982 }
983
984 /**
985 Return if hash alg is supported in TPM PCR bank.
986
987 @param HashAlg Hash algorithm to be checked.
988
989 @retval TRUE Hash algorithm is supported.
990 @retval FALSE Hash algorithm is not supported.
991 **/
992 BOOLEAN
993 IsHashAlgSupportedInPcrBank (
994 IN TPMI_ALG_HASH HashAlg
995 )
996 {
997 switch (HashAlg) {
998 case TPM_ALG_SHA1:
999 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
1000 return TRUE;
1001 }
1002 break;
1003 case TPM_ALG_SHA256:
1004 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
1005 return TRUE;
1006 }
1007 break;
1008 case TPM_ALG_SHA384:
1009 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
1010 return TRUE;
1011 }
1012 break;
1013 case TPM_ALG_SHA512:
1014 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
1015 return TRUE;
1016 }
1017 break;
1018 case TPM_ALG_SM3_256:
1019 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
1020 return TRUE;
1021 }
1022 break;
1023 }
1024
1025 return FALSE;
1026 }
1027
1028 /**
1029 Copy TPML_DIGEST_VALUES into a buffer
1030
1031 @param[in,out] Buffer Buffer to hold TPML_DIGEST_VALUES.
1032 @param[in] DigestList TPML_DIGEST_VALUES to be copied.
1033
1034 @return The end of buffer to hold TPML_DIGEST_VALUES.
1035 **/
1036 VOID *
1037 CopyDigestListToBuffer (
1038 IN OUT VOID *Buffer,
1039 IN TPML_DIGEST_VALUES *DigestList
1040 )
1041 {
1042 UINTN Index;
1043 UINT16 DigestSize;
1044
1045 CopyMem (Buffer, &DigestList->count, sizeof(DigestList->count));
1046 Buffer = (UINT8 *)Buffer + sizeof(DigestList->count);
1047 for (Index = 0; Index < DigestList->count; Index++) {
1048 if (!IsHashAlgSupportedInPcrBank (DigestList->digests[Index].hashAlg)) {
1049 DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));
1050 continue;
1051 }
1052 CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg));
1053 Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg);
1054 DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);
1055 CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);
1056 Buffer = (UINT8 *)Buffer + DigestSize;
1057 }
1058
1059 return Buffer;
1060 }
1061
1062 /**
1063 Add a new entry to the Event Log.
1064
1065 @param[in] DigestList A list of digest.
1066 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
1067 @param[in] NewEventData Pointer to the new event data.
1068
1069 @retval EFI_SUCCESS The new event log entry was added.
1070 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1071 **/
1072 EFI_STATUS
1073 TcgDxeLogHashEvent (
1074 IN TPML_DIGEST_VALUES *DigestList,
1075 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
1076 IN UINT8 *NewEventData
1077 )
1078 {
1079 EFI_STATUS Status;
1080 EFI_TPL OldTpl;
1081 UINTN Index;
1082 EFI_STATUS RetStatus;
1083 TCG_PCR_EVENT2 TcgPcrEvent2;
1084 UINT8 *DigestBuffer;
1085
1086 DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
1087
1088 RetStatus = EFI_SUCCESS;
1089 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
1090 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
1091 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
1092 switch (mTcg2EventInfo[Index].LogFormat) {
1093 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
1094 Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
1095 if (!EFI_ERROR (Status)) {
1096 //
1097 // Enter critical region
1098 //
1099 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
1100 Status = TcgDxeLogEvent (
1101 mTcg2EventInfo[Index].LogFormat,
1102 NewEventHdr,
1103 sizeof(TCG_PCR_EVENT_HDR),
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 }
1115 break;
1116 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
1117 ZeroMem (&TcgPcrEvent2, sizeof(TcgPcrEvent2));
1118 TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;
1119 TcgPcrEvent2.EventType = NewEventHdr->EventType;
1120 DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;
1121 DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList);
1122 CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));
1123 DigestBuffer = DigestBuffer + sizeof(NewEventHdr->EventSize);
1124
1125 //
1126 // Enter critical region
1127 //
1128 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
1129 Status = TcgDxeLogEvent (
1130 mTcg2EventInfo[Index].LogFormat,
1131 &TcgPcrEvent2,
1132 sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2.EventSize),
1133 NewEventData,
1134 NewEventHdr->EventSize
1135 );
1136 if (Status != EFI_SUCCESS) {
1137 RetStatus = Status;
1138 }
1139 gBS->RestoreTPL (OldTpl);
1140 //
1141 // Exit critical region
1142 //
1143 break;
1144 }
1145 }
1146 }
1147
1148 return RetStatus;
1149 }
1150
1151 /**
1152 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
1153 and add an entry to the Event Log.
1154
1155 @param[in] Flags Bitmap providing additional information.
1156 @param[in] HashData Physical address of the start of the data buffer
1157 to be hashed, extended, and logged.
1158 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
1159 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
1160 @param[in] NewEventData Pointer to the new event data.
1161
1162 @retval EFI_SUCCESS Operation completed successfully.
1163 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1164 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1165
1166 **/
1167 EFI_STATUS
1168 TcgDxeHashLogExtendEvent (
1169 IN UINT64 Flags,
1170 IN UINT8 *HashData,
1171 IN UINT64 HashDataLen,
1172 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
1173 IN UINT8 *NewEventData
1174 )
1175 {
1176 EFI_STATUS Status;
1177 TPML_DIGEST_VALUES DigestList;
1178
1179 if (!mTcgDxeData.BsCap.TPMPresentFlag) {
1180 return EFI_DEVICE_ERROR;
1181 }
1182
1183 Status = HashAndExtend (
1184 NewEventHdr->PCRIndex,
1185 HashData,
1186 (UINTN)HashDataLen,
1187 &DigestList
1188 );
1189 if (!EFI_ERROR (Status)) {
1190 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
1191 Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
1192 }
1193 }
1194
1195 if (Status == EFI_DEVICE_ERROR) {
1196 DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));
1197 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;
1198 REPORT_STATUS_CODE (
1199 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1200 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
1201 );
1202 }
1203
1204 return Status;
1205 }
1206
1207 /**
1208 The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with
1209 an opportunity to extend and optionally log events without requiring
1210 knowledge of actual TPM commands.
1211 The extend operation will occur even if this function cannot create an event
1212 log entry (e.g. due to the event log being full).
1213
1214 @param[in] This Indicates the calling context
1215 @param[in] Flags Bitmap providing additional information.
1216 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
1217 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
1218 @param[in] Event Pointer to data buffer containing information about the event.
1219
1220 @retval EFI_SUCCESS Operation completed successfully.
1221 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1222 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
1223 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1224 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
1225 **/
1226 EFI_STATUS
1227 EFIAPI
1228 Tcg2HashLogExtendEvent (
1229 IN EFI_TCG2_PROTOCOL *This,
1230 IN UINT64 Flags,
1231 IN EFI_PHYSICAL_ADDRESS DataToHash,
1232 IN UINT64 DataToHashLen,
1233 IN EFI_TCG2_EVENT *Event
1234 )
1235 {
1236 EFI_STATUS Status;
1237 TCG_PCR_EVENT_HDR NewEventHdr;
1238 TPML_DIGEST_VALUES DigestList;
1239
1240 DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent ...\n"));
1241
1242 if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {
1243 return EFI_INVALID_PARAMETER;
1244 }
1245
1246 if (!mTcgDxeData.BsCap.TPMPresentFlag) {
1247 return EFI_DEVICE_ERROR;
1248 }
1249
1250 if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {
1251 return EFI_INVALID_PARAMETER;
1252 }
1253
1254 if (Event->Header.PCRIndex > MAX_PCR_INDEX) {
1255 return EFI_INVALID_PARAMETER;
1256 }
1257
1258 NewEventHdr.PCRIndex = Event->Header.PCRIndex;
1259 NewEventHdr.EventType = Event->Header.EventType;
1260 NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;
1261 if ((Flags & PE_COFF_IMAGE) != 0) {
1262 Status = MeasurePeImageAndExtend (
1263 NewEventHdr.PCRIndex,
1264 DataToHash,
1265 (UINTN)DataToHashLen,
1266 &DigestList
1267 );
1268 if (!EFI_ERROR (Status)) {
1269 if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
1270 Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);
1271 }
1272 }
1273 if (Status == EFI_DEVICE_ERROR) {
1274 DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));
1275 mTcgDxeData.BsCap.TPMPresentFlag = FALSE;
1276 REPORT_STATUS_CODE (
1277 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1278 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
1279 );
1280 }
1281 } else {
1282 Status = TcgDxeHashLogExtendEvent (
1283 Flags,
1284 (UINT8 *) (UINTN) DataToHash,
1285 DataToHashLen,
1286 &NewEventHdr,
1287 Event->Event
1288 );
1289 }
1290 DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent - %r\n", Status));
1291 return Status;
1292 }
1293
1294 /**
1295 This service enables the sending of commands to the TPM.
1296
1297 @param[in] This Indicates the calling context
1298 @param[in] InputParameterBlockSize Size of the TPM input parameter block.
1299 @param[in] InputParameterBlock Pointer to the TPM input parameter block.
1300 @param[in] OutputParameterBlockSize Size of the TPM output parameter block.
1301 @param[in] OutputParameterBlock Pointer to the TPM output parameter block.
1302
1303 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
1304 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
1305 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1306 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
1307 **/
1308 EFI_STATUS
1309 EFIAPI
1310 Tcg2SubmitCommand (
1311 IN EFI_TCG2_PROTOCOL *This,
1312 IN UINT32 InputParameterBlockSize,
1313 IN UINT8 *InputParameterBlock,
1314 IN UINT32 OutputParameterBlockSize,
1315 IN UINT8 *OutputParameterBlock
1316 )
1317 {
1318 EFI_STATUS Status;
1319
1320 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand ...\n"));
1321
1322 if ((This == NULL) ||
1323 (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||
1324 (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {
1325 return EFI_INVALID_PARAMETER;
1326 }
1327
1328 if (!mTcgDxeData.BsCap.TPMPresentFlag) {
1329 return EFI_DEVICE_ERROR;
1330 }
1331
1332 if (InputParameterBlockSize >= mTcgDxeData.BsCap.MaxCommandSize) {
1333 return EFI_INVALID_PARAMETER;
1334 }
1335 if (OutputParameterBlockSize >= mTcgDxeData.BsCap.MaxResponseSize) {
1336 return EFI_INVALID_PARAMETER;
1337 }
1338
1339 Status = Tpm2SubmitCommand (
1340 InputParameterBlockSize,
1341 InputParameterBlock,
1342 &OutputParameterBlockSize,
1343 OutputParameterBlock
1344 );
1345 DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand - %r\n", Status));
1346 return Status;
1347 }
1348
1349 /**
1350 This service returns the currently active PCR banks.
1351
1352 @param[in] This Indicates the calling context
1353 @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.
1354
1355 @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.
1356 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1357 **/
1358 EFI_STATUS
1359 EFIAPI
1360 Tcg2GetActivePCRBanks (
1361 IN EFI_TCG2_PROTOCOL *This,
1362 OUT UINT32 *ActivePcrBanks
1363 )
1364 {
1365 if (ActivePcrBanks == NULL) {
1366 return EFI_INVALID_PARAMETER;
1367 }
1368 *ActivePcrBanks = mTcgDxeData.BsCap.ActivePcrBanks;
1369 return EFI_SUCCESS;
1370 }
1371
1372 /**
1373 This service sets the currently active PCR banks.
1374
1375 @param[in] This Indicates the calling context
1376 @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.
1377
1378 @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.
1379 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1380 **/
1381 EFI_STATUS
1382 EFIAPI
1383 Tcg2SetActivePCRBanks (
1384 IN EFI_TCG2_PROTOCOL *This,
1385 IN UINT32 ActivePcrBanks
1386 )
1387 {
1388 EFI_STATUS Status;
1389 UINT32 ReturnCode;
1390
1391 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks));
1392
1393 if (ActivePcrBanks == 0) {
1394 return EFI_INVALID_PARAMETER;
1395 }
1396 if ((ActivePcrBanks & (~mTcgDxeData.BsCap.HashAlgorithmBitmap)) != 0) {
1397 return EFI_INVALID_PARAMETER;
1398 }
1399 if (ActivePcrBanks == mTcgDxeData.BsCap.ActivePcrBanks) {
1400 //
1401 // Need clear previous SET_PCR_BANKS setting
1402 //
1403 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION, 0);
1404 } else {
1405 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, ActivePcrBanks);
1406 }
1407
1408 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
1409 Status = EFI_SUCCESS;
1410 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
1411 Status = EFI_OUT_OF_RESOURCES;
1412 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
1413 Status = EFI_UNSUPPORTED;
1414 } else {
1415 Status = EFI_DEVICE_ERROR;
1416 }
1417
1418 DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks - %r\n", Status));
1419
1420 return Status;
1421 }
1422
1423 /**
1424 This service retrieves the result of a previous invocation of SetActivePcrBanks.
1425
1426 @param[in] This Indicates the calling context
1427 @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.
1428 @param[out] Response The response from the SetActivePcrBank request.
1429
1430 @retval EFI_SUCCESS The result value could be returned.
1431 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1432 **/
1433 EFI_STATUS
1434 EFIAPI
1435 Tcg2GetResultOfSetActivePcrBanks (
1436 IN EFI_TCG2_PROTOCOL *This,
1437 OUT UINT32 *OperationPresent,
1438 OUT UINT32 *Response
1439 )
1440 {
1441 UINT32 ReturnCode;
1442
1443 if ((OperationPresent == NULL) || (Response == NULL)) {
1444 return EFI_INVALID_PARAMETER;
1445 }
1446
1447 ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);
1448 if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {
1449 return EFI_SUCCESS;
1450 } else {
1451 return EFI_UNSUPPORTED;
1452 }
1453 }
1454
1455 EFI_TCG2_PROTOCOL mTcg2Protocol = {
1456 Tcg2GetCapability,
1457 Tcg2GetEventLog,
1458 Tcg2HashLogExtendEvent,
1459 Tcg2SubmitCommand,
1460 Tcg2GetActivePCRBanks,
1461 Tcg2SetActivePCRBanks,
1462 Tcg2GetResultOfSetActivePcrBanks,
1463 };
1464
1465 /**
1466 Initialize the Event Log and log events passed from the PEI phase.
1467
1468 @retval EFI_SUCCESS Operation completed successfully.
1469 @retval EFI_OUT_OF_RESOURCES Out of memory.
1470
1471 **/
1472 EFI_STATUS
1473 SetupEventLog (
1474 VOID
1475 )
1476 {
1477 EFI_STATUS Status;
1478 VOID *TcgEvent;
1479 EFI_PEI_HOB_POINTERS GuidHob;
1480 EFI_PHYSICAL_ADDRESS Lasa;
1481 UINTN Index;
1482 UINT32 DigestListBinSize;
1483 UINT32 EventSize;
1484 TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct;
1485 UINT8 TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];
1486 TCG_PCR_EVENT_HDR FirstPcrEvent;
1487 TCG_EfiSpecIdEventAlgorithmSize *DigestSize;
1488 TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;
1489 UINT8 *VendorInfoSize;
1490 UINT32 NumberOfAlgorithms;
1491
1492 DEBUG ((EFI_D_INFO, "SetupEventLog\n"));
1493
1494 //
1495 // 1. Create Log Area
1496 //
1497 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
1498 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
1499 mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
1500 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);
1501 Status = gBS->AllocatePages (
1502 AllocateMaxAddress,
1503 EfiBootServicesData,
1504 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
1505 &Lasa
1506 );
1507 if (EFI_ERROR (Status)) {
1508 return Status;
1509 }
1510 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
1511 mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);
1512 //
1513 // To initialize them as 0xFF is recommended
1514 // because the OS can know the last entry for that.
1515 //
1516 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
1517 //
1518 // Create first entry for Log Header Entry Data
1519 //
1520 if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {
1521 //
1522 // TcgEfiSpecIdEventStruct
1523 //
1524 TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;
1525 CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof(TcgEfiSpecIdEventStruct->signature));
1526 TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);
1527 TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;
1528 TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;
1529 TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;
1530 TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);
1531 NumberOfAlgorithms = 0;
1532 DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));
1533 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
1534 TempDigestSize = DigestSize;
1535 TempDigestSize += NumberOfAlgorithms;
1536 TempDigestSize->algorithmId = TPM_ALG_SHA1;
1537 TempDigestSize->digestSize = SHA1_DIGEST_SIZE;
1538 NumberOfAlgorithms++;
1539 }
1540 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
1541 TempDigestSize = DigestSize;
1542 TempDigestSize += NumberOfAlgorithms;
1543 TempDigestSize->algorithmId = TPM_ALG_SHA256;
1544 TempDigestSize->digestSize = SHA256_DIGEST_SIZE;
1545 NumberOfAlgorithms++;
1546 }
1547 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
1548 TempDigestSize = DigestSize;
1549 TempDigestSize += NumberOfAlgorithms;
1550 TempDigestSize->algorithmId = TPM_ALG_SHA384;
1551 TempDigestSize->digestSize = SHA384_DIGEST_SIZE;
1552 NumberOfAlgorithms++;
1553 }
1554 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
1555 TempDigestSize = DigestSize;
1556 TempDigestSize += NumberOfAlgorithms;
1557 TempDigestSize->algorithmId = TPM_ALG_SHA512;
1558 TempDigestSize->digestSize = SHA512_DIGEST_SIZE;
1559 NumberOfAlgorithms++;
1560 }
1561 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
1562 TempDigestSize = DigestSize;
1563 TempDigestSize += NumberOfAlgorithms;
1564 TempDigestSize->algorithmId = TPM_ALG_SM3_256;
1565 TempDigestSize->digestSize = SM3_256_DIGEST_SIZE;
1566 NumberOfAlgorithms++;
1567 }
1568 CopyMem (TcgEfiSpecIdEventStruct + 1, &NumberOfAlgorithms, sizeof(NumberOfAlgorithms));
1569 TempDigestSize = DigestSize;
1570 TempDigestSize += NumberOfAlgorithms;
1571 VendorInfoSize = (UINT8 *)TempDigestSize;
1572 *VendorInfoSize = 0;
1573
1574 //
1575 // FirstPcrEvent
1576 //
1577 FirstPcrEvent.PCRIndex = 0;
1578 FirstPcrEvent.EventType = EV_NO_ACTION;
1579 ZeroMem (&FirstPcrEvent.Digest, sizeof(FirstPcrEvent.Digest));
1580 FirstPcrEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);
1581
1582 //
1583 // Record
1584 //
1585 Status = TcgDxeLogEvent (
1586 mTcg2EventInfo[Index].LogFormat,
1587 &FirstPcrEvent,
1588 sizeof(FirstPcrEvent),
1589 (UINT8 *)TcgEfiSpecIdEventStruct,
1590 FirstPcrEvent.EventSize
1591 );
1592 }
1593 }
1594 }
1595
1596 //
1597 // 2. Create Final Log Area
1598 //
1599 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
1600 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
1601 if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
1602 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);
1603 Status = gBS->AllocatePages (
1604 AllocateMaxAddress,
1605 EfiACPIMemoryNVS,
1606 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),
1607 &Lasa
1608 );
1609 if (EFI_ERROR (Status)) {
1610 return Status;
1611 }
1612 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);
1613
1614 //
1615 // Initialize
1616 //
1617 mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;
1618 (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
1619 (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;
1620
1621 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
1622 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
1623 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);
1624 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
1625 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;
1626 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
1627 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
1628
1629 //
1630 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
1631 //
1632 Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);
1633 if (EFI_ERROR (Status)) {
1634 return Status;
1635 }
1636 } else {
1637 //
1638 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
1639 //
1640 mTcgDxeData.FinalEventsTable[Index] = NULL;
1641 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;
1642 mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;
1643 mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;
1644 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;
1645 mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;
1646 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;
1647 mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;
1648 }
1649 }
1650 }
1651
1652 //
1653 // 3. Sync data from PEI to DXE
1654 //
1655 Status = EFI_SUCCESS;
1656 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
1657 if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
1658 GuidHob.Raw = GetHobList ();
1659 Status = EFI_SUCCESS;
1660 while (!EFI_ERROR (Status) &&
1661 (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {
1662 TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);
1663 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
1664 switch (mTcg2EventInfo[Index].LogFormat) {
1665 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
1666 Status = TcgDxeLogEvent (
1667 mTcg2EventInfo[Index].LogFormat,
1668 TcgEvent,
1669 sizeof(TCG_PCR_EVENT_HDR),
1670 ((TCG_PCR_EVENT*)TcgEvent)->Event,
1671 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize
1672 );
1673 break;
1674 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
1675 DigestListBinSize = GetDigestListBinSize ((UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE));
1676 CopyMem (&EventSize, (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize, sizeof(UINT32));
1677 Status = TcgDxeLogEvent (
1678 mTcg2EventInfo[Index].LogFormat,
1679 TcgEvent,
1680 sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),
1681 (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),
1682 EventSize
1683 );
1684 break;
1685 }
1686 }
1687 }
1688 }
1689
1690 return Status;
1691 }
1692
1693 /**
1694 Measure and log an action string, and extend the measurement result into PCR[5].
1695
1696 @param[in] String A specific string that indicates an Action event.
1697
1698 @retval EFI_SUCCESS Operation completed successfully.
1699 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1700
1701 **/
1702 EFI_STATUS
1703 TcgMeasureAction (
1704 IN CHAR8 *String
1705 )
1706 {
1707 TCG_PCR_EVENT_HDR TcgEvent;
1708
1709 TcgEvent.PCRIndex = 5;
1710 TcgEvent.EventType = EV_EFI_ACTION;
1711 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
1712 return TcgDxeHashLogExtendEvent (
1713 0,
1714 (UINT8*)String,
1715 TcgEvent.EventSize,
1716 &TcgEvent,
1717 (UINT8 *) String
1718 );
1719 }
1720
1721 /**
1722 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1723
1724 @retval EFI_SUCCESS Operation completed successfully.
1725 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1726
1727 **/
1728 EFI_STATUS
1729 MeasureHandoffTables (
1730 VOID
1731 )
1732 {
1733 EFI_STATUS Status;
1734 TCG_PCR_EVENT_HDR TcgEvent;
1735 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
1736 UINTN ProcessorNum;
1737 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
1738
1739 ProcessorLocBuf = NULL;
1740 Status = EFI_SUCCESS;
1741
1742 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
1743 //
1744 // Tcg Server spec.
1745 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1746 //
1747 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
1748
1749 if (!EFI_ERROR(Status)){
1750 TcgEvent.PCRIndex = 1;
1751 TcgEvent.EventType = EV_TABLE_OF_DEVICES;
1752 TcgEvent.EventSize = sizeof (HandoffTables);
1753
1754 HandoffTables.NumberOfTables = 1;
1755 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
1756 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
1757
1758 Status = TcgDxeHashLogExtendEvent (
1759 0,
1760 (UINT8*)(UINTN)ProcessorLocBuf,
1761 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
1762 &TcgEvent,
1763 (UINT8*)&HandoffTables
1764 );
1765
1766 FreePool(ProcessorLocBuf);
1767 }
1768 }
1769
1770 return Status;
1771 }
1772
1773 /**
1774 Measure and log Separator event, and extend the measurement result into a specific PCR.
1775
1776 @param[in] PCRIndex PCR index.
1777
1778 @retval EFI_SUCCESS Operation completed successfully.
1779 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1780
1781 **/
1782 EFI_STATUS
1783 MeasureSeparatorEvent (
1784 IN TPM_PCRINDEX PCRIndex
1785 )
1786 {
1787 TCG_PCR_EVENT_HDR TcgEvent;
1788 UINT32 EventData;
1789
1790 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));
1791
1792 EventData = 0;
1793 TcgEvent.PCRIndex = PCRIndex;
1794 TcgEvent.EventType = EV_SEPARATOR;
1795 TcgEvent.EventSize = (UINT32)sizeof (EventData);
1796 return TcgDxeHashLogExtendEvent (
1797 0,
1798 (UINT8 *)&EventData,
1799 sizeof (EventData),
1800 &TcgEvent,
1801 (UINT8 *)&EventData
1802 );
1803 }
1804
1805 /**
1806 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1807
1808 @param[in] PCRIndex PCR Index.
1809 @param[in] EventType Event type.
1810 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1811 @param[in] VendorGuid A unique identifier for the vendor.
1812 @param[in] VarData The content of the variable data.
1813 @param[in] VarSize The size of the variable data.
1814
1815 @retval EFI_SUCCESS Operation completed successfully.
1816 @retval EFI_OUT_OF_RESOURCES Out of memory.
1817 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1818
1819 **/
1820 EFI_STATUS
1821 MeasureVariable (
1822 IN TPM_PCRINDEX PCRIndex,
1823 IN TCG_EVENTTYPE EventType,
1824 IN CHAR16 *VarName,
1825 IN EFI_GUID *VendorGuid,
1826 IN VOID *VarData,
1827 IN UINTN VarSize
1828 )
1829 {
1830 EFI_STATUS Status;
1831 TCG_PCR_EVENT_HDR TcgEvent;
1832 UINTN VarNameLength;
1833 EFI_VARIABLE_DATA_TREE *VarLog;
1834
1835 DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));
1836 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
1837
1838 VarNameLength = StrLen (VarName);
1839 TcgEvent.PCRIndex = PCRIndex;
1840 TcgEvent.EventType = EventType;
1841
1842 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
1843 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
1844
1845 VarLog = (EFI_VARIABLE_DATA_TREE *)AllocatePool (TcgEvent.EventSize);
1846 if (VarLog == NULL) {
1847 return EFI_OUT_OF_RESOURCES;
1848 }
1849
1850 VarLog->VariableName = *VendorGuid;
1851 VarLog->UnicodeNameLength = VarNameLength;
1852 VarLog->VariableDataLength = VarSize;
1853 CopyMem (
1854 VarLog->UnicodeName,
1855 VarName,
1856 VarNameLength * sizeof (*VarName)
1857 );
1858 if (VarSize != 0 && VarData != NULL) {
1859 CopyMem (
1860 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
1861 VarData,
1862 VarSize
1863 );
1864 }
1865
1866 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1867 //
1868 // Digest is the event data (EFI_VARIABLE_DATA)
1869 //
1870 Status = TcgDxeHashLogExtendEvent (
1871 0,
1872 (UINT8*)VarLog,
1873 TcgEvent.EventSize,
1874 &TcgEvent,
1875 (UINT8*)VarLog
1876 );
1877 } else {
1878 Status = TcgDxeHashLogExtendEvent (
1879 0,
1880 (UINT8*)VarData,
1881 VarSize,
1882 &TcgEvent,
1883 (UINT8*)VarLog
1884 );
1885 }
1886 FreePool (VarLog);
1887 return Status;
1888 }
1889
1890 /**
1891 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1892
1893 @param[in] PCRIndex PCR Index.
1894 @param[in] EventType Event type.
1895 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1896 @param[in] VendorGuid A unique identifier for the vendor.
1897 @param[out] VarSize The size of the variable data.
1898 @param[out] VarData Pointer to the content of the variable.
1899
1900 @retval EFI_SUCCESS Operation completed successfully.
1901 @retval EFI_OUT_OF_RESOURCES Out of memory.
1902 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1903
1904 **/
1905 EFI_STATUS
1906 ReadAndMeasureVariable (
1907 IN TPM_PCRINDEX PCRIndex,
1908 IN TCG_EVENTTYPE EventType,
1909 IN CHAR16 *VarName,
1910 IN EFI_GUID *VendorGuid,
1911 OUT UINTN *VarSize,
1912 OUT VOID **VarData
1913 )
1914 {
1915 EFI_STATUS Status;
1916
1917 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);
1918 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1919 if (EFI_ERROR (Status)) {
1920 //
1921 // It is valid case, so we need handle it.
1922 //
1923 *VarData = NULL;
1924 *VarSize = 0;
1925 }
1926 } else {
1927 //
1928 // if status error, VarData is freed and set NULL by GetVariable2
1929 //
1930 if (EFI_ERROR (Status)) {
1931 return EFI_NOT_FOUND;
1932 }
1933 }
1934
1935 Status = MeasureVariable (
1936 PCRIndex,
1937 EventType,
1938 VarName,
1939 VendorGuid,
1940 *VarData,
1941 *VarSize
1942 );
1943 return Status;
1944 }
1945
1946 /**
1947 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
1948
1949 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1950 @param[in] VendorGuid A unique identifier for the vendor.
1951 @param[out] VarSize The size of the variable data.
1952 @param[out] VarData Pointer to the content of the variable.
1953
1954 @retval EFI_SUCCESS Operation completed successfully.
1955 @retval EFI_OUT_OF_RESOURCES Out of memory.
1956 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1957
1958 **/
1959 EFI_STATUS
1960 ReadAndMeasureBootVariable (
1961 IN CHAR16 *VarName,
1962 IN EFI_GUID *VendorGuid,
1963 OUT UINTN *VarSize,
1964 OUT VOID **VarData
1965 )
1966 {
1967 return ReadAndMeasureVariable (
1968 5,
1969 EV_EFI_VARIABLE_BOOT,
1970 VarName,
1971 VendorGuid,
1972 VarSize,
1973 VarData
1974 );
1975 }
1976
1977 /**
1978 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1979
1980 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1981 @param[in] VendorGuid A unique identifier for the vendor.
1982 @param[out] VarSize The size of the variable data.
1983 @param[out] VarData Pointer to the content of the variable.
1984
1985 @retval EFI_SUCCESS Operation completed successfully.
1986 @retval EFI_OUT_OF_RESOURCES Out of memory.
1987 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1988
1989 **/
1990 EFI_STATUS
1991 ReadAndMeasureSecureVariable (
1992 IN CHAR16 *VarName,
1993 IN EFI_GUID *VendorGuid,
1994 OUT UINTN *VarSize,
1995 OUT VOID **VarData
1996 )
1997 {
1998 return ReadAndMeasureVariable (
1999 7,
2000 EV_EFI_VARIABLE_DRIVER_CONFIG,
2001 VarName,
2002 VendorGuid,
2003 VarSize,
2004 VarData
2005 );
2006 }
2007
2008 /**
2009 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
2010
2011 The EFI boot variables are BootOrder and Boot#### variables.
2012
2013 @retval EFI_SUCCESS Operation completed successfully.
2014 @retval EFI_OUT_OF_RESOURCES Out of memory.
2015 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2016
2017 **/
2018 EFI_STATUS
2019 MeasureAllBootVariables (
2020 VOID
2021 )
2022 {
2023 EFI_STATUS Status;
2024 UINT16 *BootOrder;
2025 UINTN BootCount;
2026 UINTN Index;
2027 VOID *BootVarData;
2028 UINTN Size;
2029
2030 Status = ReadAndMeasureBootVariable (
2031 mBootVarName,
2032 &gEfiGlobalVariableGuid,
2033 &BootCount,
2034 (VOID **) &BootOrder
2035 );
2036 if (Status == EFI_NOT_FOUND || BootOrder == NULL) {
2037 return EFI_SUCCESS;
2038 }
2039
2040 if (EFI_ERROR (Status)) {
2041 //
2042 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
2043 //
2044 FreePool (BootOrder);
2045 return Status;
2046 }
2047
2048 BootCount /= sizeof (*BootOrder);
2049 for (Index = 0; Index < BootCount; Index++) {
2050 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
2051 Status = ReadAndMeasureBootVariable (
2052 mBootVarName,
2053 &gEfiGlobalVariableGuid,
2054 &Size,
2055 &BootVarData
2056 );
2057 if (!EFI_ERROR (Status)) {
2058 FreePool (BootVarData);
2059 }
2060 }
2061
2062 FreePool (BootOrder);
2063 return EFI_SUCCESS;
2064 }
2065
2066 /**
2067 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
2068
2069 The EFI boot variables are BootOrder and Boot#### variables.
2070
2071 @retval EFI_SUCCESS Operation completed successfully.
2072 @retval EFI_OUT_OF_RESOURCES Out of memory.
2073 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2074
2075 **/
2076 EFI_STATUS
2077 MeasureAllSecureVariables (
2078 VOID
2079 )
2080 {
2081 EFI_STATUS Status;
2082 VOID *Data;
2083 UINTN DataSize;
2084 UINTN Index;
2085
2086 Status = EFI_NOT_FOUND;
2087 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
2088 Status = ReadAndMeasureSecureVariable (
2089 mVariableType[Index].VariableName,
2090 mVariableType[Index].VendorGuid,
2091 &DataSize,
2092 &Data
2093 );
2094 if (!EFI_ERROR (Status)) {
2095 if (Data != NULL) {
2096 FreePool (Data);
2097 }
2098 }
2099 }
2100
2101 return EFI_SUCCESS;
2102 }
2103
2104 /**
2105 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
2106
2107 @retval EFI_SUCCESS Operation completed successfully.
2108 @retval EFI_OUT_OF_RESOURCES Out of memory.
2109 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2110
2111 **/
2112 EFI_STATUS
2113 MeasureLaunchOfFirmwareDebugger (
2114 VOID
2115 )
2116 {
2117 TCG_PCR_EVENT_HDR TcgEvent;
2118
2119 TcgEvent.PCRIndex = 7;
2120 TcgEvent.EventType = EV_EFI_ACTION;
2121 TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;
2122 return TcgDxeHashLogExtendEvent (
2123 0,
2124 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,
2125 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,
2126 &TcgEvent,
2127 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING
2128 );
2129 }
2130
2131 /**
2132 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
2133
2134 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
2135 - The contents of the SecureBoot variable
2136 - The contents of the PK variable
2137 - The contents of the KEK variable
2138 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
2139 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
2140 - Separator
2141 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
2142
2143 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
2144 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
2145
2146 @param[in] Event Event whose notification function is being invoked
2147 @param[in] Context Pointer to the notification function's context
2148 **/
2149 VOID
2150 EFIAPI
2151 MeasureSecureBootPolicy (
2152 IN EFI_EVENT Event,
2153 IN VOID *Context
2154 )
2155 {
2156 EFI_STATUS Status;
2157 VOID *Protocol;
2158
2159 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
2160 if (EFI_ERROR (Status)) {
2161 return;
2162 }
2163
2164 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {
2165 Status = MeasureLaunchOfFirmwareDebugger ();
2166 DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));
2167 }
2168
2169 Status = MeasureAllSecureVariables ();
2170 DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));
2171
2172 //
2173 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
2174 // and ImageVerification (Authority)
2175 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
2176 // the Authority measurement happen before ReadToBoot event.
2177 //
2178 Status = MeasureSeparatorEvent (7);
2179 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));
2180 return ;
2181 }
2182
2183 /**
2184 Ready to Boot Event notification handler.
2185
2186 Sequence of OS boot events is measured in this event notification handler.
2187
2188 @param[in] Event Event whose notification function is being invoked
2189 @param[in] Context Pointer to the notification function's context
2190
2191 **/
2192 VOID
2193 EFIAPI
2194 OnReadyToBoot (
2195 IN EFI_EVENT Event,
2196 IN VOID *Context
2197 )
2198 {
2199 EFI_STATUS Status;
2200 TPM_PCRINDEX PcrIndex;
2201
2202 PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE);
2203 if (mBootAttempts == 0) {
2204
2205 //
2206 // Measure handoff tables.
2207 //
2208 Status = MeasureHandoffTables ();
2209 if (EFI_ERROR (Status)) {
2210 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));
2211 }
2212
2213 //
2214 // Measure BootOrder & Boot#### variables.
2215 //
2216 Status = MeasureAllBootVariables ();
2217 if (EFI_ERROR (Status)) {
2218 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));
2219 }
2220
2221 //
2222 // 1. This is the first boot attempt.
2223 //
2224 Status = TcgMeasureAction (
2225 EFI_CALLING_EFI_APPLICATION
2226 );
2227 if (EFI_ERROR (Status)) {
2228 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
2229 }
2230
2231 //
2232 // 2. Draw a line between pre-boot env and entering post-boot env.
2233 // PCR[7] is already done.
2234 //
2235 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {
2236 Status = MeasureSeparatorEvent (PcrIndex);
2237 if (EFI_ERROR (Status)) {
2238 DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));
2239 }
2240 }
2241
2242 //
2243 // 3. Measure GPT. It would be done in SAP driver.
2244 //
2245
2246 //
2247 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
2248 //
2249
2250 //
2251 // 5. Read & Measure variable. BootOrder already measured.
2252 //
2253 } else {
2254 //
2255 // 6. Not first attempt, meaning a return from last attempt
2256 //
2257 Status = TcgMeasureAction (
2258 EFI_RETURNING_FROM_EFI_APPLICATOIN
2259 );
2260 if (EFI_ERROR (Status)) {
2261 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));
2262 }
2263 }
2264
2265 DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));
2266 //
2267 // Increase boot attempt counter.
2268 //
2269 mBootAttempts++;
2270 PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1);
2271 }
2272
2273 /**
2274 Exit Boot Services Event notification handler.
2275
2276 Measure invocation and success of ExitBootServices.
2277
2278 @param[in] Event Event whose notification function is being invoked
2279 @param[in] Context Pointer to the notification function's context
2280
2281 **/
2282 VOID
2283 EFIAPI
2284 OnExitBootServices (
2285 IN EFI_EVENT Event,
2286 IN VOID *Context
2287 )
2288 {
2289 EFI_STATUS Status;
2290
2291 //
2292 // Measure invocation of ExitBootServices,
2293 //
2294 Status = TcgMeasureAction (
2295 EFI_EXIT_BOOT_SERVICES_INVOCATION
2296 );
2297 if (EFI_ERROR (Status)) {
2298 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
2299 }
2300
2301 //
2302 // Measure success of ExitBootServices
2303 //
2304 Status = TcgMeasureAction (
2305 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
2306 );
2307 if (EFI_ERROR (Status)) {
2308 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
2309 }
2310 }
2311
2312 /**
2313 Exit Boot Services Failed Event notification handler.
2314
2315 Measure Failure of ExitBootServices.
2316
2317 @param[in] Event Event whose notification function is being invoked
2318 @param[in] Context Pointer to the notification function's context
2319
2320 **/
2321 VOID
2322 EFIAPI
2323 OnExitBootServicesFailed (
2324 IN EFI_EVENT Event,
2325 IN VOID *Context
2326 )
2327 {
2328 EFI_STATUS Status;
2329
2330 //
2331 // Measure Failure of ExitBootServices,
2332 //
2333 Status = TcgMeasureAction (
2334 EFI_EXIT_BOOT_SERVICES_FAILED
2335 );
2336 if (EFI_ERROR (Status)) {
2337 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
2338 }
2339
2340 }
2341
2342 /**
2343 The function install Tcg2 protocol.
2344
2345 @retval EFI_SUCCESS Tcg2 protocol is installed.
2346 @retval other Some error occurs.
2347 **/
2348 EFI_STATUS
2349 InstallTcg2 (
2350 VOID
2351 )
2352 {
2353 EFI_STATUS Status;
2354 EFI_HANDLE Handle;
2355
2356 Handle = NULL;
2357 Status = gBS->InstallMultipleProtocolInterfaces (
2358 &Handle,
2359 &gEfiTcg2ProtocolGuid,
2360 &mTcg2Protocol,
2361 NULL
2362 );
2363 return Status;
2364 }
2365
2366 /**
2367 The driver's entry point. It publishes EFI Tcg2 Protocol.
2368
2369 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2370 @param[in] SystemTable A pointer to the EFI System Table.
2371
2372 @retval EFI_SUCCESS The entry point is executed successfully.
2373 @retval other Some error occurs when executing this entry point.
2374 **/
2375 EFI_STATUS
2376 EFIAPI
2377 DriverEntry (
2378 IN EFI_HANDLE ImageHandle,
2379 IN EFI_SYSTEM_TABLE *SystemTable
2380 )
2381 {
2382 EFI_STATUS Status;
2383 EFI_EVENT Event;
2384 VOID *Registration;
2385 UINT32 MaxCommandSize;
2386 UINT32 MaxResponseSize;
2387 TPML_PCR_SELECTION Pcrs;
2388 UINTN Index;
2389 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
2390 UINT32 ActivePCRBanks;
2391 UINT32 NumberOfPCRBanks;
2392
2393 mImageHandle = ImageHandle;
2394
2395 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
2396 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
2397 DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
2398 return EFI_UNSUPPORTED;
2399 }
2400
2401 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
2402 DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
2403 return EFI_DEVICE_ERROR;
2404 }
2405
2406 Status = Tpm2RequestUseTpm ();
2407 if (EFI_ERROR (Status)) {
2408 DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));
2409 return Status;
2410 }
2411
2412 //
2413 // Fill information
2414 //
2415 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));
2416
2417 mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);
2418 mTcgDxeData.BsCap.ProtocolVersion.Major = 1;
2419 mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;
2420 mTcgDxeData.BsCap.StructureVersion.Major = 1;
2421 mTcgDxeData.BsCap.StructureVersion.Minor = 1;
2422
2423 DEBUG ((EFI_D_INFO, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));
2424 DEBUG ((EFI_D_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));
2425
2426 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);
2427 if (EFI_ERROR (Status)) {
2428 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));
2429 } else {
2430 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));
2431 }
2432
2433 DEBUG_CODE (
2434 UINT32 FirmwareVersion1;
2435 UINT32 FirmwareVersion2;
2436
2437 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);
2438 if (EFI_ERROR (Status)) {
2439 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
2440 } else {
2441 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));
2442 }
2443 );
2444
2445 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);
2446 if (EFI_ERROR (Status)) {
2447 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
2448 } else {
2449 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;
2450 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;
2451 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));
2452 }
2453
2454 //
2455 // Get supported PCR and current Active PCRs
2456 //
2457 Status = Tpm2GetCapabilityPcrs (&Pcrs);
2458 if (EFI_ERROR (Status)) {
2459 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));
2460 TpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1;
2461 ActivePCRBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;
2462 } else {
2463 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));
2464 TpmHashAlgorithmBitmap = 0;
2465 ActivePCRBanks = 0;
2466 for (Index = 0; Index < Pcrs.count; Index++) {
2467 DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));
2468 switch (Pcrs.pcrSelections[Index].hash) {
2469 case TPM_ALG_SHA1:
2470 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA1;
2471 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
2472 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1;
2473 }
2474 break;
2475 case TPM_ALG_SHA256:
2476 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA256;
2477 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
2478 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256;
2479 }
2480 break;
2481 case TPM_ALG_SHA384:
2482 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA384;
2483 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
2484 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384;
2485 }
2486 break;
2487 case TPM_ALG_SHA512:
2488 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA512;
2489 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
2490 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512;
2491 }
2492 break;
2493 case TPM_ALG_SM3_256:
2494 TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;
2495 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
2496 ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;
2497 }
2498 break;
2499 }
2500 }
2501 }
2502 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);
2503 mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);
2504
2505 //
2506 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.
2507 //
2508 NumberOfPCRBanks = 0;
2509 for (Index = 0; Index < 32; Index++) {
2510 if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {
2511 NumberOfPCRBanks++;
2512 }
2513 }
2514
2515 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {
2516 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;
2517 } else {
2518 mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks);
2519 if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) {
2520 DEBUG ((EFI_D_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks));
2521 mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;
2522 }
2523 }
2524
2525 mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
2526 if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {
2527 //
2528 // No need to expose TCG1.2 event log if SHA1 bank does not exist.
2529 //
2530 mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
2531 }
2532
2533 DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
2534 DEBUG ((EFI_D_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));
2535 DEBUG ((EFI_D_INFO, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks));
2536 DEBUG ((EFI_D_INFO, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks));
2537
2538 if (mTcgDxeData.BsCap.TPMPresentFlag) {
2539 //
2540 // Setup the log area and copy event log from hob list to it
2541 //
2542 Status = SetupEventLog ();
2543 ASSERT_EFI_ERROR (Status);
2544
2545 //
2546 // Measure handoff tables, Boot#### variables etc.
2547 //
2548 Status = EfiCreateEventReadyToBootEx (
2549 TPL_CALLBACK,
2550 OnReadyToBoot,
2551 NULL,
2552 &Event
2553 );
2554
2555 Status = gBS->CreateEventEx (
2556 EVT_NOTIFY_SIGNAL,
2557 TPL_NOTIFY,
2558 OnExitBootServices,
2559 NULL,
2560 &gEfiEventExitBootServicesGuid,
2561 &Event
2562 );
2563
2564 //
2565 // Measure Exit Boot Service failed
2566 //
2567 Status = gBS->CreateEventEx (
2568 EVT_NOTIFY_SIGNAL,
2569 TPL_NOTIFY,
2570 OnExitBootServicesFailed,
2571 NULL,
2572 &gEventExitBootServicesFailedGuid,
2573 &Event
2574 );
2575
2576 //
2577 // Create event callback, because we need access variable on SecureBootPolicyVariable
2578 // We should use VariableWriteArch instead of VariableArch, because Variable driver
2579 // may update SecureBoot value based on last setting.
2580 //
2581 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
2582 }
2583
2584 //
2585 // Install Tcg2Protocol
2586 //
2587 Status = InstallTcg2 ();
2588 DEBUG ((EFI_D_INFO, "InstallTcg2 - %r\n", Status));
2589
2590 return Status;
2591 }