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.
228 lines
7.8 KiB
228 lines
7.8 KiB
2 years ago
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Lu Ken <ken.lu@intel.com>
|
||
|
Date: Sat, 3 Jul 2021 10:50:37 -0400
|
||
|
Subject: [PATCH] Enable TDX measurement to RTMR register
|
||
|
|
||
|
Intel Trust Domain Extensions(Intel TDX) refers to an Intel technology
|
||
|
that extends Virtual Machine Extensions(VMX) and Multi-Key Total Memory
|
||
|
Encryption(MK-TME) with a new kind of virtual machine guest called a
|
||
|
Trust Domain(TD)[1]. A TD runs in a CPU mode that protects the confidentiality
|
||
|
of its memory contents and its CPU state from any other software, including
|
||
|
the hosting Virtual Machine Monitor (VMM).
|
||
|
|
||
|
Trust Domain Virtual Firmware (TDVF) is required to provide TD services to
|
||
|
the TD guest OS.[2] Its reference code is available at https://github.com/tianocore/edk2-staging/tree/TDVF.
|
||
|
|
||
|
To support TD measurement/attestation, TDs provide 4 RTMR registers like
|
||
|
TPM/TPM2 PCR as below:
|
||
|
- RTMR[0] is for TDVF configuration
|
||
|
- RTMR[1] is for the TD OS loader and kernel
|
||
|
- RTMR[2] is for the OS application
|
||
|
- RTMR[3] is reserved for special usage only
|
||
|
|
||
|
This patch adds TD Measurement protocol support along with TPM/TPM2 protocol.
|
||
|
|
||
|
References:
|
||
|
[1] https://software.intel.com/content/dam/develop/external/us/en/documents/tdx-whitepaper-v4.pdf
|
||
|
[2] https://software.intel.com/content/dam/develop/external/us/en/documents/tdx-virtual-firmware-design-guide-rev-1.pdf
|
||
|
|
||
|
Signed-off-by: Lu Ken <ken.lu@intel.com>
|
||
|
(cherry picked from commit 841a0977397cf12a5498d439b8aaf8bf28ff8544)
|
||
|
---
|
||
|
grub-core/Makefile.core.def | 1 +
|
||
|
grub-core/kern/efi/tdx.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
|
||
|
grub-core/kern/tpm.c | 4 +++
|
||
|
include/grub/efi/tdx.h | 26 +++++++++++++++++
|
||
|
include/grub/tdx.h | 36 +++++++++++++++++++++++
|
||
|
5 files changed, 137 insertions(+)
|
||
|
create mode 100644 grub-core/kern/efi/tdx.c
|
||
|
create mode 100644 include/grub/efi/tdx.h
|
||
|
create mode 100644 include/grub/tdx.h
|
||
|
|
||
|
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||
|
index 637d7203e3..2787d59c52 100644
|
||
|
--- a/grub-core/Makefile.core.def
|
||
|
+++ b/grub-core/Makefile.core.def
|
||
|
@@ -200,6 +200,7 @@ kernel = {
|
||
|
efi = kern/efi/acpi.c;
|
||
|
efi = kern/lockdown.c;
|
||
|
efi = lib/envblk.c;
|
||
|
+ efi = kern/efi/tdx.c;
|
||
|
efi = kern/efi/tpm.c;
|
||
|
i386_coreboot = kern/i386/pc/acpi.c;
|
||
|
i386_multiboot = kern/i386/pc/acpi.c;
|
||
|
diff --git a/grub-core/kern/efi/tdx.c b/grub-core/kern/efi/tdx.c
|
||
|
new file mode 100644
|
||
|
index 0000000000..3a49f8d117
|
||
|
--- /dev/null
|
||
|
+++ b/grub-core/kern/efi/tdx.c
|
||
|
@@ -0,0 +1,70 @@
|
||
|
+#include <grub/err.h>
|
||
|
+#include <grub/i18n.h>
|
||
|
+#include <grub/efi/api.h>
|
||
|
+#include <grub/efi/efi.h>
|
||
|
+#include <grub/efi/tpm.h>
|
||
|
+#include <grub/efi/tdx.h>
|
||
|
+#include <grub/mm.h>
|
||
|
+#include <grub/tpm.h>
|
||
|
+#include <grub/tdx.h>
|
||
|
+
|
||
|
+static grub_efi_guid_t tdx_guid = EFI_TDX_GUID;
|
||
|
+
|
||
|
+static inline grub_err_t grub_tdx_dprintf(grub_efi_status_t status)
|
||
|
+{
|
||
|
+ switch (status) {
|
||
|
+ case GRUB_EFI_SUCCESS:
|
||
|
+ return 0;
|
||
|
+ case GRUB_EFI_DEVICE_ERROR:
|
||
|
+ grub_dprintf ("tdx", "Command failed: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
||
|
+ status);
|
||
|
+ return GRUB_ERR_IO;
|
||
|
+ case GRUB_EFI_INVALID_PARAMETER:
|
||
|
+ grub_dprintf ("tdx", "Invalid parameter: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
||
|
+ status);
|
||
|
+ return GRUB_ERR_BAD_ARGUMENT;
|
||
|
+ case GRUB_EFI_VOLUME_FULL:
|
||
|
+ grub_dprintf ("tdx", "Volume is full: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
||
|
+ status);
|
||
|
+ return GRUB_ERR_BAD_ARGUMENT;
|
||
|
+ case GRUB_EFI_UNSUPPORTED:
|
||
|
+ grub_dprintf ("tdx", "TDX unavailable: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
||
|
+ status);
|
||
|
+ return GRUB_ERR_UNKNOWN_DEVICE;
|
||
|
+ default:
|
||
|
+ grub_dprintf ("tdx", "Unknown TDX error: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
||
|
+ status);
|
||
|
+ return GRUB_ERR_UNKNOWN_DEVICE;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+grub_err_t
|
||
|
+grub_tdx_log_event(unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
+ const char *description)
|
||
|
+{
|
||
|
+ EFI_TCG2_EVENT *event;
|
||
|
+ grub_efi_status_t status;
|
||
|
+ grub_efi_tdx_protocol_t *tdx;
|
||
|
+
|
||
|
+ tdx = grub_efi_locate_protocol (&tdx_guid, NULL);
|
||
|
+
|
||
|
+ if (!tdx)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ event = grub_zalloc(sizeof (EFI_TCG2_EVENT) + grub_strlen(description) + 1);
|
||
|
+ if (!event)
|
||
|
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||
|
+ N_("cannot allocate TCG2 event buffer"));
|
||
|
+
|
||
|
+ event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
|
||
|
+ event->Header.HeaderVersion = 1;
|
||
|
+ event->Header.PCRIndex = pcr;
|
||
|
+ event->Header.EventType = EV_IPL;
|
||
|
+ event->Size = sizeof(*event) - sizeof(event->Event) + grub_strlen(description) + 1;
|
||
|
+ grub_memcpy(event->Event, description, grub_strlen(description) + 1);
|
||
|
+
|
||
|
+ status = efi_call_5 (tdx->hash_log_extend_event, tdx, 0, (unsigned long) buf,
|
||
|
+ (grub_uint64_t) size, event);
|
||
|
+
|
||
|
+ return grub_tdx_dprintf(status);
|
||
|
+}
|
||
|
\ No newline at end of file
|
||
|
diff --git a/grub-core/kern/tpm.c b/grub-core/kern/tpm.c
|
||
|
index e5e8fced62..71cc4252c1 100644
|
||
|
--- a/grub-core/kern/tpm.c
|
||
|
+++ b/grub-core/kern/tpm.c
|
||
|
@@ -4,6 +4,7 @@
|
||
|
#include <grub/mm.h>
|
||
|
#include <grub/tpm.h>
|
||
|
#include <grub/term.h>
|
||
|
+#include <grub/tdx.h>
|
||
|
|
||
|
grub_err_t
|
||
|
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
@@ -13,6 +14,9 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
char *desc = grub_xasprintf("%s %s", kind, description);
|
||
|
if (!desc)
|
||
|
return GRUB_ERR_OUT_OF_MEMORY;
|
||
|
+
|
||
|
+ grub_tdx_log_event(buf, size, pcr, desc);
|
||
|
+
|
||
|
ret = grub_tpm_log_event(buf, size, pcr, desc);
|
||
|
grub_free(desc);
|
||
|
return ret;
|
||
|
diff --git a/include/grub/efi/tdx.h b/include/grub/efi/tdx.h
|
||
|
new file mode 100644
|
||
|
index 0000000000..9bdac2a275
|
||
|
--- /dev/null
|
||
|
+++ b/include/grub/efi/tdx.h
|
||
|
@@ -0,0 +1,26 @@
|
||
|
+/*
|
||
|
+ * GRUB -- GRand Unified Bootloader
|
||
|
+ * Copyright (C) 2015 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_TDX_HEADER
|
||
|
+#define GRUB_EFI_TDX_HEADER 1
|
||
|
+
|
||
|
+#define EFI_TDX_GUID {0x96751a3d, 0x72f4, 0x41a6, {0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b}};
|
||
|
+
|
||
|
+typedef grub_efi_tpm2_protocol_t grub_efi_tdx_protocol_t;
|
||
|
+
|
||
|
+#endif
|
||
|
\ No newline at end of file
|
||
|
diff --git a/include/grub/tdx.h b/include/grub/tdx.h
|
||
|
new file mode 100644
|
||
|
index 0000000000..4a98008e39
|
||
|
--- /dev/null
|
||
|
+++ b/include/grub/tdx.h
|
||
|
@@ -0,0 +1,36 @@
|
||
|
+/*
|
||
|
+ * GRUB -- GRand Unified Bootloader
|
||
|
+ * Copyright (C) 2015 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_TDX_HEADER
|
||
|
+#define GRUB_TDX_HEADER 1
|
||
|
+
|
||
|
+#if defined (GRUB_MACHINE_EFI)
|
||
|
+grub_err_t grub_tdx_log_event(unsigned char *buf, grub_size_t size,
|
||
|
+ grub_uint8_t pcr, const char *description);
|
||
|
+#else
|
||
|
+static inline grub_err_t grub_tdx_log_event(
|
||
|
+ unsigned char *buf __attribute__ ((unused)),
|
||
|
+ grub_size_t size __attribute__ ((unused)),
|
||
|
+ grub_uint8_t pcr __attribute__ ((unused)),
|
||
|
+ const char *description __attribute__ ((unused)))
|
||
|
+{
|
||
|
+ return 0;
|
||
|
+};
|
||
|
+#endif
|
||
|
+
|
||
|
+#endif
|