2020-09-24 15:03:31

by Ross Philipson

[permalink] [raw]
Subject: [PATCH 00/13] x86: Trenchboot secure dynamic launch Linux kernel support

The Trenchboot project focus on boot security has led to the enabling of
the Linux kernel to be directly invocable by the x86 Dynamic Launch
instruction(s) for establishing a Dynamic Root of Trust for Measurement
(DRTM). The dynamic launch will be initiated by a boot loader with
associated support added to it, for example the first targeted boot
loader will be GRUB2. An integral part of establishing the DRTM involves
measuring everything that is intended to be run (kernel image, initrd,
etc) and everything that will configure that kernel to run (command
line, boot params, etc) into specific PCRs, the DRTM PCRs (17-22), in
the TPM. Another key aspect is the dynamic launch is rooted in hardware,
that is to say the hardware (CPU) is what takes the first measurement
for the chain of integrity measurements. On Intel this is done using
the GETSEC instruction provided by Intel's TXT and the SKINIT
instruction provided by AMD's AMD-V. Information on these technologies
can be readily found online. This patchset introduces Intel TXT support.

To enable the kernel to be launched by GETSEC, a stub must be built
into the setup section of the compressed kernel to handle the specific
state that the dynamic launch process leaves the BSP in. This is
analogous to the EFI stub that is found in the same area. Also this stub
must measure everything that is going to be used as early as possible.
This stub code and subsequent code must also deal with the specific
state that the dynamic launch leaves the APs in.

A quick note on terminology. The larger open source project itself is
called Trenchboot, which is hosted on Github (links below). The kernel
feature enabling the use of the x86 technology is referred to as "Secure
Launch" within the kernel code. As such the prefixes sl_/SL_ or
slaunch/SLAUNCH will be seen in the code. The stub code discussed above
is referred to as the SL stub.

The basic flow is:

- Entry from the dynamic launch jumps to the SL stub
- SL stub fixes up the world on the BSP
- For TXT, SL stub wakes the APs, fixes up their worlds
- For TXT, APs are left halted waiting for an NMI to wake them
- SL stub jumps to startup_32
- SL main runs to measure configuration and module information into the
DRTM PCRs. It also locates the TPM event log.
- Kernel boot proceeds normally from this point.
- During early setup, slaunch_setup() runs to finish some validation
and setup tasks.
- The SMP bringup code is modified to wake the waiting APs. APs vector
to rmpiggy and start up normally from that point.
- Kernel boot finishes booting normally
- SL securityfs module is present to allow reading and writing of the
TPM event log.
- SEXIT support to leave SMX mode is present on the kexec path and
the various reboot paths (poweroff, reset, halt).

Links:

The Trenchboot project including documentation:

https://github.com/trenchboot

Intel TXT is documented in its own specification and in the SDM Instruction Set volume:

https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf
https://software.intel.com/en-us/articles/intel-sdm

AMD SKINIT is documented in the System Programming manual:

https://www.amd.com/system/files/TechDocs/24593.pdf

GRUB2 pre-launch support patchset (WIP):

https://lists.gnu.org/archive/html/grub-devel/2020-05/msg00011.html

Thanks
Ross Philipson and Daniel P. Smith

Daniel P. Smith (4):
x86: Add early TPM TIS/CRB interface support for Secure Launch
x86: Add early TPM1.2/TPM2.0 interface support for Secure Launch
x86: Add early general TPM interface support for Secure Launch
x86: Secure Launch adding event log securityfs

Ross Philipson (9):
x86: Secure Launch Kconfig
x86: Secure Launch main header file
x86: Add early SHA support for Secure Launch early measurements
x86: Secure Launch kernel early boot stub
x86: Secure Launch kernel late boot stub
x86: Secure Launch SMP bringup support
kexec: Secure Launch kexec SEXIT support
reboot: Secure Launch SEXIT support on reboot paths
tpm: Allow locality 2 to be set when initializing the TPM for Secure
Launch

Documentation/x86/boot.rst | 9 +
arch/x86/Kconfig | 36 ++
arch/x86/boot/compressed/Makefile | 8 +
arch/x86/boot/compressed/early_sha1.c | 104 ++++
arch/x86/boot/compressed/early_sha1.h | 17 +
arch/x86/boot/compressed/early_sha256.c | 6 +
arch/x86/boot/compressed/early_sha512.c | 6 +
arch/x86/boot/compressed/head_64.S | 34 +
arch/x86/boot/compressed/kernel_info.S | 7 +
arch/x86/boot/compressed/sl_main.c | 390 ++++++++++++
arch/x86/boot/compressed/sl_stub.S | 606 ++++++++++++++++++
arch/x86/boot/compressed/tpm/crb.c | 304 +++++++++
arch/x86/boot/compressed/tpm/crb.h | 20 +
arch/x86/boot/compressed/tpm/tis.c | 215 +++++++
arch/x86/boot/compressed/tpm/tis.h | 46 ++
arch/x86/boot/compressed/tpm/tpm.c | 145 +++++
arch/x86/boot/compressed/tpm/tpm.h | 48 ++
arch/x86/boot/compressed/tpm/tpm1.h | 112 ++++
arch/x86/boot/compressed/tpm/tpm1_cmds.c | 99 +++
arch/x86/boot/compressed/tpm/tpm2.h | 89 +++
arch/x86/boot/compressed/tpm/tpm2_auth.c | 44 ++
arch/x86/boot/compressed/tpm/tpm2_auth.h | 21 +
arch/x86/boot/compressed/tpm/tpm2_cmds.c | 145 +++++
arch/x86/boot/compressed/tpm/tpm2_constants.h | 66 ++
arch/x86/boot/compressed/tpm/tpm_buff.c | 121 ++++
arch/x86/boot/compressed/tpm/tpm_common.h | 127 ++++
arch/x86/boot/compressed/tpm/tpmbuff.h | 34 +
arch/x86/boot/compressed/tpm/tpmio.c | 51 ++
arch/x86/include/asm/realmode.h | 3 +
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/asm-offsets.c | 16 +
arch/x86/kernel/reboot.c | 10 +
arch/x86/kernel/setup.c | 3 +
arch/x86/kernel/slaunch.c | 856 ++++++++++++++++++++++++++
arch/x86/kernel/smpboot.c | 86 +++
arch/x86/realmode/rm/header.S | 3 +
arch/x86/realmode/rm/trampoline_64.S | 37 ++
drivers/char/tpm/tpm-chip.c | 13 +-
drivers/iommu/intel/dmar.c | 4 +
include/linux/sha512.h | 21 +
include/linux/slaunch.h | 544 ++++++++++++++++
kernel/kexec_core.c | 4 +
lib/sha1.c | 4 +
lib/sha512.c | 209 +++++++
44 files changed, 4722 insertions(+), 2 deletions(-)
create mode 100644 arch/x86/boot/compressed/early_sha1.c
create mode 100644 arch/x86/boot/compressed/early_sha1.h
create mode 100644 arch/x86/boot/compressed/early_sha256.c
create mode 100644 arch/x86/boot/compressed/early_sha512.c
create mode 100644 arch/x86/boot/compressed/sl_main.c
create mode 100644 arch/x86/boot/compressed/sl_stub.S
create mode 100644 arch/x86/boot/compressed/tpm/crb.c
create mode 100644 arch/x86/boot/compressed/tpm/crb.h
create mode 100644 arch/x86/boot/compressed/tpm/tis.c
create mode 100644 arch/x86/boot/compressed/tpm/tis.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm.c
create mode 100644 arch/x86/boot/compressed/tpm/tpm.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm1.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm1_cmds.c
create mode 100644 arch/x86/boot/compressed/tpm/tpm2.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm2_auth.c
create mode 100644 arch/x86/boot/compressed/tpm/tpm2_auth.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm2_cmds.c
create mode 100644 arch/x86/boot/compressed/tpm/tpm2_constants.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm_buff.c
create mode 100644 arch/x86/boot/compressed/tpm/tpm_common.h
create mode 100644 arch/x86/boot/compressed/tpm/tpmbuff.h
create mode 100644 arch/x86/boot/compressed/tpm/tpmio.c
create mode 100644 arch/x86/kernel/slaunch.c
create mode 100644 include/linux/sha512.h
create mode 100644 include/linux/slaunch.h
create mode 100644 lib/sha512.c

