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