Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp1105731pxb; Tue, 3 Nov 2020 23:32:23 -0800 (PST) X-Google-Smtp-Source: ABdhPJzPJI/uu6giyFhJT99dfyiERLcjR93smI34l4q9JCYufAySmlrVKyHeIUGG/zejZpUOVHxI X-Received: by 2002:a17:906:6d99:: with SMTP id h25mr23546134ejt.281.1604475142856; Tue, 03 Nov 2020 23:32:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604475142; cv=none; d=google.com; s=arc-20160816; b=RyRRz8uEE0dnGMzER04c34esnc/duMddLXXAaa2a2mb62nUOsbuKVK66fR9siQ86on 5Icifaq9zot+Sf1aJRURS/Kr0cT8nkzJr7mwz02XijgFyOYVJB4FjMo7WYaZfyB27CD3 6lXwx7qPil9ofv03adGq065nwftJ7v0vj24QxnpDjsQ7eIvMrJ8nvkia5AiK36XEyNuI 4Vl1kF1E0uTurIi4RupFauE6HxfppAvKm6v3oT+JCfKOngDVdnXYUi7cWpSH0GU0cyYa XaToab0dmxy/znS7DVKSlG4NazHzBt9A4zEhSZUfq1+evjHP6dGgmexWw9vokNz4Fgs+ 4EMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=n6uu6Z6ky+r+rcyvyYgMWjkwNM6+s9AhNr3MRBsZ2/I=; b=b4pCRriEbUcz5ldzjES7clpwzJyXTjVc9Hkj65bne44er+48Ftlcaek+7txLGNvZiH NS/MNa1AQC7fDIrJ3g8VaX3UXSIYiIz/g5M3Vc7HEOsJddcPwgPq35p+02xJuV+Jtk6p KULAql/py44puKScXUiVaGnEqNM3+QaNxdiXkZWlYJxZPyVPvWCLDSTdfQDnI+c4uy+H ZyXw6v22IBOsJszd+8eji0Zjk6FvUHU1kOSMnO/JN3uIp3q72fKPvaEvUe94bszONvva bMnJbeaOGdDwE+1x3xgz2WdRlIlSug9nhkiHTtGFLT6LLqa6mhxB5ciG4O2Vi+9dYbt1 X8xg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=E0cJ+jHr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c91si703545edf.313.2020.11.03.23.31.59; Tue, 03 Nov 2020 23:32:22 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=E0cJ+jHr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726152AbgKDHaZ (ORCPT + 99 others); Wed, 4 Nov 2020 02:30:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728504AbgKDHaY (ORCPT ); Wed, 4 Nov 2020 02:30:24 -0500 Received: from mail-lj1-x243.google.com (mail-lj1-x243.google.com [IPv6:2a00:1450:4864:20::243]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94954C0401C2 for ; Tue, 3 Nov 2020 23:30:22 -0800 (PST) Received: by mail-lj1-x243.google.com with SMTP id l10so882917lji.4 for ; Tue, 03 Nov 2020 23:30:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=n6uu6Z6ky+r+rcyvyYgMWjkwNM6+s9AhNr3MRBsZ2/I=; b=E0cJ+jHraSDuUh4fuxwuAVZS85upupkHBuQ+SK2D8bgGCXNai8aN2Gx1DXfUyYrKYe 15jV0d+lyYdbyEynlP2OT9nF+AGcCJxnMVgCfTpJ2E22tZ8mL2Yq6S3cPJcRBwyRCD+2 jcOdlkYPrH4JIjKEtu3WdGCVBuokcPx9sLTUA2lS757W4EwjchKA+O7fCdw0TscLbsNw BjcEUURS3Obhur1p+87jFKfU7h+ArWAmndGBUva9O1ScPU44CR9EGsbpPgeQTT6NdoF/ ka+ruQgFZMZN1gnKpTSOsoaMLRvha9hW70WjrnHaMTilsU5KFLpt5xcqBYVyEkzLgaHN oOjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=n6uu6Z6ky+r+rcyvyYgMWjkwNM6+s9AhNr3MRBsZ2/I=; b=Ljxl+ZHJEeZOyR3dAn7l1keBbswrrGc99T9tFDsMkzSUZCJk37x1YqY4z5p6QcSMKL mBNmS/TGu1+qX9kEWMtBzUnhoddL5pUkdx4v0MkCdZoFTvKia92d+v3U85FZwb9/PyiM 8mDhr+y1bU+6NMuLIWedfdUozJyIqID5ZR3EI1gy8u0QqfN/bbkBOnkVILz+x4zimJMk QnVDuSYwmRGBxR7E8+tDSejE3TuQD4ck1qk8w6dS4as4fS9nhK+F1lIENs1hf+uvd9cJ Qs9Mk1f344zs4nw2jQA/ekNRVYkUxT0ERtaGgIpwewpMLKA+777aCgThKmwI6jCUgxon mN5g== X-Gm-Message-State: AOAM532FI1NPdR6GCf9zvvXN0IKDyxAak4RpVqQBj797Ja0zI3qU37+2 3SsOfkK9P55C+0wSL6UzrcpOS04qZLXM+BCQnDhZ/A== X-Received: by 2002:a2e:984e:: with SMTP id e14mr1714875ljj.110.1604475020891; Tue, 03 Nov 2020 23:30:20 -0800 (PST) MIME-Version: 1.0 References: <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com> <20201104011909.GD20387@kernel.org> In-Reply-To: <20201104011909.GD20387@kernel.org> From: Sumit Garg Date: Wed, 4 Nov 2020 13:00:09 +0530 Message-ID: Subject: Re: [PATCH v4 3/3,RESEND 2] KEYS: trusted: Reserve TPM for seal and unseal operations To: Jarkko Sakkinen Cc: linux-integrity@vger.kernel.org, David Howells , Mimi Zohar , James Bottomley , "James E.J. Bottomley" , stable , kernel test robot , Peter Huewe , Jason Gunthorpe , Arnd Bergmann , Greg Kroah-Hartman , James Morris , "Serge E. Hallyn" , Jerry Snitselaar , Alexey Klimov , open list , "open list:KEYS-TRUSTED" , "open list:SECURITY SUBSYSTEM" Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Jarkko, On Wed, 4 Nov 2020 at 06:49, Jarkko Sakkinen wrote: > > When TPM 2.0 trusted keys code was moved to the trusted keys subsystem, > the operations were unwrapped from tpm_try_get_ops() and tpm_put_ops(), > which are used to take temporarily the ownership of the TPM chip. The > ownership is only taken inside tpm_send(), but this is not sufficient, > as in the key load TPM2_CC_LOAD, TPM2_CC_UNSEAL and TPM2_FLUSH_CONTEXT > need to be done as a one single atom. > > Fix this issue by introducting trusted_tpm_load() and trusted_tpm_new(), > which wrap these operations, and take the TPM chip ownership before > sending anything. I am not sure if we really need these new APIs in order to fix this issue, see below. > Use tpm_transmit_cmd() to send TPM commands instead > of tpm_send(), reverting back to the old behaviour. > > Fixes: 2e19e10131a0 ("KEYS: trusted: Move TPM2 trusted keys code") > Reported-by: "James E.J. Bottomley" > Cc: stable@vger.kernel.org > Cc: David Howells > Cc: Mimi Zohar > Cc: Sumit Garg > Signed-off-by: Jarkko Sakkinen > Reported-by: kernel test robot > --- > drivers/char/tpm/tpm.h | 4 -- > include/linux/tpm.h | 5 +- > security/keys/trusted-keys/trusted_tpm1.c | 78 +++++++++++++++-------- > security/keys/trusted-keys/trusted_tpm2.c | 6 +- > 4 files changed, 60 insertions(+), 33 deletions(-) > > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h > index 947d1db0a5cc..283f78211c3a 100644 > --- a/drivers/char/tpm/tpm.h > +++ b/drivers/char/tpm/tpm.h > @@ -164,8 +164,6 @@ extern const struct file_operations tpmrm_fops; > extern struct idr dev_nums_idr; > > ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz); > -ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf, > - size_t min_rsp_body_length, const char *desc); > int tpm_get_timeouts(struct tpm_chip *); > int tpm_auto_startup(struct tpm_chip *chip); > > @@ -194,8 +192,6 @@ static inline void tpm_msleep(unsigned int delay_msec) > int tpm_chip_start(struct tpm_chip *chip); > void tpm_chip_stop(struct tpm_chip *chip); > struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip); > -__must_check int tpm_try_get_ops(struct tpm_chip *chip); > -void tpm_put_ops(struct tpm_chip *chip); > > struct tpm_chip *tpm_chip_alloc(struct device *dev, > const struct tpm_class_ops *ops); > diff --git a/include/linux/tpm.h b/include/linux/tpm.h > index 8f4ff39f51e7..804a3f69bbd9 100644 > --- a/include/linux/tpm.h > +++ b/include/linux/tpm.h > @@ -397,6 +397,10 @@ static inline u32 tpm2_rc_value(u32 rc) > #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) > > extern int tpm_is_tpm2(struct tpm_chip *chip); > +extern __must_check int tpm_try_get_ops(struct tpm_chip *chip); > +extern void tpm_put_ops(struct tpm_chip *chip); > +extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf, > + size_t min_rsp_body_length, const char *desc); > 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, > @@ -410,7 +414,6 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip) > { > return -ENODEV; > } > - > static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, > struct tpm_digest *digest) > { > diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c > index 7a937c3c5283..20ca18e17437 100644 > --- a/security/keys/trusted-keys/trusted_tpm1.c > +++ b/security/keys/trusted-keys/trusted_tpm1.c > @@ -950,6 +950,51 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key) > return p; > } > > +static int trusted_tpm_load(struct tpm_chip *chip, > + struct trusted_key_payload *payload, > + struct trusted_key_options *options) > +{ > + int ret; > + > + if (tpm_is_tpm2(chip)) { > + ret = tpm_try_get_ops(chip); Can't we move this TPM 2.0 specific operation within tpm2_unseal_trusted() instead? > + if (!ret) { > + ret = tpm2_unseal_trusted(chip, payload, options); > + tpm_put_ops(chip); Ditto. > + } > + } else { > + ret = key_unseal(payload, options); > + } > + > + return ret; > +} > + > +static int trusted_tpm_new(struct tpm_chip *chip, > + struct trusted_key_payload *payload, > + struct trusted_key_options *options) > +{ > + int ret; > + > + ret = tpm_get_random(chip, payload->key, payload->key_len); > + if (ret < 0) > + return ret; > + > + if (ret != payload->key_len) > + return -EIO; > + > + if (tpm_is_tpm2(chip)) { > + ret = tpm_try_get_ops(chip); Same here, to move this within tpm2_seal_trusted() instead? > + if (!ret) { > + ret = tpm2_seal_trusted(chip, payload, options); > + tpm_put_ops(chip); Ditto. -Sumit > + } > + } else { > + ret = key_seal(payload, options); > + } > + > + return ret; > +} > + > /* > * trusted_instantiate - create a new trusted key > * > @@ -968,12 +1013,6 @@ static int trusted_instantiate(struct key *key, > char *datablob; > int ret = 0; > int key_cmd; > - size_t key_len; > - int tpm2; > - > - tpm2 = tpm_is_tpm2(chip); > - if (tpm2 < 0) > - return tpm2; > > if (datalen <= 0 || datalen > 32767 || !prep->data) > return -EINVAL; > @@ -1011,32 +1050,21 @@ static int trusted_instantiate(struct key *key, > > switch (key_cmd) { > case Opt_load: > - if (tpm2) > - ret = tpm2_unseal_trusted(chip, payload, options); > - else > - ret = key_unseal(payload, options); > + ret = trusted_tpm_load(chip, payload, options); > + > dump_payload(payload); > dump_options(options); > + > if (ret < 0) > - pr_info("trusted_key: key_unseal failed (%d)\n", ret); > + pr_info("%s: load failed (%d)\n", __func__, ret); > + > break; > case Opt_new: > - key_len = payload->key_len; > - ret = tpm_get_random(chip, payload->key, key_len); > - if (ret < 0) > - goto out; > + ret = trusted_tpm_new(chip, payload, options); > > - if (ret != key_len) { > - pr_info("trusted_key: key_create failed (%d)\n", ret); > - ret = -EIO; > - goto out; > - } > - if (tpm2) > - ret = tpm2_seal_trusted(chip, payload, options); > - else > - ret = key_seal(payload, options); > if (ret < 0) > - pr_info("trusted_key: key_seal failed (%d)\n", ret); > + pr_info("%s: new failed (%d)\n", __func__, ret); > + > break; > default: > ret = -EINVAL; > diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c > index 08ec7f48f01d..effdb67fac6d 100644 > --- a/security/keys/trusted-keys/trusted_tpm2.c > +++ b/security/keys/trusted-keys/trusted_tpm2.c > @@ -130,7 +130,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip, > goto out; > } > > - rc = tpm_send(chip, buf.data, tpm_buf_length(&buf)); > + rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data"); > if (rc) > goto out; > > @@ -211,7 +211,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip, > goto out; > } > > - rc = tpm_send(chip, buf.data, tpm_buf_length(&buf)); > + rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob"); > if (!rc) > *blob_handle = be32_to_cpup( > (__be32 *) &buf.data[TPM_HEADER_SIZE]); > @@ -260,7 +260,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, > options->blobauth /* hmac */, > TPM_DIGEST_SIZE); > > - rc = tpm_send(chip, buf.data, tpm_buf_length(&buf)); > + rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing"); > if (rc > 0) > rc = -EPERM; > > -- > 2.25.1 >