--
1.8.3.1


2020-09-24 15:03:38

by Ross Philipson

[permalink] [raw]
Subject: [PATCH 05/13] x86: Add early TPM1.2/TPM2.0 interface support for Secure Launch

From: "Daniel P. Smith" <[email protected]>

This commit introduces an abstraction for TPM1.2 and TPM2.0 devices
above the TPM hardware interface.

Signed-off-by: Daniel P. Smith <[email protected]>
Signed-off-by: Ross Philipson <[email protected]>
---
arch/x86/boot/compressed/Makefile | 3 +-
arch/x86/boot/compressed/tpm/tpm1.h | 112 ++++++++++++++++++++
arch/x86/boot/compressed/tpm/tpm1_cmds.c | 99 ++++++++++++++++++
arch/x86/boot/compressed/tpm/tpm2.h | 89 ++++++++++++++++
arch/x86/boot/compressed/tpm/tpm2_auth.c | 44 ++++++++
arch/x86/boot/compressed/tpm/tpm2_auth.h | 21 ++++
arch/x86/boot/compressed/tpm/tpm2_cmds.c | 145 ++++++++++++++++++++++++++
arch/x86/boot/compressed/tpm/tpm2_constants.h | 66 ++++++++++++
8 files changed, 578 insertions(+), 1 deletion(-)
create mode 100644 arch/x86/boot/compressed/tpm/tpm1.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm1_cmds.c
create mode 100644 arch/x86/boot/compressed/tpm/tpm2.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm2_auth.c
create mode 100644 arch/x86/boot/compressed/tpm/tpm2_auth.h
create mode 100644 arch/x86/boot/compressed/tpm/tpm2_cmds.c
create mode 100644 arch/x86/boot/compressed/tpm/tpm2_constants.h

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 5515afa..a4308d5 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -100,7 +100,8 @@ vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/early_sha1.o
vmlinux-objs-$(CONFIG_SECURE_LAUNCH_SHA256) += $(obj)/early_sha256.o
vmlinux-objs-$(CONFIG_SECURE_LAUNCH_SHA512) += $(obj)/early_sha512.o
vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/tpm/tpmio.o $(obj)/tpm/tpm_buff.o \
- $(obj)/tpm/tis.o $(obj)/tpm/crb.o
+ $(obj)/tpm/tis.o $(obj)/tpm/crb.o $(obj)/tpm/tpm1_cmds.o \
+ $(obj)/tpm/tpm2_cmds.o $(obj)/tpm/tpm2_auth.o

