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