All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: James Bottomley <jejb@linux.ibm.com>
Cc: qemu-devel@nongnu.org, Stefan Berger <stefanb@linux.ibm.com>,
	Markus Armbruster <armbru@redhat.com>
Subject: Re: [PATCH] tpm: add backend for mssim
Date: Mon, 12 Dec 2022 15:47:23 +0000	[thread overview]
Message-ID: <Y5dNC77CubqrfXku@redhat.com> (raw)
In-Reply-To: <4780481659602f92fffacac66e7dca41ad2787c4.camel@linux.ibm.com>

Copy'ing Markus for QAPI design feedback.

On Sat, Dec 10, 2022 at 12:10:18PM -0500, James Bottomley wrote:
> The Microsoft Simulator (mssim) is the reference emulation platform
> for the TCG TPM 2.0 specification.
> 
> https://github.com/Microsoft/ms-tpm-20-ref.git
> 
> It exports a fairly simple network socket baset protocol on two
> sockets, one for command (default 2321) and one for control (default
> 2322).  This patch adds a simple backend that can speak the mssim
> protocol over the network.  It also allows the host, and two ports to
> be specified on the qemu command line.  The benefits are twofold:
> firstly it gives us a backend that actually speaks a standard TPM
> emulation protocol instead of the linux specific TPM driver format of
> the current emulated TPM backend and secondly, using the microsoft
> protocol, the end point of the emulator can be anywhere on the
> network, facilitating the cloud use case where a central TPM service
> can be used over a control network.

What's the story with security for this ?  The patch isn't using
TLS, so talking to any emulator over anything other than localhost
looks insecure, unless I'm missing something.



> diff --git a/backends/tpm/tpm_mssim.c b/backends/tpm/tpm_mssim.c
> new file mode 100644
> index 0000000000..6864b1fbc0
> --- /dev/null
> +++ b/backends/tpm/tpm_mssim.c
> @@ -0,0 +1,266 @@
> +/*
> + * Emulator TPM driver which connects over the mssim protocol
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * Copyright (c) 2022

Copyright by whom ?  Presumably this line should have "IBM" present
if we're going to have it at all.

> + * Author: James Bottomley <jejb@linux.ibm.com>
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qemu/sockets.h"
> +
> +#include "qapi/clone-visitor.h"
> +#include "qapi/qapi-visit-tpm.h"
> +
> +#include "io/channel-socket.h"
> +
> +#include "sysemu/tpm_backend.h"
> +#include "sysemu/tpm_util.h"
> +
> +#include "qom/object.h"
> +
> +#include "tpm_int.h"
> +#include "tpm_mssim.h"
> +

> +static TPMBackend *tpm_mssim_create(QemuOpts *opts)
> +{
> +    TPMBackend *be = TPM_BACKEND(object_new(TYPE_TPM_MSSIM));
> +    TPMmssim *t = TPM_MSSIM(be);
> +    InetSocketAddress cmd_s, ctl_s;
> +    int sock;
> +    const char *host, *port, *ctrl;
> +    Error *errp = NULL;
> +
> +    host = qemu_opt_get(opts, "host");
> +    if (!host)
> +        host = "localhost";
> +    t->opts.host = g_strdup(host);
> +
> +    port = qemu_opt_get(opts, "port");
> +    if (!port)
> +        port = "2321";
> +    t->opts.port = g_strdup(port);
> +
> +    ctrl = qemu_opt_get(opts, "ctrl");
> +    if (!ctrl)
> +        ctrl = "2322";
> +    t->opts.ctrl = g_strdup(ctrl);
> +
> +    cmd_s.host = (char *)host;
> +    cmd_s.port = (char *)port;
> +
> +    ctl_s.host = (char *)host;
> +    ctl_s.port = (char *)ctrl;
> +
> +    sock = inet_connect_saddr(&cmd_s, &errp);
> +    if (sock < 0)
> +        goto fail;
> +    t->cmd_qc = QIO_CHANNEL(qio_channel_socket_new_fd(sock, &errp));
> +    if (errp)
> +        goto fail;
> +    sock = inet_connect_saddr(&ctl_s, &errp);
> +    if (sock < 0)
> +        goto fail_unref_cmd;
> +    t->ctrl_qc = QIO_CHANNEL(qio_channel_socket_new_fd(sock, &errp));
> +    if (errp)
> +        goto fail_unref_cmd;

We don't want to be using inet_connect_saddr, that's a legacy
API. All new code should be using the qio_channel_socket_connect*
family of APIs. This is trivial if the QAPI design uses SocketAddress
structs directly.

> +
> +    /* reset the TPM using a power cycle sequence, in case someone
> +     * has previously powered it up */
> +    sock = tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, &errp);
> +    if (sock != 0)
> +        goto fail_unref;
> +    sock = tpm_send_ctrl(t, TPM_SIGNAL_POWER_ON, &errp);
> +    if (sock != 0)
> +        goto fail_unref;
> +    sock = tpm_send_ctrl(t, TPM_SIGNAL_NV_ON, &errp);
> +    if (sock != 0)
> +        goto fail_unref;
> +
> +    return be;
> + fail_unref:
> +    object_unref(OBJECT(t->ctrl_qc));
> + fail_unref_cmd:
> +    object_unref(OBJECT(t->cmd_qc));
> + fail:
> +    error_prepend(&errp, ERROR_PREFIX);
> +    error_report_err(errp);
> +    object_unref(OBJECT(be));
> +
> +    return NULL;
> +}
> +
> +static const QemuOptDesc tpm_mssim_cmdline_opts[] = {
> +    TPM_STANDARD_CMDLINE_OPTS,
> +    {
> +        .name = "host",
> +        .type = QEMU_OPT_STRING,
> +        .help = "name or IP address of host to connect to (deault localhost)",
> +    },
> +    {
> +        .name = "port",
> +        .type = QEMU_OPT_STRING,
> +        .help = "port number for standard TPM commands (default 2321)",
> +    },
> +    {
> +        .name = "ctrl",
> +        .type = QEMU_OPT_STRING,
> +        .help = "control port for TPM commands (default 2322)",
> +    },
> +};
> +
> +static void tpm_mssim_class_init(ObjectClass *klass, void *data)
> +{
> +    TPMBackendClass *cl = TPM_BACKEND_CLASS(klass);
> +
> +    cl->type = TPM_TYPE_MSSIM;
> +    cl->opts = tpm_mssim_cmdline_opts;
> +    cl->desc = "TPM mssim emulator backend driver";
> +    cl->create = tpm_mssim_create;
> +    cl->cancel_cmd = tpm_mssim_cancel_cmd;
> +    cl->get_tpm_version = tpm_mssim_get_version;
> +    cl->get_buffer_size = tpm_mssim_get_buffer_size;
> +    cl->get_tpm_options = tpm_mssim_get_opts;
> +    cl->handle_request = tpm_mssim_handle_request;
> +}