# The compressed kernel is built with -fPIC/-fPIE so that a boot loader
# can place it anywhere in memory and it will still run. However, since
diff --git a/arch/x86/boot/compressed/tpm/tpm1.h b/arch/x86/boot/compressed/tpm/tpm1.h
new file mode 100644
index 0000000..498fa45
--- /dev/null
+++ b/arch/x86/boot/compressed/tpm/tpm1.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Apertus Solutions, LLC
+ *
+ * Author(s):
+ * Daniel P. Smith <[email protected]>
+ *
+ * The definitions in this header are extracted from the Trusted Computing
+ * Group's "TPM Main Specification", Parts 1-3.
+ *
+ */
+
+#ifndef _TPM1_H
+#define _TPM1_H
+
+#include "tpm.h"
+
+/* Section 2.2.3 */
+#define TPM_AUTH_DATA_USAGE u8
+#define TPM_PAYLOAD_TYPE u8
+#define TPM_VERSION_BYTE u8
+#define TPM_TAG u16
+#define TPM_PROTOCOL_ID u16
+#define TPM_STARTUP_TYPE u16
+#define TPM_ENC_SCHEME u16
+#define TPM_SIG_SCHEME u16
+#define TPM_MIGRATE_SCHEME u16
+#define TPM_PHYSICAL_PRESENCE u16
+#define TPM_ENTITY_TYPE u16
+#define TPM_KEY_USAGE u16
+#define TPM_EK_TYPE u16
+#define TPM_STRUCTURE_TAG u16
+#define TPM_PLATFORM_SPECIFIC u16
+#define TPM_COMMAND_CODE u32
+#define TPM_CAPABILITY_AREA u32
+#define TPM_KEY_FLAGS u32
+#define TPM_ALGORITHM_ID u32
+#define TPM_MODIFIER_INDICATOR u32
+#define TPM_ACTUAL_COUNT u32
+#define TPM_TRANSPORT_ATTRIBUTES u32
+#define TPM_AUTHHANDLE u32
+#define TPM_DIRINDEX u32
+#define TPM_KEY_HANDLE u32
+#define TPM_PCRINDEX u32
+#define TPM_RESULT u32
+#define TPM_RESOURCE_TYPE u32
+#define TPM_KEY_CONTROL u32
+#define TPM_NV_INDEX u32 The
+#define TPM_FAMILY_ID u32
+#define TPM_FAMILY_VERIFICATION u32
+#define TPM_STARTUP_EFFECTS u32
+#define TPM_SYM_MODE u32
+#define TPM_FAMILY_FLAGS u32
+#define TPM_DELEGATE_INDEX u32
+#define TPM_CMK_DELEGATE u32
+#define TPM_COUNT_ID u32
+#define TPM_REDIT_COMMAND u32
+#define TPM_TRANSHANDLE u32
+#define TPM_HANDLE u32
+#define TPM_FAMILY_OPERATION u32
+
+/* Section 6 */
+#define TPM_TAG_RQU_COMMAND 0x00C1
+#define TPM_TAG_RQU_AUTH1_COMMAND 0x00C2
+#define TPM_TAG_RQU_AUTH2_COMMAND 0x00C3
+#define TPM_TAG_RSP_COMMAND 0x00C4
+#define TPM_TAG_RSP_AUTH1_COMMAND 0x00C5
+#define TPM_TAG_RSP_AUTH2_COMMAND 0x00C6
+
+/* Section 16 */
+#define TPM_SUCCESS 0x0
+
+/* Section 17 */
+#define TPM_ORD_EXTEND 0x00000014
+
+#define SHA1_DIGEST_SIZE 20
+
+/* Section 5.4 */
+struct tpm_sha1_digest {
+ u8 digest[SHA1_DIGEST_SIZE];
+};
+struct tpm_digest {
+ TPM_PCRINDEX pcr;
+ union {
+ struct tpm_sha1_digest sha1;
+ } digest;
+};
+
+#define TPM_DIGEST struct tpm_sha1_digest
+#define TPM_CHOSENID_HASH TPM_DIGEST
+#define TPM_COMPOSITE_HASH TPM_DIGEST
+#define TPM_DIRVALUE TPM_DIGEST
+#define TPM_HMAC TPM_DIGEST
+#define TPM_PCRVALUE TPM_DIGEST
+#define TPM_AUDITDIGEST TPM_DIGEST
+#define TPM_DAA_TPM_SEED TPM_DIGEST
+#define TPM_DAA_CONTEXT_SEED TPM_DIGEST
+
+struct tpm_extend_cmd {
+ TPM_PCRINDEX pcr_num;
+ TPM_DIGEST digest;
+};
+
+struct tpm_extend_resp {
+ TPM_COMMAND_CODE ordinal;
+ TPM_PCRVALUE digest;
+};
+
+/* TPM Commands */
+int tpm1_pcr_extend(struct tpm *t, struct tpm_digest *d);
+
+#endif
diff --git a/arch/x86/boot/compressed/tpm/tpm1_cmds.c b/arch/x86/boot/compressed/tpm/tpm1_cmds.c
new file mode 100644
index 0000000..2d8c9e5
--- /dev/null
+++ b/arch/x86/boot/compressed/tpm/tpm1_cmds.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Apertus Solutions, LLC
+ *
+ * Author(s):
+ * Daniel P. Smith <[email protected]>
+ *
+ * The code in this file is based on the article "Writing a TPM Device Driver"
+ * published on http://ptgmedia.pearsoncmg.com.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/byteorder.h>
+#include "tpm.h"
+#include "tpmbuff.h"
+#include "tis.h"
+#include "tpm_common.h"
+#include "tpm1.h"
+
+int tpm1_pcr_extend(struct tpm *t, struct tpm_digest *d)
+{
+ int ret = 0;
+ struct tpmbuff *b = t->buff;
+ struct tpm_header *hdr;
+ struct tpm_extend_cmd *cmd;
+ size_t size;
+
+ if (b == NULL) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* ensure buffer is free for use */
+ tpmb_free(b);
+
+ hdr = (struct tpm_header *)tpmb_reserve(b);
+ if (!hdr) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+
+ hdr->tag = cpu_to_be16(TPM_TAG_RQU_COMMAND);
+ hdr->code = cpu_to_be32(TPM_ORD_EXTEND);
+
+ cmd = (struct tpm_extend_cmd *)
+ tpmb_put(b, sizeof(struct tpm_extend_cmd));
+ if (cmd == NULL) {
+ ret = -ENOMEM;
+ goto free;
+ }
+
+ cmd->pcr_num = cpu_to_be32(d->pcr);
+ memcpy(&(cmd->digest), &(d->digest), sizeof(TPM_DIGEST));
+
+ hdr->size = cpu_to_be32(tpmb_size(b));
+
+ if (be32_to_cpu(hdr->size) != t->ops.send(b)) {
+ ret = -EAGAIN;
+ goto free;
+ }
+
+ /* Reset buffer for receive */
+ tpmb_trim(b, tpmb_size(b));
+
+ hdr = (struct tpm_header *)b->head;
+ tpmb_put(b, sizeof(struct tpm_header));
+
+ /*
+ * The extend receive operation returns a struct tpm_extend_resp
+ * but the current implementation ignores the returned PCR value.
+ */
+
+ /* recv() will increase the buffer size */
+ size = t->ops.recv(t->family, b);
+ if (tpmb_size(b) != size) {
+ ret = -EAGAIN;
+ goto free;
+ }
+
+ /*
+ * On return, the code field is used for the return code out. Though
+ * the commands specifications section 16.1 implies there is an
+ * ordinal field, the return size and values point to this being
+ * incorrect.
+ *
+ * Also tis_recv() converts the header back to CPU endianness.
+ */
+ if (hdr->code != TPM_SUCCESS)
+ ret = -EAGAIN;
+
+free:
+ tpmb_free(b);
+out:
+ return ret;
+}
diff --git a/arch/x86/boot/compressed/tpm/tpm2.h b/arch/x86/boot/compressed/tpm/tpm2.h
new file mode 100644
index 0000000..4bc64f5
--- /dev/null
+++ b/arch/x86/boot/compressed/tpm/tpm2.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Apertus Solutions, LLC
+ *
+ * Author(s):
+ * Daniel P. Smith <[email protected]>
+ *
+ * The definitions in this header are extracted and/or dervied from the
+ * Trusted Computing Group's TPM 2.0 Library Specification Parts 1&2.
+ *
+ */
+
+#ifndef _TPM2_H
+#define _TPM2_H
+
+#include "tpm_common.h"
+#include "tpm2_constants.h"
+
+
+/* Table 192 Definition of TPM2B_TEMPLATE Structure:
+ * Using this as the base structure similar to the spec
+ */
+struct tpm2b {
+ u16 size;
+ u8 buffer[0];
+};
+
+// Table 32 Definition of TPMA_SESSION Bits < IN/OUT>
+struct tpma_session {
+ u8 continue_session : 1;
+ u8 audit_exclusive : 1;
+ u8 audit_reset : 1;
+ u8 reserved3_4 : 2;
+ u8 decrypt : 1;
+ u8 encrypt : 1;
+ u8 audit : 1;
+};
+
+
+// Table 72 Definition of TPMT_HA Structure < IN/OUT>
+struct tpmt_ha {
+ u16 alg; /* TPMI_ALG_HASH */
+ u8 digest[0]; /* TPMU_HA */
+};
+
+// Table 100 Definition of TPML_DIGEST_VALUES Structure
+struct tpml_digest_values {
+ u32 count;
+ struct tpmt_ha digests[0];
+};
+
+
+// Table 124 Definition of TPMS_AUTH_COMMAND Structure < IN>
+struct tpms_auth_cmd {
+ u32 *handle;
+ struct tpm2b *nonce;
+ struct tpma_session *attributes;
+ struct tpm2b *hmac;
+};
+
+// Table 125 Definition of TPMS_AUTH_RESPONSE Structure < OUT>
+struct tpms_auth_resp {
+ struct tpm2b *nonce;
+ struct tpma_session *attributes;
+ struct tpm2b *hmac;
+};
+
+struct tpm2_cmd {
+ struct tpm_header *header;
+ u32 *handles; /* TPM Handles array */
+ u32 *auth_size; /* Size of Auth Area */
+ u8 *auth; /* Authorization Area */
+ u8 *params; /* Parameters */
+ u8 *raw; /* internal raw buffer */
+};
+
+struct tpm2_resp {
+ struct tpm_header *header;
+ u32 *handles; /* TPM Handles array */
+ u32 *param_size; /* Size of Parameters */
+ struct tpm2b *params; /* Parameters */
+ u8 *auth; /* Authorization Area */
+ u8 *raw; /* internal raw buffer */
+};
+
+int tpm2_extend_pcr(struct tpm *t, u32 pcr,
+ struct tpml_digest_values *digests);
+
+#endif
diff --git a/arch/x86/boot/compressed/tpm/tpm2_auth.c b/arch/x86/boot/compressed/tpm/tpm2_auth.c
new file mode 100644
index 0000000..016ecc1
--- /dev/null
+++ b/arch/x86/boot/compressed/tpm/tpm2_auth.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Apertus Solutions, LLC
+ *
+ * Author(s):
+ * Daniel P. Smith <[email protected]>
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/const.h>
+#include <linux/string.h>
+#include <asm/byteorder.h>
+#include "tpm.h"
+#include "tpmbuff.h"
+#include "tpm2.h"
+#include "tpm2_constants.h"
+
+#define NULL_AUTH_SIZE 9
+
+u32 tpm2_null_auth_size(void)
+{
+ return NULL_AUTH_SIZE;
+}
+
+u8 *tpm2_null_auth(struct tpmbuff *b)
+{
+ u32 *handle;
+ u8 *auth = (u8 *)tpmb_put(b, NULL_AUTH_SIZE);
+
+ if (!auth)
+ return NULL;
+
+ memset(auth, 0, NULL_AUTH_SIZE);
+
+ /*
+ * The handle, the first element, is the
+ * only non-zero value in a NULL auth
+ */
+ handle = (u32 *)auth;
+ *handle = cpu_to_be32(TPM_RS_PW);
+
+ return auth;
+}
diff --git a/arch/x86/boot/compressed/tpm/tpm2_auth.h b/arch/x86/boot/compressed/tpm/tpm2_auth.h
new file mode 100644
index 0000000..1d4421c
--- /dev/null
+++ b/arch/x86/boot/compressed/tpm/tpm2_auth.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Apertus Solutions, LLC
+ *
+ * Author(s):
+ * Daniel P. Smith <[email protected]>
+ *
+ * The definitions in this header are extracted and/or dervied from the
+ * Trusted Computing Group's TPM 2.0 Library Specification Parts 1&2.
+ *
+ */
+
+#ifndef _TPM2_AUTH_H
+#define _TPM2_AUTH_H
+
+#include "tpm2.h"
+
+u32 tpm2_null_auth_size(void);
+u8 *tpm2_null_auth(struct tpmbuff *b);
+
+#endif
diff --git a/arch/x86/boot/compressed/tpm/tpm2_cmds.c b/arch/x86/boot/compressed/tpm/tpm2_cmds.c
new file mode 100644
index 0000000..8e79f9e
--- /dev/null
+++ b/arch/x86/boot/compressed/tpm/tpm2_cmds.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Apertus Solutions, LLC
+ *
+ * Author(s):
+ * Daniel P. Smith <[email protected]>
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/const.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <asm/byteorder.h>
+#include "tpm.h"
+#include "tpmbuff.h"
+#include "tpm_common.h"
+#include "tpm2.h"
+#include "tpm2_auth.h"
+#include "tis.h"
+#include "crb.h"
+
+static int tpm2_alloc_cmd(struct tpmbuff *b, struct tpm2_cmd *c, u16 tag,
+ u32 code)
+{
+ /* ensure buffer is free for use */
+ tpmb_free(b);
+
+ c->header = (struct tpm_header *)tpmb_reserve(b);
+ if (!c->header)
+ return -ENOMEM;
+
+ c->header->tag = cpu_to_be16(tag);
+ c->header->code = cpu_to_be32(code);
+
+ return 0;
+}
+
+static u16 convert_digest_list(struct tpml_digest_values *digests)
+{
+ int i;
+ u16 size = sizeof(digests->count);
+ struct tpmt_ha *h = digests->digests;
+
+ for (i = 0; i < digests->count; i++) {
+ switch (h->alg) {
+ case TPM_ALG_SHA1:
+ h->alg = cpu_to_be16(h->alg);
+ h = (struct tpmt_ha *)((u8 *)h + SHA1_SIZE);
+ size += sizeof(u16) + SHA1_SIZE;
+ break;
+ case TPM_ALG_SHA256:
+ h->alg = cpu_to_be16(h->alg);
+ h = (struct tpmt_ha *)((u8 *)h + SHA256_SIZE);
+ size += sizeof(u16) + SHA256_SIZE;
+ break;
+ case TPM_ALG_SHA384:
+ h->alg = cpu_to_be16(h->alg);
+ h = (struct tpmt_ha *)((u8 *)h + SHA384_SIZE);
+ size += sizeof(u16) + SHA384_SIZE;
+ break;
+ case TPM_ALG_SHA512:
+ h->alg = cpu_to_be16(h->alg);
+ h = (struct tpmt_ha *)((u8 *)h + SHA512_SIZE);
+ size += sizeof(u16) + SHA512_SIZE;
+ break;
+ case TPM_ALG_SM3_256:
+ h->alg = cpu_to_be16(h->alg);
+ h = (struct tpmt_ha *)((u8 *)h + SM3256_SIZE);
+ size += sizeof(u16) + SHA1_SIZE;
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ digests->count = cpu_to_be32(digests->count);
+
+ return size;
+}
+
+int tpm2_extend_pcr(struct tpm *t, u32 pcr,
+ struct tpml_digest_values *digests)
+{
+ struct tpmbuff *b = t->buff;
+ struct tpm2_cmd cmd;
+ u16 size;
+ int ret = 0;
+
+ if (b == NULL) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = tpm2_alloc_cmd(b, &cmd, TPM_ST_SESSIONS, TPM_CC_PCR_EXTEND);
+ if (ret < 0)
+ goto out;
+
+ cmd.handles = (u32 *)tpmb_put(b, sizeof(u32));
+ if (cmd.handles == NULL) {
+ ret = -ENOMEM;
+ goto free;
+ }
+
+ cmd.handles[0] = cpu_to_be32(pcr);
+
+ cmd.auth_size = (u32 *)tpmb_put(b, sizeof(u32));
+ if (cmd.auth_size == NULL) {
+ ret = -ENOMEM;
+ goto free;
+ }
+
+ cmd.auth = tpm2_null_auth(b);
+ if (cmd.auth == NULL) {
+ ret = -ENOMEM;
+ goto free;
+ }
+
+ *cmd.auth_size = cpu_to_be32(tpm2_null_auth_size());
+
+ size = convert_digest_list(digests);
+ if (size == 0) {
+ ret = -ENOMEM;
+ goto free;
+ }
+
+ cmd.params = (u8 *)tpmb_put(b, size);
+ if (cmd.params == NULL) {
+ ret = -ENOMEM;
+ goto free;
+ }
+
+ memcpy(cmd.params, digests, size);
+
+ cmd.header->size = cpu_to_be32(tpmb_size(b));
+
+ size = t->ops.send(b);
+ if (tpmb_size(b) != size)
+ ret = -EAGAIN;
+
+free:
+ tpmb_free(b);
+out:
+ return ret;
+}
diff --git a/arch/x86/boot/compressed/tpm/tpm2_constants.h b/arch/x86/boot/compressed/tpm/tpm2_constants.h
new file mode 100644
index 0000000..bf31843
--- /dev/null
+++ b/arch/x86/boot/compressed/tpm/tpm2_constants.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Apertus Solutions, LLC
+ *
+ * Author(s):
+ * Daniel P. Smith <[email protected]>
+ *
+ * The definitions in this header are extracted and/or dervied from the
+ * Trusted Computing Group's TPM 2.0 Library Specification Parts 1&2.
+ *
+ */
+
+#ifndef _TPM2_CONSTANTS_H
+#define _TPM2_CONSTANTS_H
+
+/* Table 9 Definition of (UINT16) TPM_ALG_ID Constants <IN/OUT, S> */
+#define TPM_ALG_ERROR _AT(u16, 0x0000)
+#define TPM_ALG_RSA _AT(u16, 0x0001)
+#define TPM_ALG_SHA _AT(u16, 0x0004)
+#define TPM_ALG_SHA1 _AT(u16, 0x0004)
+#define TPM_ALG_HMAC _AT(u16, 0x0005)
+#define TPM_ALG_AES _AT(u16, 0x0006)
+#define TPM_ALG_MGF1 _AT(u16, 0x0007)
+#define TPM_ALG_KEYEDHASH _AT(u16, 0x0008)
+#define TPM_ALG_XOR _AT(u16, 0x000A)
+#define TPM_ALG_SHA256 _AT(u16, 0x000B)
+#define TPM_ALG_SHA384 _AT(u16, 0x000C)
+#define TPM_ALG_SHA512 _AT(u16, 0x000D)
+#define TPM_ALG_NULL _AT(u16, 0x0010)
+#define TPM_ALG_SM3_256 _AT(u16, 0x0012)
+#define TPM_ALG_SM4 _AT(u16, 0x0013)
+#define TPM_ALG_RSASSA _AT(u16, 0x0014)
+#define TPM_ALG_RSAES _AT(u16, 0x0015)
+#define TPM_ALG_RSAPSS _AT(u16, 0x0016)
+#define TPM_ALG_OAEP _AT(u16, 0x0017)
+#define TPM_ALG_ECDSA _AT(u16, 0x0018)
+#define TPM_ALG_ECDH _AT(u16, 0x0019)
+#define TPM_ALG_ECDAA _AT(u16, 0x001A)
+#define TPM_ALG_SM2 _AT(u16, 0x001B)
+#define TPM_ALG_ECSCHNORR _AT(u16, 0x001C)
+#define TPM_ALG_ECMQV _AT(u16, 0x001D)
+#define TPM_ALG_KDF1_SP800_56A _AT(u16, 0x0020)
+#define TPM_ALG_KDF2 _AT(u16, 0x0021)
+#define TPM_ALG_KDF1_SP800_108 _AT(u16, 0x0022)
+#define TPM_ALG_ECC _AT(u16, 0x0023)
+#define TPM_ALG_SYMCIPHER _AT(u16, 0x0025)
+#define TPM_ALG_CAMELLIA _AT(u16, 0x0026)
+#define TPM_ALG_CTR _AT(u16, 0x0040)
+#define TPM_ALG_OFB _AT(u16, 0x0041)
+#define TPM_ALG_CBC _AT(u16, 0x0042)
+#define TPM_ALG_CFB _AT(u16, 0x0043)
+#define TPM_ALG_ECB _AT(u16, 0x0044)
+#define TPM_ALG_FIRST _AT(u16, 0x0001)
+#define TPM_ALG_LAST _AT(u16, 0x0044)
+
+/* Table 12 Definition of (UINT32) TPM_CC Constants (Numeric Order) <IN/OUT, S> */
+#define TPM_CC_PCR_EXTEND _AT(u32, 0x00000182)
+
+/* Table 19 Definition of (UINT16) TPM_ST Constants <IN/OUT, S> */
+#define TPM_ST_NO_SESSIONS _AT(u16, 0x8001)
+#define TPM_ST_SESSIONS _AT(u16, 0x8002)
+
+/* Table 28 Definition of (TPM_HANDLE) TPM_RH Constants <S> */
+#define TPM_RS_PW _AT(u32, 0x40000009)
+
+#endif
--
1.8.3.1

2020-09-25 05:32:13

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH 00/13] x86: Trenchboot secure dynamic launch Linux kernel support

On Thu, Sep 24, 2020 at 10:58:28AM -0400, Ross Philipson wrote:
> The Trenchboot project focus on boot security has led to the enabling of
> the Linux kernel to be directly invocable by the x86 Dynamic Launch
> instruction(s) for establishing a Dynamic Root of Trust for Measurement
> (DRTM). The dynamic launch will be initiated by a boot loader with

What is "the dynamic launch"?

> associated support added to it, for example the first targeted boot
> loader will be GRUB2. An integral part of establishing the DRTM involves
> measuring everything that is intended to be run (kernel image, initrd,
> etc) and everything that will configure that kernel to run (command
> line, boot params, etc) into specific PCRs, the DRTM PCRs (17-22), in
> the TPM. Another key aspect is the dynamic launch is rooted in hardware,
> that is to say the hardware (CPU) is what takes the first measurement
> for the chain of integrity measurements. On Intel this is done using
> the GETSEC instruction provided by Intel's TXT and the SKINIT
> instruction provided by AMD's AMD-V. Information on these technologies
> can be readily found online. This patchset introduces Intel TXT support.

Why not both Intel and AMD? You should explain this in the cover letter.

I'd be more motivated to review and test a full all encompassing x86
solution. It would increase the patch set size but would also give it
a better test coverage, which I think would be a huge plus in such a
complex patch set.

> To enable the kernel to be launched by GETSEC, a stub must be built
> into the setup section of the compressed kernel to handle the specific
> state that the dynamic launch process leaves the BSP in. This is
> analogous to the EFI stub that is found in the same area. Also this stub

How is it analogous?

> must measure everything that is going to be used as early as possible.
> This stub code and subsequent code must also deal with the specific
> state that the dynamic launch leaves the APs in.

What is "the specific state"?

> A quick note on terminology. The larger open source project itself is
> called Trenchboot, which is hosted on Github (links below). The kernel
> feature enabling the use of the x86 technology is referred to as "Secure
> Launch" within the kernel code. As such the prefixes sl_/SL_ or
> slaunch/SLAUNCH will be seen in the code. The stub code discussed above
> is referred to as the SL stub.

Is this only for Trenchboot? I'm a bit lost. What is it anyway?

> The basic flow is:
>
> - Entry from the dynamic launch jumps to the SL stub
> - SL stub fixes up the world on the BSP

What is "SL"?

> - For TXT, SL stub wakes the APs, fixes up their worlds
> - For TXT, APs are left halted waiting for an NMI to wake them
> - SL stub jumps to startup_32
> - SL main runs to measure configuration and module information into the
> DRTM PCRs. It also locates the TPM event log.
> - Kernel boot proceeds normally from this point.
> - During early setup, slaunch_setup() runs to finish some validation
> and setup tasks.

What are "some" validation and setup tasks?

> - The SMP bringup code is modified to wake the waiting APs. APs vector
> to rmpiggy and start up normally from that point.
> - Kernel boot finishes booting normally
> - SL securityfs module is present to allow reading and writing of the
> TPM event log.

What is SL securityfs module? Why is it needed? We already have
securityfs file for the event log. Why it needs to be writable?

> - SEXIT support to leave SMX mode is present on the kexec path and
> the various reboot paths (poweroff, reset, halt).

What SEXIT do and why it is required on the kexec path?

/Jarkko

2020-09-25 05:44:44

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH 05/13] x86: Add early TPM1.2/TPM2.0 interface support for Secure Launch

