You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
8.5 KiB
258 lines
8.5 KiB
From 0000000000000000000000000000000000000000 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] 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> |
|
(cherry picked from commit 4c76565b6cb885b7e144dc27f3612066844e2d19) |
|
--- |
|
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 bb59599721..ae09c1bf8b 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/mm.h> |
|
#include <grub/tpm.h> |
|
@@ -31,6 +32,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; |
|
@@ -221,6 +223,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) |
|
@@ -228,6 +274,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 0000000000..8960306890 |
|
--- /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
|
|
|