qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, Stefan Berger <stefanb@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PULL v1 30/32] tpm: tpm_passthrough: Read the buffer size from the host device
Date: Sat, 16 Dec 2017 12:41:47 -0500	[thread overview]
Message-ID: <1513446109-9013-31-git-send-email-stefanb@linux.vnet.ibm.com> (raw)
In-Reply-To: <1513446109-9013-1-git-send-email-stefanb@linux.vnet.ibm.com>

Rather than hard coding the buffer size in the tpm_passthrough
backend read the TPM I/O buffer size from the host device.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/tpm/tpm_int.h         |   9 ++++
 hw/tpm/tpm_passthrough.c |  11 ++++-
 hw/tpm/tpm_util.c        | 115 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/tpm/tpm_util.h        |   3 ++
 4 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h
index 1df5883..abbca51 100644
--- a/hw/tpm/tpm_int.h
+++ b/hw/tpm/tpm_int.h
@@ -45,11 +45,20 @@ struct tpm_resp_hdr {
 
 #define TPM_ORD_ContinueSelfTest  0x53
 #define TPM_ORD_GetTicks          0xf1
+#define TPM_ORD_GetCapability     0x65
 
+#define TPM_CAP_PROPERTY          0x05
+
+#define TPM_CAP_PROP_INPUT_BUFFER 0x124
 
 /* TPM2 defines */
 #define TPM2_ST_NO_SESSIONS       0x8001
 
 #define TPM2_CC_ReadClock         0x00000181
+#define TPM2_CC_GetCapability     0x0000017a
+
+#define TPM2_CAP_TPM_PROPERTIES   0x6
+
+#define TPM2_PT_MAX_COMMAND_SIZE  0x11e
 
 #endif /* TPM_TPM_INT_H */
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index daac67d..886af9e 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -57,6 +57,7 @@ struct TPMPassthruState {
     int cancel_fd;
 
     TPMVersion tpm_version;
+    size_t tpm_buffersize;
 };
 
 typedef struct TPMPassthruState TPMPassthruState;
@@ -201,7 +202,15 @@ static TPMVersion tpm_passthrough_get_tpm_version(TPMBackend *tb)
 
 static size_t tpm_passthrough_get_buffer_size(TPMBackend *tb)
 {
-    return 4096;
+    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
+    int ret;
+
+    ret = tpm_util_get_buffer_size(tpm_pt->tpm_fd, tpm_pt->tpm_version,
+                                   &tpm_pt->tpm_buffersize);
+    if (ret < 0) {
+        tpm_pt->tpm_buffersize = 4096;
+    }
+    return tpm_pt->tpm_buffersize;
 }
 
 /*
diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
index b852f53..a317243 100644
--- a/hw/tpm/tpm_util.c
+++ b/hw/tpm/tpm_util.c
@@ -20,10 +20,19 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
 #include "tpm_util.h"
 #include "tpm_int.h"
 #include "exec/memory.h"
 
+#define DEBUG_TPM 0
+
+#define DPRINTF(fmt, ...) do { \
+    if (DEBUG_TPM) { \
+        fprintf(stderr, "tpm-util:"fmt"\n", ## __VA_ARGS__); \
+    } \
+} while (0)
+
 /*
  * Write an error message in the given output buffer.
  */
@@ -173,3 +182,109 @@ int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version)
 
     return 1;
 }