On Thu, Sep 24, 2020 at 10:58:33AM -0400, Ross Philipson wrote:
> From: "Daniel P. Smith" <[email protected]>
>
> This commit introduces an abstraction for TPM1.2 and TPM2.0 devices
> above the TPM hardware interface.
>
> Signed-off-by: Daniel P. Smith <[email protected]>
> Signed-off-by: Ross Philipson <[email protected]>

This is way, way too PoC. I wonder why there is no RFC tag.

Please also read section 2 of

https://www.kernel.org/doc/html/v5.8/process/submitting-patches.html

You should leverage existing TPM code in a way or another. Refine it so
that it scales for your purpose and then compile it into your thing
(just include the necesary C-files with relative paths).

How it is now is never going to fly.

/Jarkko

2020-09-25 21:50:37

by Daniel P. Smith

[permalink] [raw]
Subject: Re: [PATCH 00/13] x86: Trenchboot secure dynamic launch Linux kernel support

On 9/25/20 1:30 AM, Jarkko Sakkinen wrote:
> On Thu, Sep 24, 2020 at 10:58:28AM -0400, Ross Philipson wrote:
>> The Trenchboot project focus on boot security has led to the enabling of
>> the Linux kernel to be directly invocable by the x86 Dynamic Launch
>> instruction(s) for establishing a Dynamic Root of Trust for Measurement
>> (DRTM). The dynamic launch will be initiated by a boot loader with
>
> What is "the dynamic launch"?

