From patchwork Fri Sep 15 11:27:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 13386939 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 20DD1EE6457 for ; Fri, 15 Sep 2023 11:28:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qh6zO-0002IH-5T; Fri, 15 Sep 2023 07:27:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qh6zM-0002Em-Rb; Fri, 15 Sep 2023 07:27:56 -0400 Received: from mail-pl1-x636.google.com ([2607:f8b0:4864:20::636]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qh6zL-0008Dq-Cv; Fri, 15 Sep 2023 07:27:56 -0400 Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-1c3d6d88231so17177565ad.0; Fri, 15 Sep 2023 04:27:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694777259; x=1695382059; darn=nongnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=IcdT9tgTzwyZG5PnKDZ4UxZv7lGrxB6DWITLWfeqGiM=; b=cG/1whifklAoNZAcYAUHC5dusQUmX82RQ2C2V/ZL7S5PcQa9dww6TRAw/SDaIwnJOM GJO33ljzCGcRvkW7Gpw8NHNKx13d2aIn4OyPjgauuBOsiXPqASH4VwR4U7WiMlWNkGAQ xiVIIJRBujx9+YzMpgUYpQ7RrmsoZJtbU7YA9sV+QFMFCTMykWg80SWqK6H7jTYyc3hy wH1uD6j+939Ixfy2PVOy4GzRPlFyIUevCKLRU7bHrL8t7NaqbU9aiSD0bF3V1K0QmDCv oVbiJfCrogAg2aD2k3nnMtWCzly69+Zcwqeq18gkWpFI3j998daJ6zesdflPTPPAdlAq m6LQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694777259; x=1695382059; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=IcdT9tgTzwyZG5PnKDZ4UxZv7lGrxB6DWITLWfeqGiM=; b=N/rzC7FqlAxtJoYlLPs1dnogwA5x9ovPAFuHRvxh5NdJlNLVMTDGkRqB8/Do7XQAEM TdDCYE7HlI/3Kj3/lkFB+y7D1LWT2QOpRj05XjlvvgOawV5Q5LZTEthGEoqsyo1ufO6G jbdo8KTb02PUP6HG5VjuWOtD14mwQ9HOLgJKXyM9lG/v+aKZj3oy9qglmO59FK2KecWS Yo6c2JMO5fWSjhEilCbQSxxQMlf0CwFERwb7Ll4+VXE10CFnbtrg97IIljWpkQcqYIvT T6KPg687yfNqamO9CaMMY2Npkab3gEg2nxjNKo+Klomsc+tO1jOvraj8PXx07YGVJw1/ 5kHw== X-Gm-Message-State: AOJu0YzcWz3dJ/5oAICxsaobIeWGmPpcqFp+Mbe/VZPP/217IyJtvLpv JT8Az6ZeotjgwxWEXrkonKQ= X-Google-Smtp-Source: AGHT+IH76EGh4Vle5cM6a41QZg96Mx92ipzSi/wletjpTklZwDR6jeuw6EtK1crd0GWoznQ7/y/QNA== X-Received: by 2002:a17:903:258f:b0:1c3:f4fa:b1a2 with SMTP id jb15-20020a170903258f00b001c3f4fab1a2mr1230985plb.8.1694777258646; Fri, 15 Sep 2023 04:27:38 -0700 (PDT) Received: from toolbox.alistair23.me (2403-580b-97e8-0-321-6fb2-58f1-a1b1.ip6.aussiebb.net. [2403:580b:97e8:0:321:6fb2:58f1:a1b1]) by smtp.gmail.com with ESMTPSA id u1-20020a170902e5c100b001b1a2c14a4asm3277691plf.38.2023.09.15.04.27.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 04:27:37 -0700 (PDT) From: Alistair Francis X-Google-Original-From: Alistair Francis To: lukas@wunner.de, wilfred.mallawa@wdc.com, Jonathan.Cameron@Huawei.com, jiewen.yao@intel.com, qemu-devel@nongnu.org, kbusch@kernel.org, its@irrelevant.dk, mst@redhat.com, marcel.apfelbaum@gmail.com, hchkuo@avery-design.com.tw, cbrowy@avery-design.com Cc: alistair23@gmail.com, qemu-block@nongnu.org, Alistair Francis Subject: [PATCH 1/3] hw/pci: Add all Data Object Types Date: Fri, 15 Sep 2023 21:27:21 +1000 Message-ID: <20230915112723.2033330-1-alistair.francis@wdc.com> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::636; envelope-from=alistair23@gmail.com; helo=mail-pl1-x636.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add all of the defined protocols/features from the PCIe-SIG "Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)" table. Signed-off-by: Alistair Francis --- include/hw/pci/pcie_doe.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h index 87dc17dcef..15d94661f9 100644 --- a/include/hw/pci/pcie_doe.h +++ b/include/hw/pci/pcie_doe.h @@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0) /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */ #define PCI_SIG_DOE_DISCOVERY 0x00 +#define PCI_SIG_DOE_CMA 0x01 +#define PCI_SIG_DOE_SECURED_CMA 0x02 #define PCI_DOE_DW_SIZE_MAX (1 << 18) #define PCI_DOE_PROTOCOL_NUM_MAX 256 From patchwork Fri Sep 15 11:27:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 13386938 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DD72CEE6459 for ; Fri, 15 Sep 2023 11:28:41 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qh6zO-0002JL-TH; Fri, 15 Sep 2023 07:27:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qh6zN-0002GN-Ke; Fri, 15 Sep 2023 07:27:57 -0400 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qh6zL-0008He-EI; Fri, 15 Sep 2023 07:27:57 -0400 Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1c3bd829b86so17333665ad.0; Fri, 15 Sep 2023 04:27:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694777273; x=1695382073; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gWIThUmed1nAt7l7tHIjD+bJSsuAsIVox65liSnj0oA=; b=g2ib3kkg5yozkx3Cnc8D4GTUOv1cf1WSvBehKPICO01Zl9Fck91r/b+ijThshKLh/T xRqDgykFIE4fZPRF1Rcl8i+wesXVcLp1wQ28Dc8EYi5JGhygYZ48Bq3Gdv20Hc1hAyja 1H0i8B5ADmJo8HjgHIOISxPR/Qe04IumUydSfv402mPByOjoI5vx+Tb+cA3bNYm8P3CC hH++tqpcviVcsEk5DnttU4CNr97o2jk6gEb7qTPEeZFhHxWCsZdqXSiu0/uMcvjvl4gl xkrv5vmmI13zUZPEAgZFbIpanBdtPgT22UFV6zZLL/RDg/OIzb4MNG/vgCXp4gob1z7D OZiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694777273; x=1695382073; 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:message-id:reply-to; bh=gWIThUmed1nAt7l7tHIjD+bJSsuAsIVox65liSnj0oA=; b=vJa0OUKZ4TVAKU6sS/VL79c1sCZOPh/qXaadu86o0M9vLr6yY2gt3V9QULnyQfd28r fXhekLQ4V/jihFOb8mwxS7DOM52O+2vtne+FdDEcQFpgGS4Ih6BQ0iixLWeIw8xPG+Hm OAqpIg75CwE8m/G80fkt2OH9uy14kLwAiXRP1IEp6pXxpEF3VAgZ8wC58anyweae/iZa nxKaXqxom8wla3E/1Wulqd7U7w/XN20g4686vA5aaA+mnhqm45FbEO5sQ17JSnMezala 2tuMIM7T3r5sFKmAn02Y9nyDHa6w/Jqy5stoUexL12EdeRebU+TM6CMsLcXiDdULjHfn t5kg== X-Gm-Message-State: AOJu0YzBLBy+c8Xena3nkSRPvBAh785fjqozndzjDEkWJ3fXgj2fItpo 8NtN+Jrq7kUvShOjexc+gD8= X-Google-Smtp-Source: AGHT+IHkl3FmhCZa2fAgTqtjvDC4u4UdDxgJXTo9MzNZfOItOA5XTa/Y8Wf/Z7g5eXeJfc2VRXcezQ== X-Received: by 2002:a17:902:dac2:b0:1c4:172b:2f7c with SMTP id q2-20020a170902dac200b001c4172b2f7cmr1504637plx.0.1694777273518; Fri, 15 Sep 2023 04:27:53 -0700 (PDT) Received: from toolbox.alistair23.me (2403-580b-97e8-0-321-6fb2-58f1-a1b1.ip6.aussiebb.net. [2403:580b:97e8:0:321:6fb2:58f1:a1b1]) by smtp.gmail.com with ESMTPSA id u1-20020a170902e5c100b001b1a2c14a4asm3277691plf.38.2023.09.15.04.27.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 04:27:52 -0700 (PDT) From: Alistair Francis X-Google-Original-From: Alistair Francis To: lukas@wunner.de, wilfred.mallawa@wdc.com, Jonathan.Cameron@Huawei.com, jiewen.yao@intel.com, qemu-devel@nongnu.org, kbusch@kernel.org, its@irrelevant.dk, mst@redhat.com, marcel.apfelbaum@gmail.com, hchkuo@avery-design.com.tw, cbrowy@avery-design.com Cc: alistair23@gmail.com, qemu-block@nongnu.org, Jonathan Cameron , Jonathan Cameron , Alistair Francis Subject: [PATCH 2/3] backends: Initial support for SPDM socket support Date: Fri, 15 Sep 2023 21:27:22 +1000 Message-ID: <20230915112723.2033330-2-alistair.francis@wdc.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230915112723.2033330-1-alistair.francis@wdc.com> References: <20230915112723.2033330-1-alistair.francis@wdc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::635; envelope-from=alistair23@gmail.com; helo=mail-pl1-x635.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Huai-Cheng Kuo SPDM enables authentication, attestation and key exchange to assist in providing infrastructure security enablement. It's a standard published by the DMTF [1]. SPDM currently supports PCIe DOE and MCTP transports, but it can be extended to support others in the future. This patch adds support to QEMU to connect to an external SPDM instance. SPDM support can be added to any QEMU device by exposing a TCP socket to a SPDM server. The server can then implement the SPDM decoding/encoding support, generally using libspdm [2]. This is similar to how the current TPM implementation works and means that the heavy lifting of setting up certificate chains, capabilities, measurements and complex crypto can be done outside QEMU by a well supported and tested library. 1: https://www.dmtf.org/standards/SPDM 2: https://github.com/DMTF/libspdm Signed-off-by: Huai-Cheng Kuo Signed-off-by: Chris Browy Co-developed-by: Jonathan Cameron Signed-off-by: Jonathan Cameron [ Changes by AF: - Convert to be more QEMU-ified - Move to backends as it isn't PCIe specific ] Signed-off-by: Alistair Francis Signed-off-by: Wilfred Mallawa --- include/sysemu/spdm-socket.h | 44 +++++++ backends/spdm-socket.c | 215 +++++++++++++++++++++++++++++++++++ backends/Kconfig | 4 + backends/meson.build | 2 + 4 files changed, 265 insertions(+) create mode 100644 include/sysemu/spdm-socket.h create mode 100644 backends/spdm-socket.c diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h new file mode 100644 index 0000000000..24e6fccb83 --- /dev/null +++ b/include/sysemu/spdm-socket.h @@ -0,0 +1,44 @@ +/* + * QEMU SPDM socket support + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef SPDM_REQUESTER_H +#define SPDM_REQUESTER_H + +int spdm_socket_connect(uint16_t port, Error **errp); +uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type, + void *req, uint32_t req_len, + void *rsp, uint32_t rsp_len); +void spdm_socket_close(const int socket, uint32_t transport_type); + +#define SPDM_SOCKET_COMMAND_NORMAL 0x0001 +#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE 0x8001 +#define SPDM_SOCKET_COMMAND_CONTINUE 0xFFFD +#define SPDM_SOCKET_COMMAND_SHUTDOWN 0xFFFE +#define SPDM_SOCKET_COMMAND_UNKOWN 0xFFFF +#define SPDM_SOCKET_COMMAND_TEST 0xDEAD + +#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP 0x01 +#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE 0x02 + +#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE 0x1200 + +#endif diff --git a/backends/spdm-socket.c b/backends/spdm-socket.c new file mode 100644 index 0000000000..2f31ba80ba --- /dev/null +++ b/backends/spdm-socket.c @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * QEMU SPDM socket support + * + * This is based on: + * https://github.com/DMTF/spdm-emu/blob/07c0a838bcc1c6207c656ac75885c0603e344b6f/spdm_emu/spdm_emu_common/command.c + * but has been re-written to match QEMU style + * + * Copyright (c) 2021, DMTF. All rights reserved. + * Copyright (c) 2023. Western Digital Corporation or its affiliates. + */ + +#include "qemu/osdep.h" +#include "sysemu/spdm-socket.h" +#include "qapi/error.h" + +static bool read_bytes(const int socket, uint8_t *buffer, + size_t number_of_bytes) +{ + ssize_t number_received = 0; + ssize_t result; + + while (number_received < number_of_bytes) { + result = recv(socket, buffer + number_received, + number_of_bytes - number_received, 0); + if (result <= 0) { + return false; + } + number_received += result; + } + return true; +} + +static bool read_data32(const int socket, uint32_t *data) +{ + bool result; + + result = read_bytes(socket, (uint8_t *)data, sizeof(uint32_t)); + if (!result) { + return result; + } + *data = ntohl(*data); + return true; +} + +static bool read_multiple_bytes(const int socket, uint8_t *buffer, + uint32_t *bytes_received, + uint32_t max_buffer_length) +{ + uint32_t length; + bool result; + + result = read_data32(socket, &length); + if (!result) { + return result; + } + + if (length > max_buffer_length) { + return false; + } + + if (bytes_received) { + *bytes_received = length; + } + + if (length == 0) { + return true; + } + + return read_bytes(socket, buffer, length); +} + +static bool receive_platform_data(const int socket, + uint32_t transport_type, + uint32_t *command, + uint8_t *receive_buffer, + uint32_t *bytes_to_receive) +{ + bool result; + uint32_t response; + uint32_t bytes_received; + + result = read_data32(socket, &response); + if (!result) { + return result; + } + *command = response; + + result = read_data32(socket, &transport_type); + if (!result) { + return result; + } + + bytes_received = 0; + result = read_multiple_bytes(socket, receive_buffer, &bytes_received, + *bytes_to_receive); + if (!result) { + return result; + } + *bytes_to_receive = bytes_received; + + return result; +} + +static bool write_bytes(const int socket, const uint8_t *buffer, + uint32_t number_of_bytes) +{ + ssize_t number_sent = 0; + ssize_t result; + + while (number_sent < number_of_bytes) { + result = send(socket, buffer + number_sent, + number_of_bytes - number_sent, 0); + if (result == -1) { + return false; + } + number_sent += result; + } + return true; +} + +static bool write_data32(const int socket, uint32_t data) +{ + data = htonl(data); + return write_bytes(socket, (uint8_t *)&data, sizeof(uint32_t)); +} + +static bool write_multiple_bytes(const int socket, const uint8_t *buffer, + uint32_t bytes_to_send) +{ + bool result; + + result = write_data32(socket, bytes_to_send); + if (!result) { + return result; + } + + return write_bytes(socket, buffer, bytes_to_send); +} + +static bool send_platform_data(const int socket, + uint32_t transport_type, uint32_t command, + const uint8_t *send_buffer, size_t bytes_to_send) +{ + bool result; + + result = write_data32(socket, command); + if (!result) { + return result; + } + + result = write_data32(socket, transport_type); + if (!result) { + return result; + } + + return write_multiple_bytes(socket, send_buffer, bytes_to_send); +} + +int spdm_socket_connect(uint16_t port, Error **errp) +{ + int client_socket; + struct sockaddr_in server_addr; + + client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (client_socket < 0) { + error_setg(errp, "cannot create socket: %s", strerror(errno)); + return -1; + } + + memset((char *)&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + server_addr.sin_port = htons(port); + + + if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + error_setg(errp, "cannot connect: %s", strerror(errno)); + close(client_socket); + return -1; + } + + return client_socket; +} + +uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type, + void *req, uint32_t req_len, + void *rsp, uint32_t rsp_len) +{ + uint32_t command; + bool result; + + result = send_platform_data(socket, transport_type, + SPDM_SOCKET_COMMAND_NORMAL, + req, req_len); + if (!result) { + return 0; + } + + result = receive_platform_data(socket, transport_type, &command, + (uint8_t *)rsp, &rsp_len); + if (!result) { + return 0; + } + + assert(command != 0); + + return rsp_len; +} + +void spdm_socket_close(const int socket, uint32_t transport_type) +{ + send_platform_data(socket, transport_type, + SPDM_SOCKET_COMMAND_SHUTDOWN, NULL, 0); +} diff --git a/backends/Kconfig b/backends/Kconfig index f35abc1609..648e58a9b3 100644 --- a/backends/Kconfig +++ b/backends/Kconfig @@ -1 +1,5 @@ source tpm/Kconfig + +config SPDM_SOCKET + bool + default y diff --git a/backends/meson.build b/backends/meson.build index 914c7c4afb..77d48ffdaa 100644 --- a/backends/meson.build +++ b/backends/meson.build @@ -26,4 +26,6 @@ endif system_ss.add(when: gio, if_true: files('dbus-vmstate.c')) system_ss.add(when: 'CONFIG_SGX', if_true: files('hostmem-epc.c')) +system_ss.add(when: 'CONFIG_SPDM_SOCKET', if_true: files('spdm-socket.c')) + subdir('tpm') From patchwork Fri Sep 15 11:27:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 13386937 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 976C4EE6457 for ; Fri, 15 Sep 2023 11:28:27 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qh6zc-0002Lg-Jn; Fri, 15 Sep 2023 07:28:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qh6za-0002L9-PK; Fri, 15 Sep 2023 07:28:10 -0400 Received: from mail-pl1-x62e.google.com ([2607:f8b0:4864:20::62e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qh6zY-0008Rq-MP; Fri, 15 Sep 2023 07:28:10 -0400 Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1c43166b7e5so5068625ad.3; Fri, 15 Sep 2023 04:28:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694777287; x=1695382087; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=u4pxKo28EN6eNVmjJP/msaheYD+q2Vlgd5Eur6zPdZc=; b=e+N+3CblN+b6tgg+G9bKS1G0B2yIGtlT0dDLUfvNFlwMAnW9cLtr5VugrPkJAMsTDI 9c0OvYB7rryI1i61UOijl75ykzFu/XYI1nR/beoc00KCbdAAYJN5xVc389b0Cuk6dFu8 iPZxKWmU1yc0H9HrPDrsG/QQy67ZId293i+faTHZ2j6vs2zWkyJk5xzOQk1SIRqNzm3r qlmqGnRDQVy59FtZcJpO8Br4jQy9FDHxCthv0fMR7vLw0GfItGFwZwN1ysMvYpJqzIjE LNlQ3szZvcaUWK8YHRYFL8R7+0yux8TnHD2Q8OVwvZXw8Ji/LE3NjZjedrFYp9ZfG9Lx k83A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694777287; x=1695382087; 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:message-id:reply-to; bh=u4pxKo28EN6eNVmjJP/msaheYD+q2Vlgd5Eur6zPdZc=; b=m2yC1vovM/o3b16RpLrGl9Bumxd3BeY+Hwf8kmzyhQLrU60tHo+KCXM/KR7Ph4r8Wl V2VkvMf9/S72kGZ0Rc/dp67J3z/YnOspJ0Y+Twj5CUoNfxYZ4t1RFXyMIAT7MKAs/k2W mj4Zh+E6WdS7KEILf1sa1SBYJthsGfLzcn2TAh7Cw6FB1CmZM4fLGoaU0clFYiraaNNh w/LTgyIiUCDz+bnmTUIZjd8AMhXKm9Zeu6HPbazClDw6jBd9OJWQ2TNkAMsELY3QAXZn 1sl44mT+if5tcY12WXOSWFydKKYhu006bYCDarHaQOovDO+/PV5KGuuiharEQCU2zfqt GO7w== X-Gm-Message-State: AOJu0Yw9cz7uyIFyTBLg1HekwiZgcN2uHAUajSO7U4Et5NpFitDsbhSe ttvH0cVzrUTAn0OM9ey6f4k= X-Google-Smtp-Source: AGHT+IFPiEyw5Fpjjx1d3laDrBZXFkIKscPsFPwaQ2/ZAP0evtYWgid63Rk2VZQvlWM4+9GhhTnkkw== X-Received: by 2002:a17:902:9684:b0:1b8:8af0:416f with SMTP id n4-20020a170902968400b001b88af0416fmr1177787plp.1.1694777286848; Fri, 15 Sep 2023 04:28:06 -0700 (PDT) Received: from toolbox.alistair23.me (2403-580b-97e8-0-321-6fb2-58f1-a1b1.ip6.aussiebb.net. [2403:580b:97e8:0:321:6fb2:58f1:a1b1]) by smtp.gmail.com with ESMTPSA id u1-20020a170902e5c100b001b1a2c14a4asm3277691plf.38.2023.09.15.04.28.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 04:28:06 -0700 (PDT) From: Alistair Francis X-Google-Original-From: Alistair Francis To: lukas@wunner.de, wilfred.mallawa@wdc.com, Jonathan.Cameron@Huawei.com, jiewen.yao@intel.com, qemu-devel@nongnu.org, kbusch@kernel.org, its@irrelevant.dk, mst@redhat.com, marcel.apfelbaum@gmail.com, hchkuo@avery-design.com.tw, cbrowy@avery-design.com Cc: alistair23@gmail.com, qemu-block@nongnu.org, Alistair Francis Subject: [PATCH 3/3] hw/nvme: Add SPDM over DOE support Date: Fri, 15 Sep 2023 21:27:23 +1000 Message-ID: <20230915112723.2033330-3-alistair.francis@wdc.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230915112723.2033330-1-alistair.francis@wdc.com> References: <20230915112723.2033330-1-alistair.francis@wdc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62e; envelope-from=alistair23@gmail.com; helo=mail-pl1-x62e.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Wilfred Mallawa Setup Data Object Exchance (DOE) as an extended capability for the NVME controller and connect SPDM to it (CMA) to it. Signed-off-by: Wilfred Mallawa Signed-off-by: Alistair Francis --- docs/specs/index.rst | 1 + docs/specs/spdm.rst | 56 +++++++++++++++++++++++++++++++++++++ include/hw/pci/pci_device.h | 5 ++++ include/hw/pci/pcie_doe.h | 3 ++ hw/nvme/ctrl.c | 52 ++++++++++++++++++++++++++++++++++ hw/nvme/trace-events | 1 + 6 files changed, 118 insertions(+) create mode 100644 docs/specs/spdm.rst diff --git a/docs/specs/index.rst b/docs/specs/index.rst index e58be38c41..c398541388 100644 --- a/docs/specs/index.rst +++ b/docs/specs/index.rst @@ -24,3 +24,4 @@ guest hardware that is specific to QEMU. acpi_erst sev-guest-firmware fw_cfg + spdm diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst new file mode 100644 index 0000000000..0f96d618ef --- /dev/null +++ b/docs/specs/spdm.rst @@ -0,0 +1,56 @@ +====================================================== +QEMU Security Protocols and Data Models (SPDM) Support +====================================================== + +SPDM enables authentication, attestation and key exchange to assist in +providing infrastructure security enablement. It's a standard published +by the DMTF https://www.dmtf.org/standards/SPDM. + +Setting up a SPDM server +======================== + +When using QEMU with SPDM devices QEMU will connect to a server which +implements the SPDM functionality. + +spdm-emu +-------- + +You can use spdm-emu https://github.com/dmtf/spdm-emu to model the +SPDM responder. + +.. code-block:: shell + + $ cd spdm-emu + $ git submodule init; git submodule update --recursive + $ mkdir build; cd build + $ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl .. + $ make -j32 + $ make copy_sample_key # Build certificates, required for SPDM authentication. + +The responder can then be launched with + +.. code-block:: shell + + $ cd bin + $ ./spdm_responder_emu --trans PCI_DOE + +Connecting an SPDM NVMe device +============================== + +Once a SPDM server is running we can start QEMU and connect to the server. + +For an NVMe device first let's setup a block we can use + +.. code-block:: shell + + $ cd qemu-spdm/linux/image + $ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive + +Then you can add this to your QEMU command line: + +.. code-block:: shell + + -drive file=blknvme,if=none,id=mynvme,format=raw \ + -device nvme,drive=mynvme,serial=deadbeef,spdm=2323 + +At which point QEMU will connect to the SPDM server. diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h index d3dd0f64b2..b8379c78f1 100644 --- a/include/hw/pci/pci_device.h +++ b/include/hw/pci/pci_device.h @@ -3,6 +3,7 @@ #include "hw/pci/pci.h" #include "hw/pci/pcie.h" +#include "hw/pci/pcie_doe.h" #define TYPE_PCI_DEVICE "pci-device" typedef struct PCIDeviceClass PCIDeviceClass; @@ -157,6 +158,10 @@ struct PCIDevice { MSIVectorReleaseNotifier msix_vector_release_notifier; MSIVectorPollNotifier msix_vector_poll_notifier; + /* DOE */ + DOECap doe_spdm; + uint16_t spdm_port; + /* ID of standby device in net_failover pair */ char *failover_pair_id; uint32_t acpi_index; diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h index 15d94661f9..eb8f4e393d 100644 --- a/include/hw/pci/pcie_doe.h +++ b/include/hw/pci/pcie_doe.h @@ -108,6 +108,9 @@ struct DOECap { /* Protocols and its callback response */ DOEProtocol *protocols; uint16_t protocol_num; + + /* Used for spdm-socket */ + int socket; }; void pcie_doe_init(PCIDevice *pdev, DOECap *doe_cap, uint16_t offset, diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 90687b168a..1ff30a9ad4 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -203,6 +203,7 @@ #include "sysemu/hostmem.h" #include "hw/pci/msix.h" #include "hw/pci/pcie_sriov.h" +#include "sysemu/spdm-socket.h" #include "migration/vmstate.h" #include "nvme.h" @@ -8077,6 +8078,28 @@ static int nvme_add_pm_capability(PCIDevice *pci_dev, uint8_t offset) return 0; } +static bool pcie_doe_spdm_rsp(DOECap *doe_cap) +{ + void *req = pcie_doe_get_write_mbox_ptr(doe_cap); + uint32_t req_len = pcie_doe_get_obj_len(req) * 4; + void *rsp = doe_cap->read_mbox; + uint32_t rsp_len = SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE; + uint32_t recvd; + + recvd = spdm_socket_rsp(doe_cap->socket, + SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE, + req, req_len, rsp, rsp_len); + doe_cap->read_mbox_len += DIV_ROUND_UP(recvd, 4); + + return (recvd == 0) ? false : true; +} + +static DOEProtocol doe_spdm_prot[] = { + { PCI_VENDOR_ID_PCI_SIG, PCI_SIG_DOE_CMA, pcie_doe_spdm_rsp }, + { PCI_VENDOR_ID_PCI_SIG, PCI_SIG_DOE_SECURED_CMA, pcie_doe_spdm_rsp }, + { } +}; + static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp) { ERRP_GUARD(); @@ -8133,6 +8156,23 @@ static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp) nvme_update_msixcap_ts(pci_dev, n->conf_msix_qsize); + pcie_cap_deverr_init(pci_dev); + + /* DOE Initialisation */ + if (pci_dev->spdm_port) { + uint16_t doe_offset = n->params.sriov_max_vfs ? + PCI_CONFIG_SPACE_SIZE + PCI_ARI_SIZEOF + : PCI_CONFIG_SPACE_SIZE; + + pcie_doe_init(pci_dev, &pci_dev->doe_spdm, doe_offset, doe_spdm_prot, true, 0); + + pci_dev->doe_spdm.socket = spdm_socket_connect(pci_dev->spdm_port, errp); + + if (pci_dev->doe_spdm.socket < 0 ) { + trace_pci_cma_err_openspdm_conn(); + } + } + if (n->params.cmb_size_mb) { nvme_init_cmb(n, pci_dev); } @@ -8419,6 +8459,7 @@ static Property nvme_props[] = { params.sriov_max_vi_per_vf, 0), DEFINE_PROP_UINT8("sriov_max_vq_per_vf", NvmeCtrl, params.sriov_max_vq_per_vf, 0), + DEFINE_PROP_UINT16("spdm", PCIDevice, spdm_port, 0), DEFINE_PROP_END_OF_LIST(), }; @@ -8501,10 +8542,20 @@ static void nvme_pci_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len) { nvme_sriov_pre_write_ctrl(dev, address, val, len); + pcie_doe_write_config(&dev->doe_spdm, address, val, len); pci_default_write_config(dev, address, val, len); pcie_cap_flr_write_config(dev, address, val, len); } +static uint32_t nvme_pci_read_config(PCIDevice *dev, uint32_t address, int len) +{ + uint32_t val; + if (pcie_doe_read_config(&dev->doe_spdm, address, len, &val)) { + return val; + } + return pci_default_read_config(dev, address, len); +} + static const VMStateDescription nvme_vmstate = { .name = "nvme", .unmigratable = 1, @@ -8517,6 +8568,7 @@ static void nvme_class_init(ObjectClass *oc, void *data) pc->realize = nvme_realize; pc->config_write = nvme_pci_write_config; + pc->config_read = nvme_pci_read_config; pc->exit = nvme_exit; pc->class_id = PCI_CLASS_STORAGE_EXPRESS; pc->revision = 2; diff --git a/hw/nvme/trace-events b/hw/nvme/trace-events index 3a67680c6a..c0e2ce9fda 100644 --- a/hw/nvme/trace-events +++ b/hw/nvme/trace-events @@ -191,6 +191,7 @@ pci_nvme_err_startfail(void) "setting controller enable bit failed" pci_nvme_err_startfail_virt_state(uint16_t vq, uint16_t vi) "nvme_start_ctrl failed due to ctrl state: vi=%u vq=%u" pci_nvme_err_invalid_mgmt_action(uint8_t action) "action=0x%"PRIx8"" pci_nvme_err_ignored_mmio_vf_offline(uint64_t addr, unsigned size) "addr 0x%"PRIx64" size %d" +pci_cma_err_openspdm_conn(void) "Failed to connect to OpenSPDM, SPDM disabled" # undefined behavior pci_nvme_ub_mmiowr_misaligned32(uint64_t offset) "MMIO write not 32-bit aligned, offset=0x%"PRIx64""