+
+int tpm_util_get_buffer_size(int tpm_fd, TPMVersion tpm_version,
+                             size_t *buffersize)
+{
+    unsigned char buf[1024];
+    int ret;
+
+    switch (tpm_version) {
+    case TPM_VERSION_1_2: {
+        const struct tpm_req_get_buffer_size {
+            struct tpm_req_hdr hdr;
+            uint32_t capability;
+            uint32_t len;
+            uint32_t subcap;
+        } QEMU_PACKED tpm_get_buffer_size = {
+            .hdr = {
+                .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
+                .len = cpu_to_be32(sizeof(tpm_get_buffer_size)),
+                .ordinal = cpu_to_be32(TPM_ORD_GetCapability),
+            },
+            .capability = cpu_to_be32(TPM_CAP_PROPERTY),
+            .len = cpu_to_be32(sizeof(uint32_t)),
+            .subcap = cpu_to_be32(TPM_CAP_PROP_INPUT_BUFFER),
+        };
+        struct tpm_resp_get_buffer_size {
+            struct tpm_resp_hdr hdr;
+            uint32_t len;
+            uint32_t buffersize;
+        } QEMU_PACKED *tpm_resp = (struct tpm_resp_get_buffer_size *)buf;
+
+        ret = tpm_util_request(tpm_fd, (unsigned char *)&tpm_get_buffer_size,
+                               sizeof(tpm_get_buffer_size), buf, sizeof(buf));
+        if (ret < 0) {
+            return ret;
+        }
+
+        if (be32_to_cpu(tpm_resp->hdr.len) != sizeof(*tpm_resp) ||
+            be32_to_cpu(tpm_resp->len) != sizeof(uint32_t)) {
+            DPRINTF("tpm_resp->hdr.len = %u, expected = %zu\n",
+                    be32_to_cpu(tpm_resp->hdr.len), sizeof(*tpm_resp));
+            DPRINTF("tpm_resp->len = %u, expected = %zu\n",
+                    be32_to_cpu(tpm_resp->len), sizeof(uint32_t));
+            error_report("tpm_util: Got unexpected response to "
+                         "TPM_GetCapability; errcode: 0x%x",
+                         be32_to_cpu(tpm_resp->hdr.errcode));
+            return -EFAULT;
+        }
+        *buffersize = be32_to_cpu(tpm_resp->buffersize);
+        break;
+    }
+    case TPM_VERSION_2_0: {
+        const struct tpm2_req_get_buffer_size {
+            struct tpm_req_hdr hdr;
+            uint32_t capability;
+            uint32_t property;
+            uint32_t count;
+        } QEMU_PACKED tpm2_get_buffer_size = {
+            .hdr = {
+                .tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
+                .len = cpu_to_be32(sizeof(tpm2_get_buffer_size)),
+                .ordinal = cpu_to_be32(TPM2_CC_GetCapability),
+            },
+            .capability = cpu_to_be32(TPM2_CAP_TPM_PROPERTIES),
+            .property = cpu_to_be32(TPM2_PT_MAX_COMMAND_SIZE),
+            .count = cpu_to_be32(2), /* also get TPM2_PT_MAX_RESPONSE_SIZE */
+        };
+        struct tpm2_resp_get_buffer_size {
+            struct tpm_resp_hdr hdr;
+            uint8_t more;
+            uint32_t capability;
+            uint32_t count;
+            uint32_t property1;
+            uint32_t value1;
+            uint32_t property2;
+            uint32_t value2;
+        } QEMU_PACKED *tpm2_resp = (struct tpm2_resp_get_buffer_size *)buf;
+
+        ret = tpm_util_request(tpm_fd, (unsigned char *)&tpm2_get_buffer_size,
+                               sizeof(tpm2_get_buffer_size), buf, sizeof(buf));
+        if (ret < 0) {
+            return ret;
+        }
+
+        if (be32_to_cpu(tpm2_resp->hdr.len) != sizeof(*tpm2_resp) ||
+            be32_to_cpu(tpm2_resp->count) != 2) {
+            DPRINTF("tpm2_resp->hdr.len = %u, expected = %zu\n",
+                    be32_to_cpu(tpm2_resp->hdr.len), sizeof(*tpm2_resp));
+            DPRINTF("tpm2_resp->len = %u, expected = %u\n",
+                    be32_to_cpu(tpm2_resp->count), 2);
+            error_report("tpm_util: Got unexpected response to "
+                         "TPM2_GetCapability; errcode: 0x%x",
+                         be32_to_cpu(tpm2_resp->hdr.errcode));
+            return -EFAULT;
+        }
+        *buffersize = MAX(be32_to_cpu(tpm2_resp->value1),
+                          be32_to_cpu(tpm2_resp->value2));
+        break;
+    }
+    case TPM_VERSION_UNSPEC:
+        return -EFAULT;
+    }
+
+    DPRINTF("buffersize of device: %zu\n", *buffersize);
+
+    return 0;
+}
diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h
index aca10c9..1c17e39 100644
--- a/hw/tpm/tpm_util.h
+++ b/hw/tpm/tpm_util.h
@@ -36,4 +36,7 @@ static inline uint32_t tpm_cmd_get_size(const void *b)
     return be32_to_cpu(*(const uint32_t *)(b + 2));
 }
 