Dynamic launch is the term used to reference the event/process of
restarting a system without reboot to establish the DRTM. It is defined
in the TCG Glossary[1], is discussed in detail in the TCG D-RTM
Architecture specification[2], and covered in minimal detail in sections
9.5.5 and 34.2 of the TCG TPM2.0 Architecture specification[3].

[1]
https://trustedcomputinggroup.org/wp-content/uploads/TCG-Glossary-V1.1-Rev-1.0.pdf
[2]
https://trustedcomputinggroup.org/wp-content/uploads/TCG_D-RTM_Architecture_v1-0_Published_06172013.pdf
[3]
https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf

>> associated support added to it, for example the first targeted boot
>> loader will be GRUB2. An integral part of establishing the DRTM involves
>> measuring everything that is intended to be run (kernel image, initrd,
>> etc) and everything that will configure that kernel to run (command
>> line, boot params, etc) into specific PCRs, the DRTM PCRs (17-22), in
>> the TPM. Another key aspect is the dynamic launch is rooted in hardware,
>> that is to say the hardware (CPU) is what takes the first measurement
>> for the chain of integrity measurements. On Intel this is done using
>> the GETSEC instruction provided by Intel's TXT and the SKINIT
>> instruction provided by AMD's AMD-V. Information on these technologies
>> can be readily found online. This patchset introduces Intel TXT support.
>
> Why not both Intel and AMD? You should explain this in the cover letter.

