]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Library / DxeTpmMeasurementLib / DxeTpmMeasurementLib.c
1 /** @file
2 This library is used by other modules to measure data to TPM and Confidential
3 Computing (CC) measure registers.
4
5 Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved. <BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <PiDxe.h>
11
12 #include <Protocol/TcgService.h>
13 #include <Protocol/Tcg2Protocol.h>
14
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/MemoryAllocationLib.h>
17 #include <Library/UefiBootServicesTableLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/TpmMeasurementLib.h>
20
21 #include <Guid/Acpi.h>
22 #include <IndustryStandard/Acpi.h>
23 #include <Protocol/CcMeasurement.h>
24
25 /**
26 Tpm12 measure and log data, and extend the measurement result into a specific PCR.
27
28 @param[in] PcrIndex PCR Index.
29 @param[in] EventType Event type.
30 @param[in] EventLog Measurement event log.
31 @param[in] LogLen Event log length in bytes.
32 @param[in] HashData The start of the data buffer to be hashed, extended.
33 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
34
35 @retval EFI_SUCCESS Operation completed successfully.
36 @retval EFI_UNSUPPORTED TPM device not available.
37 @retval EFI_OUT_OF_RESOURCES Out of memory.
38 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
39 **/
40 STATIC
41 EFI_STATUS
42 Tpm12MeasureAndLogData (
43 IN UINT32 PcrIndex,
44 IN UINT32 EventType,
45 IN VOID *EventLog,
46 IN UINT32 LogLen,
47 IN VOID *HashData,
48 IN UINT64 HashDataLen
49 )
50 {
51 EFI_STATUS Status;
52 EFI_TCG_PROTOCOL *TcgProtocol;
53 TCG_PCR_EVENT *TcgEvent;
54 EFI_PHYSICAL_ADDRESS EventLogLastEntry;
55 UINT32 EventNumber;
56
57 TcgEvent = NULL;
58
59 //
60 // Tpm activation state is checked in HashLogExtendEvent
61 //
62 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
63 if (EFI_ERROR (Status)) {
64 return Status;
65 }
66
67 TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (sizeof (TCG_PCR_EVENT_HDR) + LogLen);
68 if (TcgEvent == NULL) {
69 return EFI_OUT_OF_RESOURCES;
70 }
71
72 TcgEvent->PCRIndex = PcrIndex;
73 TcgEvent->EventType = EventType;
74 TcgEvent->EventSize = LogLen;
75 CopyMem (&TcgEvent->Event[0], EventLog, LogLen);
76 EventNumber = 1;
77 Status = TcgProtocol->HashLogExtendEvent (
78 TcgProtocol,
79 (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
80 HashDataLen,
81 TPM_ALG_SHA,
82 TcgEvent,
83 &EventNumber,
84 &EventLogLastEntry
85 );
86
87 FreePool (TcgEvent);
88
89 return Status;
90 }
91
92 /**
93 Tpm20 measure and log data, and extend the measurement result into a specific PCR.
94
95 @param[in] PcrIndex PCR Index.
96 @param[in] EventType Event type.
97 @param[in] EventLog Measurement event log.
98 @param[in] LogLen Event log length in bytes.
99 @param[in] HashData The start of the data buffer to be hashed, extended.
100 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
101
102 @retval EFI_SUCCESS Operation completed successfully.
103 @retval EFI_UNSUPPORTED TPM device not available.
104 @retval EFI_OUT_OF_RESOURCES Out of memory.
105 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
106 **/
107 STATIC
108 EFI_STATUS
109 Tpm20MeasureAndLogData (
110 IN UINT32 PcrIndex,
111 IN UINT32 EventType,
112 IN VOID *EventLog,
113 IN UINT32 LogLen,
114 IN VOID *HashData,
115 IN UINT64 HashDataLen
116 )
117 {
118 EFI_STATUS Status;
119 EFI_TCG2_PROTOCOL *Tcg2Protocol;
120 EFI_TCG2_EVENT *Tcg2Event;
121
122 //
123 // TPMPresentFlag is checked in HashLogExtendEvent
124 //
125 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);
126 if (EFI_ERROR (Status)) {
127 return Status;
128 }
129
130 Tcg2Event = (EFI_TCG2_EVENT *)AllocateZeroPool (LogLen + sizeof (EFI_TCG2_EVENT));
131 if (Tcg2Event == NULL) {
132 return EFI_OUT_OF_RESOURCES;
133 }
134
135 Tcg2Event->Size = (UINT32)LogLen + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event);
136 Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
137 Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
138 Tcg2Event->Header.PCRIndex = PcrIndex;
139 Tcg2Event->Header.EventType = EventType;
140 CopyMem (&Tcg2Event->Event[0], EventLog, LogLen);
141
142 Status = Tcg2Protocol->HashLogExtendEvent (
143 Tcg2Protocol,
144 0,
145 (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
146 HashDataLen,
147 Tcg2Event
148 );
149 FreePool (Tcg2Event);
150
151 return Status;
152 }
153
154 /**
155 Cc measure and log data, and extend the measurement result into a
156 specific CC MR.
157
158 @param[in] CcProtocol Instance of CC measurement protocol
159 @param[in] PcrIndex PCR Index.
160 @param[in] EventType Event type.
161 @param[in] EventLog Measurement event log.
162 @param[in] LogLen Event log length in bytes.
163 @param[in] HashData The start of the data buffer to be hashed, extended.
164 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
165
166 @retval EFI_SUCCESS Operation completed successfully.
167 @retval EFI_UNSUPPORTED CC guest not available.
168 @retval EFI_OUT_OF_RESOURCES Out of memory.
169 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
170 @retval EFI_INVALID_PARAMETER The input parameter is invalid.
171 **/
172 STATIC
173 EFI_STATUS
174 CcMeasureAndLogData (
175 IN EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol,
176 IN UINT32 PcrIndex,
177 IN UINT32 EventType,
178 IN VOID *EventLog,
179 IN UINT32 LogLen,
180 IN VOID *HashData,
181 IN UINT64 HashDataLen
182 )
183 {
184 EFI_STATUS Status;
185 EFI_CC_EVENT *EfiCcEvent;
186 EFI_CC_MR_INDEX MrIndex;
187
188 if (CcProtocol == NULL) {
189 return EFI_INVALID_PARAMETER;
190 }
191
192 Status = CcProtocol->MapPcrToMrIndex (CcProtocol, PcrIndex, &MrIndex);
193 if (EFI_ERROR (Status)) {
194 return Status;
195 }
196
197 EfiCcEvent = (EFI_CC_EVENT *)AllocateZeroPool (LogLen + sizeof (EFI_CC_EVENT));
198 if (EfiCcEvent == NULL) {
199 return EFI_OUT_OF_RESOURCES;
200 }
201
202 EfiCcEvent->Size = (UINT32)LogLen + sizeof (EFI_CC_EVENT) - sizeof (EfiCcEvent->Event);
203 EfiCcEvent->Header.HeaderSize = sizeof (EFI_CC_EVENT_HEADER);
204 EfiCcEvent->Header.HeaderVersion = EFI_CC_EVENT_HEADER_VERSION;
205 EfiCcEvent->Header.MrIndex = MrIndex;
206 EfiCcEvent->Header.EventType = EventType;
207 CopyMem (&EfiCcEvent->Event[0], EventLog, LogLen);
208
209 Status = CcProtocol->HashLogExtendEvent (
210 CcProtocol,
211 0,
212 (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
213 HashDataLen,
214 EfiCcEvent
215 );
216 FreePool (EfiCcEvent);
217
218 return Status;
219 }
220
221 /**
222 Tpm measure and log data, and extend the measurement result into a specific PCR.
223
224 @param[in] PcrIndex PCR Index.
225 @param[in] EventType Event type.
226 @param[in] EventLog Measurement event log.
227 @param[in] LogLen Event log length in bytes.
228 @param[in] HashData The start of the data buffer to be hashed, extended.
229 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
230
231 @retval EFI_SUCCESS Operation completed successfully.
232 @retval EFI_UNSUPPORTED TPM device not available.
233 @retval EFI_OUT_OF_RESOURCES Out of memory.
234 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
235 **/
236 EFI_STATUS
237 EFIAPI
238 TpmMeasureAndLogData (
239 IN UINT32 PcrIndex,
240 IN UINT32 EventType,
241 IN VOID *EventLog,
242 IN UINT32 LogLen,
243 IN VOID *HashData,
244 IN UINT64 HashDataLen
245 )
246 {
247 EFI_STATUS Status;
248 EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;
249
250 Status = gBS->LocateProtocol (&gEfiCcMeasurementProtocolGuid, NULL, (VOID **)&CcProtocol);
251 if (!EFI_ERROR (Status)) {
252 //
253 // Try to measure using Cc measurement protocol
254 //
255 Status = CcMeasureAndLogData (
256 CcProtocol,
257 PcrIndex,
258 EventType,
259 EventLog,
260 LogLen,
261 HashData,
262 HashDataLen
263 );
264 } else {
265 //
266 // Try to measure using Tpm20 protocol
267 //
268 Status = Tpm20MeasureAndLogData (
269 PcrIndex,
270 EventType,
271 EventLog,
272 LogLen,
273 HashData,
274 HashDataLen
275 );
276
277 if (EFI_ERROR (Status)) {
278 //
279 // Try to measure using Tpm1.2 protocol
280 //
281 Status = Tpm12MeasureAndLogData (
282 PcrIndex,
283 EventType,
284 EventLog,
285 LogLen,
286 HashData,
287 HashDataLen
288 );
289 }
290 }
291
292 return Status;
293 }