From nobody Tue Oct 22 12:06:51 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4XXrWd5MKhz5FDp0; Tue, 22 Oct 2024 12:06:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4XXrWb2XRBz4rD1; Tue, 22 Oct 2024 12:06:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1729598811; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=E/2z700VQghB4E+hu8tBYhaQHgc6elUOeCi9zN0pe7g=; b=GIzcrcU0nnE/WBt/h9Gh3I+sUkj24VMgcBSoFzW40qQLwGxA2pWHESGRSRUT5xf9dIgeRV 2nT237GBpv+9FOCLTs0MK5joYNP6nqW79aHQEdVr8leRqpwoI8/e9vBcX2z9H3w5HgO3EJ 7BmGL+8MO/tt2Iy4BCvp360DXcsHQ8ZZqN3jvcIGiv2hBjVVG48SjfTcWHrgWPHV23PdE8 GJRpUKvBwboQX2Yg9AclNY/bZezwkyB/FPQARBzfE0yLicD5O5BD/KzK2dMpTP1MBiar8w W6AGT972a6AAu17pVvyy+3oX6qp5kUi1Q93ac275lXW4nz4QKp9GPo4v3fw7Xg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1729598811; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=E/2z700VQghB4E+hu8tBYhaQHgc6elUOeCi9zN0pe7g=; b=CNzt2FmKOseKFYvgNXD7sScXtcDhUwbjvWpsGKmdzDAWTfXGUmjjMSL6XjaL44SW3g9Cqa BUllgX25EnktQoKo+07JohzGKoPPslSFZgHyfqxmMaAs2u5yakXnFxv7B5OavzkMy029NM ZldNRVdv5PH6yvtjBYFeK9DWgSAhOib1OBtHyfjA3Hg4E7g1ZvVYEi6VuZyicflIc/hEUm D9YlMRrhjUZ4sATW3xCuxweKBnwdwiplW6v2QpLDx1Mpm/p+/0ostxTqmnbcmsKF3KX7he SoKslM6+S9UgbH3Wc9cvh599ksBItdZ99rf4uX4bFX4+kEoJ25LoQwpoic332w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1729598811; a=rsa-sha256; cv=none; b=RRixh7SqWuFRx/dGEwkIh2rN+Ccstgeu6/xwWOFK48wiTv6PyZ1SNmja8GwZLiQlBOki8V si9BK/rJSukMEA9uhIEAtk2xrA4LtWpJXeHdicAykL4h/en08/a+yzLfqAXM3Y1S7D9qmW 3l6dhnkI7Vw8NLKc9CgwowgYom9fu0OYO/4om1dt/dn1cEWnWxCCAKWH/0Ggz1tlP/VjV2 emSe2+pErYNTbHBn6L0WZz83jDHdyPdJgq5+mCAEJB7NLnjjS4ve3FKIcEBJITyZxrB7sL XuvIZEDDuGqJ/j8WBm/qSetYVCIdd5FZ2AMJXxxMuEf2HoXF2KA3Tp11bUW+Gg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4XXrWb1XvLz1Cw3; Tue, 22 Oct 2024 12:06:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 49MC6p6k085297; Tue, 22 Oct 2024 12:06:51 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 49MC6pt3085294; Tue, 22 Oct 2024 12:06:51 GMT (envelope-from git) Date: Tue, 22 Oct 2024 12:06:51 GMT Message-Id: <202410221206.49MC6pt3085294@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Corvin =?utf-8?Q?K=C3=B6hne?= Subject: git: d93fbcf0222b - main - bhyve: TPM 2.0 emulation with swtpm List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: corvink X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d93fbcf0222b05fcd7704b35bc94e5513c2682e2 Auto-Submitted: auto-generated The branch main has been updated by corvink: URL: https://cgit.FreeBSD.org/src/commit/?id=d93fbcf0222b05fcd7704b35bc94e5513c2682e2 commit d93fbcf0222b05fcd7704b35bc94e5513c2682e2 Author: Hans Rosenfeld AuthorDate: 2024-09-09 08:45:40 +0000 Commit: Corvin Köhne CommitDate: 2024-10-22 12:04:24 +0000 bhyve: TPM 2.0 emulation with swtpm Implement a TPM 2.0 emulation backend to connect to a running swtpm instance using a UNIX domain socket. Reviewed by: corvink MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D46373 --- usr.sbin/bhyve/Makefile | 1 + usr.sbin/bhyve/bhyve.8 | 26 +++++--- usr.sbin/bhyve/bhyve_config.5 | 45 ++++++++++---- usr.sbin/bhyve/tpm_emul_swtpm.c | 132 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 20 deletions(-) diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile index 8b6631de1519..e5e8bf9b5567 100644 --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -60,6 +60,7 @@ SRCS= \ sockstream.c \ tpm_device.c \ tpm_emul_passthru.c \ + tpm_emul_swtpm.c \ tpm_intf_crb.c \ tpm_ppi_qemu.c \ uart_backend.c \ diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index 5d7462a73c5e..62e567fd359d 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -435,7 +435,7 @@ PCI 16550 serial device. .It Cm lpc LPC PCI-ISA bridge with COM1, COM2, COM3, and COM4 16550 serial ports, a boot ROM, and, -optionally, a fwcfg type, and the debug/test device. +optionally, a TPM module, a fwcfg type, and the debug/test device. The LPC bridge emulation can only be configured on bus 0. .It Cm fbuf Raw framebuffer device attached to VNC server. @@ -636,16 +636,25 @@ access is appropriately restricted. .Sm on .El .Pp -Emulate a TPM device. The argument -.Ar path -needs to point to a valid TPM device path, i.e. -.Pa /dev/tpm0 . -.Pp +Emulate a TPM device. Supported options for .Ar type : .Bl -tag -width 10n .It Cm passthru -pass a physical TPM device through to the guest +Use a physical TPM device. +The argument +.Ar path +needs to point to a valid TPM device path, i.e. +.Pa /dev/tpm0 . +.It Cm swtpm +Connect to a running +.Cm swtpm +instance. +The argument +.Ar path +needs to point to a UNIX domain socket that a +.Cm swtpm +process is listening on. .El .Pp The @@ -655,7 +664,8 @@ are: .It Cm version= Ns Ar version Version of the TPM device according to the TCG specification. Defaults to -.Cm 2.0 +.Cm 2.0 , +which is the only version currently supported. .El .Ss Boot ROM device backends .Sm off diff --git a/usr.sbin/bhyve/bhyve_config.5 b/usr.sbin/bhyve/bhyve_config.5 index 51c0751f0f10..3f9d9130787b 100644 --- a/usr.sbin/bhyve/bhyve_config.5 +++ b/usr.sbin/bhyve/bhyve_config.5 @@ -160,15 +160,6 @@ Message (e.g. TightVNC). .It Va pci.enable_bars Ta bool Ta Ta Enable and map PCI BARs before executing any guest code. This setting is false by default when using a boot ROM and true otherwise. -.It Va tpm.path Ta string Ta Ta -Path to the host TPM device. -This is typically /dev/tpm0. -.It Va tpm.type Ta string Ta Ta -Type of the TPM device passed to the guest. -Currently, only "passthru" is supported. -.It Va tpm.version Ta string Ta 2.0 Ta -Version of the TPM device according to the TCG specification. -Currently, only version 2.0 is supported. .It Va rtc.use_localtime Ta bool Ta true Ta The real time clock uses the local time of the host. If this is set to false, the real time clock uses UTC. @@ -288,9 +279,8 @@ Intel e82545 network interface. VGA framebuffer device attached to VNC server. .It Li lpc LPC PCI-ISA bridge with COM1-COM4 16550 serial ports, -a boot ROM, -an optional fwcfg type, -and an optional debug/test device. +a boot ROM, and, optionally, a TPM module, a fwcfg type, +and a debug/test device. This device must be configured on bus 0. .It Li hda High Definition audio controller. @@ -602,6 +592,37 @@ This value is required for the Intel GOP driver to work properly. .It Va subdevice Ta 0 .El .El +.Ss TPM Device Settings +The TPM device stores its configuration under a top-level +.Va tpm +node rather than under the LPC TPM device's node. +Only one TPM device is supported. +The following nodes are available under +.Va tpm : +.Bl -column "tpm.version" "Format" "Default" +.It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description +.It Va tpm.path Ta string Ta Ta +Path to the TPM backend. +Depending on the +.Va tpm.type , +this is either the host TPM device, typically +.Pa /dev/tpm0 , +or any UNIX domain socket on which a +.Cm swtpm +process is listening. +.It Va tpm.type Ta string Ta Ta +Type of the TPM device passed to the guest. +This can be either +.Dq passthru +to use the host TPM devices, or +.Dq swtpm +to connect to a running +.Cm swtpm +process. +.It Va tpm.version Ta string Ta 2.0 Ta +Version of the TPM device according to the TCG specification. +Currently, only version 2.0 is supported. +.El .Ss NVMe Controller Settings Each NVMe controller supports a single storage device. The device can be backed either by a memory disk described by the diff --git a/usr.sbin/bhyve/tpm_emul_swtpm.c b/usr.sbin/bhyve/tpm_emul_swtpm.c new file mode 100644 index 000000000000..aaa0c9c358cd --- /dev/null +++ b/usr.sbin/bhyve/tpm_emul_swtpm.c @@ -0,0 +1,132 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Hans Rosenfeld + * Author: Hans Rosenfeld + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "tpm_device.h" +#include "tpm_emul.h" + +struct tpm_swtpm { + int fd; +}; + +struct tpm_resp_hdr { + uint16_t tag; + uint32_t len; + uint32_t errcode; +} __packed; + +static int +tpm_swtpm_init(void **sc, nvlist_t *nvl) +{ + struct tpm_swtpm *tpm; + const char *path; + struct sockaddr_un tpm_addr; + + tpm = calloc(1, sizeof (struct tpm_swtpm)); + if (tpm == NULL) { + warnx("%s: failed to allocate tpm_swtpm", __func__); + return (ENOMEM); + } + + path = get_config_value_node(nvl, "path"); + if (path == NULL) { + warnx("%s: no socket path specified", __func__); + return (ENOENT); + } + + tpm->fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (tpm->fd < 0) { + warnx("%s: unable to open tpm socket", __func__); + return (ENOENT); + } + + bzero(&tpm_addr, sizeof (tpm_addr)); + tpm_addr.sun_family = AF_UNIX; + strlcpy(tpm_addr.sun_path, path, sizeof (tpm_addr.sun_path) - 1); + + if (connect(tpm->fd, (struct sockaddr *)&tpm_addr, sizeof (tpm_addr)) == + -1) { + warnx("%s: unable to connect to tpm socket \"%s\"", __func__, + path); + return (ENOENT); + } + + *sc = tpm; + + return (0); +} + +static int +tpm_swtpm_execute_cmd(void *sc, void *cmd, uint32_t cmd_size, void *rsp, + uint32_t rsp_size) +{ + struct tpm_swtpm *tpm; + ssize_t len; + + if (rsp_size < (ssize_t)sizeof(struct tpm_resp_hdr)) { + warn("%s: rsp_size of %u is too small", __func__, rsp_size); + return (EINVAL); + } + + tpm = sc; + + len = send(tpm->fd, cmd, cmd_size, MSG_NOSIGNAL|MSG_DONTWAIT); + if (len == -1) + err(1, "%s: cmd send failed, is swtpm running?", __func__); + if (len != cmd_size) { + warn("%s: cmd write failed (bytes written: %zd / %d)", __func__, + len, cmd_size); + return (EFAULT); + } + + len = recv(tpm->fd, rsp, rsp_size, 0); + if (len == -1) + err(1, "%s: rsp recv failed, is swtpm running?", __func__); + if (len < (ssize_t)sizeof(struct tpm_resp_hdr)) { + warn("%s: rsp read failed (bytes read: %zd / %d)", __func__, + len, rsp_size); + return (EFAULT); + } + + return (0); +} + +static void +tpm_swtpm_deinit(void *sc) +{ + struct tpm_swtpm *tpm; + + tpm = sc; + if (tpm == NULL) + return; + + if (tpm->fd >= 0) + close(tpm->fd); + + free(tpm); +} + +static const struct tpm_emul tpm_emul_swtpm = { + .name = "swtpm", + .init = tpm_swtpm_init, + .deinit = tpm_swtpm_deinit, + .execute_cmd = tpm_swtpm_execute_cmd, +}; +TPM_EMUL_SET(tpm_emul_swtpm);