The work for this is split across different teams with different
resourcing levels resulting in one organization working Intel and
another working AMD. This then raised the concern over submitting a
single patch set developed by two groups pseudo-independently. In this
situation the result would be patches being submitted from one
organization that had no direct development or testing and therefore
could not sign off on a subset of the patches being submitted.

> I'd be more motivated to review and test a full all encompassing x86
> solution. It would increase the patch set size but would also give it
> a better test coverage, which I think would be a huge plus in such a
> complex patch set.

We would not disagree with those sentiments but see the previous
response about the conflict that exists.

>> To enable the kernel to be launched by GETSEC, a stub must be built
>> into the setup section of the compressed kernel to handle the specific
>> state that the dynamic launch process leaves the BSP in. This is
>> analogous to the EFI stub that is found in the same area. Also this stub
>
> How is it analogous?

It is analogous as we used it as the pattern to follow for adding a
configurable entry point to the kernel. There was a discussion on this
when we published the RFC patches[4].

[4] https://lkml.org/lkml/2020/3/25/982

>> must measure everything that is going to be used as early as possible.
>> This stub code and subsequent code must also deal with the specific
>> state that the dynamic launch leaves the APs in.
>
> What is "the specific state"?

The details are a bit more than I would prefer to explain here, I would
recommend reading section 2.3 and 2.4 of Intel's TXT Software
Development Guide[5] for all the details of the state and the prescribed
initialization sequence.