+int tpm_util_get_buffer_size(int tpm_fd, TPMVersion tpm_version,
+                             size_t *buffersize);
+
 #endif /* TPM_TPM_UTIL_H */
-- 
2.5.5

  parent reply	other threads:[~2017-12-16 17:42 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-16 17:41 [Qemu-devel] [PULL v1 00/32] Merge tpm 2017/12/15 Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 01/32] tpm-tis: remove unused locty_number Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 02/32] tpm: move TpmIf in include/sysemu/tpm.h Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 03/32] tpm-backend: store TPMIf interface, improve backend_init() Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 04/32] tpm-tis: no longer expose TPMState Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 05/32] tpm-be: call request_completed() out of thread Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 06/32] tpm-be: report error instead of front-end Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 07/32] tpm-be: ask model to the TPM interface Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 08/32] tpm: remove unused opened code Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 09/32] tpm-passthrough: don't save guessed cancel_path in options Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 10/32] tpm-be: update optional function pointers Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 11/32] tpm-passthrough: pass TPMPassthruState to handle_device_opts Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 12/32] tpm-backend: move set 'id' to common code Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 13/32] tpm-passthrough: make it safer to destroy after creation Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 14/32] tpm-passthrough: simplify create() Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 15/32] tpm-passthrough: workaround a possible race Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 16/32] tpm-tis: simplify header inclusion Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 17/32] tpm: rename qemu_find_tpm() -> qemu_find_tpm_be() Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 18/32] tpm: lookup the the TPM interface instead of TIS device Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 19/32] tpm: add TPM interface to lookup TPM version Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 20/32] tpm: add tpm_cmd_get_size() to tpm_util Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 21/32] acpi: change TPM TIS data conditions Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 22/32] tpm-emulator: add a FIXME comment about blocking cancel Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 23/32] tpm-tis: remove redundant 'tpm_tis:' in error messages Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 24/32] tpm-tis: check that at most one TPM device exists Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 25/32] qdev: add DEFINE_PROP_TPMBE Stefan Berger
2017-12-18 15:10   ` Laurent Vivier
2017-12-18 15:30     ` Cornelia Huck
2017-12-18 15:44       ` Laurent Vivier
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 26/32] tpm-tis: use DEFINE_PROP_TPMBE Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 27/32] tpm: remove tpm_register_model() Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 28/32] tpm: Move getting TPM buffer size to backends Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 29/32] tpm: pull tpm_util_request() out of tpm_util_test() Stefan Berger
2017-12-16 17:41 ` Stefan Berger [this message]
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 31/32] tpm: tpm_emulator: get and set buffer size of device Stefan Berger
2017-12-16 17:41 ` [Qemu-devel] [PULL v1 32/32] tpm: tpm_passthrough: Fail startup if FE buffer size < BE buffer size Stefan Berger
2017-12-17 21:34 ` [Qemu-devel] [PULL v1 00/32] Merge tpm 2017/12/15 Peter Maydell
2017-12-18 11:18   ` Thomas Huth
2017-12-18 11:50     ` Thomas Huth
2017-12-18 12:33       ` Peter Maydell

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=1513446109-9013-31-git-send-email-stefanb@linux.vnet.ibm.com \
    --to=stefanb@linux.vnet.ibm.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).