From nobody Tue Dec 16 16:35:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A949C324B3B; Wed, 10 Dec 2025 17:20:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387240; cv=none; b=r5PSH6HLmJpcYu9qeR4Ii237lMul41VhTRjN02HTdMWjhf1Jki+pRa0wuzIYjCYI1uAYltkaZjKmb+oYDYXNNioAot6MF/jLDCuW94xvrht9DGYMBVbMBJ23I8Sq1Gqr+ao5TNLe82HFdi/AKPajgU3rOFyXWMpfYeU5wip0XFA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387240; c=relaxed/simple; bh=oKOYQ71Z+3HVJRFfeQlrhZzg8coYWIMYBLNyPIQ6zBg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=k7akdfqFZUt9OSAWah12KZILEDeC2AzMsdkCVjXb+b3nQANQbWed0Q+ZgTTgR7GEpx/CwZr0XZR1xPkdsmPyzlAGD+t1W5Q1WhBEpr5rePt9AH1FbSzpmcv05sfmPDvTacqut0gROTkdQYkwQWmZcUI9Wx2tbu0wc9D+GUnAElM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rlBz1who; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rlBz1who" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C0E46C4CEF1; Wed, 10 Dec 2025 17:20:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765387240; bh=oKOYQ71Z+3HVJRFfeQlrhZzg8coYWIMYBLNyPIQ6zBg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rlBz1whoH137JQKUdbf5NFbxwg5SoUu6Mc032J2kAI8IGiO8Ac6sTTvVTUIbAjByR euga85shpXGSRILbDS01uLDlQVRd3H96YDCb6gXaDhCvs9HlfUzBLBdZp+9mjb5Ja0 MfVK5P08NGWP6VgyE5blzxyD0zior4gJzr6W78AmsYdAw/TQXCGDS4tNMXc2KIDagy lhK0ow/RZFJj2nFyOLpAYMT4Qlg4dnsIq/s8pGvZ+neBHeL4LT14bXkhoqHxZQ+Qet l5H1Lb6v741Ic323PPmIjt25lQEZCyetDvpeJ3ILtaRKum4lPFGR6H39ILNHjVWX/+ AYHkcuXEtqVrw== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , James Bottomley , Mimi Zohar , keyrings@vger.kernel.org (open list:KEYS/KEYRINGS), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v4 1/8] KEYS: trusted: Remove dead branch from tpm2_unseal_cmd Date: Wed, 10 Dec 2025 19:20:19 +0200 Message-Id: <20251210172027.109938-2-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251210172027.109938-1-jarkko@kernel.org> References: <20251210172027.109938-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" TPM2_Unseal requires TPM2_ST_SESSIONS, and tpm2_unseal_cmd() always does set up either password or HMAC session. Remove the branch in tpm2_unseal_cmd() conditionally setting TPM2_ST_NO_SESSIONS. It is faulty but luckily it is never exercised at run-time, and thus does not cause regressions. Signed-off-by: Jarkko Sakkinen --- security/keys/trusted-keys/trusted_tpm2.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trus= ted-keys/trusted_tpm2.c index 9074ae1a5896..27424e1a4a63 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -450,9 +450,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, struct trusted_key_options *options, u32 blob_handle) { - struct tpm_header *head; u16 data_len; - int offset; u8 *data; int rc; =20 @@ -488,14 +486,8 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, tpm_buf_append_u16(buf, options->blobauth_len); tpm_buf_append(buf, options->blobauth, options->blobauth_len); =20 - if (tpm2_chip_auth(chip)) { + if (tpm2_chip_auth(chip)) tpm_buf_append_hmac_session(chip, buf, TPM2_SA_ENCRYPT, NULL, 0); - } else { - offset =3D buf->handles * 4 + TPM_HEADER_SIZE; - head =3D (struct tpm_header *)buf->data; - if (tpm_buf_length(buf) =3D=3D offset) - head->tag =3D cpu_to_be16(TPM2_ST_NO_SESSIONS); - } } =20 rc =3D tpm_buf_fill_hmac_session(chip, buf); --=20 2.39.5 From nobody Tue Dec 16 16:35:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6663F7260F; Wed, 10 Dec 2025 17:20:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387248; cv=none; b=Uf53D8nJP0nIj68NUBHt/2SDoyfUIWYAY0rKey8d0bCg1bCDAT0ERwh6DtPW4erGR6mKRbA0SnL1dmzArfh1pPd+WnJYoQI4QPqE7W12Mw15AJqiBH17GE3nAZChiJ35+96dl3tfnS8M8TcSdZ7xaZNCJ/vke6ekjXwm5Rgw/lA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387248; c=relaxed/simple; bh=YLxoju7ac/XDRjKgxiY9Rq9+9lm1HK2m5estBbEKcmw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KFOlU80E7p7LeMHW16Cmf/OwL4o93KCiUyAkgn7RcMLmee8nYbLGFTfJoollE3xhT8LjDRPnFwNMzBQk9PwdCPywUs+YlE++3pGHjomU0VdduTshZVBVCTx8mt5OcUJdzzxyKOR18grV6ih3DY7izMgZ6hayYNw56PgyN4vczx8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J1r9MKXz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="J1r9MKXz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F72AC4CEF1; Wed, 10 Dec 2025 17:20:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765387246; bh=YLxoju7ac/XDRjKgxiY9Rq9+9lm1HK2m5estBbEKcmw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J1r9MKXz/MJc65c5Ch56fTRwFLK2bpH781ed11ziVtpocg728QetQ1ydbQG2jXSR5 C3oDSkfbmag7lYku3hrmHZrfu5CDf+dPWLWck9U7iYlEc0bozpr5ULX7GZunl1zmVv QGC2dnFEiZkVO94sHQgzp027DPKj3gzI8fzhhY5zNNbhHBzuzLPG0X7ahCNhtv7iT3 3BeinH5JnJvsOfCgIx8+MbYE8AYd4QnhULNZBW8G4nppRTfjuthkEIe+VRzlkSuB75 SxqtvL+gg1s1WX21JVLBQxKlVGyyvusDp9/Aj+lau6X4vUy9/Lv8IP+LCtKOa5ADtt moD9pmzPPSNoA== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Peter Huewe , Jason Gunthorpe , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , linux-kernel@vger.kernel.org (open list), keyrings@vger.kernel.org (open list:KEYS/KEYRINGS), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v4 2/8] tpm2-sessions: Define TPM2_NAME_MAX_SIZE Date: Wed, 10 Dec 2025 19:20:20 +0200 Message-Id: <20251210172027.109938-3-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251210172027.109938-1-jarkko@kernel.org> References: <20251210172027.109938-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This is somewhat cosmetic change but it does serve a purpose on tracking the value set for the maximum length of TPM names, and to clearly states what components it is composed of. It also anchors the value so that when buffers are declared for this particular purpose, the same value is used for the capacity. Signed-off-by: Jarkko Sakkinen --- v2: - Rename TPM2_NAME_SIZE as TPM2_NULL_NAME_SIZE. --- drivers/char/tpm/tpm-sysfs.c | 2 +- drivers/char/tpm/tpm2-sessions.c | 2 +- include/linux/tpm.h | 37 +++++++++++++++++++++----------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c index f5dcadb1ab3c..0f321c307bc6 100644 --- a/drivers/char/tpm/tpm-sysfs.c +++ b/drivers/char/tpm/tpm-sysfs.c @@ -313,7 +313,7 @@ static ssize_t null_name_show(struct device *dev, struc= t device_attribute *attr, char *buf) { struct tpm_chip *chip =3D to_tpm_chip(dev); - int size =3D TPM2_NAME_SIZE; + int size =3D TPM2_NULL_NAME_SIZE; =20 bin2hex(buf, chip->null_key_name, size); size *=3D 2; diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessi= ons.c index 79f27a46bd7f..a0c88fb1804c 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -137,7 +137,7 @@ struct tpm2_auth { * we must compute and remember */ u32 name_h[AUTH_MAX_NAMES]; - u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE]; + u8 name[AUTH_MAX_NAMES][TPM2_MAX_NAME_SIZE]; }; =20 #ifdef CONFIG_TCG_TPM2_HMAC diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 42e2a091f43d..922a43ef23b5 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -28,9 +28,33 @@ #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ #define TPM_BUFSIZE 4096 =20 +/* + * SHA-512 is, as of today, the largest digest in the TCG algorithm reposi= tory. + */ #define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE + +/* + * A TPM name digest i.e., TPMT_HA, is a concatenation of TPM_ALG_ID of the + * name algorithm and hash of TPMT_PUBLIC. + */ +#define TPM2_MAX_NAME_SIZE (TPM2_MAX_DIGEST_SIZE + 2) + +/* + * The maximum number of PCR banks. + */ #define TPM2_MAX_PCR_BANKS 8 =20 +/* + * fixed define for the size of a name. This is actually HASHALG size + * plus 2, so 32 for SHA256 + */ +#define TPM2_NULL_NAME_SIZE 34 + +/* + * The maximum size for an object context + */ +#define TPM2_MAX_CONTEXT_SIZE 4096 + struct tpm_chip; struct trusted_key_payload; struct trusted_key_options; @@ -140,17 +164,6 @@ struct tpm_chip_seqops { /* fixed define for the curve we use which is NIST_P256 */ #define EC_PT_SZ 32 =20 -/* - * fixed define for the size of a name. This is actually HASHALG size - * plus 2, so 32 for SHA256 - */ -#define TPM2_NAME_SIZE 34 - -/* - * The maximum size for an object context - */ -#define TPM2_MAX_CONTEXT_SIZE 4096 - struct tpm_chip { struct device dev; struct device devs; @@ -212,7 +225,7 @@ struct tpm_chip { /* saved context for NULL seed */ u8 null_key_context[TPM2_MAX_CONTEXT_SIZE]; /* name of NULL seed */ - u8 null_key_name[TPM2_NAME_SIZE]; + u8 null_key_name[TPM2_NULL_NAME_SIZE]; u8 null_ec_key_x[EC_PT_SZ]; u8 null_ec_key_y[EC_PT_SZ]; struct tpm2_auth *auth; --=20 2.39.5 From nobody Tue Dec 16 16:35:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6BCC1327201; Wed, 10 Dec 2025 17:20:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387252; cv=none; b=AfqssvtTvzLOpQNfYhJlMrBImfZ0ZPKNacYJz8Q0I+13+Cjr6tDjWpS/6U0RMH+/VmbWYAP2Q/+eMAf+gyK88xmCVAB7n+VO4mI3t9u8+dKkFuK0pyVb9SMf8AthnMnIcA2PXE3o3vITIjcD6NbXtl5w61t0my2A2tdWckS4xZo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387252; c=relaxed/simple; bh=8ikrJONg0iAyMyovZ0kE7z4nq1oqelOAHiNhFFpOxB0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UjRDmVSNJgneUZ5HVu7ueEO3c3koAosrDYHIFN9wQno4pisSlpPYo2L0pG9szEIGcYCUsORCjZ7XGve92TtVsl2039Ya+FKqC9lUE4XwhmOuv3XbDHLWw+2/y7JLesPPWeZKzsNfdrEu4U8wCqy6ZIBvW7fNKkgyEHfaRR1RYLU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Kj1WrMR7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Kj1WrMR7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7248CC19421; Wed, 10 Dec 2025 17:20:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765387252; bh=8ikrJONg0iAyMyovZ0kE7z4nq1oqelOAHiNhFFpOxB0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Kj1WrMR7yI4FSWCxQnBVmLFWh3mhvftVychm8j9rO4P0nmierSIeuY6UdmALpUXA0 ZK9/0jiueYA/as3nX1F0bJJZ4ava6eVLiPsQ/80AFaFlHA9onJbcb9bYFkcrf4WTjg 25qoLwJ2ArTVBJmvvq2sV/pBSyU7QkfZth7YSPbZb2eUoHbAHDOeIxPd4wovzqwW7E FDXMyH4zeTgIgxJduJm64Z0FcTAdFaf6k5e/JvwG8IsWa/skdf99bRZdHgTc87r9F/ WgJNR5v3GnsnVN+5MW/NMCdTAXdycgh50/swunxj6kSTS0oN4vmkRBP/WEDTbxdWia dIh9lYtQL4paA== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Peter Huewe , Jason Gunthorpe , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , James Bottomley , Mimi Zohar , linux-kernel@vger.kernel.org (open list), keyrings@vger.kernel.org (open list:KEYS/KEYRINGS), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v4 3/8] KEYS: trusted: Re-orchestrate tpm2_read_public() calls Date: Wed, 10 Dec 2025 19:20:21 +0200 Message-Id: <20251210172027.109938-4-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251210172027.109938-1-jarkko@kernel.org> References: <20251210172027.109938-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" tpm2_load_cmd() and tpm2_unseal_cmd() use the same parent, and calls to tpm_buf_append_name() cause the exact same TPM2_ReadPublic command to be sent to the chip, causing unnecessary traffic. 1. Export tpm2_read_public in order to make it callable from 'trusted_tpm2'. 2. Re-orchestrate tpm2_seal_trusted() and tpm2_unseal_trusted() in order to halve the name resolutions required: 2a. Move tpm2_read_public() calls into trusted_tpm2. 2b. Pass TPM name to tpm_buf_append_name(). 2c. Rework tpm_buf_append_name() to use the pre-resolved name. Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm2-cmd.c | 3 +- drivers/char/tpm/tpm2-sessions.c | 95 +++++------------ include/linux/tpm.h | 10 +- security/keys/trusted-keys/trusted_tpm2.c | 124 ++++++++++++++-------- 4 files changed, 118 insertions(+), 114 deletions(-) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 543c1c62c938..436ee82620e4 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -199,7 +199,8 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND); =20 if (!disable_pcr_integrity) { - rc =3D tpm_buf_append_name(chip, buf, pcr_idx, NULL); + rc =3D tpm_buf_append_name(chip, buf, pcr_idx, (u8 *)&pcr_idx, + sizeof(u32)); if (rc) return rc; tpm_buf_append_hmac_session(chip, buf, 0, NULL, 0); diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessi= ons.c index a0c88fb1804c..0816a91134fc 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -136,8 +136,8 @@ struct tpm2_auth { * handle, but they are part of the session by name, which * we must compute and remember */ - u32 name_h[AUTH_MAX_NAMES]; u8 name[AUTH_MAX_NAMES][TPM2_MAX_NAME_SIZE]; + u16 name_size_tbl[AUTH_MAX_NAMES]; }; =20 #ifdef CONFIG_TCG_TPM2_HMAC @@ -163,7 +163,17 @@ static int name_size(const u8 *name) } } =20 -static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name) +/** + * tpm2_read_public: Resolve TPM name for a handle + * @chip: TPM chip to use. + * @handle: TPM handle. + * @name: A buffer for returning the name blob. Must have a + * capacity of 'SHA512_DIGET_SIZE + 2' bytes at minimum + * + * Returns size of TPM handle name of success. + * Returns tpm_transmit_cmd error codes when TPM2_ReadPublic fails. + */ +int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name) { u32 mso =3D tpm2_handle_mso(handle); off_t offset =3D TPM_HEADER_SIZE; @@ -212,14 +222,16 @@ static int tpm2_read_public(struct tpm_chip *chip, u3= 2 handle, void *name) memcpy(name, &buf->data[offset], rc); return name_size_alg; } +EXPORT_SYMBOL_GPL(tpm2_read_public); #endif /* CONFIG_TCG_TPM2_HMAC */ =20 /** - * tpm_buf_append_name() - add a handle area to the buffer - * @chip: the TPM chip structure - * @buf: The buffer to be appended - * @handle: The handle to be appended - * @name: The name of the handle (may be NULL) + * tpm_buf_append_name() - Append a handle and store TPM name + * @chip: TPM chip to use. + * @buf: TPM buffer containing the TPM command in-transit. + * @handle: TPM handle to be appended. + * @name: TPM name of the handle + * @name_size: Size of the TPM name. * * In order to compute session HMACs, we need to know the names of the * objects pointed to by the handles. For most objects, this is simply @@ -236,15 +248,14 @@ static int tpm2_read_public(struct tpm_chip *chip, u3= 2 handle, void *name) * will be caused by an incorrect programming model and indicated by a * kernel message. * - * Ends the authorization session on failure. + * Returns zero on success. + * Returns -EIO when the authorization area state is malformed. */ int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, - u32 handle, u8 *name) + u32 handle, u8 *name, u16 name_size) { #ifdef CONFIG_TCG_TPM2_HMAC - enum tpm2_mso_type mso =3D tpm2_handle_mso(handle); struct tpm2_auth *auth; - u16 name_size_alg; int slot; int ret; #endif @@ -269,36 +280,15 @@ int tpm_buf_append_name(struct tpm_chip *chip, struct= tpm_buf *buf, } tpm_buf_append_u32(buf, handle); auth->session +=3D 4; - - if (mso =3D=3D TPM2_MSO_PERSISTENT || - mso =3D=3D TPM2_MSO_VOLATILE || - mso =3D=3D TPM2_MSO_NVRAM) { - if (!name) { - ret =3D tpm2_read_public(chip, handle, auth->name[slot]); - if (ret < 0) - goto err; - - name_size_alg =3D ret; - } - } else { - if (name) { - dev_err(&chip->dev, "handle 0x%08x does not use a name\n", - handle); - ret =3D -EIO; - goto err; - } - } - - auth->name_h[slot] =3D handle; - if (name) - memcpy(auth->name[slot], name, name_size_alg); + memcpy(auth->name[slot], name, name_size); + auth->name_size_tbl[slot] =3D name_size; #endif return 0; =20 #ifdef CONFIG_TCG_TPM2_HMAC err: tpm2_end_auth_session(chip); - return tpm_ret_to_err(ret); + return ret; #endif } EXPORT_SYMBOL_GPL(tpm_buf_append_name); @@ -606,22 +596,8 @@ int tpm_buf_fill_hmac_session(struct tpm_chip *chip, s= truct tpm_buf *buf) attrs =3D chip->cc_attrs_tbl[i]; =20 handles =3D (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0); + offset_s +=3D handles * sizeof(u32); =20 - /* - * just check the names, it's easy to make mistakes. This - * would happen if someone added a handle via - * tpm_buf_append_u32() instead of tpm_buf_append_name() - */ - for (i =3D 0; i < handles; i++) { - u32 handle =3D tpm_buf_read_u32(buf, &offset_s); - - if (auth->name_h[i] !=3D handle) { - dev_err(&chip->dev, "invalid handle 0x%08x\n", handle); - ret =3D -EIO; - goto err; - } - } - /* point offset_s to the start of the sessions */ val =3D tpm_buf_read_u32(buf, &offset_s); /* point offset_p to the start of the parameters */ offset_p =3D offset_s + val; @@ -682,23 +658,8 @@ int tpm_buf_fill_hmac_session(struct tpm_chip *chip, s= truct tpm_buf *buf) /* ordinal is already BE */ sha256_update(&sctx, (u8 *)&head->ordinal, sizeof(head->ordinal)); /* add the handle names */ - for (i =3D 0; i < handles; i++) { - enum tpm2_mso_type mso =3D tpm2_handle_mso(auth->name_h[i]); - - if (mso =3D=3D TPM2_MSO_PERSISTENT || - mso =3D=3D TPM2_MSO_VOLATILE || - mso =3D=3D TPM2_MSO_NVRAM) { - ret =3D name_size(auth->name[i]); - if (ret < 0) - goto err; - - sha256_update(&sctx, auth->name[i], ret); - } else { - __be32 h =3D cpu_to_be32(auth->name_h[i]); - - sha256_update(&sctx, (u8 *)&h, 4); - } - } + for (i =3D 0; i < handles; i++) + sha256_update(&sctx, auth->name[i], auth->name_size_tbl[i]); if (offset_s !=3D tpm_buf_length(buf)) sha256_update(&sctx, &buf->data[offset_s], tpm_buf_length(buf) - offset_s); diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 922a43ef23b5..9f684fc7ae04 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -543,7 +543,7 @@ static inline struct tpm2_auth *tpm2_chip_auth(struct t= pm_chip *chip) } =20 int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, - u32 handle, u8 *name); + u32 handle, u8 *name, u16 name_size); void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *bu= f, u8 attributes, u8 *passphrase, int passphraselen); @@ -557,6 +557,7 @@ int tpm_buf_fill_hmac_session(struct tpm_chip *chip, st= ruct tpm_buf *buf); int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf, int rc); void tpm2_end_auth_session(struct tpm_chip *chip); +int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name); #else #include =20 @@ -580,6 +581,13 @@ static inline int tpm_buf_check_hmac_response(struct t= pm_chip *chip, { return rc; } + +static inline int tpm2_read_public(struct tpm_chip *chip, u32 handle, + void *name) +{ + memcpy(name, &handle, sizeof(u32)); + return sizeof(u32); +} #endif /* CONFIG_TCG_TPM2_HMAC */ =20 #endif diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trus= ted-keys/trusted_tpm2.c index 27424e1a4a63..63539b344ffb 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -203,7 +203,9 @@ int tpm2_seal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options) { + u8 parent_name[TPM2_MAX_NAME_SIZE]; off_t offset =3D TPM_HEADER_SIZE; + u16 parent_name_size; int blob_len =3D 0; int hash; u32 flags; @@ -220,6 +222,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip, if (rc) return rc; =20 + rc =3D tpm2_read_public(chip, options->keyhandle, parent_name); + if (rc < 0) + goto out_put; + + parent_name_size =3D rc; + rc =3D tpm2_start_auth_session(chip); if (rc) goto out_put; @@ -234,7 +242,8 @@ int tpm2_seal_trusted(struct tpm_chip *chip, tpm_buf_init(buf, TPM_BUFSIZE); tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); =20 - rc =3D tpm_buf_append_name(chip, buf, options->keyhandle, NULL); + rc =3D tpm_buf_append_name(chip, buf, options->keyhandle, parent_name, + parent_name_size); if (rc) goto out_put; =20 @@ -326,48 +335,38 @@ int tpm2_seal_trusted(struct tpm_chip *chip, } =20 /** - * tpm2_load_cmd() - execute a TPM2_Load command - * - * @chip: TPM chip to use - * @payload: the key data in clear and encrypted form - * @options: authentication values and other options - * @blob_handle: returned blob handle + * tpm2_load_cmd() - Execute TPM2_Load + * @chip: TPM chip to use. + * @payload: Key data in clear text. + * @options: Trusted key options. + * @parent_name: A cryptographic name, i.e. a TPMT_HA blob, of the + * parent key. + * @blob: The decoded payload for the key. + * @blob_handle: On success, will contain handle to the loaded keyedhash + * blob. * - * Return: 0 on success. - * -E2BIG on wrong payload size. - * -EPERM on tpm error status. - * < 0 error from tpm_send. + * Return -E2BIG when the blob size is too small for all the data. + * Returns tpm_transmit_cmd() error codes when either TPM2_Load fails. */ static int tpm2_load_cmd(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options, + u8 *parent_name, + u16 parent_name_size, + const u8 *blob, u32 *blob_handle) { u8 *blob_ref __free(kfree) =3D NULL; unsigned int private_len; unsigned int public_len; unsigned int blob_len; - u8 *blob, *pub; + const u8 *pub; int rc; u32 attrs; =20 - rc =3D tpm2_key_decode(payload, options, &blob); - if (rc) { - /* old form */ - blob =3D payload->blob; - payload->old_format =3D 1; - } else { - /* Bind for cleanup: */ - blob_ref =3D blob; - } - - /* new format carries keyhandle but old format doesn't */ - if (!options->keyhandle) - return -EINVAL; - /* must be big enough for at least the two be16 size counts */ if (payload->blob_len < 4) - return -EINVAL; + return -E2BIG; =20 private_len =3D get_unaligned_be16(blob); =20 @@ -406,7 +405,8 @@ static int tpm2_load_cmd(struct tpm_chip *chip, tpm_buf_init(buf, TPM_BUFSIZE); tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD); =20 - rc =3D tpm_buf_append_name(chip, buf, options->keyhandle, NULL); + rc =3D tpm_buf_append_name(chip, buf, options->keyhandle, parent_name, + parent_name_size); if (rc) return rc; =20 @@ -434,20 +434,23 @@ static int tpm2_load_cmd(struct tpm_chip *chip, } =20 /** - * tpm2_unseal_cmd() - execute a TPM2_Unload command + * tpm2_unseal_cmd() - Execute TPM2_Unload * - * @chip: TPM chip to use - * @payload: the key data in clear and encrypted form - * @options: authentication values and other options - * @blob_handle: blob handle + * @chip: TPM chip to use + * @payload: Key data in clear text. + * @options: Trusted key options. + * @parent_name: A cryptographic name, i.e. a TPMT_HA blob, of the + * parent key. + * @blob_handle: Handle to the loaded keyedhash blob. * - * Return: 0 on success - * -EPERM on tpm error status - * < 0 error from tpm_send + * Return -E2BIG when the blob size is too small for all the data. + * Returns tpm_transmit_cmd() error codes when either TPM2_Load fails. */ static int tpm2_unseal_cmd(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options, + u8 *parent_name, + u16 parent_name_size, u32 blob_handle) { u16 data_len; @@ -465,7 +468,8 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, tpm_buf_init(buf, TPM_BUFSIZE); tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL); =20 - rc =3D tpm_buf_append_name(chip, buf, options->keyhandle, NULL); + rc =3D tpm_buf_append_name(chip, buf, options->keyhandle, parent_name, + parent_name_size); if (rc) return rc; =20 @@ -526,30 +530,60 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, } =20 /** - * tpm2_unseal_trusted() - unseal the payload of a trusted key + * tpm2_unseal_trusted() - Unseal a trusted key + * @chip: TPM chip to use. + * @payload: Key data in clear text. + * @options: Trusted key options. * - * @chip: TPM chip to use - * @payload: the key data in clear and encrypted form - * @options: authentication values and other options - * - * Return: Same as with tpm_send. + * Return -E2BIG when the blob size is too small for all the data. + * Return -EINVAL when parent's key handle has not been set. + * Returns tpm_transmit_cmd() error codes when either TPM2_Load or TPM2_Un= seal + * fails. */ int tpm2_unseal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options) { + u8 *blob_ref __free(kfree) =3D NULL; + u8 parent_name[TPM2_MAX_NAME_SIZE]; + u16 parent_name_size; u32 blob_handle; + u8 *blob; int rc; =20 + /* + * Try to decode the provided blob as an ASN.1 blob. Assume that the + * blob is in the legacy format if decoding does not end successfully. + */ + rc =3D tpm2_key_decode(payload, options, &blob); + if (rc) { + blob =3D payload->blob; + payload->old_format =3D 1; + } else { + blob_ref =3D blob; + } + + if (!options->keyhandle) + return -EINVAL; + rc =3D tpm_try_get_ops(chip); if (rc) return rc; =20 - rc =3D tpm2_load_cmd(chip, payload, options, &blob_handle); + rc =3D tpm2_read_public(chip, options->keyhandle, parent_name); + if (rc < 0) + goto out; + + parent_name_size =3D rc; + + rc =3D tpm2_load_cmd(chip, payload, options, parent_name, + parent_name_size, blob, &blob_handle); if (rc) goto out; =20 - rc =3D tpm2_unseal_cmd(chip, payload, options, blob_handle); + rc =3D tpm2_unseal_cmd(chip, payload, options, parent_name, + parent_name_size, blob_handle); + tpm2_flush_context(chip, blob_handle); =20 out: --=20 2.39.5 From nobody Tue Dec 16 16:35:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E6A0324B3B; Wed, 10 Dec 2025 17:20:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387257; cv=none; b=n8qFOAO8f7Q6E0MrCCuQ/NNmQ35/RO+UDCbPbxdOA2+/W9G2GhOiLNRB4hqBQrU9tQVypv7Vl0WopmAjrVQ2XvjVW38WNXeYvxS7xMMsy3mEmsORb1mzxKLF5s+lO1H1zB5MPiQeURKAG8583+tVzC0XIYT2kFfqrSy9sf6Pr8I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387257; c=relaxed/simple; bh=Wz61wVnDzRdflPtBF10cm2FsT3zRCVnTKs79IJUARzE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=b9lhbuobHN4bQNqV5jaW5QwdcNgfNAkkynSlh+xubEyW5M3NggXFMGdQxnkfN1UUDc3H7nP/X8RtwKXrbi1OGUWGN43FJUyQwIEgHfeTu8Av+1vZZEVqOjamk/VHixfuoXsTgPM8HtS/b4Qp63FDM7pECpUCZy1yhsJ0DvjyX1E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MXRWXBwq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MXRWXBwq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8EF48C4CEF1; Wed, 10 Dec 2025 17:20:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765387257; bh=Wz61wVnDzRdflPtBF10cm2FsT3zRCVnTKs79IJUARzE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MXRWXBwqd5Dk2odW1HkXZC8CC6gaKL0RtZvaf8a+LBdrsfp+y3htAeMG3mMMh3HLr 4LsIbzM6rw4eMK3DlOG2xCFkZsswAqYfCYPGtv6w2hiO8n7qcH2lTxrD7cwydoF5fq k2Q/6iz+0N46oT3m9ayVHSLg74b+PGFk0FIlKcJ0QGI17lithnsGs2KkOkysVRCr+Z 1hFJ7SM3/mDB6UGpInomKGu1VzQgvoi9529cOpRLD9PA/T54s/7OrRQnezI6ARvvDd HneT5XZ+CQK0RVislEEUQmmD2reLOT1u4rbqyCqIMN574byI5Stagwqip4M8CIzBeK V3iqAeYL5ByDQ== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Peter Huewe , Jason Gunthorpe , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , linux-kernel@vger.kernel.org (open list), keyrings@vger.kernel.org (open list:KEYS/KEYRINGS), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v4 4/8] tpm2-sessions: Remove AUTH_MAX_NAMES Date: Wed, 10 Dec 2025 19:20:22 +0200 Message-Id: <20251210172027.109938-5-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251210172027.109938-1-jarkko@kernel.org> References: <20251210172027.109938-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In all of the call sites only one session is ever append. Thus, reduce AUTH_MAX_NAMES, which leads into removing constant completely. Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm2-sessions.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessi= ons.c index 0816a91134fc..62a200ae72d7 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -72,9 +72,6 @@ #include #include =20 -/* maximum number of names the TPM must remember for authorization */ -#define AUTH_MAX_NAMES 3 - #define AES_KEY_BYTES AES_KEYSIZE_128 #define AES_KEY_BITS (AES_KEY_BYTES*8) =20 @@ -136,8 +133,8 @@ struct tpm2_auth { * handle, but they are part of the session by name, which * we must compute and remember */ - u8 name[AUTH_MAX_NAMES][TPM2_MAX_NAME_SIZE]; - u16 name_size_tbl[AUTH_MAX_NAMES]; + u8 name[TPM2_MAX_NAME_SIZE]; + u16 name_size; }; =20 #ifdef CONFIG_TCG_TPM2_HMAC @@ -254,11 +251,14 @@ EXPORT_SYMBOL_GPL(tpm2_read_public); int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, u32 handle, u8 *name, u16 name_size) { -#ifdef CONFIG_TCG_TPM2_HMAC struct tpm2_auth *auth; - int slot; int ret; -#endif + + if (tpm_buf_length(buf) !=3D TPM_HEADER_SIZE) { + dev_err(&chip->dev, "too many handles\n"); + ret =3D -EIO; + goto err; + } =20 if (!tpm2_chip_auth(chip)) { tpm_buf_append_handle(buf, handle); @@ -266,12 +266,6 @@ int tpm_buf_append_name(struct tpm_chip *chip, struct = tpm_buf *buf, } =20 #ifdef CONFIG_TCG_TPM2_HMAC - slot =3D (tpm_buf_length(buf) - TPM_HEADER_SIZE) / 4; - if (slot >=3D AUTH_MAX_NAMES) { - dev_err(&chip->dev, "too many handles\n"); - ret =3D -EIO; - goto err; - } auth =3D chip->auth; if (auth->session !=3D tpm_buf_length(buf)) { dev_err(&chip->dev, "session state malformed"); @@ -280,16 +274,14 @@ int tpm_buf_append_name(struct tpm_chip *chip, struct= tpm_buf *buf, } tpm_buf_append_u32(buf, handle); auth->session +=3D 4; - memcpy(auth->name[slot], name, name_size); - auth->name_size_tbl[slot] =3D name_size; + memcpy(auth->name, name, name_size); + auth->name_size =3D name_size; #endif return 0; =20 -#ifdef CONFIG_TCG_TPM2_HMAC err: tpm2_end_auth_session(chip); return ret; -#endif } EXPORT_SYMBOL_GPL(tpm_buf_append_name); =20 @@ -658,8 +650,7 @@ int tpm_buf_fill_hmac_session(struct tpm_chip *chip, st= ruct tpm_buf *buf) /* ordinal is already BE */ sha256_update(&sctx, (u8 *)&head->ordinal, sizeof(head->ordinal)); /* add the handle names */ - for (i =3D 0; i < handles; i++) - sha256_update(&sctx, auth->name[i], auth->name_size_tbl[i]); + sha256_update(&sctx, auth->name, auth->name_size); if (offset_s !=3D tpm_buf_length(buf)) sha256_update(&sctx, &buf->data[offset_s], tpm_buf_length(buf) - offset_s); --=20 2.39.5 From nobody Tue Dec 16 16:35:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 981DC7260F; Wed, 10 Dec 2025 17:21:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387263; cv=none; b=m7/7C8fDKb1xz8+nBiQ432Jof4AgA97dluxVlgFFcB25c5jqo3PHPPcvuKGr9VmLQb+SmZzuZacDdT1yHLcNGF03nXb3gZN5A5+XC9XsUfHFCOSBoDuE9wyfc5Td/WrdqXrQrnjVGe6IG7klCa3epDSWV+/gmn4JYzuNlmmYN/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387263; c=relaxed/simple; bh=WJPWwhEnL9cZ2qZj1SQCBIP02Hql/+FLIpMhmf94jhE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rITwgRIEpp7NWuVQW9FmxY1th72j1HFwSYEwkdRk5dSJv7WM1MI7GVknLNzM6TszGI+3U3CCYyV/sNI0HprLanSRdvpKPHLxCw2HgmKRAZA/I5Gb3Dbqgw5b5V9UArDXZb89bfevRMDOFCyyNJmAK+8MnKKi4i7RK9rs5aQtOmE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cHP4LWfc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cHP4LWfc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B2154C4CEF1; Wed, 10 Dec 2025 17:21:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765387263; bh=WJPWwhEnL9cZ2qZj1SQCBIP02Hql/+FLIpMhmf94jhE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cHP4LWfcicVy/gvHLfmB7NL/c1tbUhavAXLFNl0zdqaYSTqUww2OHLWK9IpxCh45K SGWcIcibikDaWqq3OgOQNbpHdoICfCge/IPeM6Bchqt/CU5vXow/200HqWT5y79+Lp 5MZvgtULICbxZgdS2EC88Os9rlF1QAYPmuwEyNUPOIGD5qKScbImavroNd2Z49/Ol9 ac7YXT3J5jY7WD9CddsFe4odi25LRlP3KrRcH8rylrTIlhRvHoajxXhswZNnGaqKxs uATnL+u7Ji2IrQaiyFLpRpy8osfoo+QFaQAmJSeZ0Bq/FWEXdpxeLlNMSt6IKx4Hc4 Zrnd9LAqtBPjw== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Peter Huewe , Jason Gunthorpe , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , linux-kernel@vger.kernel.org (open list), keyrings@vger.kernel.org (open list:KEYS/KEYRINGS), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v4 5/8] tpm-buf: Remove tpm_buf_append_handle Date: Wed, 10 Dec 2025 19:20:23 +0200 Message-Id: <20251210172027.109938-6-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251210172027.109938-1-jarkko@kernel.org> References: <20251210172027.109938-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since the number of handles is fixed to a single handle, eliminate all uses of buf->handles and deduce values during compile-time. Signed-off-by: Jarkko Sakkinen --- v2: - Streamline the code change and remove dead code. --- drivers/char/tpm/tpm-buf.c | 25 ------------------------- drivers/char/tpm/tpm2-cmd.c | 6 ++---- drivers/char/tpm/tpm2-sessions.c | 14 ++------------ include/linux/tpm.h | 2 -- 4 files changed, 4 insertions(+), 43 deletions(-) diff --git a/drivers/char/tpm/tpm-buf.c b/drivers/char/tpm/tpm-buf.c index 73be8a87b472..752c69b8a4f5 100644 --- a/drivers/char/tpm/tpm-buf.c +++ b/drivers/char/tpm/tpm-buf.c @@ -40,7 +40,6 @@ static void __tpm_buf_reset(struct tpm_buf *buf, u16 buf_= size, u16 tag, u32 ordi buf->flags =3D 0; buf->length =3D sizeof(*head); buf->capacity =3D buf_size - sizeof(*buf); - buf->handles =3D 0; head->tag =3D cpu_to_be16(tag); head->length =3D cpu_to_be32(sizeof(*head)); head->ordinal =3D cpu_to_be32(ordinal); @@ -56,7 +55,6 @@ static void __tpm_buf_reset_sized(struct tpm_buf *buf, u1= 6 buf_size) buf->flags =3D TPM_BUF_TPM2B; buf->length =3D 2; buf->capacity =3D buf_size - sizeof(*buf); - buf->handles =3D 0; buf->data[0] =3D 0; buf->data[1] =3D 0; } @@ -177,29 +175,6 @@ void tpm_buf_append_u32(struct tpm_buf *buf, const u32= value) } EXPORT_SYMBOL_GPL(tpm_buf_append_u32); =20 -/** - * tpm_buf_append_handle() - Add a handle - * @buf: &tpm_buf instance - * @handle: a TPM object handle - * - * Add a handle to the buffer, and increase the count tracking the number = of - * handles in the command buffer. Works only for command buffers. - */ -void tpm_buf_append_handle(struct tpm_buf *buf, u32 handle) -{ - if (buf->flags & TPM_BUF_INVALID) - return; - - if (buf->flags & TPM_BUF_TPM2B) { - WARN(1, "tpm-buf: invalid type: TPM2B\n"); - buf->flags |=3D TPM_BUF_INVALID; - return; - } - - tpm_buf_append_u32(buf, handle); - buf->handles++; -} - /** * tpm_buf_read() - Read from a TPM buffer * @buf: &tpm_buf instance diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 436ee82620e4..bc50d6b734cf 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -205,7 +205,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, return rc; tpm_buf_append_hmac_session(chip, buf, 0, NULL, 0); } else { - tpm_buf_append_handle(buf, pcr_idx); + tpm_buf_append_u32(buf, pcr_idx); tpm_buf_append_auth(chip, buf, NULL, 0); } =20 @@ -281,10 +281,8 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, s= ize_t max) TPM2_SA_CONTINUE_SESSION, NULL, 0); } else { - offset =3D buf->handles * 4 + TPM_HEADER_SIZE; head =3D (struct tpm_header *)buf->data; - if (tpm_buf_length(buf) =3D=3D offset) - head->tag =3D cpu_to_be16(TPM2_ST_NO_SESSIONS); + head->tag =3D cpu_to_be16(TPM2_ST_NO_SESSIONS); } tpm_buf_append_u16(buf, num_bytes); err =3D tpm_buf_fill_hmac_session(chip, buf); diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessi= ons.c index 62a200ae72d7..f2b8ca893e15 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -261,7 +261,7 @@ int tpm_buf_append_name(struct tpm_chip *chip, struct t= pm_buf *buf, } =20 if (!tpm2_chip_auth(chip)) { - tpm_buf_append_handle(buf, handle); + tpm_buf_append_u32(buf, handle); return 0; } =20 @@ -288,17 +288,7 @@ EXPORT_SYMBOL_GPL(tpm_buf_append_name); void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf, u8 *passphrase, int passphrase_len) { - /* offset tells us where the sessions area begins */ - int offset =3D buf->handles * 4 + TPM_HEADER_SIZE; - u32 len =3D 9 + passphrase_len; - - if (tpm_buf_length(buf) !=3D offset) { - /* not the first session so update the existing length */ - len +=3D get_unaligned_be32(&buf->data[offset]); - put_unaligned_be32(len, &buf->data[offset]); - } else { - tpm_buf_append_u32(buf, len); - } + tpm_buf_append_u32(buf, 9 + passphrase_len); /* auth handle */ tpm_buf_append_u32(buf, TPM2_RS_PW); /* nonce */ diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 9f684fc7ae04..e68995df8796 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -395,7 +395,6 @@ enum tpm_buf_flags { */ struct tpm_buf { u8 flags; - u8 handles; u16 length; u16 capacity; u8 data[]; @@ -441,7 +440,6 @@ void tpm_buf_append_u32(struct tpm_buf *buf, const u32 = value); u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset); u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset); u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset); -void tpm_buf_append_handle(struct tpm_buf *buf, u32 handle); =20 /* * Check if TPM device is in the firmware upgrade mode. --=20 2.39.5 From nobody Tue Dec 16 16:35:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE48F3271E6; Wed, 10 Dec 2025 17:21:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387269; cv=none; b=MffMg9OLJm3hxIO406uoVz1uldsqOl+xo+MrO3k+y8tBf1vp+Ad6dJEq1sD1uAoQunalXatu4M+WLgiiLFI7T7MMdyPRzWaqwnFhjfOA8viQCiuNtaQD70AmDcckTnVUtkrDcvBY9idKE9No5YLl7m1GTg4vzqHo6eBUnzR07Zw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387269; c=relaxed/simple; bh=8qxVDOf6i/LJKg4klr1DvoFMVF1HifDlP9xBWCvLKZw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WwUdNawn92dYQeKmRmmY2NQFl5EDrVwKAvYz71QeVWxTlkGid1FjvlC5UhQVkyirUyLH137gpip/Jn7Oj1NbO02Nt9M7tVisTJKcGpVlktAc2sjVVspxLy3VwDZIIEAqw4lgFMW6xS38g06J6DsYxHFvAIlRHUlem1PpxomPTLw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DNtsvBVz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DNtsvBVz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3FB71C4CEF1; Wed, 10 Dec 2025 17:21:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765387268; bh=8qxVDOf6i/LJKg4klr1DvoFMVF1HifDlP9xBWCvLKZw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DNtsvBVz/OxNPNValOvZDwJ/RICOApzb6RES/e0p6heZmGAJF51985wdiM0e3jAM2 ajPjHZdFjTq3uoJCMZ+7Q3BsdlwHmp1mbXgsn2OUgRmmQfOtuoVJ4jQrUrdWVvbNxr aSqWyZ4gG66vThC3oDimzLyqvylzCX09tIFjm4I3VxqnO5GmIuko29x3a7qMF9WkjO Ueo+KS3NJ6pxdakP51qt11tHHdbLAAAWhsmLZ+vHQ86eTI0FZ1OKZtBXehkaYIkAIo Nj36LAL5u6CEFM3HFOxV7jqeD0EUZgobhvO8rNWME5pDsszclC5yGw2i0zUq3Ui4f6 vsG6tma9cyibg== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Peter Huewe , Jason Gunthorpe , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , linux-kernel@vger.kernel.org (open list), keyrings@vger.kernel.org (open list:KEYS/KEYRINGS), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v4 6/8] tpm: Orchestrate TPM commands in tpm_get_random() Date: Wed, 10 Dec 2025 19:20:24 +0200 Message-Id: <20251210172027.109938-7-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251210172027.109938-1-jarkko@kernel.org> References: <20251210172027.109938-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" tpm1_get_random() and tpm2_get_random() contain duplicate orchestration code. Consolidate orchestration to tpm_get_random(). Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm-interface.c | 165 ++++++++++++++++++++++++++++--- drivers/char/tpm/tpm.h | 2 - drivers/char/tpm/tpm1-cmd.c | 62 ------------ drivers/char/tpm/tpm2-cmd.c | 95 ------------------ 4 files changed, 154 insertions(+), 170 deletions(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interf= ace.c index f745a098908b..ab52a1cb0a78 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include "tpm.h" =20 /* @@ -486,19 +486,143 @@ int tpm_pm_resume(struct device *dev) } EXPORT_SYMBOL_GPL(tpm_pm_resume); =20 +struct tpm1_get_random_out { + __be32 rng_data_len; + u8 rng_data[TPM_MAX_RNG_DATA]; +} __packed; + +static int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max) +{ + struct tpm1_get_random_out *resp; + u32 recd; + int rc; + + if (!out || !max || max > TPM_MAX_RNG_DATA) + return -EINVAL; + + struct tpm_buf *buf __free(kfree) =3D kzalloc(TPM_BUFSIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + tpm_buf_init(buf, TPM_BUFSIZE); + tpm_buf_reset(buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GETRANDOM); + tpm_buf_append_u32(buf, max); + + rc =3D tpm_transmit_cmd(chip, buf, sizeof(resp->rng_data_len), "TPM_GetRa= ndom"); + if (rc) { + if (rc > 0) + rc =3D -EIO; + return rc; + } + + resp =3D (struct tpm1_get_random_out *)&buf->data[TPM_HEADER_SIZE]; + + recd =3D be32_to_cpu(resp->rng_data_len); + if (recd > max) + return -EIO; + + if (buf->length < TPM_HEADER_SIZE + sizeof(resp->rng_data_len) + recd) + return -EIO; + + memcpy(out, resp->rng_data, recd); + return recd; +} + +struct tpm2_get_random_out { + __be16 size; + u8 buffer[TPM_MAX_RNG_DATA]; +} __packed; + +static int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max) +{ + struct tpm2_get_random_out *resp; + struct tpm_header *head; + off_t offset; + u32 recd; + int ret; + + if (!out || !max || max > TPM_MAX_RNG_DATA) + return -EINVAL; + + struct tpm_buf *buf __free(kfree) =3D kzalloc(TPM_BUFSIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + tpm_buf_init(buf, TPM_BUFSIZE); + tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM); + if (tpm2_chip_auth(chip)) { + tpm_buf_append_hmac_session(chip, buf, + TPM2_SA_ENCRYPT | TPM2_SA_CONTINUE_SESSION, + NULL, 0); + } else { + head =3D (struct tpm_header *)buf->data; + head->tag =3D cpu_to_be16(TPM2_ST_NO_SESSIONS); + } + tpm_buf_append_u16(buf, max); + + ret =3D tpm_buf_fill_hmac_session(chip, buf); + if (ret) + return ret; + + ret =3D tpm_transmit_cmd(chip, buf, offsetof(struct tpm2_get_random_out, = buffer), + "TPM2_GetRandom"); + + ret =3D tpm_buf_check_hmac_response(chip, buf, ret); + if (ret) { + if (ret > 0) + ret =3D -EIO; + + goto out; + } + + head =3D (struct tpm_header *)buf->data; + offset =3D TPM_HEADER_SIZE; + + /* Skip the parameter size field: */ + if (be16_to_cpu(head->tag) =3D=3D TPM2_ST_SESSIONS) + offset +=3D 4; + + resp =3D (struct tpm2_get_random_out *)&buf->data[offset]; + recd =3D min_t(u32, be16_to_cpu(resp->size), max); + + if (tpm_buf_length(buf) < + TPM_HEADER_SIZE + offsetof(struct tpm2_get_random_out, buffer) + recd= ) { + ret =3D -EIO; + goto out; + } + + memcpy(out, resp->buffer, recd); + return recd; + +out: + tpm2_end_auth_session(chip); + return ret; +} + /** - * tpm_get_random() - get random bytes from the TPM's RNG - * @chip: a &struct tpm_chip instance, %NULL for the default chip - * @out: destination buffer for the random bytes - * @max: the max number of bytes to write to @out + * tpm_get_random() - Get random bytes from the TPM's RNG + * @chip: A &tpm_chip instance. Whenset to %NULL, the default chip is used. + * @out: Destination buffer for the acquired random bytes. + * @max: The maximum number of bytes to write to @out. * - * Return: number of random bytes read or a negative error value. + * Iterates pulling more bytes from TPM up until all of the @max bytes hav= e been + * received. + * + * Returns the number of random bytes read on success. + * Returns -EINVAL when @out is NULL, or @max is not between zero and + * %TPM_MAX_RNG_DATA. + * Returns tpm_transmit_cmd() error codes when the TPM command results an + * error. */ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max) { + u32 num_bytes =3D max; + u8 *out_ptr =3D out; + int retries =3D 5; + int total =3D 0; int rc; =20 - if (!out || max > TPM_MAX_RNG_DATA) + if (!out || !max || max > TPM_MAX_RNG_DATA) return -EINVAL; =20 if (!chip) @@ -508,11 +632,30 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, si= ze_t max) if (rc) return rc; =20 - if (chip->flags & TPM_CHIP_FLAG_TPM2) - rc =3D tpm2_get_random(chip, out, max); - else - rc =3D tpm1_get_random(chip, out, max); + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + rc =3D tpm2_start_auth_session(chip); + if (rc) + return rc; + } + + do { + if (chip->flags & TPM_CHIP_FLAG_TPM2) + rc =3D tpm2_get_random(chip, out_ptr, num_bytes); + else + rc =3D tpm1_get_random(chip, out_ptr, num_bytes); + + if (rc < 0) + goto err; + + out_ptr +=3D rc; + total +=3D rc; + num_bytes -=3D rc; + } while (retries-- && total < max); + + tpm_put_ops(chip); + return total ? total : -EIO; =20 +err: tpm_put_ops(chip); return rc; } diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 5395927c62fc..c4bbd8f04605 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -250,7 +250,6 @@ int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,= const u8 *hash, int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf); ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap, const char *desc, size_t min_cap_length); -int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max); int tpm1_get_pcr_allocation(struct tpm_chip *chip); unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal= ); int tpm_pm_suspend(struct device *dev); @@ -290,7 +289,6 @@ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, struct tpm_digest *digest, u16 *digest_size_ptr); int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, struct tpm_digest *digests); -int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max); ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id, u32 *value, const char *desc); =20 diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index 11090053ef54..d8f16e66666b 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c @@ -502,68 +502,6 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_= id, cap_t *cap, } EXPORT_SYMBOL_GPL(tpm1_getcap); =20 -#define TPM_ORD_GET_RANDOM 70 -struct tpm1_get_random_out { - __be32 rng_data_len; - u8 rng_data[TPM_MAX_RNG_DATA]; -} __packed; - -/** - * tpm1_get_random() - get random bytes from the TPM's RNG - * @chip: a &struct tpm_chip instance - * @dest: destination buffer for the random bytes - * @max: the maximum number of bytes to write to @dest - * - * Return: - * * number of bytes read - * * -errno (positive TPM return codes are masked to -EIO) - */ -int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max) -{ - struct tpm1_get_random_out *out; - u32 num_bytes =3D min_t(u32, max, TPM_MAX_RNG_DATA); - u32 total =3D 0; - int retries =3D 5; - u32 recd; - int rc; - - struct tpm_buf *buf __free(kfree) =3D kzalloc(TPM_BUFSIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - tpm_buf_init(buf, TPM_BUFSIZE); - do { - tpm_buf_reset(buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_RANDOM); - tpm_buf_append_u32(buf, num_bytes); - - rc =3D tpm_transmit_cmd(chip, buf, sizeof(out->rng_data_len), "TPM_GetRa= ndom"); - if (rc) { - if (rc > 0) - rc =3D -EIO; - return rc; - } - - out =3D (struct tpm1_get_random_out *)&buf->data[TPM_HEADER_SIZE]; - - recd =3D be32_to_cpu(out->rng_data_len); - if (recd > num_bytes) - return -EFAULT; - - if (buf->length < TPM_HEADER_SIZE + - sizeof(out->rng_data_len) + recd) - return -EFAULT; - - memcpy(dest, out->rng_data, recd); - - dest +=3D recd; - total +=3D recd; - num_bytes -=3D recd; - } while (retries-- && total < max); - - rc =3D total ? (int)total : -EIO; - return rc; -} - #define TPM_ORD_PCRREAD 21 int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf) { diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index bc50d6b734cf..f066efb54a2c 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -233,101 +233,6 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_id= x, return rc; } =20 -struct tpm2_get_random_out { - __be16 size; - u8 buffer[TPM_MAX_RNG_DATA]; -} __packed; - -/** - * tpm2_get_random() - get random bytes from the TPM RNG - * - * @chip: a &tpm_chip instance - * @dest: destination buffer - * @max: the max number of random bytes to pull - * - * Return: - * size of the buffer on success, - * -errno otherwise (positive TPM return codes are masked to -EIO) - */ -int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) -{ - struct tpm2_get_random_out *out; - struct tpm_header *head; - u32 recd; - u32 num_bytes =3D max; - int err; - int total =3D 0; - int retries =3D 5; - u8 *dest_ptr =3D dest; - off_t offset; - - if (!num_bytes || max > TPM_MAX_RNG_DATA) - return -EINVAL; - - struct tpm_buf *buf __free(kfree) =3D kzalloc(TPM_BUFSIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - err =3D tpm2_start_auth_session(chip); - if (err) - return err; - - tpm_buf_init(buf, TPM_BUFSIZE); - do { - tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM); - if (tpm2_chip_auth(chip)) { - tpm_buf_append_hmac_session(chip, buf, - TPM2_SA_ENCRYPT | - TPM2_SA_CONTINUE_SESSION, - NULL, 0); - } else { - head =3D (struct tpm_header *)buf->data; - head->tag =3D cpu_to_be16(TPM2_ST_NO_SESSIONS); - } - tpm_buf_append_u16(buf, num_bytes); - err =3D tpm_buf_fill_hmac_session(chip, buf); - if (err) - return err; - - err =3D tpm_transmit_cmd(chip, buf, - offsetof(struct tpm2_get_random_out, - buffer), - "TPM2_GetRandom"); - err =3D tpm_buf_check_hmac_response(chip, buf, err); - if (err) { - if (err > 0) - err =3D -EIO; - goto out; - } - - head =3D (struct tpm_header *)buf->data; - offset =3D TPM_HEADER_SIZE; - /* Skip the parameter size field: */ - if (be16_to_cpu(head->tag) =3D=3D TPM2_ST_SESSIONS) - offset +=3D 4; - - out =3D (struct tpm2_get_random_out *)&buf->data[offset]; - recd =3D min_t(u32, be16_to_cpu(out->size), num_bytes); - if (tpm_buf_length(buf) < - TPM_HEADER_SIZE + - offsetof(struct tpm2_get_random_out, buffer) + - recd) { - err =3D -EFAULT; - goto out; - } - memcpy(dest_ptr, out->buffer, recd); - - dest_ptr +=3D recd; - total +=3D recd; - num_bytes -=3D recd; - } while (retries-- && total < max); - - return total ? total : -EIO; -out: - tpm2_end_auth_session(chip); - return err; -} - /** * tpm2_flush_context() - execute a TPM2_FlushContext command * @chip: TPM chip to use --=20 2.39.5 From nobody Tue Dec 16 16:35:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AAC2B3271F4; Wed, 10 Dec 2025 17:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387274; cv=none; b=HGwOcz0/vL9zviUGw3huH39tm6X2m8ftzVpHvXtAOp6V5fsaic7KX4wxP1YwrZlZzmVsrQzntqKhUrs5MJvud4lmcI6k3AsPnzQzMjad6xZj8000JFXCPYiNjTXWQNvMFiJHddS0B43yhwyjv6zmS4Gv8pfJHzIsrh0iETjZcPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387274; c=relaxed/simple; bh=kqsz75FRwe7BwNAXl/0a3oLZCU/8TrrYjPcsTX5SiOo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EZasiVQuuqh5d39y+H0gE0YiX+v5ADXc2wOsXjjcK2x2T5fTjFKpqyAW1T1xQTlz38XiJlxtUX3UQq2IvkZhzuBWO8kuZUtLtBi+W/+kUXsuv/2l3EGrQ+4uXZeZOuR5cFTrzl43kC8N1H2SXDlzs2BJckHRMjnS2bj3hs8inlA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X4Nc66g3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="X4Nc66g3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7421C4CEF1; Wed, 10 Dec 2025 17:21:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765387274; bh=kqsz75FRwe7BwNAXl/0a3oLZCU/8TrrYjPcsTX5SiOo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X4Nc66g394+zyWrBiPZ+M2804j0FS4MWmmHbb9ZBaGM+IYEnKNIv+5qR21dESz+KB mXxBdimNvLcC9J+z2+019kP+mL2+8EkTo7y6nl1ZmC+vubJS9W01jVUZiOItFGbXmn UDdUwEN28SNUdZfinZmgDdfWweqOVydxLedfzM1mhdqnfZIGy/MpAqg6PGO3JW+ADh 1P3/CTTy7lQ8iCoXTaxBq/IfZt6E+I4bUv4Da7z/20tCYgRQ4ZssN9i+oXpg82DhA/ +KSGXiRru/AOw7cF/jWI2obBeOwp+INbAw3g8qB5751CTPR+YFpbZSD3fW/CWBUG0/ +RG2U8GTygksw== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , "David S . Miller" , Herbert Xu , Peter Huewe , Jason Gunthorpe , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , James Bottomley , Mimi Zohar , linux-kernel@vger.kernel.org (open list), keyrings@vger.kernel.org (open list:KEYS/KEYRINGS), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v4 7/8] tpm: Send only one at most TPM2_GetRandom command Date: Wed, 10 Dec 2025 19:20:25 +0200 Message-Id: <20251210172027.109938-8-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251210172027.109938-1-jarkko@kernel.org> References: <20251210172027.109938-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" hwrng framework does not have a requirement that the all bytes requested need to be provided. By enforcing such a requirement internally, TPM driver can cause unpredictability in latency, as a single tpm_get_random() call can result multiple TPM commands. Especially, when TCG_TPM2_HMAC is enabled, extra roundtrips could have significant effect to the system latency. Add a wait-parameter to enforce the old behavior and set it to true only at the call sites for TPM 1.2 keys. At the call sites of hwrng, set @wait to false. Cc: David S. Miller Cc: Herbert Xu Signed-off-by: Jarkko Sakkinen --- v4: - Fixed grammar mistakes. --- drivers/char/tpm/tpm-chip.c | 2 +- drivers/char/tpm/tpm-interface.c | 11 +++++++++-- include/linux/tpm.h | 2 +- security/keys/trusted-keys/trusted_tpm1.c | 8 ++++---- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 082b910ddf0d..8fca4373e2df 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -494,7 +494,7 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data= , size_t max, bool wait) { struct tpm_chip *chip =3D container_of(rng, struct tpm_chip, hwrng); =20 - return tpm_get_random(chip, data, max); + return tpm_get_random(chip, data, max, false); } =20 static bool tpm_is_hwrng_enabled(struct tpm_chip *chip) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interf= ace.c index ab52a1cb0a78..5cc2bbabd57a 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -604,9 +604,11 @@ static int tpm2_get_random(struct tpm_chip *chip, u8 *= out, size_t max) * @chip: A &tpm_chip instance. Whenset to %NULL, the default chip is used. * @out: Destination buffer for the acquired random bytes. * @max: The maximum number of bytes to write to @out. + * @wait: Set to true when all of the @max bytes need to be acquired. * * Iterates pulling more bytes from TPM up until all of the @max bytes hav= e been - * received. + * received, when @wait it sets true. Otherwise, the queries for @max byte= s from + * TPM exactly once, and returns the bytes that were received. * * Returns the number of random bytes read on success. * Returns -EINVAL when @out is NULL, or @max is not between zero and @@ -614,7 +616,7 @@ static int tpm2_get_random(struct tpm_chip *chip, u8 *o= ut, size_t max) * Returns tpm_transmit_cmd() error codes when the TPM command results an * error. */ -int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max) +int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max, bool wait) { u32 num_bytes =3D max; u8 *out_ptr =3D out; @@ -647,6 +649,11 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, siz= e_t max) if (rc < 0) goto err; =20 + if (!wait) { + total =3D rc; + break; + } + out_ptr +=3D rc; total +=3D rc; num_bytes -=3D rc; diff --git a/include/linux/tpm.h b/include/linux/tpm.h index e68995df8796..177833d6b965 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -485,7 +485,7 @@ extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_= idx, struct tpm_digest *digest); extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, struct tpm_digest *digests); -extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max); +int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max, bool wait); extern struct tpm_chip *tpm_default_chip(void); void tpm2_flush_context(struct tpm_chip *chip, u32 handle); int tpm2_find_hash_alg(unsigned int crypto_id); diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trus= ted-keys/trusted_tpm1.c index 759c1ecb0435..f36f6a0b533f 100644 --- a/security/keys/trusted-keys/trusted_tpm1.c +++ b/security/keys/trusted-keys/trusted_tpm1.c @@ -361,7 +361,7 @@ static int osap(struct tpm_buf *tb, struct osapsess *s, unsigned char ononce[TPM_NONCE_SIZE]; int ret; =20 - ret =3D tpm_get_random(chip, ononce, TPM_NONCE_SIZE); + ret =3D tpm_get_random(chip, ononce, TPM_NONCE_SIZE, true); if (ret < 0) return ret; =20 @@ -454,7 +454,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytyp= e, memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE); sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash); =20 - ret =3D tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE); + ret =3D tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE, true); if (ret < 0) goto out; =20 @@ -565,7 +565,7 @@ static int tpm_unseal(struct tpm_buf *tb, } =20 ordinal =3D htonl(TPM_ORD_UNSEAL); - ret =3D tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE); + ret =3D tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE, true); if (ret < 0) return ret; =20 @@ -938,7 +938,7 @@ static int trusted_tpm_unseal(struct trusted_key_payloa= d *p, char *datablob) =20 static int trusted_tpm_get_random(unsigned char *key, size_t key_len) { - return tpm_get_random(chip, key, key_len); + return tpm_get_random(chip, key, key_len, true); } =20 static int __init init_digests(void) --=20 2.39.5 From nobody Tue Dec 16 16:35:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C3961327201; Wed, 10 Dec 2025 17:21:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387279; cv=none; b=Yq8i5ou7K2zfVOp/iKMBYjscBW8JhrekyuH9o4JhaxqS6J14ZasK+tjzYPErJfwzU0hl41SW3IX6QiDK3poqx3MMMvybo0nkUdGFSV/HMEZbG52wc3FxqevQTHqGnsKdvBJodPIwj+Xng4QSzg5zwDB3CeBcM/IxNVR3JXaGE7Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765387279; c=relaxed/simple; bh=ose2oB/fvx8BkW6CVHK5os3jHRlOiK5rAT97U08pq4o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fj+5weI7sGHEW3bIlXIV0w0sn/ML5dLPNj8foCWDat+S+yeckr9Ef+isCR2UDgnBLthz3Bz7EpgypwuaWHOsmmG6ZfX0IHCyLQjewp0XRYF5YRa+DFfj7FC6n+fwbyWroiiCZfQmRtKBOKgzX+QAXo3/AoKv6kytkEEj6c2uu88= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tpUfYW3C; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tpUfYW3C" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C57BDC4CEF1; Wed, 10 Dec 2025 17:21:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765387279; bh=ose2oB/fvx8BkW6CVHK5os3jHRlOiK5rAT97U08pq4o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tpUfYW3CJAtqL5S3ySrAUNOfthY6VO45ff4gk18o0lkNLxPBfZmHFQMcPnae6EsLL JaTKlcPK1E+ttAmn4x0imK4gFb/wBqcz6ihhrIC37FPEu9Z/pJfuoTkl62ks28vBbg 9cWgHDAs1eTvwlqRC2he4zo0jyXPpU2Vkmaz+woclH44juIxRgd3splrFbuCgYyp1n p7h+gzDJ9S/R0ZmAznq5qfClV2Npl5VlTo/pttVuOoKrcB9DRaoYhziTZGRh8fD47P uX01UBvOrQm2If1hoRROCEmuqx+XfCDrKaT3xJqFQ4xdHNtM97jxmhUErCmH7hIMef DRx+FpaeEW6dQ== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Peter Huewe , Jason Gunthorpe , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , linux-kernel@vger.kernel.org (open list), keyrings@vger.kernel.org (open list:KEYS/KEYRINGS), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v4 8/8] tpm: In tpm_get_random() replace 'retries' with a zero check Date: Wed, 10 Dec 2025 19:20:26 +0200 Message-Id: <20251210172027.109938-9-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251210172027.109938-1-jarkko@kernel.org> References: <20251210172027.109938-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check for zero byte read instead of having retries counter in order to make wait flag properly enforcing. Progress is still guaranteed given the zero check and iterations are capped up to TPM_MAX_RNG_DATA iterations at most (as per theoretical limit). Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm-interface.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interf= ace.c index 5cc2bbabd57a..594ad095a90b 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -620,7 +620,6 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size= _t max, bool wait) { u32 num_bytes =3D max; u8 *out_ptr =3D out; - int retries =3D 5; int total =3D 0; int rc; =20 @@ -646,8 +645,12 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, siz= e_t max, bool wait) else rc =3D tpm1_get_random(chip, out_ptr, num_bytes); =20 - if (rc < 0) + if (rc <=3D 0) { + if (!rc) + rc =3D -EIO; + goto err; + } =20 if (!wait) { total =3D rc; @@ -657,7 +660,7 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size= _t max, bool wait) out_ptr +=3D rc; total +=3D rc; num_bytes -=3D rc; - } while (retries-- && total < max); + } while (total < max); =20 tpm_put_ops(chip); return total ? total : -EIO; --=20 2.39.5