[5]
https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf

>> A quick note on terminology. The larger open source project itself is
>> called Trenchboot, which is hosted on Github (links below). The kernel
>> feature enabling the use of the x86 technology is referred to as "Secure
>> Launch" within the kernel code. As such the prefixes sl_/SL_ or
>> slaunch/SLAUNCH will be seen in the code. The stub code discussed above
>> is referred to as the SL stub.
>
> Is this only for Trenchboot? I'm a bit lost. What is it anyway?

TrenchBoot is a meta-project that is working to bring a unified approach
to using DRTM across CPU implementations and open source projects.
Currently we are working to integrate a dynamic launch preamble (the
code that sets up for calling the dynamic launch CPU instruction) in
GRUB, building an open AMD Secure Loader that aligns with how Intel's
SINIT ACM hands off to an MLE, bring the first directly launchable
implementation to Linux (Secure Launch) with Xen being the next directly
launchable implementation, providing the u-root project a secure launch
initramfs init routine to demonstrate a policy driven measurement and
attestation framework that can be used in conjunction with a Secure
Launch kernel.


>> The basic flow is:
>>
>> - Entry from the dynamic launch jumps to the SL stub
>> - SL stub fixes up the world on the BSP
>
> What is "SL"?

As mentioned above, it is just shorthand for Secure Launch.

>> - For TXT, SL stub wakes the APs, fixes up their worlds
>> - For TXT, APs are left halted waiting for an NMI to wake them
>> - SL stub jumps to startup_32
>> - SL main runs to measure configuration and module information into the
>> DRTM PCRs. It also locates the TPM event log.
>> - Kernel boot proceeds normally from this point.
>> - During early setup, slaunch_setup() runs to finish some validation
>> and setup tasks.
>
> What are "some" validation and setup tasks?

The validation and setup steps are to ensure the environment was setup
in a manner that we expected as outlined in the Intel TXT Software
Development guide[4]. At this point these are,
- Ensure that SENTER completed successfully and was not initiated by TBOOT.
- Check that the private MMIO register bank is available.
- Fetch values needed from the TXT heap for later operations.
- Verify the PMR values cover the MLE and other memory regions that need
to be secure.
- Reserve certain TXT specific areas of physical memory.
- Fetch the copy of the DMAR table from the TXT heap to provide to the
IOMMU driver later.

>> - The SMP bringup code is modified to wake the waiting APs. APs vector
>> to rmpiggy and start up normally from that point.
>> - Kernel boot finishes booting normally
>> - SL securityfs module is present to allow reading and writing of the
>> TPM event log.
>
> What is SL securityfs module? Why is it needed? We already have
> securityfs file for the event log. Why it needs to be writable?

The securityfs nodes provides access to the TXT registers to inspect the
details from the dynamic launch and access to the DRTM event log. The
DRTM event log is setup by the DRTM process and is a different/separate
event log from the SRTM/UEFI event log. We need write access for use
cases where the Secure Launch kernel is being used as an intermediate
launch kernel where additional measurements about the final target
environment are being collected.

>> - SEXIT support to leave SMX mode is present on the kexec path and
>> the various reboot paths (poweroff, reset, halt).
>
> What SEXIT do and why it is required on the kexec path?

The SEXIT instruction "exits" SMX mode. The why is because when in SMX
mode the CPU has a set of behaviors different than what is typically
expected, especially for SMP management. As good custodians, this
ensures that the system is in a usable state for a follow-on kernel that
is not SMX/Secure Launch aware. From a security use case perspective,
leaving SMX mode disables access to localities 1-3 of the TPM. This
essentially "locks" the values in the DRTM PCRs from further
modification/extends until another dynamic launch event is fired which
will in turn result in the DRTM PCRs being reset.

> /Jarkko
>


2020-09-28 00:01:42

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH 00/13] x86: Trenchboot secure dynamic launch Linux kernel support

On Fri, Sep 25, 2020 at 05:32:50PM -0400, Daniel P. Smith wrote:
> The work for this is split across different teams with different
> resourcing levels resulting in one organization working Intel and
> another working AMD. This then raised the concern over submitting a
> single patch set developed by two groups pseudo-independently. In this
> situation the result would be patches being submitted from one
> organization that had no direct development or testing and therefore
> could not sign off on a subset of the patches being submitted.

Not sure if internal team structures qualify as a techical argument for
upstream code.

> > I'd be more motivated to review and test a full all encompassing x86
> > solution. It would increase the patch set size but would also give it
> > a better test coverage, which I think would be a huge plus in such a
> > complex patch set.
>
> We would not disagree with those sentiments but see the previous
> response about the conflict that exists.

At minimum, you have to make the case that the AMD support is easy to
tackle in to the framework of things you have later on.

/Jarkko

2020-09-29 23:50:11

by Daniel P. Smith

[permalink] [raw]
Subject: Re: [PATCH 05/13] x86: Add early TPM1.2/TPM2.0 interface support for Secure Launch

On 9/25/20 1:43 AM, Jarkko Sakkinen wrote:
> On Thu, Sep 24, 2020 at 10:58:33AM -0400, Ross Philipson wrote:
>> From: "Daniel P. Smith" <[email protected]>
>>
>> This commit introduces an abstraction for TPM1.2 and TPM2.0 devices
>> above the TPM hardware interface.
>>
>> Signed-off-by: Daniel P. Smith <[email protected]>
>> Signed-off-by: Ross Philipson <[email protected]>
>
> This is way, way too PoC. I wonder why there is no RFC tag.

An RFC was sent back in March and we incorporated the feedback we
received at that time.

> Please also read section 2 of
>
> https://www.kernel.org/doc/html/v5.8/process/submitting-patches.html
>
> You should leverage existing TPM code in a way or another. Refine it so
> that it scales for your purpose and then compile it into your thing
> (just include the necesary C-files with relative paths).

We explained during the RFC phase that we took a fair bit of time and a
very hard look to see if we could #include sections out the TPM driver
but as it is today none of the TPM driver's c files can be included
outside of the mainline kernel. If you look at the early boot stub for
the compressed kernel you will see that we are interacting with the TPM
as the first thing upon leaving the assembly world and entering C. Since
we weren't going to be able to get the mainline TPM driver plucked down,
we could either 1.) borrow an implementation from a colleague that
provides the minimum command strings hard coded in C macros to send
measurements to the TPM or 2.) reuse the TPM implementation we wrote for
TrenchBoot's AMD Secure Loader (LZ). The former is not well supported
and the latter will be getting maintenance under TB. While this is not
preferred, we had to weigh this versus trying to convince you and the
other TPM driver maintainers on a significant refactoring of the TPM
driver. It was elected for the reuse of a clean implementation that can
be replaced later if/when the TPM driver was refactored. When we
explained this during the RFC and it was not rejected, therefore we
carried it forward into this submission.


