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