]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.c
SecurityPkg/TcgEventLogRecordLib: add new lib for firmware measurement
[mirror_edk2.git] / SecurityPkg / Library / TcgEventLogRecordLib / TcgEventLogRecordLib.c
CommitLineData
a13947b2
QZ
1/** @file\r
2 This library is used by other modules to measure data to TPM.\r
3\r
4Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include <Uefi/UefiBaseType.h>\r
10#include <Pi/PiFirmwareVolume.h>\r
11\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/ReportStatusCodeLib.h>\r
15#include <Library/PcdLib.h>\r
16#include <Library/PrintLib.h>\r
17#include <Library/TcgEventLogRecordLib.h>\r
18#include <Library/TpmMeasurementLib.h>\r
19\r
20#include <IndustryStandard/UefiTcgPlatform.h>\r
21\r
22/**\r
23 Get the FvName from the FV header.\r
24\r
25 Causion: The FV is untrusted input.\r
26\r
27 @param[in] FvBase Base address of FV image.\r
28 @param[in] FvLength Length of FV image.\r
29\r
30 @return FvName pointer\r
31 @retval NULL FvName is NOT found\r
32**/\r
33VOID *\r
34TpmMeasurementGetFvName (\r
35 IN EFI_PHYSICAL_ADDRESS FvBase,\r
36 IN UINT64 FvLength\r
37 )\r
38{\r
39 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
40 EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;\r
41\r
42 if (FvBase >= MAX_ADDRESS) {\r
43 return NULL;\r
44 }\r
45 if (FvLength >= MAX_ADDRESS - FvBase) {\r
46 return NULL;\r
47 }\r
48 if (FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {\r
49 return NULL;\r
50 }\r
51\r
52 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;\r
53 if (FvHeader->Signature != EFI_FVH_SIGNATURE) {\r
54 return NULL;\r
55 }\r
56 if (FvHeader->ExtHeaderOffset < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {\r
57 return NULL;\r
58 }\r
59 if (FvHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) {\r
60 return NULL;\r
61 }\r
62 FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset);\r
63\r
64 return &FvExtHeader->FvName;\r
65}\r
66\r
67/**\r
68 Measure a FirmwareBlob.\r
69\r
70 @param[in] PcrIndex PcrIndex of the measurement.\r
71 @param[in] Description Description for this FirmwareBlob.\r
72 @param[in] FirmwareBlobBase Base address of this FirmwareBlob.\r
73 @param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.\r
74\r
75 @retval EFI_SUCCESS Operation completed successfully.\r
76 @retval EFI_UNSUPPORTED TPM device not available.\r
77 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
78 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
79**/\r
80EFI_STATUS\r
81EFIAPI\r
82MeasureFirmwareBlob (\r
83 IN UINT32 PcrIndex,\r
84 IN CHAR8 *Description OPTIONAL,\r
85 IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,\r
86 IN UINT64 FirmwareBlobLength\r
87 )\r
88{\r
89 EFI_PLATFORM_FIRMWARE_BLOB FvBlob;\r
90 PLATFORM_FIRMWARE_BLOB2_STRUCT FvBlob2;\r
91 VOID *FvName;\r
92 UINT32 EventType;\r
93 VOID *EventLog;\r
94 UINT32 EventLogSize;\r
95 EFI_STATUS Status;\r
96\r
97 FvName = TpmMeasurementGetFvName (FirmwareBlobBase, FirmwareBlobLength);\r
98\r
99 if (((Description != NULL) || (FvName != NULL)) &&\r
100 (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) {\r
101 if (Description != NULL) {\r
102 AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "%a", Description);\r
103 } else {\r
104 AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);\r
105 }\r
106\r
107 FvBlob2.BlobDescriptionSize = sizeof(FvBlob2.BlobDescription);\r
108 FvBlob2.BlobBase = FirmwareBlobBase;\r
109 FvBlob2.BlobLength = FirmwareBlobLength;\r
110\r
111 EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;\r
112 EventLog = &FvBlob2;\r
113 EventLogSize = sizeof(FvBlob2);\r
114 } else {\r
115 FvBlob.BlobBase = FirmwareBlobBase;\r
116 FvBlob.BlobLength = FirmwareBlobLength;\r
117\r
118 EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
119 EventLog = &FvBlob;\r
120 EventLogSize = sizeof(FvBlob);\r
121 }\r
122\r
123 Status = TpmMeasureAndLogData (\r
124 PcrIndex,\r
125 EventType,\r
126 EventLog,\r
127 EventLogSize,\r
128 (VOID*)(UINTN)FirmwareBlobBase,\r
129 FirmwareBlobLength\r
130 );\r
131\r
132 return Status;\r
133}\r
134\r
135/**\r
136 Measure a HandoffTable.\r
137\r
138 @param[in] PcrIndex PcrIndex of the measurement.\r
139 @param[in] Description Description for this HandoffTable.\r
140 @param[in] TableGuid GUID of this HandoffTable.\r
141 @param[in] TableAddress Base address of this HandoffTable.\r
142 @param[in] TableLength Size in bytes of this HandoffTable.\r
143\r
144 @retval EFI_SUCCESS Operation completed successfully.\r
145 @retval EFI_UNSUPPORTED TPM device not available.\r
146 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
147 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
148**/\r
149EFI_STATUS\r
150EFIAPI\r
151MeasureHandoffTable (\r
152 IN UINT32 PcrIndex,\r
153 IN CHAR8 *Description OPTIONAL,\r
154 IN EFI_GUID *TableGuid,\r
155 IN VOID *TableAddress,\r
156 IN UINTN TableLength\r
157 )\r
158{\r
159 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
160 HANDOFF_TABLE_POINTERS2_STRUCT HandoffTables2;\r
161 UINT32 EventType;\r
162 VOID *EventLog;\r
163 UINT32 EventLogSize;\r
164 EFI_STATUS Status;\r
165\r
166 if ((Description != NULL) &&\r
167 (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) {\r
168 AsciiSPrint((CHAR8*)HandoffTables2.TableDescription, sizeof(HandoffTables2.TableDescription), "%a", Description);\r
169\r
170 HandoffTables2.TableDescriptionSize = sizeof(HandoffTables2.TableDescription);\r
171 HandoffTables2.NumberOfTables = 1;\r
172 CopyGuid (&(HandoffTables2.TableEntry[0].VendorGuid), TableGuid);\r
173 HandoffTables2.TableEntry[0].VendorTable = TableAddress;\r
174\r
175 EventType = EV_EFI_HANDOFF_TABLES2;\r
176 EventLog = &HandoffTables2;\r
177 EventLogSize = sizeof(HandoffTables2);\r
178 } else {\r
179 HandoffTables.NumberOfTables = 1;\r
180 CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), TableGuid);\r
181 HandoffTables.TableEntry[0].VendorTable = TableAddress;\r
182\r
183 EventType = EV_EFI_HANDOFF_TABLES;\r
184 EventLog = &HandoffTables;\r
185 EventLogSize = sizeof(HandoffTables);\r
186 }\r
187\r
188 Status = TpmMeasureAndLogData (\r
189 PcrIndex,\r
190 EventType,\r
191 EventLog,\r
192 EventLogSize,\r
193 TableAddress,\r
194 TableLength\r
195 );\r
196 return Status;\r
197}\r