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