>  
> +##
> +# @TPMmssimOptions:
> +#
> +# Information for the mssim emulator connection
> +#
> +# @host: host name or IP address to connect to
> +# @port: port for the standard TPM commands
> +# @ctrl: control port for TPM state changes
> +#
> +# Since: 7.2.0
> +##
> +{ 'struct': 'TPMmssimOptions',
> +  'data': {
> +      'host': 'str',
> +      'port': 'str',
> +      'ctrl': 'str' },
> +  'if': 'CONFIG_TPM' }

We don't want to be adding new code using plain host/port combos,
as that misses extra functionality for controlling IPv4 vs IPv6
usage.

The existing 'emulator' backend references a chardev, but I'm
not especially in favour of using the chardev indirection either,
when all we should really need is a SocketAddress

IOW, from a QAPI design POV, IMHO the best practice would be

 { 'struct': 'TPMmssimOptions',
   'data': {
       'command': 'SocketAddress',
       'control': 'SocketAddress' },
   'if': 'CONFIG_TPM' }


The main wrinkle with this is that exprssing nested struct fields
with QemuOpts is a disaster zone, and -tpmdev doesn't yet support
JSON syntax.

IMHO we should just fix the latter problem, as I don't think it
ought to be too hard. Probably a cut+paste / search/replace job
on the chanmge we did for -device in:

  commit 5dacda5167560b3af8eadbce5814f60ba44b467e
  Author: Kevin Wolf <kwolf@redhat.com>
  Date:   Fri Oct 8 15:34:42 2021 +0200

    vl: Enable JSON syntax for -device

This would mean we could use plain -tpmdev for a local instance

   -tpmdev mssim,id=tpm0 \
    -device tpm-crb,tpmdev=tpm0 \

but to use a remote emulator we would use

    -tpmdev "{'backend': 'mssim', 'id': 'tpm0',
              'command': {
	         'type': 'inet',
		 'host': 'remote',
		 'port': '4455'
               },
              'control': {
	         'type': 'inet',
		 'host': 'remote',
		 'port': '4456'
               }}"

(without the whitepace/newlines, which i just used for sake of clarity)

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  parent reply	other threads:[~2022-12-12 15:47 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-10 17:10 [PATCH] tpm: add backend for mssim James Bottomley
2022-12-12 13:43 ` Stefan Berger
2022-12-12 13:59   ` James Bottomley
2022-12-12 14:27     ` Stefan Berger
2022-12-12 14:32       ` James Bottomley
2022-12-12 14:44         ` Stefan Berger
2022-12-12 14:47           ` James Bottomley
2022-12-12 15:20             ` Stefan Berger
2022-12-12 15:28               ` James Bottomley
2022-12-12 15:46                 ` Stefan Berger
2022-12-12 15:47 ` Daniel P. Berrangé [this message]
2022-12-12 16:38   ` James Bottomley
2022-12-12 16:59     ` Stefan Berger
2022-12-12 18:48       ` James Bottomley
2022-12-12 18:58         ` Stefan Berger
2022-12-12 19:12           ` James Bottomley
2022-12-12 19:32             ` Stefan Berger
2022-12-12 20:24               ` Stefan Berger
2022-12-12 21:36               ` James Bottomley
2022-12-12 22:02                 ` Stefan Berger
2022-12-12 22:27                   ` James Bottomley
2022-12-12 22:43                     ` Stefan Berger
2022-12-14 11:52                   ` Daniel P. Berrangé
2022-12-14 12:43                     ` James Bottomley
2022-12-15  2:42                       ` Stefan Berger
2022-12-14 11:55           ` Daniel P. Berrangé
2022-12-12 22:06   ` James Bottomley
2022-12-14 11:31     ` Daniel P. Berrangé
2022-12-14 12:47       ` James Bottomley
2022-12-14 14:17         ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y5dNC77CubqrfXku@redhat.com \
    --to=berrange@redhat.com \
    --cc=armbru@redhat.com \
    --cc=jejb@linux.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanb@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.