Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp1253158rwb; Tue, 27 Sep 2022 10:19:40 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6KlD+mb0dO7/sFqNez2MHApVCewUDM2rafMgT1Oi2v+N0ZEAgjEHiaMMhcU5uM2t4LbJGI X-Received: by 2002:a17:906:5a45:b0:77a:406c:6867 with SMTP id my5-20020a1709065a4500b0077a406c6867mr23206397ejc.437.1664299179978; Tue, 27 Sep 2022 10:19:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664299179; cv=none; d=google.com; s=arc-20160816; b=PicoiMHMKXCjvzPbj5bI450o2K6+yMcktoG5TdGdCbGOBYgZl3/0eOZx7vmggU/uyl HN8cjYd/bqxHGd16aLJvVQIljlZDo7j7K1/2BzO7TiIouTFvOU6wb74hrJ2AMDgKA+CP JqbdBEtlYndy45LlgjYB6F37ZD/gVCrhS1bJDllP2HEBcvR3bYQVd6fIA5JaCdZ9aF8o 2pLTuz+Rq62CCj1NEC+CYrtjXB2iF9mmro21vmw6l3gD83togcXaR2lkvljV6VUqdPQ2 2FyLdNyLu8uD4RZh8w9NLH596bhEk7XZY0/JMGDB6yElAa5RnL5N3IVVAaXY/rt8fd6M p1fg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=mSKd3PtpzAza9oMdVi8/s+oWI/q2zUDumX4CktWslcw=; b=nFeLNqMvCi0Qfp9EoHewEtOCzXjlpai+8JaLqfPkb5p+cAAVV0jSEsP9etnuBUJElG SMUDp+1yA/1Th580w/a72bZiVgjMyJuqdsnpr+Rij4ZvenZtL0gQZ1xPS/NPQgmwRT9K jObODQifDTD3FOc4SexmwJaFiPoRPkcxdCAcUHwzUzbCLYU2rIud/ckEOelcv4kTFQfm XhfMwz4qERO6d5gyNbc3ekfLVRXg2+dELcK8ZXjO4+R4/S+iIMsuQnfc+lXcrOJHOjFU 9Pj5rZ9jqu6TBiI+3o+yw8rdOVzsaU4F2atbhf7m+3vEbxI1ScDQEqGUU73VgAhzqDTZ t31g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=b67lqlqG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p2-20020a056402074200b00456767d38edsi1856338edy.581.2022.09.27.10.19.13; Tue, 27 Sep 2022 10:19:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=b67lqlqG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233141AbiI0QuY (ORCPT + 99 others); Tue, 27 Sep 2022 12:50:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233194AbiI0Qt5 (ORCPT ); Tue, 27 Sep 2022 12:49:57 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8FE533869D for ; Tue, 27 Sep 2022 09:49:54 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id v1so9589677plo.9 for ; Tue, 27 Sep 2022 09:49:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=mSKd3PtpzAza9oMdVi8/s+oWI/q2zUDumX4CktWslcw=; b=b67lqlqGEJd8Urm2MeXENq+KGhE/5CUpM7BMbT/smTMYSu7lydR58E2kNif6HOpNq8 S2kYfv0oOKzVjUz0qTHkH8QoWaejmPcZd3lLTh+qy8wL38p2RS3V/L1FWFK9LP2rT/TC +xzPW8iTnSn9wfhThuZy6xh0XlKiZG50KFfJY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=mSKd3PtpzAza9oMdVi8/s+oWI/q2zUDumX4CktWslcw=; b=CjEPEbnY6yl0tlTNesE2p0LM6zEQMQWKkyQ7aCMaDvEXEFVpEuhZyiQxjZ8ARi/P9C 1rZZhhhH2g7POTttJSFJW+kqmiYLa1NxbwLMnTmVey+FK9yaEeqJizHp2X5P3EZMuhU1 kbwYyciqr02+wlvnKM4AwGNC/+MTmGlnxYT1wUBVvaAS/qBsJTIfm+cEoYJSwDpEuNd6 R6nfkRmSYY8ylyD4DUXERtGx5ztAnGc/oeX8+aCuuGZBwTb31Af6h3myoZzFl526hxDL SYZLhF7irkH+xn7R9FI9oIIFMfP6Be1hi59xXoa6eywWYWDjta/dN15vBA66E5FYN3Bj HcWQ== X-Gm-Message-State: ACrzQf3KcGoYc16t2BULFqqyuPfcGngD6HgqBijvEN7oMylrYg8GTX1T SnCcYUC+oN9WYsnTnVES7cOVhlwKog7MzjoyEZg= X-Received: by 2002:a17:902:7081:b0:178:6154:9d79 with SMTP id z1-20020a170902708100b0017861549d79mr28726431plk.79.1664297393524; Tue, 27 Sep 2022 09:49:53 -0700 (PDT) Received: from evgreen-glaptop.lan ([73.231.74.141]) by smtp.gmail.com with ESMTPSA id p13-20020a63950d000000b00434272fe870sm1753509pgd.88.2022.09.27.09.49.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Sep 2022 09:49:53 -0700 (PDT) From: Evan Green To: linux-kernel@vger.kernel.org Cc: linux-integrity@vger.kernel.org, apronin@chromium.org, dlunev@google.com, jarkko@kernel.org, Pavel Machek , Ben Boeckel , rjw@rjwysocki.net, corbet@lwn.net, linux-pm@vger.kernel.org, zohar@linux.ibm.com, Kees Cook , Eric Biggers , jejb@linux.ibm.com, gwendal@chromium.org, Matthew Garrett , Matthew Garrett , Matthew Garrett , Evan Green , Jason Gunthorpe , Peter Huewe Subject: [PATCH v3 03/11] tpm: Allow PCR 23 to be restricted to kernel-only use Date: Tue, 27 Sep 2022 09:49:14 -0700 Message-Id: <20220927094559.v3.3.I9ded8c8caad27403e9284dfc78ad6cbd845bc98d@changeid> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20220927164922.3383711-1-evgreen@chromium.org> References: <20220927164922.3383711-1-evgreen@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Matthew Garrett Under certain circumstances it might be desirable to enable the creation of TPM-backed secrets that are only accessible to the kernel. In an ideal world this could be achieved by using TPM localities, but these don't appear to be available on consumer systems. An alternative is to simply block userland from modifying one of the resettable PCRs, leaving it available to the kernel. If the kernel ensures that no userland can access the TPM while it is carrying out work, it can reset PCR 23, extend it to an arbitrary value, create or load a secret, and then reset the PCR again. Even if userland somehow obtains the sealed material, it will be unable to unseal it since PCR 23 will never be in the appropriate state. Link: https://lore.kernel.org/lkml/20210220013255.1083202-3-matthewgarrett@google.com/ Signed-off-by: Matthew Garrett Signed-off-by: Evan Green --- Changes in v3: - Fix up commit message (Jarkko) - tpm2_find_and_validate_cc() was split (Jarkko) - Simply fully restrict TPM1 since v2 failed to account for tunnelled transport sessions (Stefan and Jarkko). Changes in v2: - Fixed sparse warnings drivers/char/tpm/Kconfig | 12 ++++++++++++ drivers/char/tpm/tpm-dev-common.c | 8 ++++++++ drivers/char/tpm/tpm.h | 19 +++++++++++++++++++ drivers/char/tpm/tpm1-cmd.c | 13 +++++++++++++ drivers/char/tpm/tpm2-cmd.c | 22 ++++++++++++++++++++++ 5 files changed, 74 insertions(+) diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 927088b2c3d3f2..c8ed54c66e399a 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -211,4 +211,16 @@ config TCG_FTPM_TEE This driver proxies for firmware TPM running in TEE. source "drivers/char/tpm/st33zp24/Kconfig" + +config TCG_TPM_RESTRICT_PCR + bool "Restrict userland access to PCR 23" + depends on TCG_TPM + help + If set, block userland from extending or resetting PCR 23. This allows it + to be restricted to in-kernel use, preventing userland from being able to + make use of data sealed to the TPM by the kernel. This is required for + secure hibernation support, but should be left disabled if any userland + may require access to PCR23. This is a TPM2-only feature, and if enabled + on a TPM1 machine will cause all usermode TPM commands to return EPERM due + to the complications introduced by tunnelled sessions in TPM1.2. endif # TCG_TPM diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c index dc4c0a0a512903..7a4e618c7d1942 100644 --- a/drivers/char/tpm/tpm-dev-common.c +++ b/drivers/char/tpm/tpm-dev-common.c @@ -198,6 +198,14 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf, priv->response_read = false; *off = 0; + if (priv->chip->flags & TPM_CHIP_FLAG_TPM2) + ret = tpm2_cmd_restricted(priv->chip, priv->data_buffer, size); + else + ret = tpm1_cmd_restricted(priv->chip, priv->data_buffer, size); + + if (ret) + goto out; + /* * If in nonblocking mode schedule an async job to send * the command return the size. diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 9c9e5d75b37c78..9f4e64e22807a2 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -246,4 +246,23 @@ void tpm_bios_log_setup(struct tpm_chip *chip); void tpm_bios_log_teardown(struct tpm_chip *chip); int tpm_dev_common_init(void); void tpm_dev_common_exit(void); + +#ifdef CONFIG_TCG_TPM_RESTRICT_PCR +#define TPM_RESTRICTED_PCR 23 + +int tpm1_cmd_restricted(struct tpm_chip *chip, u8 *buffer, size_t size); +int tpm2_cmd_restricted(struct tpm_chip *chip, u8 *buffer, size_t size); +#else +static inline int tpm1_cmd_restricted(struct tpm_chip *chip, u8 *buffer, + size_t size) +{ + return 0; +} + +static inline int tpm2_cmd_restricted(struct tpm_chip *chip, u8 *buffer, + size_t size) +{ + return 0; +} +#endif #endif diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index cf64c738510529..1869e89215fcb9 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c @@ -811,3 +811,16 @@ int tpm1_get_pcr_allocation(struct tpm_chip *chip) return 0; } + +#ifdef CONFIG_TCG_TPM_RESTRICT_PCR +int tpm1_cmd_restricted(struct tpm_chip *chip, u8 *buffer, size_t size) +{ + /* + * Restrict all usermode commands on TPM1.2. Ideally we'd just restrict + * TPM_ORD_PCR_EXTEND and TPM_ORD_PCR_RESET, but TPM1.2 also supports + * tunnelled transport sessions where the kernel would be unable to filter + * commands. + */ + return -EPERM; +} +#endif diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 69126a6770386e..9c92a3e1e3f463 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -821,3 +821,25 @@ int tpm2_find_cc(struct tpm_chip *chip, u32 cc) return -1; } + +#ifdef CONFIG_TCG_TPM_RESTRICT_PCR +int tpm2_cmd_restricted(struct tpm_chip *chip, u8 *buffer, size_t size) +{ + int cc = tpm2_find_and_validate_cc(chip, NULL, buffer, size); + __be32 *handle; + + switch (cc) { + case TPM2_CC_PCR_EXTEND: + case TPM2_CC_PCR_RESET: + if (size < (TPM_HEADER_SIZE + sizeof(u32))) + return -EINVAL; + + handle = (__be32 *)&buffer[TPM_HEADER_SIZE]; + if (be32_to_cpu(*handle) == TPM_RESTRICTED_PCR) + return -EPERM; + break; + } + + return 0; +} +#endif -- 2.31.0