1 /* SPDX-License-Identifier: LGPL-2.1+ */
9 #define EFI_TCG_PROTOCOL_GUID { 0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd} }
11 typedef struct _TCG_VERSION
{
18 typedef struct tdEFI_TCG2_VERSION
{
23 typedef struct _TCG_BOOT_SERVICE_CAPABILITY
{
25 struct _TCG_VERSION StructureVersion
;
26 struct _TCG_VERSION ProtocolSpecVersion
;
27 UINT8 HashAlgorithmBitmap
;
28 BOOLEAN TPMPresentFlag
;
29 BOOLEAN TPMDeactivatedFlag
;
30 } TCG_BOOT_SERVICE_CAPABILITY
;
32 typedef struct tdTREE_BOOT_SERVICE_CAPABILITY
{
34 EFI_TCG2_VERSION StructureVersion
;
35 EFI_TCG2_VERSION ProtocolVersion
;
36 UINT32 HashAlgorithmBitmap
;
37 UINT32 SupportedEventLogs
;
38 BOOLEAN TrEEPresentFlag
;
39 UINT16 MaxCommandSize
;
40 UINT16 MaxResponseSize
;
41 UINT32 ManufacturerID
;
42 } TREE_BOOT_SERVICE_CAPABILITY
;
44 typedef UINT32 TCG_ALGORITHM_ID
;
45 #define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm
47 #define SHA1_DIGEST_SIZE 20
49 typedef struct _TCG_DIGEST
{
50 UINT8 Digest
[SHA1_DIGEST_SIZE
];
55 typedef struct _TCG_PCR_EVENT
{
58 struct _TCG_DIGEST digest
;
63 INTERFACE_DECL(_EFI_TCG
);
65 typedef EFI_STATUS(EFIAPI
* EFI_TCG_STATUS_CHECK
) (IN
struct _EFI_TCG
* This
,
66 OUT
struct _TCG_BOOT_SERVICE_CAPABILITY
* ProtocolCapability
,
67 OUT UINT32
* TCGFeatureFlags
,
68 OUT EFI_PHYSICAL_ADDRESS
* EventLogLocation
,
69 OUT EFI_PHYSICAL_ADDRESS
* EventLogLastEntry
);
71 typedef EFI_STATUS(EFIAPI
* EFI_TCG_HASH_ALL
) (IN
struct _EFI_TCG
* This
,
73 IN UINT64 HashDataLen
,
74 IN TCG_ALGORITHM_ID AlgorithmId
,
75 IN OUT UINT64
* HashedDataLen
, IN OUT UINT8
** HashedDataResult
);
77 typedef EFI_STATUS(EFIAPI
* EFI_TCG_LOG_EVENT
) (IN
struct _EFI_TCG
* This
,
78 IN
struct _TCG_PCR_EVENT
* TCGLogData
,
79 IN OUT UINT32
* EventNumber
, IN UINT32 Flags
);
81 typedef EFI_STATUS(EFIAPI
* EFI_TCG_PASS_THROUGH_TO_TPM
) (IN
struct _EFI_TCG
* This
,
82 IN UINT32 TpmInputParameterBlockSize
,
83 IN UINT8
* TpmInputParameterBlock
,
84 IN UINT32 TpmOutputParameterBlockSize
,
85 IN UINT8
* TpmOutputParameterBlock
);
87 typedef EFI_STATUS(EFIAPI
* EFI_TCG_HASH_LOG_EXTEND_EVENT
) (IN
struct _EFI_TCG
* This
,
88 IN EFI_PHYSICAL_ADDRESS HashData
,
89 IN UINT64 HashDataLen
,
90 IN TCG_ALGORITHM_ID AlgorithmId
,
91 IN
struct _TCG_PCR_EVENT
* TCGLogData
,
92 IN OUT UINT32
* EventNumber
,
93 OUT EFI_PHYSICAL_ADDRESS
* EventLogLastEntry
);
95 typedef struct _EFI_TCG
{
96 EFI_TCG_STATUS_CHECK StatusCheck
;
97 EFI_TCG_HASH_ALL HashAll
;
98 EFI_TCG_LOG_EVENT LogEvent
;
99 EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTPM
;
100 EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent
;
103 #define EFI_TCG2_PROTOCOL_GUID {0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }}
105 typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL
;
107 typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP
;
108 typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT
;
109 typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP
;
111 #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
112 #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002
114 typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY
{
116 EFI_TCG2_VERSION StructureVersion
;
117 EFI_TCG2_VERSION ProtocolVersion
;
118 EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap
;
119 EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs
;
120 BOOLEAN TPMPresentFlag
;
121 UINT16 MaxCommandSize
;
122 UINT16 MaxResponseSize
;
123 UINT32 ManufacturerID
;
124 UINT32 NumberOfPCRBanks
;
125 EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks
;
126 } EFI_TCG2_BOOT_SERVICE_CAPABILITY
;
128 #define EFI_TCG2_EVENT_HEADER_VERSION 1
132 UINT16 HeaderVersion
;
135 } __attribute__((packed
)) EFI_TCG2_EVENT_HEADER
;
137 typedef struct tdEFI_TCG2_EVENT
{
139 EFI_TCG2_EVENT_HEADER Header
;
141 } __attribute__((packed
)) EFI_TCG2_EVENT
;
143 typedef EFI_STATUS(EFIAPI
* EFI_TCG2_GET_CAPABILITY
) (IN EFI_TCG2_PROTOCOL
* This
,
144 IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY
* ProtocolCapability
);
146 typedef EFI_STATUS(EFIAPI
* EFI_TCG2_GET_EVENT_LOG
) (IN EFI_TCG2_PROTOCOL
* This
,
147 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
,
148 OUT EFI_PHYSICAL_ADDRESS
* EventLogLocation
,
149 OUT EFI_PHYSICAL_ADDRESS
* EventLogLastEntry
,
150 OUT BOOLEAN
* EventLogTruncated
);
152 typedef EFI_STATUS(EFIAPI
* EFI_TCG2_HASH_LOG_EXTEND_EVENT
) (IN EFI_TCG2_PROTOCOL
* This
,
154 IN EFI_PHYSICAL_ADDRESS DataToHash
,
155 IN UINT64 DataToHashLen
, IN EFI_TCG2_EVENT
* EfiTcgEvent
);
157 typedef EFI_STATUS(EFIAPI
* EFI_TCG2_SUBMIT_COMMAND
) (IN EFI_TCG2_PROTOCOL
* This
,
158 IN UINT32 InputParameterBlockSize
,
159 IN UINT8
* InputParameterBlock
,
160 IN UINT32 OutputParameterBlockSize
, IN UINT8
* OutputParameterBlock
);
162 typedef EFI_STATUS(EFIAPI
* EFI_TCG2_GET_ACTIVE_PCR_BANKS
) (IN EFI_TCG2_PROTOCOL
* This
, OUT UINT32
* ActivePcrBanks
);
164 typedef EFI_STATUS(EFIAPI
* EFI_TCG2_SET_ACTIVE_PCR_BANKS
) (IN EFI_TCG2_PROTOCOL
* This
, IN UINT32 ActivePcrBanks
);
166 typedef EFI_STATUS(EFIAPI
* EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS
) (IN EFI_TCG2_PROTOCOL
* This
,
167 OUT UINT32
* OperationPresent
, OUT UINT32
* Response
);
169 typedef struct tdEFI_TCG2_PROTOCOL
{
170 EFI_TCG2_GET_CAPABILITY GetCapability
;
171 EFI_TCG2_GET_EVENT_LOG GetEventLog
;
172 EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent
;
173 EFI_TCG2_SUBMIT_COMMAND SubmitCommand
;
174 EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks
;
175 EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks
;
176 EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks
;
179 static EFI_STATUS
tpm1_measure_to_pcr_and_event_log(const EFI_TCG
*tcg
, UINT32 pcrindex
, const EFI_PHYSICAL_ADDRESS buffer
,
180 UINTN buffer_size
, const CHAR16
*description
) {
182 TCG_PCR_EVENT
*tcg_event
;
184 EFI_PHYSICAL_ADDRESS event_log_last
;
187 desc_len
= (StrLen(description
) + 1) * sizeof(CHAR16
);
189 tcg_event
= AllocateZeroPool(desc_len
+ sizeof(TCG_PCR_EVENT
));
192 return EFI_OUT_OF_RESOURCES
;
194 tcg_event
->EventSize
= desc_len
;
195 CopyMem((VOID
*) & tcg_event
->Event
[0], (VOID
*) description
, desc_len
);
197 tcg_event
->PCRIndex
= pcrindex
;
198 tcg_event
->EventType
= EV_IPL
;
201 status
= uefi_call_wrapper(tcg
->HashLogExtendEvent
, 7,
202 (EFI_TCG
*) tcg
, buffer
, buffer_size
, TCG_ALG_SHA
, tcg_event
, &event_number
, &event_log_last
);
204 if (EFI_ERROR(status
))
207 uefi_call_wrapper(BS
->FreePool
, 1, tcg_event
);
213 * According to TCG EFI Protocol Specification for TPM 2.0 family,
214 * all events generated after the invocation of EFI_TCG2_GET_EVENT_LOG
215 * shall be stored in an instance of an EFI_CONFIGURATION_TABLE aka
216 * EFI TCG 2.0 final events table. Hence, it is necessary to trigger the
217 * internal switch through calling get_event_log() in order to allow
218 * to retrieve the logs from OS runtime.
220 static EFI_STATUS
trigger_tcg2_final_events_table(const EFI_TCG2
*tcg
, EFI_TCG2_EVENT_LOG_FORMAT log_fmt
)
222 EFI_PHYSICAL_ADDRESS loc
;
223 EFI_PHYSICAL_ADDRESS last_loc
;
225 return uefi_call_wrapper(tcg
->GetEventLog
, 5, (EFI_TCG2
*) tcg
,
226 log_fmt
, &loc
, &last_loc
, &truncated
);
229 static EFI_STATUS
tpm2_measure_to_pcr_and_event_log(const EFI_TCG2
*tcg
, UINT32 pcrindex
, const EFI_PHYSICAL_ADDRESS buffer
,
230 UINT64 buffer_size
, const CHAR16
*description
, EFI_TCG2_EVENT_LOG_FORMAT log_fmt
) {
232 EFI_TCG2_EVENT
*tcg_event
;
234 static BOOLEAN triggered
= FALSE
;
236 if (triggered
== FALSE
) {
237 status
= trigger_tcg2_final_events_table(tcg
, log_fmt
);
238 if (EFI_ERROR(status
))
244 desc_len
= StrLen(description
) * sizeof(CHAR16
);
246 tcg_event
= AllocateZeroPool(sizeof(*tcg_event
) - sizeof(tcg_event
->Event
) + desc_len
+ 1);
249 return EFI_OUT_OF_RESOURCES
;
251 tcg_event
->Size
= sizeof(*tcg_event
) - sizeof(tcg_event
->Event
) + desc_len
+ 1;
252 tcg_event
->Header
.HeaderSize
= sizeof(EFI_TCG2_EVENT_HEADER
);
253 tcg_event
->Header
.HeaderVersion
= EFI_TCG2_EVENT_HEADER_VERSION
;
254 tcg_event
->Header
.PCRIndex
= pcrindex
;
255 tcg_event
->Header
.EventType
= EV_IPL
;
257 CopyMem((VOID
*) tcg_event
->Event
, (VOID
*) description
, desc_len
);
259 status
= uefi_call_wrapper(tcg
->HashLogExtendEvent
, 5, (EFI_TCG2
*) tcg
, 0, buffer
, (UINT64
) buffer_size
, tcg_event
);
261 uefi_call_wrapper(BS
->FreePool
, 1, tcg_event
);
263 if (EFI_ERROR(status
))
269 static EFI_TCG
* tcg1_interface_check(void) {
270 EFI_GUID tpm_guid
= EFI_TCG_PROTOCOL_GUID
;
273 TCG_BOOT_SERVICE_CAPABILITY capability
;
275 EFI_PHYSICAL_ADDRESS event_log_location
;
276 EFI_PHYSICAL_ADDRESS event_log_last_entry
;
278 status
= LibLocateProtocol(&tpm_guid
, (void **) &tcg
);
280 if (EFI_ERROR(status
))
283 capability
.Size
= (UINT8
) sizeof(capability
);
284 status
= uefi_call_wrapper(tcg
->StatusCheck
, 5, tcg
, &capability
, &features
, &event_log_location
, &event_log_last_entry
);
286 if (EFI_ERROR(status
))
289 if (capability
.TPMDeactivatedFlag
)
292 if (!capability
.TPMPresentFlag
)
298 static EFI_TCG2
* tcg2_interface_check(EFI_TCG2_BOOT_SERVICE_CAPABILITY
*caps
) {
299 EFI_GUID tpm2_guid
= EFI_TCG2_PROTOCOL_GUID
;
303 status
= LibLocateProtocol(&tpm2_guid
, (void **) &tcg
);
305 if (EFI_ERROR(status
))
308 caps
->Size
= (UINT8
) sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY
);
309 status
= uefi_call_wrapper(tcg
->GetCapability
, 2, tcg
, caps
);
311 if (EFI_ERROR(status
))
314 if (caps
->StructureVersion
.Major
== 1 &&
315 caps
->StructureVersion
.Minor
== 0) {
316 TCG_BOOT_SERVICE_CAPABILITY
*caps_1_0
;
317 caps_1_0
= (TCG_BOOT_SERVICE_CAPABILITY
*)caps
;
318 if (caps_1_0
->TPMPresentFlag
)
322 if (!caps
->TPMPresentFlag
)
328 EFI_STATUS
tpm_log_event(UINT32 pcrindex
, const EFI_PHYSICAL_ADDRESS buffer
, UINTN buffer_size
, const CHAR16
*description
) {
331 EFI_TCG2_BOOT_SERVICE_CAPABILITY caps
;
333 tpm2
= tcg2_interface_check(&caps
);
335 EFI_TCG2_EVENT_LOG_BITMAP supported_logs
;
336 EFI_TCG2_EVENT_LOG_FORMAT log_fmt
;
338 if (caps
.StructureVersion
.Major
== 1 &&
339 caps
.StructureVersion
.Minor
== 0)
340 supported_logs
= ((TREE_BOOT_SERVICE_CAPABILITY
*)&caps
)->SupportedEventLogs
;
342 supported_logs
= caps
.SupportedEventLogs
;
344 if (supported_logs
& EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
)
345 log_fmt
= EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
;
347 log_fmt
= EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
;
349 return tpm2_measure_to_pcr_and_event_log(tpm2
, pcrindex
, buffer
, buffer_size
, description
, log_fmt
);
352 tpm1
= tcg1_interface_check();
354 return tpm1_measure_to_pcr_and_event_log(tpm1
, pcrindex
, buffer
, buffer_size
, description
);
356 /* No active TPM found, so don't return an error */