Blame SOURCES/0278-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch

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