#include "macro-fundamental.h"
#include "measure.h"
#include "memory-util-fundamental.h"
+#include "proto/cc-measurement.h"
#include "proto/tcg.h"
#include "tpm2-pcr.h"
#include "util.h"
tcg_event);
}
+static EFI_STATUS cc_measure_to_mr_and_event_log(
+ EFI_CC_MEASUREMENT_PROTOCOL *cc,
+ uint32_t pcrindex,
+ EFI_PHYSICAL_ADDRESS buffer,
+ uint64_t buffer_size,
+ const char16_t *description) {
+
+ _cleanup_free_ EFI_CC_EVENT *event = NULL;
+ uint32_t mr;
+ EFI_STATUS err;
+ size_t desc_len;
+
+ assert(cc);
+ assert(description);
+
+ /* MapPcrToMrIndex service provides callers information on
+ * how the TPM PCR registers are mapped to the CC measurement
+ * registers (MR) in the vendor implementation. */
+ err = cc->MapPcrToMrIndex(cc, pcrindex, &mr);
+ if (err != EFI_SUCCESS)
+ return EFI_NOT_FOUND;
+
+ desc_len = strsize16(description);
+ event = xmalloc(offsetof(EFI_CC_EVENT, Event) + desc_len);
+ *event = (EFI_CC_EVENT) {
+ .Size = offsetof(EFI_CC_EVENT, Event) + desc_len,
+ .Header.HeaderSize = sizeof(EFI_CC_EVENT_HEADER),
+ .Header.HeaderVersion = EFI_CC_EVENT_HEADER_VERSION,
+ .Header.MrIndex = mr,
+ .Header.EventType = EV_IPL,
+ };
+
+ memcpy(event->Event, description, desc_len);
+
+ return cc->HashLogExtendEvent(
+ cc,
+ 0,
+ buffer,
+ buffer_size,
+ event);
+}
+
+static EFI_CC_MEASUREMENT_PROTOCOL *cc_interface_check(void) {
+ EFI_CC_BOOT_SERVICE_CAPABILITY capability = {
+ .Size = sizeof(capability),
+ };
+ EFI_STATUS err;
+ EFI_CC_MEASUREMENT_PROTOCOL *cc;
+
+ err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_CC_MEASUREMENT_PROTOCOL), NULL, (void **) &cc);
+ if (err != EFI_SUCCESS)
+ return NULL;
+
+ err = cc->GetCapability(cc, &capability);
+ if (err != EFI_SUCCESS)
+ return NULL;
+
+ if (!(capability.SupportedEventLogs & EFI_CC_EVENT_LOG_FORMAT_TCG_2))
+ return NULL;
+
+ return cc;
+}
+
static EFI_TCG_PROTOCOL *tcg1_interface_check(void) {
EFI_PHYSICAL_ADDRESS event_log_location, event_log_last_entry;
EFI_TCG_BOOT_SERVICE_CAPABILITY capability = {
if (tpm1)
err = tpm1_measure_to_pcr_and_event_log(tpm1, pcrindex, buffer, buffer_size, description);
else {
- /* No active TPM found, so don't return an error */
+ EFI_CC_MEASUREMENT_PROTOCOL *cc;
+
+ cc = cc_interface_check();
+ if (cc)
+ err = cc_measure_to_mr_and_event_log(cc, pcrindex, buffer, buffer_size, description);
+ else {
+ /* No active TPM found, so don't return an error */
- if (ret_measured)
- *ret_measured = false;
+ if (ret_measured)
+ *ret_measured = false;
- return EFI_SUCCESS;
+ return EFI_SUCCESS;
+ }
}
}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+/* The UEFI specification defines the interface between the confidential virtual guest OS and
+ * virtual firmware as EFI_CC_MEASUREMENT_PROTOCOL. The measurements are captured in the CC eventlog
+ * that follows the TCG2 format. TPM PCR registers are mapped to vendor specific measurement registers
+ * and the mapping can be queried using MapPcrToMrIndex service as part of the protocol.
+ *
+ * The "Confidential Computing" section in the UEFI specification covers the details. */
+
+#define EFI_CC_MEASUREMENT_PROTOCOL_GUID \
+ GUID_DEF(0x96751a3d, 0x72f4, 0x41a6, 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b)
+
+#define EFI_CC_EVENT_HEADER_VERSION 1
+#define EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002
+
+typedef struct {
+ uint8_t Type;
+ uint8_t SubType;
+} EFI_CC_TYPE;
+
+typedef struct {
+ uint8_t Major;
+ uint8_t Minor;
+} EFI_CC_VERSION;
+
+typedef struct {
+ uint8_t Size;
+ EFI_CC_VERSION StructureVersion;
+ EFI_CC_VERSION ProtocolVersion;
+ uint32_t HashAlgorithmBitmap;
+ uint32_t SupportedEventLogs;
+ EFI_CC_TYPE CcType;
+} EFI_CC_BOOT_SERVICE_CAPABILITY;
+
+typedef struct {
+ uint32_t HeaderSize;
+ uint16_t HeaderVersion;
+ uint32_t MrIndex;
+ uint32_t EventType;
+} _packed_ EFI_CC_EVENT_HEADER;
+
+typedef struct {
+ uint32_t Size;
+ EFI_CC_EVENT_HEADER Header;
+ uint8_t Event[];
+} _packed_ EFI_CC_EVENT;
+
+typedef struct EFI_CC_MEASUREMENT_PROTOCOL EFI_CC_MEASUREMENT_PROTOCOL;
+struct EFI_CC_MEASUREMENT_PROTOCOL {
+ EFI_STATUS (EFIAPI *GetCapability)(
+ EFI_CC_MEASUREMENT_PROTOCOL *This,
+ EFI_CC_BOOT_SERVICE_CAPABILITY *ProtocolCapability);
+ void *GetEventLog;
+ EFI_STATUS (EFIAPI *HashLogExtendEvent)(
+ EFI_CC_MEASUREMENT_PROTOCOL *This,
+ uint64_t Flags,
+ EFI_PHYSICAL_ADDRESS DataToHash,
+ uint64_t DataToHashLen,
+ EFI_CC_EVENT *EfiCcEvent);
+ EFI_STATUS (EFIAPI *MapPcrToMrIndex)(
+ EFI_CC_MEASUREMENT_PROTOCOL *This,
+ uint32_t PcrIndex,
+ uint32_t *MrIndex);
+};