From patchwork Fri Feb 14 00:27:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13974215 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4F0B35228; Fri, 14 Feb 2025 00:27:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492878; cv=none; b=FNclAOne/Ra8YvTiTPYMqccrl7K1Casy0/L/gFJ8dB7z4St8SaS/Qudy+gIW33h2/+RmUxUM54VY83208hKQTFW8gmVx5phf0/AXIgo3ec1dt3vP0i6ryVdxF0C035JyAoZWRq9GciWdYtFkMQ9nU3Xvq5YBV3s9NCMMPMv8MD0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492878; c=relaxed/simple; bh=ZixwQJUuEXAoTI4MJdSnEFALiqrdtAKNVE63vO12Kh8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HWWrZ/kQPDx47823t78PAJT3CXF8x6uV9o1MZDelUMeLIoT1PX/R7Mc48zVACS4flBWCjtag/eUt6ETfRCvO590vi50Onn2VKtt5xQtRv0cSmJiH1AMYIjOcwbM0WHMNjJocXFmqQSiZtethyCXBjG/5YVk7aZMB0LYRAsPBlYc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2F3651682; Thu, 13 Feb 2025 16:28:16 -0800 (PST) Received: from beelzebub.ast.arm.com (u203013-lin.austin.arm.com [10.118.28.29]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 99E2B3F762; Thu, 13 Feb 2025 16:27:55 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/5] tpm_crb: implement driver compliant to CRB over FF-A Date: Thu, 13 Feb 2025 18:27:41 -0600 Message-Id: <20250214002745.878890-2-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250214002745.878890-1-stuart.yoder@arm.com> References: <20250214002745.878890-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-acpi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The Arm specification TPM Service CRB over FF-A specification defines the FF-A messages to interact with a CRB-based TPM implemented as an FF-A secure partition. Spec URL: https://developer.arm.com/documentation/den0138/latest/ This driver is probed when a TPM Secure Partition is discovered by the FF-A subsystem. It exposes APIs used by the TPM CRB driver to send notifications to the TPM. Signed-off-by: Stuart Yoder --- drivers/char/tpm/Kconfig | 9 + drivers/char/tpm/Makefile | 1 + drivers/char/tpm/tpm_crb_ffa.c | 310 +++++++++++++++++++++++++++++++++ drivers/char/tpm/tpm_crb_ffa.h | 30 ++++ 4 files changed, 350 insertions(+) create mode 100644 drivers/char/tpm/tpm_crb_ffa.c create mode 100644 drivers/char/tpm/tpm_crb_ffa.h diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 0fc9a510e059..4c85b8c00b12 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -210,6 +210,15 @@ config TCG_CRB from within Linux. To compile this driver as a module, choose M here; the module will be called tpm_crb. +config TCG_ARM_CRB_FFA + tristate "TPM CRB over Arm FF-A Transport" + depends on ARM_FFA_TRANSPORT + default y if (TCG_CRB && ARM_FFA_TRANSPORT) + help + If the Arm FF-A transport is used to access the TPM say Yes. + To compile this driver as a module, choose M here; the module + will be called tpm_crb_ffa. + config TCG_VTPM_PROXY tristate "VTPM Proxy Interface" depends on TCG_TPM diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 9bb142c75243..2b004df8c04b 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -42,5 +42,6 @@ obj-$(CONFIG_TCG_IBMVTPM) += tpm_ibmvtpm.o obj-$(CONFIG_TCG_TIS_ST33ZP24) += st33zp24/ obj-$(CONFIG_TCG_XEN) += xen-tpmfront.o obj-$(CONFIG_TCG_CRB) += tpm_crb.o +obj-$(CONFIG_TCG_ARM_CRB_FFA) += tpm_crb_ffa.o obj-$(CONFIG_TCG_VTPM_PROXY) += tpm_vtpm_proxy.o obj-$(CONFIG_TCG_FTPM_TEE) += tpm_ftpm_tee.o diff --git a/drivers/char/tpm/tpm_crb_ffa.c b/drivers/char/tpm/tpm_crb_ffa.c new file mode 100644 index 000000000000..3bd9fd81ec21 --- /dev/null +++ b/drivers/char/tpm/tpm_crb_ffa.c @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Arm Ltd. + * + * Maintained by: + * + * This device driver implements the TPM CRB start method + * as defined in the TPM Service Command Response Buffer + * Interface Over FF-A (DEN0138). + */ + +#define pr_fmt(fmt) "CRB_FFA: " fmt + +#include +#include "tpm_crb_ffa.h" + +/* TPM service function status codes */ +#define CRB_FFA_OK 0x05000001 +#define CRB_FFA_OK_RESULTS_RETURNED 0x05000002 +#define CRB_FFA_NOFUNC 0x8e000001 +#define CRB_FFA_NOTSUP 0x8e000002 +#define CRB_FFA_INVARG 0x8e000005 +#define CRB_FFA_INV_CRB_CTRL_DATA 0x8e000006 +#define CRB_FFA_ALREADY 0x8e000009 +#define CRB_FFA_DENIED 0x8e00000a +#define CRB_FFA_NOMEM 0x8e00000b + +#define CRB_FFA_VERSION_MAJOR 1 +#define CRB_FFA_VERSION_MINOR 0 + +/* version encoding */ +#define CRB_FFA_MAJOR_VERSION_MASK GENMASK(30, 16) +#define CRB_FFA_MINOR_VERSION_MASK GENMASK(15, 0) +#define CRB_FFA_MAJOR_VERSION(x) ((u16)(FIELD_GET(CRB_FFA_MAJOR_VERSION_MASK, (x)))) +#define CRB_FFA_MINOR_VERSION(x) ((u16)(FIELD_GET(CRB_FFA_MINOR_VERSION_MASK, (x)))) + +/* + * Normal world sends requests with FFA_MSG_SEND_DIRECT_REQ and + * responses are returned with FFA_MSG_SEND_DIRECT_RESP for normal + * messages. + * + * All requests with FFA_MSG_SEND_DIRECT_REQ and FFA_MSG_SEND_DIRECT_RESP + * are using the AArch32 SMC calling convention with register usage as + * defined in FF-A specification: + * w0: Function ID (0x8400006F or 0x84000070) + * w1: Source/Destination IDs + * w2: Reserved (MBZ) + * w3-w7: Implementation defined, free to be used below + */ + +/* + * Returns the version of the interface that is available + * Call register usage: + * w3: Not used (MBZ) + * w4: TPM service function ID, CRB_FFA_GET_INTERFACE_VERSION + * w5-w7: Reserved (MBZ) + * + * Return register usage: + * w3: Not used (MBZ) + * w4: TPM service function status + * w5: TPM service interface version + * Bits[31:16]: major version + * Bits[15:0]: minor version + * w6-w7: Reserved (MBZ) + * + * Possible function status codes in register w4: + * CRB_FFA_OK_RESULTS_RETURNED: The version of the interface has been + * returned. + */ +#define CRB_FFA_GET_INTERFACE_VERSION 0x0f000001 + +/* + * Return information on a given feature of the TPM service + * Call register usage: + * w3: Not used (MBZ) + * w4: TPM service function ID, CRB_FFA_START + * w5: Start function qualifier + * Bits[31:8] (MBZ) + * Bits[7:0] + * 0: Notifies TPM that a command is ready to be processed + * 1: Notifies TPM that a locality request is ready to be processed + * w6: TPM locality, one of 0..4 + * -If the start function qualifier is 0, identifies the locality + * from where the command originated. + * -If the start function qualifier is 1, identifies the locality + * of the locality request + * w6-w7: Reserved (MBZ) + * + * Return register usage: + * w3: Not used (MBZ) + * w4: TPM service function status + * w5-w7: Reserved (MBZ) + * + * Possible function status codes in register w4: + * CRB_FFA_OK: the TPM service has been notified successfully + * CRB_FFA_INVARG: one or more arguments are not valid + * CRB_FFA_INV_CRB_CTRL_DATA: CRB control data or locality control + * data at the given TPM locality is not valid + * CRB_FFA_DENIED: the TPM has previously disabled locality requests and + * command processing at the given locality + */ +#define CRB_FFA_START 0x0f000201 + +struct tpm_crb_ffa { + struct ffa_device *ffa_dev; + u16 major_version; + u16 minor_version; + struct mutex msg_data_lock; + struct ffa_send_direct_data direct_msg_data; +}; + +static struct tpm_crb_ffa *tpm_crb_ffa; + +static int tpm_crb_ffa_to_linux_errno(int errno) +{ + int rc; + + switch (errno) { + case CRB_FFA_OK: + rc = 0; + break; + case CRB_FFA_OK_RESULTS_RETURNED: + rc = 0; + break; + case CRB_FFA_NOFUNC: + rc = -ENOENT; + break; + case CRB_FFA_NOTSUP: + rc = -EPERM; + break; + case CRB_FFA_INVARG: + rc = -EINVAL; + break; + case CRB_FFA_INV_CRB_CTRL_DATA: + rc = -ENOEXEC; + break; + case CRB_FFA_ALREADY: + rc = -EEXIST; + break; + case CRB_FFA_DENIED: + rc = -EACCES; + break; + case CRB_FFA_NOMEM: + rc = -ENOMEM; + break; + default: + rc = -EINVAL; + } + + return rc; +} + +int tpm_crb_ffa_init(void) +{ + if (tpm_crb_ffa == NULL) + return -ENOENT; + + if (IS_ERR_VALUE(tpm_crb_ffa)) + return -ENODEV; + + return 0; +} +EXPORT_SYMBOL_GPL(tpm_crb_ffa_init); + +static int __tpm_crb_ffa_send_recieve(unsigned long func_id, + unsigned long a0, unsigned long a1, unsigned long a2) +{ + int ret; + const struct ffa_msg_ops *msg_ops; + + if (tpm_crb_ffa == NULL) + return -ENOENT; + + msg_ops = tpm_crb_ffa->ffa_dev->ops->msg_ops; + + memset(&tpm_crb_ffa->direct_msg_data, 0x00, + sizeof(struct ffa_send_direct_data)); + + tpm_crb_ffa->direct_msg_data.data1 = func_id; + tpm_crb_ffa->direct_msg_data.data2 = a0; + tpm_crb_ffa->direct_msg_data.data3 = a1; + tpm_crb_ffa->direct_msg_data.data4 = a2; + + ret = msg_ops->sync_send_receive(tpm_crb_ffa->ffa_dev, + &tpm_crb_ffa->direct_msg_data); + if (!ret) + ret = tpm_crb_ffa_to_linux_errno(tpm_crb_ffa->direct_msg_data.data1); + + return ret; +} + +int tpm_crb_ffa_get_interface_version(uint16_t *major, uint16_t *minor) +{ + int rc; + + if (tpm_crb_ffa == NULL) + return -ENOENT; + + if (IS_ERR_VALUE(tpm_crb_ffa)) + return -ENODEV; + + if (major == NULL || minor == NULL) + return -EINVAL; + + guard(mutex)(&tpm_crb_ffa->msg_data_lock); + + rc = __tpm_crb_ffa_send_recieve(CRB_FFA_GET_INTERFACE_VERSION, 0x00, 0x00, 0x00); + if (!rc) { + *major = CRB_FFA_MAJOR_VERSION(tpm_crb_ffa->direct_msg_data.data2); + *minor = CRB_FFA_MINOR_VERSION(tpm_crb_ffa->direct_msg_data.data2); + } + + return rc; +} +EXPORT_SYMBOL_GPL(tpm_crb_ffa_get_interface_version); + +int tpm_crb_ffa_start(int request_type, int locality) +{ + if (tpm_crb_ffa == NULL) + return -ENOENT; + + if (IS_ERR_VALUE(tpm_crb_ffa)) + return -ENODEV; + + guard(mutex)(&tpm_crb_ffa->msg_data_lock); + + return __tpm_crb_ffa_send_recieve(CRB_FFA_START, request_type, locality, 0x00); +} +EXPORT_SYMBOL_GPL(tpm_crb_ffa_start); + +static int tpm_crb_ffa_probe(struct ffa_device *ffa_dev) +{ + int rc; + struct tpm_crb_ffa *p; + + /* only one instance of a TPM partition is supported */ + if (tpm_crb_ffa && !IS_ERR_VALUE(tpm_crb_ffa)) + return -EEXIST; + + tpm_crb_ffa = ERR_PTR(-ENODEV); // set tpm_crb_ffa so we can detect probe failure + + if (!ffa_partition_supports_direct_recv(ffa_dev)) { + pr_err("TPM partition doesn't support direct message receive.\n"); + return -EINVAL; + } + + p = kzalloc(sizeof(*tpm_crb_ffa), GFP_KERNEL); + if (!p) + return -ENOMEM; + tpm_crb_ffa = p; + + mutex_init(&tpm_crb_ffa->msg_data_lock); + tpm_crb_ffa->ffa_dev = ffa_dev; + ffa_dev_set_drvdata(ffa_dev, tpm_crb_ffa); + + /* if TPM is aarch32 use 32-bit SMCs */ + if (!ffa_partition_check_property(ffa_dev, FFA_PARTITION_AARCH64_EXEC)) + ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev); + + /* verify compatibility of TPM service version number */ + rc = tpm_crb_ffa_get_interface_version(&tpm_crb_ffa->major_version, + &tpm_crb_ffa->minor_version); + if (rc) { + pr_err("failed to get crb interface version. rc:%d", rc); + goto out; + } + + pr_info("ABI version %u.%u", tpm_crb_ffa->major_version, + tpm_crb_ffa->minor_version); + + if ((tpm_crb_ffa->major_version != CRB_FFA_VERSION_MAJOR) || + (tpm_crb_ffa->minor_version < CRB_FFA_VERSION_MINOR)) { + pr_err("Incompatible ABI version"); + goto out; + } + + return 0; + +out: + kfree(tpm_crb_ffa); + tpm_crb_ffa = ERR_PTR(-ENODEV); + return -EINVAL; +} + +static void tpm_crb_ffa_remove(struct ffa_device *ffa_dev) +{ + kfree(tpm_crb_ffa); + tpm_crb_ffa = NULL; +} + +static const struct ffa_device_id tpm_crb_ffa_device_id[] = { + /* 17b862a4-1806-4faf-86b3-089a58353861 */ + { UUID_INIT(0x17b862a4, 0x1806, 0x4faf, + 0x86, 0xb3, 0x08, 0x9a, 0x58, 0x35, 0x38, 0x61) }, + {} +}; + +static struct ffa_driver tpm_crb_ffa_driver = { + .name = "ffa-crb", + .probe = tpm_crb_ffa_probe, + .remove = tpm_crb_ffa_remove, + .id_table = tpm_crb_ffa_device_id, +}; + +module_ffa_driver(tpm_crb_ffa_driver); + +MODULE_AUTHOR("Arm"); +MODULE_DESCRIPTION("FFA CRB driver"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/char/tpm/tpm_crb_ffa.h b/drivers/char/tpm/tpm_crb_ffa.h new file mode 100644 index 000000000000..da73c299c48c --- /dev/null +++ b/drivers/char/tpm/tpm_crb_ffa.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Arm Ltd. + * + * Authors: + * Stuart Yoder + * + * Maintained by: + * + * This device driver implements the TPM CRB start method + * as defined in the TPM Service Command Response Buffer + * Interface Over FF-A (DEN0138). + */ +#ifndef _TPM_CRB_FFA_H +#define _TPM_CRB_FFA_H + +#if IS_ENABLED(CONFIG_TCG_ARM_CRB_FFA) +int tpm_crb_ffa_init(void); +int tpm_crb_ffa_get_interface_version(uint16_t *major, uint16_t *minor); +int tpm_crb_ffa_start(int request_type, int locality); +#else +static inline int tpm_crb_ffa_init(void) { return 0; } +static inline int tpm_crb_ffa_get_interface_version(uint16_t *major, uint16_t *minor) { return 0; } +static inline int tpm_crb_ffa_start(int request_type, int locality) { return 0; } +#endif + +#define CRB_FFA_START_TYPE_COMMAND 0 +#define CRB_FFA_START_TYPE_LOCALITY_REQUEST 1 + +#endif From patchwork Fri Feb 14 00:27:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13974217 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 533ED53BE; Fri, 14 Feb 2025 00:27:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492878; cv=none; b=D8dgTlkzT5dvD5jlVSAEYAxWlm3zOFFg14nAQI7m/08F5Lp5QJUNDvmmSZTQsYjpJSvSpka+rwljU75/i5OLasQnbxj/7BF70qf8EixhPk0frJCm7OTrMKOXNMnFx6+zf/53H+S9Mq8hSNNXJVml7+Fe9Pu1UjcX7s1yEeQhoRU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492878; c=relaxed/simple; bh=erurvnKCndlcZUUX0TdrNA0ewd1gfKnrKe9z/7uPwPA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bklr+JqnqOLjKgwHqEuUZcs5wBI5sEIfI1viDcFno9Yv4t2QmCTnCNJ/RRrz0KkxzazuF5p2AT5uD1emrX04BUnQJzIzLl3I45AwWbuEGOjrlGpjBCXzV7VBHU4FsCvrQi78E47Cem5Tu+X+mWPsZXDIj2XtCqoihjL+2vt9Gik= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 427151AED; Thu, 13 Feb 2025 16:28:16 -0800 (PST) Received: from beelzebub.ast.arm.com (u203013-lin.austin.arm.com [10.118.28.29]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id B089C3F5A1; Thu, 13 Feb 2025 16:27:55 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 2/5] tpm_crb: refactor check for idle support into TPM into inline function Date: Thu, 13 Feb 2025 18:27:42 -0600 Message-Id: <20250214002745.878890-3-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250214002745.878890-1-stuart.yoder@arm.com> References: <20250214002745.878890-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-acpi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Refactor the two checks for whether the TPM supports idle into a single inline function. Signed-off-by: Stuart Yoder --- drivers/char/tpm/tpm_crb.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index ea085b14ab7c..d696226906a2 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -115,6 +115,16 @@ struct tpm2_crb_pluton { u64 reply_addr; }; +static inline bool tpm_crb_has_idle(u32 start_method) +{ + if ((start_method == ACPI_TPM2_START_METHOD) || + (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || + (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) + return false; + else + return true; +} + static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, unsigned long timeout) { @@ -173,9 +183,7 @@ static int __crb_go_idle(struct device *dev, struct crb_priv *priv) { int rc; - if ((priv->sm == ACPI_TPM2_START_METHOD) || - (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || - (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) + if (!tpm_crb_has_idle(priv->sm)) return 0; iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req); @@ -222,9 +230,7 @@ static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv) { int rc; - if ((priv->sm == ACPI_TPM2_START_METHOD) || - (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || - (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) + if (!tpm_crb_has_idle(priv->sm)) return 0; iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req); From patchwork Fri Feb 14 00:27:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13974214 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 54A1563B9; Fri, 14 Feb 2025 00:27:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492878; cv=none; b=ab4NAED82ywLgfAj4TmJrYw3+Yj+KW+eLDjt7RVTriEjw30L6am+GMsAATAkOF/fY5smRnLpyCJz7pqpss/4yh42c++M5L63S5Wbd/TOtMw25HxUpJ/H8OywN5+D3eXKvRuc2tf/KIuhX8tEBzUpsUdk9YOhTwUqoXDJzP8cq4s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492878; c=relaxed/simple; bh=SvYIUsvI5FBjGU4eAJImdjcnKIvJmowA4jxSaBrpb2Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qymrn9Oex5PGV3G0YedwfJ61X6pLD0ovDk0TDYdNJDGrHkLfaJpUwWJvHzuyyPVQIxF1GuFC1AZ4COxHGKN8S4QygkqWFyO/yvbhAC8W7jP+RpOqMIVMcq1zfObxBtjvOD2Pn+q3vw4hB7UKmhEpEy5b0zMsbwOMaV8u0HkzsAM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5E6B41E2F; Thu, 13 Feb 2025 16:28:16 -0800 (PST) Received: from beelzebub.ast.arm.com (u203013-lin.austin.arm.com [10.118.28.29]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C3ADC3F762; Thu, 13 Feb 2025 16:27:55 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/5] ACPICA: add start method for Arm FF-A Date: Thu, 13 Feb 2025 18:27:43 -0600 Message-Id: <20250214002745.878890-4-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250214002745.878890-1-stuart.yoder@arm.com> References: <20250214002745.878890-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-acpi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add TPM start method for Arm FF-A defined in the TCG ACPI specification v1.4. Link: https://github.com/acpica/acpica/pull/1000 Signed-off-by: Stuart Yoder --- include/acpi/actbl3.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h index 5cd755143b7d..a97b1dbab975 100644 --- a/include/acpi/actbl3.h +++ b/include/acpi/actbl3.h @@ -466,6 +466,7 @@ struct acpi_tpm2_phy { #define ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC 11 /* V1.2 Rev 8 */ #define ACPI_TPM2_RESERVED 12 #define ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON 13 +#define ACPI_TPM2_CRB_WITH_ARM_FFA 15 /* Optional trailer appears after any start_method subtables */ From patchwork Fri Feb 14 00:27:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13974216 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 975496FC5; Fri, 14 Feb 2025 00:27:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492878; cv=none; b=GjbVzh2AjiQLkol2Sb4Bs+doQfNag5VFyDR3jbqxz0kSlp2KssY1KclfrGeGS/wcd2c8j2gJ22OVF4IwP6iuHXD0PICKY/rbjPbwIaJaAmVl9D6AM3OAnecgzkwA+/ESm3VfARsNijF5QmXatA0ksh1epzoDuuDuWxQn058ueD4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492878; c=relaxed/simple; bh=OqYUk/Qg81szF76C0zKm3qqVF4r6kYELaEc6i/c3Qjk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XPXQKh2ejMS+tlv0aJ4RrL7ho5ao89lig3Y0peeHDc01coBdBHZwxogGdqDDWobsC37ljb9dUVohtsV47wO1cuZqpqwaPSSNas9kEERQz2PVKBHrXgQEL22nbaZF6ijgjZ1vsY3km3QtjbAPw6ImQhl2g+XCjIK4Vz+whT/jOC0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7241E26BE; Thu, 13 Feb 2025 16:28:16 -0800 (PST) Received: from beelzebub.ast.arm.com (u203013-lin.austin.arm.com [10.118.28.29]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id DFF5A3F5A1; Thu, 13 Feb 2025 16:27:55 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 4/5] tpm_crb: add support for the Arm FF-A start method Date: Thu, 13 Feb 2025 18:27:44 -0600 Message-Id: <20250214002745.878890-5-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250214002745.878890-1-stuart.yoder@arm.com> References: <20250214002745.878890-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-acpi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The TCG ACPI spec v1.4 defines a start method for the TPMs implemented with the Arm CRB over FF-A ABI. Add support for the FF-A start method, and use interfaces provided by the ffa_crb driver to interact with the FF-A based TPM. Signed-off-by: Stuart Yoder --- drivers/char/tpm/tpm_crb.c | 65 +++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index d696226906a2..486be5ea82bb 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -19,6 +19,7 @@ #ifdef CONFIG_ARM64 #include #endif +#include "tpm_crb_ffa.h" #include "tpm.h" #define ACPI_SIG_TPM2 "TPM2" @@ -100,6 +101,8 @@ struct crb_priv { u32 smc_func_id; u32 __iomem *pluton_start_addr; u32 __iomem *pluton_reply_addr; + u8 ffa_flags; + u8 ffa_attributes; }; struct tpm2_crb_smc { @@ -110,6 +113,14 @@ struct tpm2_crb_smc { u32 smc_func_id; }; +/* CRB over FFA start method parameters in TCG2 ACPI table */ +struct tpm2_crb_ffa { + u8 flags; + u8 attributes; + u16 partition_id; + u8 reserved[8]; +}; + struct tpm2_crb_pluton { u64 start_addr; u64 reply_addr; @@ -119,7 +130,8 @@ static inline bool tpm_crb_has_idle(u32 start_method) { if ((start_method == ACPI_TPM2_START_METHOD) || (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || - (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) + (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) || + (start_method == ACPI_TPM2_CRB_WITH_ARM_FFA)) return false; else return true; @@ -261,6 +273,7 @@ static int crb_cmd_ready(struct tpm_chip *chip) static int __crb_request_locality(struct device *dev, struct crb_priv *priv, int loc) { + int rc; u32 value = CRB_LOC_STATE_LOC_ASSIGNED | CRB_LOC_STATE_TPM_REG_VALID_STS; @@ -268,6 +281,13 @@ static int __crb_request_locality(struct device *dev, return 0; iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl); + + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_LOCALITY_REQUEST, loc); + if (rc) + return rc; + } + if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, value, value, TPM2_TIMEOUT_C)) { dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); @@ -287,6 +307,7 @@ static int crb_request_locality(struct tpm_chip *chip, int loc) static int __crb_relinquish_locality(struct device *dev, struct crb_priv *priv, int loc) { + int rc; u32 mask = CRB_LOC_STATE_LOC_ASSIGNED | CRB_LOC_STATE_TPM_REG_VALID_STS; u32 value = CRB_LOC_STATE_TPM_REG_VALID_STS; @@ -295,6 +316,13 @@ static int __crb_relinquish_locality(struct device *dev, return 0; iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl); + + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_LOCALITY_REQUEST, loc); + if (rc) + return rc; + } + if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value, TPM2_TIMEOUT_C)) { dev_warn(dev, "TPM_LOC_STATE_x.Relinquish timed out\n"); @@ -443,6 +471,11 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len) rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id); } + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start); + rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, chip->locality); + } + if (rc) return rc; @@ -451,6 +484,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len) static void crb_cancel(struct tpm_chip *chip) { + int rc; struct crb_priv *priv = dev_get_drvdata(&chip->dev); iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel); @@ -459,6 +493,12 @@ static void crb_cancel(struct tpm_chip *chip) (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)) && crb_do_acpi_start(chip)) dev_err(&chip->dev, "ACPI Start failed\n"); + + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, chip->locality); + if (rc) + dev_err(&chip->dev, "FF-A Start failed\n"); + } } static bool crb_req_canceled(struct tpm_chip *chip, u8 status) @@ -616,6 +656,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, * stuff that puts the control area outside the ACPI IO region. */ if ((priv->sm == ACPI_TPM2_COMMAND_BUFFER) || + (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) || (priv->sm == ACPI_TPM2_MEMORY_MAPPED)) { if (iores && buf->control_address == iores->start + @@ -737,6 +778,7 @@ static int crb_acpi_add(struct acpi_device *device) struct tpm_chip *chip; struct device *dev = &device->dev; struct tpm2_crb_smc *crb_smc; + struct tpm2_crb_ffa *crb_ffa; struct tpm2_crb_pluton *crb_pluton; acpi_status status; u32 sm; @@ -775,6 +817,27 @@ static int crb_acpi_add(struct acpi_device *device) priv->smc_func_id = crb_smc->smc_func_id; } + if (sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + if (buf->header.length < (sizeof(*buf) + sizeof(*crb_ffa))) { + dev_err(dev, + FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n", + buf->header.length, + ACPI_TPM2_CRB_WITH_ARM_FFA); + rc = -EINVAL; + goto out; + } + crb_ffa = ACPI_ADD_PTR(struct tpm2_crb_ffa, buf, sizeof(*buf)); + priv->ffa_flags = crb_ffa->flags; + priv->ffa_attributes = crb_ffa->attributes; + rc = tpm_crb_ffa_init(); + if (rc) { + if (rc == -ENOENT) { // FF-A driver is not available yet + rc = -EPROBE_DEFER; + } + goto out; + } + } + if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) { if (buf->header.length < (sizeof(*buf) + sizeof(*crb_pluton))) { dev_err(dev, From patchwork Fri Feb 14 00:27:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13974218 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C659CCA4E; Fri, 14 Feb 2025 00:27:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492880; cv=none; b=qWdhxj53AIYhvGjPOgtNkYhRJ3jpQvYIQmf/Q7xrBTDkYdoeJ8rwQ0/zdnCyfhK+ykQG2l4Viyu2pDClOEFA0FsF2BaJru5MKHA3nmT7YrXLodK6Y7goMAalpT3z32VltFe8Fy1uMhgd5y4wrbGinLH1mDl+OTxMXPfLcrhpoHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739492880; c=relaxed/simple; bh=jUSUz00ESf+S26jtK/k3pKofGf7cV8jQzbW7nQEsROM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=l+FCfgNwqQRqCBXwsOJ4aUerSjut7UNXHrQ2T0k6GytsU5o34NwA78L/8bKTdFI/nLfYUu+1dHSHeCkYSKjzw7lNyPZoqJ8QmqiS2P7uff9cM4sK0WqDkJRY/EOz6I7hLgkjmfD5ewfr1WrMoAwhZKE1FMpee8dTMRZEuQgbJFs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 855F4271B; Thu, 13 Feb 2025 16:28:16 -0800 (PST) Received: from beelzebub.ast.arm.com (u203013-lin.austin.arm.com [10.118.28.29]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id F37613F762; Thu, 13 Feb 2025 16:27:55 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 5/5] Documentation: tpm: add documentation for the CRB FF-A interface Date: Thu, 13 Feb 2025 18:27:45 -0600 Message-Id: <20250214002745.878890-6-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250214002745.878890-1-stuart.yoder@arm.com> References: <20250214002745.878890-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-acpi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add documentation providing details of how the CRB driver interacts with FF-A. Signed-off-by: Stuart Yoder --- Documentation/security/tpm/tpm_ffa_crb.rst | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/security/tpm/tpm_ffa_crb.rst diff --git a/Documentation/security/tpm/tpm_ffa_crb.rst b/Documentation/security/tpm/tpm_ffa_crb.rst new file mode 100644 index 000000000000..0184193da3c7 --- /dev/null +++ b/Documentation/security/tpm/tpm_ffa_crb.rst @@ -0,0 +1,65 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================== +TPM CRB over FF-A Driver +======================== + +The TPM Command Response Buffer (CRB) interface is a standard TPM interface +defined in the TCG PC Client Platform TPM Profile (PTP) Specification [1]_. +The CRB provides a structured set of control registers a client uses when +interacting with a TPM as well as a data buffer for storing TPM commands and +responses. A CRB interface can be implemented in: + +- hardware registers in a discrete TPM chip + +- in memory for a TPM running in isolated environment where shared memory + allows a client to interact with the TPM + +The Firmware Framework for Arm A-profile (FF-A) [2]_ is a specification +that defines interfaces and protocols for the following purposes: + +- Compartmentalize firmware into software partitions that run in the Arm + Secure world environment (also know as TrustZone) + +- Provide a standard interface for software components in the Non-secure + state, for example OS and Hypervisors, to communicate with this firmware. + +A TPM can be implemented as an FF-A secure service. This could be a firmware +TPM or could potentially be a TPM service that acts as a proxy to a discrete +TPM chip. An FF-A based TPM abstracts hardware details (e.g. bus controller +and chip selects) away from the OS and can protect locality 4 from access +by an OS. The TCG-defined CRB interface is used by clients to interact +with the TPM service. + +The Arm TPM Service Command Response Buffer Interface Over FF-A [3]_ +specification defines FF-A messages that can be used by a client to signal +when updates have been made to the CRB. + +How the Linux CRB driver interacts with FF-A is summarized below: + +- The tpm_crb_ffa driver registers with the FF-A subsystem in the kernel + with an architected TPM service UUID defined in the CRB over FF-A spec. + +- If a TPM service is discovered by FF-A, the probe() function in the + tpm_crb_ffa driver runs, and the driver initializes. + +- The probing and initialization of the Linux CRB driver is triggered + by the discovery of a TPM advertised via ACPI. The CRB driver can + detect the type of TPM through the ACPI 'start' method. The start + method for Arm FF-A was defined in TCG ACPI v1.4 [4]_. + +- When the CRB driver performs its normal functions such as signaling 'start' + and locality request/relinquish it invokes the tpm_crb_ffa_start() funnction + in the tpm_crb_ffa driver which handles the FF-A messaging to the TPM. + +References +========== + +.. [1] **TCG PC Client Platform TPM Profile (PTP) Specification** + https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/ +.. [2] **Arm Firmware Framework for Arm A-profile (FF-A)** + https://developer.arm.com/documentation/den0077/latest/ +.. [3] **Arm TPM Service Command Response Buffer Interface Over FF-A** + https://developer.arm.com/documentation/den0138/latest/ +.. [4] **TCG ACPI Specification** + https://trustedcomputinggroup.org/resource/tcg-acpi-specification/