forked from pool/grub2
261 lines
8.5 KiB
Diff
261 lines
8.5 KiB
Diff
|
From 029c952f37dedb086c85bfb5fbc0de15cd4dbf0f Mon Sep 17 00:00:00 2001
|
||
|
From: Lu Ken <ken.lu@intel.com>
|
||
|
Date: Wed, 13 Jul 2022 10:06:12 +0800
|
||
|
Subject: [PATCH 3/3] efi/tpm: Add EFI_CC_MEASUREMENT_PROTOCOL support
|
||
|
|
||
|
The EFI_CC_MEASUREMENT_PROTOCOL abstracts the measurement for virtual firmware
|
||
|
in confidential computing environment. It is similar to the EFI_TCG2_PROTOCOL.
|
||
|
It was proposed by Intel and ARM and approved by UEFI organization.
|
||
|
|
||
|
It is defined in Intel GHCI specification: https://cdrdv2.intel.com/v1/dl/getContent/726790 .
|
||
|
The EDKII header file is available at https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/CcMeasurement.h .
|
||
|
|
||
|
Signed-off-by: Lu Ken <ken.lu@intel.com>
|
||
|
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||
|
---
|
||
|
grub-core/commands/efi/tpm.c | 48 +++++++++++
|
||
|
include/grub/efi/cc.h | 151 +++++++++++++++++++++++++++++++++++
|
||
|
2 files changed, 199 insertions(+)
|
||
|
create mode 100644 include/grub/efi/cc.h
|
||
|
|
||
|
diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
|
||
|
index e032617d8..630fd8a82 100644
|
||
|
--- a/grub-core/commands/efi/tpm.c
|
||
|
+++ b/grub-core/commands/efi/tpm.c
|
||
|
@@ -22,6 +22,7 @@
|
||
|
#include <grub/i18n.h>
|
||
|
#include <grub/efi/api.h>
|
||
|
#include <grub/efi/efi.h>
|
||
|
+#include <grub/efi/cc.h>
|
||
|
#include <grub/efi/tpm.h>
|
||
|
#include <grub/tpm2/tpm2.h>
|
||
|
#include <grub/mm.h>
|
||
|
@@ -32,6 +33,7 @@ typedef TCG_PCR_EVENT grub_tpm_event_t;
|
||
|
|
||
|
static grub_efi_guid_t tpm_guid = EFI_TPM_GUID;
|
||
|
static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID;
|
||
|
+static grub_efi_guid_t cc_measurement_guid = GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID;
|
||
|
|
||
|
static grub_efi_handle_t *grub_tpm_handle;
|
||
|
static grub_uint8_t grub_tpm_version;
|
||
|
@@ -308,6 +310,50 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||
|
return grub_efi_log_event_status (status);
|
||
|
}
|
||
|
|
||
|
+static void
|
||
|
+grub_cc_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
+ const char *description)
|
||
|
+{
|
||
|
+ grub_efi_cc_event_t *event;
|
||
|
+ grub_efi_status_t status;
|
||
|
+ grub_efi_cc_protocol_t *cc;
|
||
|
+ grub_efi_cc_mr_index_t mr;
|
||
|
+
|
||
|
+ cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL);
|
||
|
+ if (cc == NULL)
|
||
|
+ return;
|
||
|
+
|
||
|
+ status = efi_call_3 (cc->map_pcr_to_mr_index, cc, pcr, &mr);
|
||
|
+ if (status != GRUB_EFI_SUCCESS)
|
||
|
+ {
|
||
|
+ grub_efi_log_event_status (status);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ event = grub_zalloc (sizeof (grub_efi_cc_event_t) +
|
||
|
+ grub_strlen (description) + 1);
|
||
|
+ if (event == NULL)
|
||
|
+ {
|
||
|
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate CC event buffer"));
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ event->Header.HeaderSize = sizeof (grub_efi_cc_event_header_t);
|
||
|
+ event->Header.HeaderVersion = GRUB_EFI_CC_EVENT_HEADER_VERSION;
|
||
|
+ event->Header.MrIndex = mr;
|
||
|
+ event->Header.EventType = EV_IPL;
|
||
|
+ event->Size = sizeof (*event) + grub_strlen (description) + 1;
|
||
|
+ grub_strcpy ((char *) event->Event, description);
|
||
|
+
|
||
|
+ status = efi_call_5 (cc->hash_log_extend_event, cc, 0,
|
||
|
+ (grub_efi_physical_address_t)(grub_addr_t) buf,
|
||
|
+ (grub_efi_uint64_t) size, event);
|
||
|
+ grub_free (event);
|
||
|
+
|
||
|
+ if (status != GRUB_EFI_SUCCESS)
|
||
|
+ grub_efi_log_event_status (status);
|
||
|
+}
|
||
|
+
|
||
|
grub_err_t
|
||
|
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
const char *description)
|
||
|
@@ -315,6 +361,8 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
grub_efi_handle_t tpm_handle;
|
||
|
grub_efi_uint8_t protocol_version;
|
||
|
|
||
|
+ grub_cc_log_event(buf, size, pcr, description);
|
||
|
+
|
||
|
if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
|
||
|
return 0;
|
||
|
|
||
|
diff --git a/include/grub/efi/cc.h b/include/grub/efi/cc.h
|
||
|
new file mode 100644
|
||
|
index 000000000..896030689
|
||
|
--- /dev/null
|
||
|
+++ b/include/grub/efi/cc.h
|
||
|
@@ -0,0 +1,151 @@
|
||
|
+/*
|
||
|
+ * GRUB -- GRand Unified Bootloader
|
||
|
+ * Copyright (C) 2022 Free Software Foundation, Inc.
|
||
|
+ *
|
||
|
+ * GRUB is free software: you can redistribute it and/or modify
|
||
|
+ * it under the terms of the GNU General Public License as published by
|
||
|
+ * the Free Software Foundation, either version 3 of the License, or
|
||
|
+ * (at your option) any later version.
|
||
|
+ *
|
||
|
+ * GRUB is distributed in the hope that it will be useful,
|
||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU General Public License
|
||
|
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||
|
+ */
|
||
|
+
|
||
|
+#ifndef GRUB_EFI_CC_H
|
||
|
+#define GRUB_EFI_CC_H 1
|
||
|
+
|
||
|
+#include <grub/efi/api.h>
|
||
|
+#include <grub/efi/efi.h>
|
||
|
+#include <grub/err.h>
|
||
|
+
|
||
|
+#define GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID \
|
||
|
+ { 0x96751a3d, 0x72f4, 0x41a6, \
|
||
|
+ { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b } \
|
||
|
+ };
|
||
|
+
|
||
|
+struct grub_efi_cc_version
|
||
|
+{
|
||
|
+ grub_efi_uint8_t Major;
|
||
|
+ grub_efi_uint8_t Minor;
|
||
|
+};
|
||
|
+typedef struct grub_efi_cc_version grub_efi_cc_version_t;
|
||
|
+
|
||
|
+/* EFI_CC Type/SubType definition. */
|
||
|
+#define GRUB_EFI_CC_TYPE_NONE 0
|
||
|
+#define GRUB_EFI_CC_TYPE_SEV 1
|
||
|
+#define GRUB_EFI_CC_TYPE_TDX 2
|
||
|
+
|
||
|
+struct grub_efi_cc_type
|
||
|
+{
|
||
|
+ grub_efi_uint8_t Type;
|
||
|
+ grub_efi_uint8_t SubType;
|
||
|
+};
|
||
|
+typedef struct grub_efi_cc_type grub_efi_cc_type_t;
|
||
|
+
|
||
|
+typedef grub_efi_uint32_t grub_efi_cc_event_log_bitmap_t;
|
||
|
+typedef grub_efi_uint32_t grub_efi_cc_event_log_format_t;
|
||
|
+typedef grub_efi_uint32_t grub_efi_cc_event_algorithm_bitmap_t;
|
||
|
+typedef grub_efi_uint32_t grub_efi_cc_mr_index_t;
|
||
|
+
|
||
|
+/* Intel TDX measure register index. */
|
||
|
+#define GRUB_TDX_MR_INDEX_MRTD 0
|
||
|
+#define GRUB_TDX_MR_INDEX_RTMR0 1
|
||
|
+#define GRUB_TDX_MR_INDEX_RTMR1 2
|
||
|
+#define GRUB_TDX_MR_INDEX_RTMR2 3
|
||
|
+#define GRUB_TDX_MR_INDEX_RTMR3 4
|
||
|
+
|
||
|
+#define GRUB_EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002
|
||
|
+#define GRUB_EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004
|
||
|
+#define GRUB_EFI_CC_EVENT_HEADER_VERSION 1
|
||
|
+
|
||
|
+struct grub_efi_cc_event_header
|
||
|
+{
|
||
|
+ /* Size of the event header itself (sizeof(EFI_TD_EVENT_HEADER)). */
|
||
|
+ grub_efi_uint32_t HeaderSize;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Header version. For this version of this specification,
|
||
|
+ * the value shall be 1.
|
||
|
+ */
|
||
|
+ grub_efi_uint16_t HeaderVersion;
|
||
|
+
|
||
|
+ /* Index of the MR that shall be extended. */
|
||
|
+ grub_efi_cc_mr_index_t MrIndex;
|
||
|
+
|
||
|
+ /* Type of the event that shall be extended (and optionally logged). */
|
||
|
+ grub_efi_uint32_t EventType;
|
||
|
+} GRUB_PACKED;
|
||
|
+typedef struct grub_efi_cc_event_header grub_efi_cc_event_header_t;
|
||
|
+
|
||
|
+struct grub_efi_cc_event
|
||
|
+{
|
||
|
+ /* Total size of the event including the Size component, the header and the Event data. */
|
||
|
+ grub_efi_uint32_t Size;
|
||
|
+ grub_efi_cc_event_header_t Header;
|
||
|
+ grub_efi_uint8_t Event[0];
|
||
|
+} GRUB_PACKED;
|
||
|
+typedef struct grub_efi_cc_event grub_efi_cc_event_t;
|
||
|
+
|
||
|
+struct grub_efi_cc_boot_service_capability
|
||
|
+{
|
||
|
+ /* Allocated size of the structure. */
|
||
|
+ grub_efi_uint8_t Size;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Version of the grub_efi_cc_boot_service_capability_t structure itself.
|
||
|
+ * For this version of the protocol, the Major version shall be set to 1
|
||
|
+ * and the Minor version shall be set to 1.
|
||
|
+ */
|
||
|
+ grub_efi_cc_version_t StructureVersion;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Version of the EFI TD protocol.
|
||
|
+ * For this version of the protocol, the Major version shall be set to 1
|
||
|
+ * and the Minor version shall be set to 1.
|
||
|
+ */
|
||
|
+ grub_efi_cc_version_t ProtocolVersion;
|
||
|
+
|
||
|
+ /* Supported hash algorithms. */
|
||
|
+ grub_efi_cc_event_algorithm_bitmap_t HashAlgorithmBitmap;
|
||
|
+
|
||
|
+ /* Bitmap of supported event log formats. */
|
||
|
+ grub_efi_cc_event_log_bitmap_t SupportedEventLogs;
|
||
|
+
|
||
|
+ /* Indicates the CC type. */
|
||
|
+ grub_efi_cc_type_t CcType;
|
||
|
+};
|
||
|
+typedef struct grub_efi_cc_boot_service_capability grub_efi_cc_boot_service_capability_t;
|
||
|
+
|
||
|
+struct grub_efi_cc_protocol
|
||
|
+{
|
||
|
+ grub_efi_status_t
|
||
|
+ (*get_capability) (struct grub_efi_cc_protocol *this,
|
||
|
+ grub_efi_cc_boot_service_capability_t *ProtocolCapability);
|
||
|
+
|
||
|
+ grub_efi_status_t
|
||
|
+ (*get_event_log) (struct grub_efi_cc_protocol *this,
|
||
|
+ grub_efi_cc_event_log_format_t EventLogFormat,
|
||
|
+ grub_efi_physical_address_t *EventLogLocation,
|
||
|
+ grub_efi_physical_address_t *EventLogLastEntry,
|
||
|
+ grub_efi_boolean_t *EventLogTruncated);
|
||
|
+
|
||
|
+ grub_efi_status_t
|
||
|
+ (*hash_log_extend_event) (struct grub_efi_cc_protocol *this,
|
||
|
+ grub_efi_uint64_t Flags,
|
||
|
+ grub_efi_physical_address_t DataToHash,
|
||
|
+ grub_efi_uint64_t DataToHashLen,
|
||
|
+ grub_efi_cc_event_t *EfiCcEvent);
|
||
|
+
|
||
|
+ grub_efi_status_t
|
||
|
+ (*map_pcr_to_mr_index) (struct grub_efi_cc_protocol *this,
|
||
|
+ grub_efi_uint32_t PcrIndex,
|
||
|
+ grub_efi_cc_mr_index_t *MrIndex);
|
||
|
+};
|
||
|
+typedef struct grub_efi_cc_protocol grub_efi_cc_protocol_t;
|
||
|
+
|
||
|
+#endif
|
||
|
--
|
||
|
2.35.3
|
||
|
|