From patchwork Fri Dec 9 16:06:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 13069952 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DCB1C4167B for ; Fri, 9 Dec 2022 16:10:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229728AbiLIQK2 (ORCPT ); Fri, 9 Dec 2022 11:10:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229683AbiLIQK1 (ORCPT ); Fri, 9 Dec 2022 11:10:27 -0500 Received: from bedivere.hansenpartnership.com (bedivere.hansenpartnership.com [96.44.175.130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF9E438A1; Fri, 9 Dec 2022 08:10:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hansenpartnership.com; s=20151216; t=1670602226; bh=jZVB+9oPPrrYNMHjSQd3P3o1B8BU91qtvsviRtwEVFE=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References:From; b=ax9Q8tH0H7YiaiBXb2uh5laVlZQ8AQWfs/6YBHdLHB3alo8vsLQa+nvlrgbbJ3bvk vVMqlr4pMvb7yqli+DOI5HGE53bUoQXN5fBHzprr2yXXO3CelQCaDshuDQUSvBkuX4 T0bG0dCjP6FfmXSOoqiaqLQjZLRS7n9eXVx/8lgU= Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 742CC1281045; Fri, 9 Dec 2022 11:10:26 -0500 (EST) Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SxKq1fu9EOIE; Fri, 9 Dec 2022 11:10:26 -0500 (EST) Received: from lingrow.int.hansenpartnership.com (unknown [153.66.160.227]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id DE62612803C0; Fri, 9 Dec 2022 11:10:25 -0500 (EST) From: James Bottomley To: linux-integrity@vger.kernel.org Cc: Ard Biesheuvel , Jarkko Sakkinen , keyrings@vger.kernel.org Subject: [PATCH 08/11] tpm: add session encryption protection to tpm2_get_random() Date: Fri, 9 Dec 2022 11:06:08 -0500 Message-Id: <20221209160611.30207-9-James.Bottomley@HansenPartnership.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221209160611.30207-1-James.Bottomley@HansenPartnership.com> References: <20221209160611.30207-1-James.Bottomley@HansenPartnership.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org If some entity is snooping the TPM bus, they can see the random numbers we're extracting from the TPM and do prediction attacks against their consumers. Foil this attack by using response encryption to prevent the attacker from seeing the random sequence. Signed-off-by: James Bottomley --- drivers/char/tpm/tpm2-cmd.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 001360d5956d..3ac438e8ffbb 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -289,29 +289,40 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) int total = 0; int retries = 5; u8 *dest_ptr = dest; + struct tpm2_auth *auth; if (!num_bytes || max > TPM_MAX_RNG_DATA) return -EINVAL; - err = tpm_buf_init(&buf, 0, 0); + err = tpm2_start_auth_session(chip, &auth); if (err) return err; + err = tpm_buf_init(&buf, 0, 0); + if (err) { + tpm2_end_auth_session(auth); + return err; + } + do { - tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM); + tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM); + tpm_buf_append_hmac_session_opt(&buf, auth, TPM2_SA_ENCRYPT + | TPM2_SA_CONTINUE_SESSION, + NULL, 0); tpm_buf_append_u16(&buf, num_bytes); + tpm_buf_fill_hmac_session(&buf, auth); err = tpm_transmit_cmd(chip, &buf, offsetof(struct tpm2_get_random_out, buffer), "attempting get random"); + err = tpm_buf_check_hmac_response(&buf, auth, err); if (err) { if (err > 0) err = -EIO; goto out; } - out = (struct tpm2_get_random_out *) - &buf.data[TPM_HEADER_SIZE]; + out = (struct tpm2_get_random_out *)tpm_buf_parameters(&buf); recd = min_t(u32, be16_to_cpu(out->size), num_bytes); if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + @@ -328,6 +339,8 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) } while (retries-- && total < max); tpm_buf_destroy(&buf); + tpm2_end_auth_session(auth); + return total ? total : -EIO; out: tpm_buf_destroy(&buf);