From patchwork Fri Jul 28 19:30:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 127860 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:918b:0:b0:3e4:2afc:c1 with SMTP id s11csp684533vqg; Fri, 28 Jul 2023 13:50:42 -0700 (PDT) X-Google-Smtp-Source: APBJJlGY55GkI6y3bs4tH2o6aTV632yWDLGaARBlmZTsTxC6lXKANTnkttdAorDU5M4j3kPoufgT X-Received: by 2002:a05:6a20:7f9a:b0:125:3445:8af0 with SMTP id d26-20020a056a207f9a00b0012534458af0mr3602312pzj.7.1690577441795; Fri, 28 Jul 2023 13:50:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690577441; cv=none; d=google.com; s=arc-20160816; b=DEyNfo8uxRKti5zkMTs+E6ldccZWRbjuK9Hcypkp/fq/RmmHAfvP96H9rt9JN9DP89 3iJ6s7iHGXeXaCEXB7/XXgMzSGv2iogoHGFVRSv7F1BmidkL1OS/4vsJ3TtoeT35SAnK ZvJec/3GHM8TUgoZ5Q6MeO91/7mU7xYR0/TcvvgWx8dbeABOoyzu22Wiihi9uYQXtQrT nRRWsDcIjFTU+CDJ0A9lWyY/T5lW69YH8FpHc70qbuvtS2L/6Wl773j7peIRcoWKwskZ b9p6Z7aVORoWoMnuYoUF22ijLy+05Yu+d/btmjAQAcS8AULMeZ1Jsjmdy4z65zTAwAl8 hhBQ== 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 :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:dkim-signature; bh=9jWpR89J8C42S8gZsptkwqX1F+QxaALqai5V/03zk7g=; fh=CM+S36Mjp1XaV3NC2nPjgYbUvniageHJNnD2+rlTR2c=; b=zSGh3xM+9u1CbST9GtQJcEvRa2jTOyD0NBSSW4t44wIV3+us3KZgP8SzETSYdZfTjn 2iULdDLYdJE+jGFFuKCrpYe9eOd1ajgSBhzYeJ8Qwu5VPZBsrAwLKUkSlYgbSrPxFjxK MudKEgBRfCceA41RmlXPcbQUYLREVBejPsllhKmSqA0ImT1LvAQtPECdyTueEcA5GZet 8CbmcguCKTSi63CzAD/W0s3vR8076oo4Zi1i8ZBz6ybJHew/NxnhjRmQxMvJDuL6uKoD BMpR3QvtrjsMnahcI2E3sqE8KwNgXPzo8LpHv+so5/443QDkOL+gPrMvs7SmjnneyCW3 sRaw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=SsAtewQN; 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=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y21-20020a056a00191500b006825e062715si3677350pfi.228.2023.07.28.13.50.28; Fri, 28 Jul 2023 13:50:41 -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=@intel.com header.s=Intel header.b=SsAtewQN; 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233800AbjG1TbG (ORCPT + 99 others); Fri, 28 Jul 2023 15:31:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233779AbjG1TbD (ORCPT ); Fri, 28 Jul 2023 15:31:03 -0400 Received: from mgamail.intel.com (unknown [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF1162D5D; Fri, 28 Jul 2023 12:30:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1690572659; x=1722108659; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mGaMlBipNmPfGhHLAGsqi0OkKPmtkBtlrURLdYIcgyI=; b=SsAtewQNkZTLC6BNFnMjtP+oG0dOXfVgcpMbt1f0Xiqe5PiyX9aKJx9C W8A0Vcm2OGT6/5tXZ+W2ZJZNkorBHulpWH21N/juniDomxpVx0G/hGVpA jTz0dvK6Y4imeUUqzJloENqW/GpDzfn4fkK2Nmj+3O8iaFGE1W4ACHlN1 ulP4bMcWpOc7HLO4tamX3gdhPNpuLYEWZG3KrduR5JqSnemvK1367dY+M Wx8SSgdpJjx8amlZIkdsLnitUAVxvTmYSKcVp8vWbkz+rMkuUwMZAoGiq UKtqXIqQPvITyanL29Kmtbou0VfvtgT+hx/LkLqWXSwdohvjomuFGaipC g==; X-IronPort-AV: E=McAfee;i="6600,9927,10785"; a="348958854" X-IronPort-AV: E=Sophos;i="6.01,238,1684825200"; d="scan'208";a="348958854" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2023 12:30:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10785"; a="797529634" X-IronPort-AV: E=Sophos;i="6.01,238,1684825200"; d="scan'208";a="797529634" Received: from cheehong-laptop.gar.corp.intel.com (HELO dwillia2-xfh.jf.intel.com) ([10.212.158.179]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2023 12:30:58 -0700 Subject: [PATCH 1/4] keys: Introduce tsm keys From: Dan Williams To: dhowells@redhat.com Cc: Kuppuswamy Sathyanarayanan , Kuppuswamy Sathyanarayanan , Jarkko Sakkinen , Dionna Amalie Glaze , Greg Kroah-Hartman , Samuel Ortiz , peterz@infradead.org, linux-coco@lists.linux.dev, keyrings@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org Date: Fri, 28 Jul 2023 12:30:58 -0700 Message-ID: <169057265801.180586.10867293237672839356.stgit@dwillia2-xfh.jf.intel.com> In-Reply-To: <169057265210.180586.7950140104251236598.stgit@dwillia2-xfh.jf.intel.com> References: <169057265210.180586.7950140104251236598.stgit@dwillia2-xfh.jf.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham 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 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772698593398839345 X-GMAIL-MSGID: 1772698931336927814 One of the common operations of a TSM (Trusted Security Module) is to provide a way for a TVM (confidential computing guest execution environment) to take a measurement of its run state and use that with a key-exchange protocol to establish a shared secret with a third-party / remote attestation agent. The concept is common across TSMs, but the implementations are unfortunately vendor specific. While the industry grapples with a common definition of this attestation format [1], Linux need not make this problem worse by defining a new ABI per TSM that wants to perform a similar operation. The current momentum has been to invent new ioctl-ABI per TSM per function which at best is an abdication of the kernel's responsibility to make common infrastructure concepts share common ABI. The proposal, targeted to conceptually work with TDX, SEV, COVE if not more, is to define a new key type that produces a TSM common blob format and moves the vendor specificity inside that envelope. The common Linux definition is: " " This approach later allows for the standardization of the attestation blob format without needing to change the Linux ABI. TSM specific options are encoded in the frontend request format where the options like SEV:vmpl (privilege level) can be specified and TSMs that do not support them can decide to ignore them or fail if they are specified. For now, "privlevel=" and "format=" are the only implemented options. Example of establishing a tsm key and dumping the provider-specific report: dd if=/dev/urandom of=pubkey bs=1 count=64 keyctl add tsm tsm_test "auth $(xxd -p -c 0 < pubkey) privlevel=2" @u keyctl print 280877394 | awk '{ print $3 }' | xxd -p -c 0 -r | hexdump -C Now, this patch ends up being a fairly simple custom-key format because most of the follow-on work that happens after publishing a TSM-wrapped public-key is performed by userspace. The TSM key is just one step in establishing a shared secret that can be used to unlock other keys. For example a user-key could be populated with the resulting shared secret and that could be used as a master-key for an encrypted-key (security/keys/encrypted-keys/encrypted.c). While the discussion that led to this proposal hinted at a new trusted-key (security/keys/trusted-keys/trusted_core.c) type rooted in the TSM [2], more work is needed to fetch a secret from the TSM directly. The trusted-key core expects a pre-established secure channel to seal and unseal secrets locally. For that reason a "tsm" flavor trusted-key is saved for follow on work. That will likely starting as a wrapper around SNP_GET_DERIVED_KEY. Link: http://lore.kernel.org/r/64961c3baf8ce_142af829436@dwillia2-xfh.jf.intel.com.notmuch [1] Link: http://lore.kernel.org/r/CAAH4kHYLETfPk-sMD-QSJd0fJ7Qnt04FBwFuEkpnehB5U7D_yw@mail.gmail.com [2] Cc: Kuppuswamy Sathyanarayanan Tested-by: Kuppuswamy Sathyanarayanan Cc: David Howells Cc: Jarkko Sakkinen Cc: Dionna Amalie Glaze Cc: Greg Kroah-Hartman Cc: Samuel Ortiz Signed-off-by: Dan Williams --- include/keys/tsm.h | 71 ++++++++++++ security/keys/Kconfig | 12 ++ security/keys/Makefile | 1 security/keys/tsm.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 366 insertions(+) create mode 100644 include/keys/tsm.h create mode 100644 security/keys/tsm.c diff --git a/include/keys/tsm.h b/include/keys/tsm.h new file mode 100644 index 000000000000..61a81017d8f5 --- /dev/null +++ b/include/keys/tsm.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __TSM_H +#define __TSM_H + +#include +#include + +/* + * @TSM_DATA_MAX: a reasonable max with enough space for known attestation + * report formats. This mirrors the trusted/encrypted key blob max size. + */ +#define TSM_DATA_MAX 32767 +#define TSM_PUBKEY_MAX 64 +#define TSM_FORMAT_MAX 16 + +/** + * DOC: TSM Keys + * + * Trusted Security Module Keys are a common provider of blobs that + * facilitate key-exchange between a TVM (confidential computing guest) + * and an attestation service. A TSM key combines a user-defined blob + * (likely a public-key for a key-exchance protocol) with a signed + * attestation report. That combined blob is then used to obtain + * secrets provided by an agent that can validate the attestation + * report. + * + * A full implementation uses a tsm key to, for example, establish a + * shared secret and then use that communication channel to instantiate + * other keys. The expectation is that the requester of the tsm key + * knows a priori the key-exchange protocol associated with the + * 'pubkey'. + * + * The attestation report format is TSM provider specific, when / if a + * standard materializes it is only a change to the auth_blob_desc + * member of 'struct tsm_key_payload', to convey that common format. + */ + +/** + * struct tsm_key_payload - generic payload for vendor TSM blobs + * @privlevel: optional privilege level to associate with @pubkey + * @pubkey_len: how much of @pubkey is valid + * @pubkey: the public key-exchange blob to include in the attestation report + * @auth_blob_desc: base ascii descriptor of @auth_blob + * @auth_blob_format: for TSMs with multiple formats, extend @auth_blob_desc + * @auth_blob_len: TSM provider length of the array it publishes in @auth_blob + * @auth_blob: TSM specific attestation report blob + */ +struct tsm_key_payload { + int privlevel; + size_t pubkey_len; + u8 pubkey[TSM_PUBKEY_MAX]; + const char *auth_blob_desc; + char auth_blob_format[TSM_FORMAT_MAX]; + size_t auth_blob_len; + u8 *auth_blob; +}; + +/* + * arch specific ops, only one is expected to be registered at a time + * i.e. only one of SEV, TDX, COVE, etc. + */ +struct tsm_key_ops { + const char *name; + struct module *module; + int (*auth_new)(struct tsm_key_payload *t, void *provider_data); +}; + +int register_tsm_provider(const struct tsm_key_ops *ops, void *provider_data); +void unregister_tsm_provider(const struct tsm_key_ops *ops); + +#endif /* __TSM_H */ diff --git a/security/keys/Kconfig b/security/keys/Kconfig index abb03a1b2a5c..f530cbd876fc 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig @@ -133,3 +133,15 @@ config KEY_NOTIFICATIONS on keys and keyrings on which the caller has View permission. This makes use of pipes to handle the notification buffer and provides KEYCTL_WATCH_KEY to enable/disable watches. + +config TSM_KEYS + tristate "TSM-based (Confidential Computing) keys" + help + TSM (Trusted Security Module) key support arranges to convey a blob to + a confidentiality and integrity protected virtual machine / guest + (TVM). The blob instantiation flow involves submitting the measurement + report of a TVM, obtained from the platform TSM, to a remote + attestation service that only provides the key if the report passes + validation. The report format is vendor specific and the validation is + user policy, so this feature requires a /etc/request-key.conf handler + for communicating with the remote attestation provider. diff --git a/security/keys/Makefile b/security/keys/Makefile index 5f40807f05b3..96972a4815d5 100644 --- a/security/keys/Makefile +++ b/security/keys/Makefile @@ -28,5 +28,6 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += keyctl_pkey.o # Key types # obj-$(CONFIG_BIG_KEYS) += big_key.o +obj-$(CONFIG_TSM_KEYS) += tsm.o obj-$(CONFIG_TRUSTED_KEYS) += trusted-keys/ obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted-keys/ diff --git a/security/keys/tsm.c b/security/keys/tsm.c new file mode 100644 index 000000000000..d9532319f819 --- /dev/null +++ b/security/keys/tsm.c @@ -0,0 +1,282 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2023 Intel Corporation. All rights reserved. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct tsm_provider { + const struct tsm_key_ops *ops; + void *data; +} provider; +static DECLARE_RWSEM(tsm_key_rwsem); + +static const struct tsm_key_ops *get_ops(void) +{ + down_read(&tsm_key_rwsem); + return provider.ops; +} + +static void *get_data(void) +{ + lockdep_assert_held(&tsm_key_rwsem); + return provider.data; +} + +static void put_ops(void) +{ + up_read(&tsm_key_rwsem); +} + +int register_tsm_provider(const struct tsm_key_ops *ops, + void *provider_data) +{ + const struct tsm_key_ops *conflict; + int rc; + + down_write(&tsm_key_rwsem); + conflict = provider.ops; + if (conflict) { + pr_err("\"%s\" ops already registered\n", conflict->name); + rc = -EEXIST; + goto out; + } + try_module_get(ops->module); + provider.ops = ops; + provider.data = provider_data; + rc = 0; +out: + up_write(&tsm_key_rwsem); + return rc; +} +EXPORT_SYMBOL_GPL(register_tsm_provider); + +void unregister_tsm_provider(const struct tsm_key_ops *ops) +{ + down_write(&tsm_key_rwsem); + provider.ops = NULL; + provider.data = NULL; + module_put(ops->module); + up_write(&tsm_key_rwsem); +} +EXPORT_SYMBOL_GPL(unregister_tsm_provider); + +enum { + Opt_err, + Opt_auth, + Opt_format, + Opt_privlevel, +}; + +static const match_table_t tsm_tokens = { + { Opt_auth, "auth" }, + { Opt_privlevel, "privlevel=%s" }, + { Opt_format, "format=%s" }, + { Opt_err, NULL }, +}; + +/* + * tsm_parse - parse the tsm request data + * + * input format: "auth [options]" + * + * Checks for options and parses a hex blob of data to be wrapped by the + * TSM attestation format. + * + * options: + * privlevel= integer for selecting the privelege level of the + * request, if the platform TSM supports that concept. To + * date only SEV accepts this option. Default 0. + * format= string modifier for the format, if the platform TSM + * supports multiple formats. To date only SEV accepts an + * "extended" argument. Default "". + * + * On success returns 0, otherwise -EINVAL. + */ +static int tsm_parse(char *input, struct tsm_key_payload *t) +{ + substring_t args[MAX_OPT_ARGS]; + unsigned long optmask = 0; + unsigned int privlevel; + int token, rc; + char *p; + + /* all tsm keys must start with "auth" as a placeholder command */ + p = strsep(&input, " \t"); + if (!p) + return -EINVAL; + token = match_token(p, tsm_tokens, args); + switch (token) { + case Opt_auth: + break; + default: + return -EINVAL; + } + + /* next is the pubkey hex blob */ + p = strsep(&input, " \t"); + if (!p) + return -EINVAL; + t->pubkey_len = strlen(p) / 2; + if (t->pubkey_len > TSM_PUBKEY_MAX) + return -EINVAL; + rc = hex2bin(t->pubkey, p, t->pubkey_len); + if (rc < 0) + return -EINVAL; + + /* last is zero or more options */ + while ((p = strsep(&input, " \t"))) { + if (*p == '\0' || *p == ' ' || *p == '\t') + continue; + token = match_token(p, tsm_tokens, args); + /* each option can appear only once */ + if (test_and_set_bit(token, &optmask)) + return -EINVAL; + switch (token) { + case Opt_privlevel: + rc = kstrtouint(args[0].from, 16, &privlevel); + if (rc) + return rc; + t->privlevel = privlevel; + break; + case Opt_format: + if (strlen(args[0].from) >= TSM_FORMAT_MAX) + return -EINVAL; + strscpy(t->auth_blob_format, args[0].from, + TSM_FORMAT_MAX); + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int tsm_instantiate(struct key *key, struct key_preparsed_payload *prep) +{ + size_t datalen = prep->datalen; + const struct tsm_key_ops *ops; + int rc; + + if (datalen <= 0 || datalen > TSM_DATA_MAX || !prep->data) + return -EINVAL; + + char *datablob __free(kfree) = + kmemdup_nul(prep->data, datalen, GFP_KERNEL); + if (!datablob) + return -ENOMEM; + + struct tsm_key_payload *t __free(kfree) = + kzalloc(sizeof(*t), GFP_KERNEL); + if (!t) + return -ENOMEM; + + rc = tsm_parse(datablob, t); + if (rc < 0) + return rc; + + ops = get_ops(); + if (ops) + rc = ops->auth_new(t, get_data()); + else + rc = -ENXIO; + put_ops(); + + if (rc) + return rc; + + rc = key_payload_reserve(key, sizeof(*t) + t->auth_blob_len); + if (rc) { + kvfree(t->auth_blob); + return rc; + } + + rcu_assign_keypointer(key, t); + no_free_ptr(t); + return 0; +} + +/* + * tsm_read - format and copy out the tsm auth record + * + * The resulting datablob format is: + * + * + * On success, return to userspace the size of the formatted payload. + */ +static long tsm_read(const struct key *key, char *buffer, size_t buflen) +{ + size_t asciiblob_len, desc_len; + struct tsm_key_payload *t; + char *buf, *format = NULL; + const int nr_spaces = 2; + + t = dereference_key_locked(key); + + desc_len = strlen(t->auth_blob_desc); + if (t->auth_blob_format[0]) { + format = &t->auth_blob_format[0]; + desc_len += strlen(format) + 1; + } + + asciiblob_len = + t->pubkey_len * 2 + desc_len + t->auth_blob_len * 2 + nr_spaces; + + if (!buffer || buflen < asciiblob_len) + return asciiblob_len; + + buf = bin2hex(buffer, t->pubkey, t->pubkey_len); + if (format) + buf += sprintf(buf, " %s:%s ", t->auth_blob_desc, format); + else + buf += sprintf(buf, " %s ", t->auth_blob_desc); + buf = bin2hex(buf, t->auth_blob, t->auth_blob_len); + + /* sanity check for future changes to this function */ + WARN_ON_ONCE(buf - buffer != asciiblob_len); + + return asciiblob_len; +} + +static void tsm_destroy(struct key *key) +{ + struct tsm_key_payload *t = key->payload.data[0]; + + kvfree(t->auth_blob); + kfree(t); +} + +static struct key_type key_type_tsm = { + .name = "tsm", + .instantiate = tsm_instantiate, + .destroy = tsm_destroy, + .describe = user_describe, + .read = tsm_read, +}; + +static int __init tsm_key_init(void) +{ + return register_key_type(&key_type_tsm); +} +module_init(tsm_key_init); + +static void __exit tsm_key_exit(void) +{ + unregister_key_type(&key_type_tsm); +} +module_exit(tsm_key_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Provide Trusted Security Module attestation reports as Key payloads"); From patchwork Fri Jul 28 19:31:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 127854 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:918b:0:b0:3e4:2afc:c1 with SMTP id s11csp678714vqg; Fri, 28 Jul 2023 13:35:37 -0700 (PDT) X-Google-Smtp-Source: APBJJlGSZzHuBH1fzW45y2b9/c8AnRcvRi9eh2p+UEEqXOEo7FdvmGAv2oHO1uAhvHzliAEu+ljQ X-Received: by 2002:aa7:c443:0:b0:522:55bf:21af with SMTP id n3-20020aa7c443000000b0052255bf21afmr2416390edr.7.1690576537300; Fri, 28 Jul 2023 13:35:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690576537; cv=none; d=google.com; s=arc-20160816; b=d7de5cv9G9G8bqkFG8bb5+zgs8RsdXaOBbrul4tyZ4EFvJ/DlKf9i1WbeeGP4mCbSH FlmbWyjHvRNQgqwHi70zoxrFW0ce4ES11jzaVopsRZ+42AgORWMEi+I3cLl8n0jXmBGA 63yvdl5QXQ5oE7uJW+NWdr6k7KQI+yVFCGVrQHp9etC5FG7iflTYblc2MsRri9Gz6ysx RLr6u3SxfrraONiCiLIn1M0WEJUQRz7IlcJ1wvLUN/VtPXBMdebdjZiYhZ4pJBDN4Eer U36o/lbIMIfKuTsgGFLm5uc1hEVUMLi5qWqBWJgyUvM2UbugVWG+VAyCNlfZZl56HQ5J XAHw== 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 :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:dkim-signature; bh=GonjnQrBGfeUJbVhGUntAkPPQOcrGXmdQOxxZZbNP5o=; fh=VUmUrHGFkTtXjIDywqDNwmDa+bm3A2NVF5lswC6u7/E=; b=i3TbsnYHeRFBt3kT24I9CC7D7KlmBg9UYhCrijUhzgibXv5g/chTFZ2aIoqpdPW5M2 EQb73NNfqGnOgubLla0J0YFPAkvsBNl4LfZuciRcdtkjoGlQhWaG3Jp6Tfj/V/5BhbmN hePZQk8pxHoNpCCWB4eZiG4wev1ARZz8I4aS48aT0gxEHfbAt1wx1/Awv1wgCcojvPQ8 5Qv4Uy+8XxhR64ZijYcs0FJ8OWm6212+bx7VcxsvDb6Zbi5tSCJZ1qrxGLhB1PJyvPKQ lv0thUEoJdhh8bFjK/y+yQGz4ZKBxITMYb28c9fNcZjF+jVFUmwLv/vVnDWY2qE93ytN tUXQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="Y/nsKeO2"; 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=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c15-20020aa7df0f000000b0052229e19114si3269392edy.471.2023.07.28.13.35.13; Fri, 28 Jul 2023 13:35:37 -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=@intel.com header.s=Intel header.b="Y/nsKeO2"; 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233779AbjG1TbO (ORCPT + 99 others); Fri, 28 Jul 2023 15:31:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233837AbjG1TbG (ORCPT ); Fri, 28 Jul 2023 15:31:06 -0400 Received: from mgamail.intel.com (unknown [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B24A2736; Fri, 28 Jul 2023 12:31:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1690572665; x=1722108665; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZKEMKTZcxb+bR5sevS5HirhkX4iYwm8FNvR5plo9bz8=; b=Y/nsKeO2ccCHbcJ5ElgM+6O1+yydrPdT11Stfs/TB3eFFmoEGEaYmW0s w2DNC8dz+P59286ou+eDVY1nBEQPX3fnN1mVj/covmOy+DGOYd9/XT3/d b/8YMm4ORNZoArlUepOipsrO8RsPYrtEmzKGTF01tM2hwvkRrh7alr7N/ cvUKHe6WWR532Q9Qsnv11Ef2WvgfgNg6U6ptoVJpaKBDeTmGQWaBbcwJC 8YNhaQ2G0cGC0B2MTyfgZ3xSoLpY8fxJXAEXqlNuevs8gdmtAGQB0yBE2 TT87PouhfY8Z/nBULQ5ZuVkzZP3b+p2UwzuSdsLdftr4YYjkQSnjxPGZu w==; X-IronPort-AV: E=McAfee;i="6600,9927,10785"; a="348958868" X-IronPort-AV: E=Sophos;i="6.01,238,1684825200"; d="scan'208";a="348958868" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2023 12:31:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10785"; a="797529706" X-IronPort-AV: E=Sophos;i="6.01,238,1684825200"; d="scan'208";a="797529706" Received: from cheehong-laptop.gar.corp.intel.com (HELO dwillia2-xfh.jf.intel.com) ([10.212.158.179]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2023 12:31:04 -0700 Subject: [PATCH 2/4] virt: sevguest: Prep for kernel internal {get, get_ext}_report() From: Dan Williams To: dhowells@redhat.com Cc: Borislav Petkov , Tom Lendacky , Dionna Glaze , Brijesh Singh , peterz@infradead.org, linux-coco@lists.linux.dev, keyrings@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org Date: Fri, 28 Jul 2023 12:31:04 -0700 Message-ID: <169057266405.180586.11333199807740052979.stgit@dwillia2-xfh.jf.intel.com> In-Reply-To: <169057265210.180586.7950140104251236598.stgit@dwillia2-xfh.jf.intel.com> References: <169057265210.180586.7950140104251236598.stgit@dwillia2-xfh.jf.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham 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 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772697983147471552 X-GMAIL-MSGID: 1772697983147471552 In preparation for using the TSM key facility to convey attestation blobs to userspace, add an argument to flag whether @arg is a user buffer or a kernel buffer. While TSM keys is meant to replace existing confidenital computing ioctl() implementations for attestation report retrieval the old ioctl() path needs to stick around for a deprecation period. No behavior change intended, just introduce the copy wrappers and @type argument. Note that these wrappers are similar to copy_{to,from}_sockptr(). If this approach moves forward that concept is something that can be generalized into a helper with a generic name. Cc: Borislav Petkov Cc: Tom Lendacky Cc: Dionna Glaze Cc: Brijesh Singh Signed-off-by: Dan Williams --- drivers/virt/coco/sev-guest/sev-guest.c | 48 ++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c index 97dbe715e96a..f48c4764a7a2 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -470,7 +470,32 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, return 0; } -static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) +enum snp_arg_type { + SNP_UARG, + SNP_KARG, +}; + +static unsigned long copy_from(void *to, unsigned long from, unsigned long n, + enum snp_arg_type type) +{ + if (type == SNP_UARG) + return copy_from_user(to, (void __user *)from, n); + memcpy(to, (void *)from, n); + return 0; +} + +static unsigned long copy_to(unsigned long to, const void *from, + unsigned long n, enum snp_arg_type type) +{ + if (type == SNP_UARG) + return copy_to_user((void __user *)to, from, n); + memcpy((void *)to, from, n); + return 0; +} + +static int get_report(struct snp_guest_dev *snp_dev, + struct snp_guest_request_ioctl *arg, + enum snp_arg_type type) { struct snp_guest_crypto *crypto = snp_dev->crypto; struct snp_report_resp *resp; @@ -482,7 +507,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io if (!arg->req_data || !arg->resp_data) return -EINVAL; - if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) + if (copy_from(&req, arg->req_data, sizeof(req), type)) return -EFAULT; /* @@ -501,7 +526,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io if (rc) goto e_free; - if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp))) + if (copy_to(arg->resp_data, resp, sizeof(*resp), type)) rc = -EFAULT; e_free: @@ -550,7 +575,9 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque return rc; } -static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) +static int get_ext_report(struct snp_guest_dev *snp_dev, + struct snp_guest_request_ioctl *arg, + enum snp_arg_type type) { struct snp_guest_crypto *crypto = snp_dev->crypto; struct snp_ext_report_req req; @@ -562,7 +589,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques if (!arg->req_data || !arg->resp_data) return -EINVAL; - if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) + if (copy_from(&req, arg->req_data, sizeof(req), type)) return -EFAULT; /* userspace does not want certificate data */ @@ -611,14 +638,13 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques if (ret) goto e_free; - if (npages && - copy_to_user((void __user *)req.certs_address, snp_dev->certs_data, - req.certs_len)) { + if (npages && copy_to(req.certs_address, snp_dev->certs_data, + req.certs_len, type)) { ret = -EFAULT; goto e_free; } - if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp))) + if (copy_to(arg->resp_data, resp, sizeof(*resp), type)) ret = -EFAULT; e_free: @@ -653,13 +679,13 @@ static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long switch (ioctl) { case SNP_GET_REPORT: - ret = get_report(snp_dev, &input); + ret = get_report(snp_dev, &input, SNP_UARG); break; case SNP_GET_DERIVED_KEY: ret = get_derived_key(snp_dev, &input); break; case SNP_GET_EXT_REPORT: - ret = get_ext_report(snp_dev, &input); + ret = get_ext_report(snp_dev, &input, SNP_UARG); break; default: break; From patchwork Fri Jul 28 19:31:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 127863 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:918b:0:b0:3e4:2afc:c1 with SMTP id s11csp687566vqg; Fri, 28 Jul 2023 13:58:43 -0700 (PDT) X-Google-Smtp-Source: APBJJlHdWKYrzETQ4vZS5iy+2ElIcrpbtbYXqZYtKxX8NoAjNOx39g4eUWizFNEtCioGjs7Rr53P X-Received: by 2002:a05:6512:210c:b0:4fc:6e21:ff53 with SMTP id q12-20020a056512210c00b004fc6e21ff53mr2497844lfr.11.1690577922763; Fri, 28 Jul 2023 13:58:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690577922; cv=none; d=google.com; s=arc-20160816; b=vyaLJJ7Wb+BDg7LuJAaIXR8zcw1YXwrqqd6sgHXrYRc584qlytKg+/FxL+qJKR7pjM P24z5uMlpI8IIOnueJU3BE/iLDVP4SjHhxK9k115wgKRPPA8tbn67m+Be6B5ZD53bJU8 0r09L26rVV+FqGxz+6PQjNMG56yx1YtmCInfyXAvEH5Y/RHzbXHtTQ3zrVwn4AkLKxaR EBb4+CKOmihdAjBj4IaZE+Bpxm/5bmr0xLt1ydj5YnPUzK46aBU34pFzzoNpc6IsUD5g 3uaAVXuJYCuBJXZIED/9S0hdnMaBSL0GdwGSvmaZGNccrc7y+4lj+/MkNTZ5SCaU/3xM n78w== 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 :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:dkim-signature; bh=EMMaKjcmf0w6Qeck97k95pB3VR1xSDdwNYw3ZCcMyNg=; fh=gWY/434ZlUKhkJL3W34j7PSQNPTL6WoAZGX1LzxRtAs=; b=Sr4AVNLeYTQH70OqMahhXtlOwzC5HtGaCljWEfVGwOeiLi8MDBdWiNxN5oQ9pPOrpw IfA5FVrSgxKIttNEtm11M2xkq90ENSSP59IKED/W0A6p6/wIf6wdyhl59KdMLcfXR1h+ boaH7EmM6fiI6bz8GuuNLRZB8hYrvgeD6rr4RDvpWM7Gvz1VXLpmeGYUViiARP4krhIW 32C1zQfTKpkSv78WyURi96N9U09cs/Xvm4sbTkhF/lPToibd0dyQvGz+OV1e6Ui32Map w0rnFpQ2jQkCZk/1qHHdRl6eQI2Zyzin870KgtKhOmDNwo9eZEMkycM3/Dz1ntDTDGQP yAGQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=YLsLnojc; 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=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s13-20020a056402164d00b005222b1807e7si3209390edx.370.2023.07.28.13.58.18; Fri, 28 Jul 2023 13:58:42 -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=@intel.com header.s=Intel header.b=YLsLnojc; 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234669AbjG1Tb1 (ORCPT + 99 others); Fri, 28 Jul 2023 15:31:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234226AbjG1TbN (ORCPT ); Fri, 28 Jul 2023 15:31:13 -0400 Received: from mgamail.intel.com (unknown [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 268DD448C; Fri, 28 Jul 2023 12:31:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1690572671; x=1722108671; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RReoo07Z8COfyQe4vCo2LnNBVJrUhMSozbnkyWWcdFM=; b=YLsLnojcakGLqg6bJDCDLohIWqBqDNKU3DTWmrn5tn34wxmzwf27l7DJ kvC7+8F7SauzrgETPrCrBlY3YZj9sUm+hzSk3XJIWVXC7TO0e0KuLJQsW yOlbCWGYg3dM52o2PZUyqBTA2VxC5xrn+GatRjvVawyvzXyU44xyYt86K aa3OMN4njjqizTxI3SyNy8ecdR8vfLZpXUQiireVJodYZEVb6h/roQ+nf elhWg7PmUIygWhUjaAzqdiO7F6Rc3j1rdW2RdsOwgVWkpLZZsC0eg7vHc L6+L+SLHEGyswRYz4HFE4puclomP7Zt58yovAizrgTYfUZNRKr4+E5K9u w==; X-IronPort-AV: E=McAfee;i="6600,9927,10785"; a="348958883" X-IronPort-AV: E=Sophos;i="6.01,238,1684825200"; d="scan'208";a="348958883" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2023 12:31:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10785"; a="797529731" X-IronPort-AV: E=Sophos;i="6.01,238,1684825200"; d="scan'208";a="797529731" Received: from cheehong-laptop.gar.corp.intel.com (HELO dwillia2-xfh.jf.intel.com) ([10.212.158.179]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2023 12:31:10 -0700 Subject: [PATCH 3/4] mm/slab: Add __free() support for kvfree From: Dan Williams To: dhowells@redhat.com Cc: Andrew Morton , Peter Zijlstra , Greg Kroah-Hartman , linux-coco@lists.linux.dev, keyrings@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org Date: Fri, 28 Jul 2023 12:31:10 -0700 Message-ID: <169057267001.180586.1162740444367661440.stgit@dwillia2-xfh.jf.intel.com> In-Reply-To: <169057265210.180586.7950140104251236598.stgit@dwillia2-xfh.jf.intel.com> References: <169057265210.180586.7950140104251236598.stgit@dwillia2-xfh.jf.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham 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 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772699436210047760 X-GMAIL-MSGID: 1772699436210047760 Allow for the declaration of variables that trigger kvfree() when they go out of scope. Cc: Andrew Morton Cc: Peter Zijlstra Cc: Greg Kroah-Hartman Signed-off-by: Dan Williams --- include/linux/slab.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/slab.h b/include/linux/slab.h index 848c7c82ad5a..241025367943 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -746,6 +746,8 @@ static inline __alloc_size(1, 2) void *kvcalloc(size_t n, size_t size, gfp_t fla extern void *kvrealloc(const void *p, size_t oldsize, size_t newsize, gfp_t flags) __realloc_size(3); extern void kvfree(const void *addr); +DEFINE_FREE(kvfree, void *, if (_T) kvfree(_T)) + extern void kvfree_sensitive(const void *addr, size_t len); unsigned int kmem_cache_size(struct kmem_cache *s); From patchwork Fri Jul 28 19:31:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 127869 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:918b:0:b0:3e4:2afc:c1 with SMTP id s11csp697129vqg; Fri, 28 Jul 2023 14:18:25 -0700 (PDT) X-Google-Smtp-Source: APBJJlHKbrGAmgAdNC4lsH6BIa707g6QmQzRUpvCee2EsZIp/lX2ku41XI1ZVcJXODfs11heNf7J X-Received: by 2002:a05:6a20:1e46:b0:132:cc63:b099 with SMTP id cy6-20020a056a201e4600b00132cc63b099mr2855036pzb.57.1690579104684; Fri, 28 Jul 2023 14:18:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690579104; cv=none; d=google.com; s=arc-20160816; b=OQikFjEYKbd/zAX/AanYPVzOQ9P5uvwfF1TiKcV/u3ycKLHinGbH7mYui03UHMgtYO Cq7NOBrhyyk1kurvSPS4VF9qydPNaB4bHA3QwXZd1MxveV3Gkmv8P+byu0m/Ms4ZatDw Y06a80k4UC8soGbxLAm4JSyzzuwKuNslEeuqXpfpVR2XbKY3xJlcZXz1aJK76AR6WLJX yPzoRliF7BdlnZSgImXBnKuNchoRi/cWUkWjX4aQz/82XG5aSB6Ki3OHtWXX76it0sV0 1bDvICr3W4AliotkGtkDR5aY/pc6LksaXEwAY038TjnFF+glPltKezd+WOCxekxka0RM 5rCw== 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 :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:dkim-signature; bh=oXwNNlapPHd+Slp/b0Lu2jRYy3UDjso3u5csbsxFO+M=; fh=VUmUrHGFkTtXjIDywqDNwmDa+bm3A2NVF5lswC6u7/E=; b=vvzBhTOQyVoKZwXWZ/i/NbHZ4+QNhOFQAF/q+vRIqRppdpd6wESf/aGc81h666WgGt 5b85ikKCQmoSWOlbavo5ZSgKFsVukrRgSU/311bdsUBNJ+oQEoiKHFTwCWCcOTen9LOj qBkPoJd5RoH+lEx3SWOTeFc5nrH9idVkHMwVfR3bOYWr5hcRIIB+MmEx89DjzX9MMhnM InHFtVKmrYFEe11cGkCnqOhUlULxcnCcBdpohhYKHYKgcXfFK055scV+Ok4XNF157ga1 RgPyrlH9rVVGOUDe+9SfWQTmpCIaDVacbySm9MB/chBSxEGiya6wzVDGMhZT6Hb9fS1z Kt+g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=WTPuKzK5; 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=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o15-20020a63a80f000000b0055793097dbesi3494480pgf.469.2023.07.28.14.18.11; Fri, 28 Jul 2023 14:18:24 -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=@intel.com header.s=Intel header.b=WTPuKzK5; 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234402AbjG1Tbu (ORCPT + 99 others); Fri, 28 Jul 2023 15:31:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234254AbjG1Tbo (ORCPT ); Fri, 28 Jul 2023 15:31:44 -0400 Received: from mgamail.intel.com (unknown [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A163268B; Fri, 28 Jul 2023 12:31:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1690572689; x=1722108689; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZmjmGLkvlIjh8KgnWd4vxpMs4lTuf4Wk7sbNKNMFp8U=; b=WTPuKzK5XobA6Sm+c1I2DA0Ff/Ssu2SMO+MSAgrAosreBiIJ6r6l6qn+ NWNYzIy8vylJU3LyQ2l3+rFunizuyWAXJDKE4JtEiNE0qQVkk7As0MZKY ETE3/+voU1ujHKhkCkTVuH+MPTpohdGM7m7G60n9Fx3xKy4MhirpO4v1N R91S96ijr9eUh8Yg/shnGiH5N4M7C3OfFFzEsOd6P3yqwZ3mRN45T4OVK /2WgxrXo93HQGZmm6M1Nx3usIUzHy9tBFFLSRCS6UrZwykg5A9JKMLw4t YOdm/YBUplC1oKzJjZkVHbbossCrDwVSF4x6dfcSBKCkUVMgFUDK4EX0f A==; X-IronPort-AV: E=McAfee;i="6600,9927,10785"; a="348958904" X-IronPort-AV: E=Sophos;i="6.01,238,1684825200"; d="scan'208";a="348958904" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2023 12:31:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10785"; a="797529767" X-IronPort-AV: E=Sophos;i="6.01,238,1684825200"; d="scan'208";a="797529767" Received: from cheehong-laptop.gar.corp.intel.com (HELO dwillia2-xfh.jf.intel.com) ([10.212.158.179]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2023 12:31:16 -0700 Subject: [PATCH 4/4] virt: sevguest: Add TSM key support for SNP_{GET, GET_EXT}_REPORT From: Dan Williams To: dhowells@redhat.com Cc: Borislav Petkov , Tom Lendacky , Dionna Glaze , Brijesh Singh , peterz@infradead.org, linux-coco@lists.linux.dev, keyrings@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org Date: Fri, 28 Jul 2023 12:31:15 -0700 Message-ID: <169057267580.180586.15710177655506555147.stgit@dwillia2-xfh.jf.intel.com> In-Reply-To: <169057265210.180586.7950140104251236598.stgit@dwillia2-xfh.jf.intel.com> References: <169057265210.180586.7950140104251236598.stgit@dwillia2-xfh.jf.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham 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 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772700674878521912 X-GMAIL-MSGID: 1772700674878521912 The sevguest driver was a first mover in the confidential computing space. As a first mover that afforded some leeway to build the driver without concern for common infrastructure. Now that sevguest is no longer a singleton [1] the common operation of building and transmitting attestation report blobs can / should be made common. In this model the so called "TSM-provider" implementations can share a common envelope ABI even if the contents of that envelope remain vendor-specific. When / if the industry agrees on an attestation record format, that definition can also fit in the same ABI. In the meantime the kernel's maintenance burden is reduced and collaboration on the commons is increased. Convert sevguest to use TSM keys to retrieve the blobs that the SNP_{GET,GET_EXT}_REPORT ioctls produce. The flow for retrieving the SNP_GET_REPORT blob via the keyctl utility would be: dd if=/dev/urandom of=pubkey bs=1 count=64 keyctl add tsm tsm_test "auth $(xxd -p -c 0 < pubkey) privlevel=2" @u keyctl print $key_id | awk '{ print $3 }' | xxd -p -c 0 -r | hexdump -C ...while the SNP_GET_EXT_REPORT flow adds the "format=extended" option to the request flow: keyctl add tsm tsm_test "auth $(xxd -p -c 0 < pubkey) privlevel=2 format=extended" @u The output format from 'keyctl print' is: ...where the blobs are hex encoded and the descriptor string is either "sev" or "sev:extended" in this case. Note, the Keys subsystem frontend for the functionality that SNP_GET_DERIVED_KEY represents is saved for follow-on work that likely needs to become a new trusted-keys type. The old ioctls can be lazily deprecated, the main motivation of this effort is to stop the proliferation of new ioctls, and to increase cross-vendor colloboration. Note, only compile-tested. Link: http://lore.kernel.org/r/64961c3baf8ce_142af829436@dwillia2-xfh.jf.intel.com.notmuch [1] Cc: Borislav Petkov Cc: Tom Lendacky Cc: Dionna Glaze Cc: Brijesh Singh Signed-off-by: Dan Williams --- drivers/virt/coco/sev-guest/Kconfig | 2 + drivers/virt/coco/sev-guest/sev-guest.c | 87 +++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/drivers/virt/coco/sev-guest/Kconfig b/drivers/virt/coco/sev-guest/Kconfig index da2d7ca531f0..bce43d4639ce 100644 --- a/drivers/virt/coco/sev-guest/Kconfig +++ b/drivers/virt/coco/sev-guest/Kconfig @@ -2,9 +2,11 @@ config SEV_GUEST tristate "AMD SEV Guest driver" default m depends on AMD_MEM_ENCRYPT + depends on KEYS select CRYPTO select CRYPTO_AEAD2 select CRYPTO_GCM + select TSM_KEYS help SEV-SNP firmware provides the guest a mechanism to communicate with the PSP without risk from a malicious hypervisor who wishes to read, diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c index f48c4764a7a2..2bdca268272d 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -769,6 +770,84 @@ static u8 *get_vmpck(int id, struct snp_secrets_page_layout *layout, u32 **seqno return key; } +static int sev_auth_new(struct tsm_key_payload *t, void *provider_data) +{ + struct snp_guest_dev *snp_dev = provider_data; + const int report_size = SZ_16K; + const int ext_size = + PAGE_ALIGN_DOWN(TSM_DATA_MAX - report_size - sizeof(*t)); + int ret; + + if (t->pubkey_len != 64) + return -EINVAL; + + if (t->auth_blob_format[0] && + strcmp(t->auth_blob_format, "extended") != 0) + return -EINVAL; + + if (t->auth_blob_format[0]) { + u8 *buf __free(kvfree) = + kvzalloc(report_size + ext_size, GFP_KERNEL); + + struct snp_ext_report_req req = { + .data = { .vmpl = t->privlevel }, + .certs_address = (__u64)buf + report_size, + .certs_len = ext_size, + }; + memcpy(&req.data.user_data, t->pubkey, 64); + + struct snp_guest_request_ioctl input = { + .msg_version = 1, + .req_data = (__u64) &req, + .resp_data = (__u64) buf, + }; + + ret = get_ext_report(snp_dev, &input, SNP_KARG); + if (ret) + return ret; + + no_free_ptr(buf); + t->auth_blob = buf; + t->auth_blob_len = report_size + ext_size; + t->auth_blob_desc = "sev"; + } else { + u8 *buf __free(kvfree) = kvzalloc(report_size, GFP_KERNEL); + + struct snp_report_req req = { + .vmpl = t->privlevel, + }; + memcpy(&req.user_data, t->pubkey, 64); + + struct snp_guest_request_ioctl input = { + .msg_version = 1, + .req_data = (__u64) &req, + .resp_data = (__u64) buf, + }; + + ret = get_report(snp_dev, &input, SNP_KARG); + if (ret) + return ret; + + no_free_ptr(buf); + t->auth_blob = buf; + t->auth_blob_len = report_size; + t->auth_blob_desc = "sev"; + } + + return 0; +} + +static const struct tsm_key_ops sev_tsm_ops = { + .name = KBUILD_MODNAME, + .module = THIS_MODULE, + .auth_new = sev_auth_new, +}; + +static void unregister_sev_tsm(void *data) +{ + unregister_tsm_provider(&sev_tsm_ops); +} + static int __init sev_guest_probe(struct platform_device *pdev) { struct snp_secrets_page_layout *layout; @@ -842,6 +921,14 @@ static int __init sev_guest_probe(struct platform_device *pdev) snp_dev->input.resp_gpa = __pa(snp_dev->response); snp_dev->input.data_gpa = __pa(snp_dev->certs_data); + ret = register_tsm_provider(&sev_tsm_ops, snp_dev); + if (ret) + goto e_free_cert_data; + + ret = devm_add_action_or_reset(&pdev->dev, unregister_sev_tsm, NULL); + if (ret) + goto e_free_cert_data; + ret = misc_register(misc); if (ret) goto e_free_cert_data;