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