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