1 /** @file
2   This library is used by other modules to measure data to TPM.
3 
4 Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include <PiDxe.h>
10 
11 #include <Protocol/TcgService.h>
12 #include <Protocol/Tcg2Protocol.h>
13 
14 #include <Library/BaseMemoryLib.h>
15 #include <Library/MemoryAllocationLib.h>
16 #include <Library/UefiBootServicesTableLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/TpmMeasurementLib.h>
19 
20 #include <Guid/Acpi.h>
21 #include <IndustryStandard/Acpi.h>
22 
23 
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 EFI_STATUS
Tpm12MeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)41 Tpm12MeasureAndLogData (
42   IN UINT32             PcrIndex,
43   IN UINT32             EventType,
44   IN VOID               *EventLog,
45   IN UINT32             LogLen,
46   IN VOID               *HashData,
47   IN UINT64             HashDataLen
48   )
49 {
50   EFI_STATUS                Status;
51   EFI_TCG_PROTOCOL          *TcgProtocol;
52   TCG_PCR_EVENT             *TcgEvent;
53   EFI_PHYSICAL_ADDRESS      EventLogLastEntry;
54   UINT32                    EventNumber;
55 
56   TcgEvent = NULL;
57 
58   //
59   // Tpm activation state is checked in HashLogExtendEvent
60   //
61   Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);
62   if (EFI_ERROR(Status)){
63     return Status;
64   }
65 
66   TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (sizeof (TCG_PCR_EVENT_HDR) + LogLen);
67   if(TcgEvent == NULL) {
68     return EFI_OUT_OF_RESOURCES;
69   }
70 
71   TcgEvent->PCRIndex  = PcrIndex;
72   TcgEvent->EventType = EventType;
73   TcgEvent->EventSize = LogLen;
74   CopyMem (&TcgEvent->Event[0], EventLog, LogLen);
75   EventNumber = 1;
76   Status = TcgProtocol->HashLogExtendEvent (
77                           TcgProtocol,
78                           (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
79                           HashDataLen,
80                           TPM_ALG_SHA,
81                           TcgEvent,
82                           &EventNumber,
83                           &EventLogLastEntry
84                           );
85 
86   FreePool (TcgEvent);
87 
88   return Status;
89 }
90 
91 /**
92   Tpm20 measure and log data, and extend the measurement result into a specific PCR.
93 
94   @param[in]  PcrIndex         PCR Index.
95   @param[in]  EventType        Event type.
96   @param[in]  EventLog         Measurement event log.
97   @param[in]  LogLen           Event log length in bytes.
98   @param[in]  HashData         The start of the data buffer to be hashed, extended.
99   @param[in]  HashDataLen      The length, in bytes, of the buffer referenced by HashData
100 
101   @retval EFI_SUCCESS           Operation completed successfully.
102   @retval EFI_UNSUPPORTED       TPM device not available.
103   @retval EFI_OUT_OF_RESOURCES  Out of memory.
104   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
105 **/
106 EFI_STATUS
Tpm20MeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)107 Tpm20MeasureAndLogData (
108   IN UINT32             PcrIndex,
109   IN UINT32             EventType,
110   IN VOID               *EventLog,
111   IN UINT32             LogLen,
112   IN VOID               *HashData,
113   IN UINT64             HashDataLen
114   )
115 {
116   EFI_STATUS                Status;
117   EFI_TCG2_PROTOCOL         *Tcg2Protocol;
118   EFI_TCG2_EVENT            *Tcg2Event;
119 
120   //
121   // TPMPresentFlag is checked in HashLogExtendEvent
122   //
123   Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);
124   if (EFI_ERROR (Status)) {
125     return Status;
126   }
127 
128   Tcg2Event = (EFI_TCG2_EVENT *) AllocateZeroPool (LogLen + sizeof (EFI_TCG2_EVENT));
129   if(Tcg2Event == NULL) {
130     return EFI_OUT_OF_RESOURCES;
131   }
132 
133   Tcg2Event->Size = (UINT32)LogLen + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event);
134   Tcg2Event->Header.HeaderSize    = sizeof(EFI_TCG2_EVENT_HEADER);
135   Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
136   Tcg2Event->Header.PCRIndex      = PcrIndex;
137   Tcg2Event->Header.EventType     = EventType;
138   CopyMem (&Tcg2Event->Event[0], EventLog, LogLen);
139 
140   Status = Tcg2Protocol->HashLogExtendEvent (
141                            Tcg2Protocol,
142                            0,
143                            (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,
144                            HashDataLen,
145                            Tcg2Event
146                            );
147   FreePool (Tcg2Event);
148 
149   return Status;
150 }
151 
152 /**
153   Tpm measure and log data, and extend the measurement result into a specific PCR.
154 
155   @param[in]  PcrIndex         PCR Index.
156   @param[in]  EventType        Event type.
157   @param[in]  EventLog         Measurement event log.
158   @param[in]  LogLen           Event log length in bytes.
159   @param[in]  HashData         The start of the data buffer to be hashed, extended.
160   @param[in]  HashDataLen      The length, in bytes, of the buffer referenced by HashData
161 
162   @retval EFI_SUCCESS               Operation completed successfully.
163   @retval EFI_UNSUPPORTED       TPM device not available.
164   @retval EFI_OUT_OF_RESOURCES  Out of memory.
165   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
166 **/
167 EFI_STATUS
168 EFIAPI
TpmMeasureAndLogData(IN UINT32 PcrIndex,IN UINT32 EventType,IN VOID * EventLog,IN UINT32 LogLen,IN VOID * HashData,IN UINT64 HashDataLen)169 TpmMeasureAndLogData (
170   IN UINT32             PcrIndex,
171   IN UINT32             EventType,
172   IN VOID               *EventLog,
173   IN UINT32             LogLen,
174   IN VOID               *HashData,
175   IN UINT64             HashDataLen
176   )
177 {
178   EFI_STATUS  Status;
179 
180   //
181   // Try to measure using Tpm20 protocol
182   //
183   Status = Tpm20MeasureAndLogData(
184              PcrIndex,
185              EventType,
186              EventLog,
187              LogLen,
188              HashData,
189              HashDataLen
190              );
191 
192   if (EFI_ERROR (Status)) {
193     //
194     // Try to measure using Tpm1.2 protocol
195     //
196     Status = Tpm12MeasureAndLogData(
197                PcrIndex,
198                EventType,
199                EventLog,
200                LogLen,
201                HashData,
202                HashDataLen
203                );
204   }
205 
206   return Status;
207 }
208