> How it is now is never going to fly.

We would gladly work with you and the other TPM maintainers on a
refactoring of the TPM driver to separate core logic into standalone
files that both the driver and the compressed kernel can share.

> /Jarkko
>


2020-09-30 03:24:17

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH 05/13] x86: Add early TPM1.2/TPM2.0 interface support for Secure Launch

On Tue, Sep 29, 2020 at 07:47:52PM -0400, Daniel P. Smith wrote:
> TrenchBoot's AMD Secure Loader (LZ). The former is not well supported
> and the latter will be getting maintenance under TB. While this is not
> preferred, we had to weigh this versus trying to convince you and the
> other TPM driver maintainers on a significant refactoring of the TPM
> driver. It was elected for the reuse of a clean implementation that can
> be replaced later if/when the TPM driver was refactored. When we
> explained this during the RFC and it was not rejected, therefore we
> carried it forward into this submission.

What does it anyway mean when you say "RFC was not rejected"? I don't
get the semantics of that sentence. It probably neither was ack'd,
right? I do not really care what happened with the RFC. All I can say
is that in the current state this totally PoC from top to bottom.

> > How it is now is never going to fly.
>
> We would gladly work with you and the other TPM maintainers on a
> refactoring of the TPM driver to separate core logic into standalone
> files that both the driver and the compressed kernel can share.

Yes, exactly. You have to refactor out the common parts. This is way too
big patch to spend time on giving any more specific advice. Should be in
way smaller chunks. For (almost) any possible, this is of unacceptable
size.

I think that it'd be best first to keep the common files in
drivers/char/tpm and include them your code with relative paths in the
Makefile. At least up until we have clear view what are the common
parts.

You might also want to refactor drivers/char/tpm/tpm.h and include/linux
TPM headers to move more stuff into include/linux.

If you are expecting a quick upstreaming process, please do not. This
will take considerable amount of time to get right.

/Jarkko

2020-09-30 03:26:29

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH 05/13] x86: Add early TPM1.2/TPM2.0 interface support for Secure Launch

On Wed, Sep 30, 2020 at 06:19:57AM +0300, Jarkko Sakkinen wrote:
> On Tue, Sep 29, 2020 at 07:47:52PM -0400, Daniel P. Smith wrote:
> > TrenchBoot's AMD Secure Loader (LZ). The former is not well supported
> > and the latter will be getting maintenance under TB. While this is not
> > preferred, we had to weigh this versus trying to convince you and the
> > other TPM driver maintainers on a significant refactoring of the TPM
> > driver. It was elected for the reuse of a clean implementation that can
> > be replaced later if/when the TPM driver was refactored. When we
> > explained this during the RFC and it was not rejected, therefore we
> > carried it forward into this submission.
>
> What does it anyway mean when you say "RFC was not rejected"? I don't
> get the semantics of that sentence. It probably neither was ack'd,
> right? I do not really care what happened with the RFC. All I can say
> is that in the current state this totally PoC from top to bottom.
>
> > > How it is now is never going to fly.
> >
> > We would gladly work with you and the other TPM maintainers on a
> > refactoring of the TPM driver to separate core logic into standalone
> > files that both the driver and the compressed kernel can share.
>
> Yes, exactly. You have to refactor out the common parts. This is way too
> big patch to spend time on giving any more specific advice. Should be in
> way smaller chunks. For (almost) any possible, this is of unacceptable
^ " patch"
> size.
>
> I think that it'd be best first to keep the common files in
> drivers/char/tpm and include them your code with relative paths in the
> Makefile. At least up until we have clear view what are the common
> parts.
>
> You might also want to refactor drivers/char/tpm/tpm.h and include/linux
> TPM headers to move more stuff into include/linux.
>
> If you are expecting a quick upstreaming process, please do not. This
> will take considerable amount of time to get right.

/Jarkko

2021-01-20 00:56:44

by Daniel P. Smith

[permalink] [raw]
Subject: Re: [PATCH 05/13] x86: Add early TPM1.2/TPM2.0 interface support for Secure Launch

On 9/25/20 1:43 AM, Jarkko Sakkinen wrote:
> On Thu, Sep 24, 2020 at 10:58:33AM -0400, Ross Philipson wrote:
>> From: "Daniel P. Smith" <[email protected]>
>>
>> This commit introduces an abstraction for TPM1.2 and TPM2.0 devices
>> above the TPM hardware interface.
>>
>> Signed-off-by: Daniel P. Smith <[email protected]>
>> Signed-off-by: Ross Philipson <[email protected]>
>
> This is way, way too PoC. I wonder why there is no RFC tag.
>
> Please also read section 2 of
>
> https://www.kernel.org/doc/html/v5.8/process/submitting-patches.html
>
> You should leverage existing TPM code in a way or another. Refine it so
> that it scales for your purpose and then compile it into your thing
> (just include the necesary C-files with relative paths).
>
> How it is now is never going to fly.
>
> /Jarkko
>

After attempts to engage in finding alternative approaches, it appears
that the only welcomed approach for sending measurements from the
compressed kernel would be a major rewrite of the mainline TPM driver to:

1. Abstract out the mainline kernel infrastructure that is used by the
driver

2. Find ways to introduce a minimal amount of the equivalent
infrastructure into the compressed kernel, to make the driver code
reusable within the compressed kernel.

This approach would exceed the scope of changes we want to introduce to
non-SecureLaunch code to enable direct DRTM launch for the Linux kernel.

After careful consideration and discussions with colleagues from the
trusted computing community, an alternative has been crafted. We aim to
submit a version 2 with the following approach:

1. SecureLaunch will take measurements in the compressed kernel as we do
in version 1, but instead of immediately sending them to the TPM, they
will be stored in the DRTM TPM event log.

2. When the SecureLaunch module in the mainline kernel comes on line, it
can send measurements to the TPM using the mainline TPM driver.

While it would be ideal to record measurements at the time they are
taken, the mainline kernel is measured alongside the compressed kernel
as a single measurement. This means the same measured entity stays in
control, prior to execution by any other entity within the system.

At a later date, if the TPM maintainers refactor the TPM driver for
reuse within the compressed kernel, then the sending of measurements can
be revisited.

For individuals and distributions that may prefer to record DRTM
measurements earlier, the TrenchBoot project will do its best to
maintain an external patch to provide that capability to a mainline LTS
kernel.

V/r,
Daniel P. Smith