1 /** @file
2 This library is used by other modules to measure data to TPM.
3
4 Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <PiDxe.h>
16
17 #include <Protocol/TcgService.h>
18 #include <Protocol/Tcg2Protocol.h>
19
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/TpmMeasurementLib.h>
25
26 #include <Guid/Acpi.h>
27 #include <IndustryStandard/Acpi.h>
28
29
30
31 /**
32 Tpm12 measure and log data, and extend the measurement result into a specific PCR.
33
34 @param[in] PcrIndex PCR Index.
35 @param[in] EventType Event type.
36 @param[in] EventLog Measurement event log.
37 @param[in] LogLen Event log length in bytes.
38 @param[in] HashData The start of the data buffer to be hashed, extended.
39 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
40
41 @retval EFI_SUCCESS Operation completed successfully.
42 @retval EFI_UNSUPPORTED TPM device not available.
43 @retval EFI_OUT_OF_RESOURCES Out of memory.
44 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
45 **/
46 EFI_STATUS
Tpm12MeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)47 Tpm12MeasureAndLogData (
48 IN UINT32 PcrIndex,
49 IN UINT32 EventType,
50 IN VOID *EventLog,
51 IN UINT32 LogLen,
52 IN VOID *HashData,
53 IN UINT64 HashDataLen
54 )
55 {
56 EFI_STATUS Status;
57 EFI_TCG_PROTOCOL *TcgProtocol;
58 TCG_PCR_EVENT *TcgEvent;
59 EFI_PHYSICAL_ADDRESS EventLogLastEntry;
60 UINT32 EventNumber;
61
62 TcgEvent = NULL;
63
64 //
65 // Tpm active/deactive state is checked in HashLogExtendEvent
66 //
67 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);
68 if (EFI_ERROR(Status)){
69 return Status;
70 }
71
72 TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (sizeof (TCG_PCR_EVENT_HDR) + LogLen);
73 if(TcgEvent == NULL) {
74 return EFI_OUT_OF_RESOURCES;
75 }
76
77 TcgEvent->PCRIndex = PcrIndex;
78 TcgEvent->EventType = EventType;
79 TcgEvent->EventSize = LogLen;
80 CopyMem (&TcgEvent->Event[0], EventLog, LogLen);
81 EventNumber = 1;
82 Status = TcgProtocol->HashLogExtendEvent (
83 TcgProtocol,
84 (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
85 HashDataLen,
86 TPM_ALG_SHA,
87 TcgEvent,
88 &EventNumber,
89 &EventLogLastEntry
90 );
91
92 FreePool (TcgEvent);
93
94 return Status;
95 }
96
97 /**
98 Tpm20 measure and log data, and extend the measurement result into a specific PCR.
99
100 @param[in] PcrIndex PCR Index.
101 @param[in] EventType Event type.
102 @param[in] EventLog Measurement event log.
103 @param[in] LogLen Event log length in bytes.
104 @param[in] HashData The start of the data buffer to be hashed, extended.
105 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
106
107 @retval EFI_SUCCESS Operation completed successfully.
108 @retval EFI_UNSUPPORTED TPM device not available.
109 @retval EFI_OUT_OF_RESOURCES Out of memory.
110 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
111 **/
112 EFI_STATUS
Tpm20MeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)113 Tpm20MeasureAndLogData (
114 IN UINT32 PcrIndex,
115 IN UINT32 EventType,
116 IN VOID *EventLog,
117 IN UINT32 LogLen,
118 IN VOID *HashData,
119 IN UINT64 HashDataLen
120 )
121 {
122 EFI_STATUS Status;
123 EFI_TCG2_PROTOCOL *Tcg2Protocol;
124 EFI_TCG2_EVENT *Tcg2Event;
125
126 //
127 // TPMPresentFlag is checked in HashLogExtendEvent
128 //
129 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);
130 if (EFI_ERROR (Status)) {
131 return Status;
132 }
133
134 Tcg2Event = (EFI_TCG2_EVENT *) AllocateZeroPool (LogLen + sizeof (EFI_TCG2_EVENT));
135 if(Tcg2Event == NULL) {
136 return EFI_OUT_OF_RESOURCES;
137 }
138
139 Tcg2Event->Size = (UINT32)LogLen + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event);
140 Tcg2Event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
141 Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
142 Tcg2Event->Header.PCRIndex = PcrIndex;
143 Tcg2Event->Header.EventType = EventType;
144 CopyMem (&Tcg2Event->Event[0], EventLog, LogLen);
145
146 Status = Tcg2Protocol->HashLogExtendEvent (
147 Tcg2Protocol,
148 0,
149 (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
150 HashDataLen,
151 Tcg2Event
152 );
153 FreePool (Tcg2Event);
154
155 return Status;
156 }
157
158 /**
159 Tpm measure and log data, and extend the measurement result into a specific PCR.
160
161 @param[in] PcrIndex PCR Index.
162 @param[in] EventType Event type.
163 @param[in] EventLog Measurement event log.
164 @param[in] LogLen Event log length in bytes.
165 @param[in] HashData The start of the data buffer to be hashed, extended.
166 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
167
168 @retval EFI_SUCCESS Operation completed successfully.
169 @retval EFI_UNSUPPORTED TPM device not available.
170 @retval EFI_OUT_OF_RESOURCES Out of memory.
171 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
172 **/
173 EFI_STATUS
174 EFIAPI
TpmMeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)175 TpmMeasureAndLogData (
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
186 //
187 // Try to measure using Tpm1.2 protocol
188 //
189 Status = Tpm12MeasureAndLogData(
190 PcrIndex,
191 EventType,
192 EventLog,
193 LogLen,
194 HashData,
195 HashDataLen
196 );
197 if (EFI_ERROR (Status)) {
198 //
199 // Try to measure using Tpm20 protocol
200 //
201 Status = Tpm20MeasureAndLogData(
202 PcrIndex,
203 EventType,
204 EventLog,
205 LogLen,
206 HashData,
207 HashDataLen
208 );
209 }
210
211 return Status;
212 }
213