From mboxrd@z Thu Jan 1 00:00:00 1970 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 91E23285C89; Sat, 13 Dec 2025 20:33:38 +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=1765658018; cv=none; b=Hd38Gos3yxXZDZY4KyMK2yXATvkrVzsMeVayTo6n2aowUkNxLfDS0jBEUDatd0vGZwcJFvkVFPqzWVG9NnTWDKFg94s8/OenBLZlXywvzD8bDHm8ewai+fLYXUnohxFZVBIo1LGPaTwX+WVDqWGQNyPQPFG+pOOYwFxvlpD8xHM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765658018; c=relaxed/simple; bh=kqsz75FRwe7BwNAXl/0a3oLZCU/8TrrYjPcsTX5SiOo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aV2pJokXFUM2wHUUSaTEw+08cAcI5BX4OaNtHb13SWcN3pd3Ygi0QIpBVlDVthQ4eOFFBD5erz2nyQFbGibGbkYKxgOBJCJAzXTATaHniGx6jOgfsijsj7BEWLVxQMd7gDMh1+ZEAckR9dE816EE45cevqFKEjvPGLIMUNp+nSc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gYHddVy3; 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="gYHddVy3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DEB5AC113D0; Sat, 13 Dec 2025 20:33:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765658017; bh=kqsz75FRwe7BwNAXl/0a3oLZCU/8TrrYjPcsTX5SiOo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gYHddVy3tGGu7XXihxsEnJreG7OsgvOkv8YGlkqjGc9kVi5Dwh4hnnRPezcaV3/fn qkGIYvI39ZDn96rawXfyxM2ArVp5fIolGYBnwfXiSUAMYgcmb7onED4wboMV5XHC9Z ZYBf5PTHMfza0yRaE8Rq7zMCJsj9XQM0oZCRbzypVyQWSz6O7bkVDLTgDvgrTyvC6w tQiI44wxTi7BlakKbBgcS2K+9OF6fD9fA+DfkqQJFh1uPXO00hezXifP6AYrYAMjGK xfraQsrbWJvZCLncJaeDWFFTJ6xky4Kce/GucfXIvx4qDkDT0zJvtNVzm6xfGtMmSA hPrXrmcop1NYw== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Ross Philipson , 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 v5 11/12] tpm: Send only one at most TPM2_GetRandom command Date: Sat, 13 Dec 2025 22:32:18 +0200 Message-Id: <20251213203220.317498-12-jarkko@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251213203220.317498-1-jarkko@kernel.org> References: <20251213203220.317498-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 = container_of(rng, struct tpm_chip, hwrng); - return tpm_get_random(chip, data, max); + return tpm_get_random(chip, data, max, false); } static bool tpm_is_hwrng_enabled(struct tpm_chip *chip) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.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 have been - * received. + * received, when @wait it sets true. Otherwise, the queries for @max bytes 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 *out, 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 = max; u8 *out_ptr = out; @@ -647,6 +649,11 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max) if (rc < 0) goto err; + if (!wait) { + total = rc; + break; + } + out_ptr += rc; total += rc; num_bytes -= 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/trusted-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; - ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE); + ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE, true); if (ret < 0) return ret; @@ -454,7 +454,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE); sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash); - ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE); + ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE, true); if (ret < 0) goto out; @@ -565,7 +565,7 @@ static int tpm_unseal(struct tpm_buf *tb, } ordinal = htonl(TPM_ORD_UNSEAL); - ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE); + ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE, true); if (ret < 0) return ret; @@ -938,7 +938,7 @@ static int trusted_tpm_unseal(struct trusted_key_payload *p, char *datablob) 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); } static int __init init_digests(void) -- 2.39.5