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