qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Berger <stefanb@linux.ibm.com>
To: qemu-devel@nongnu.org, marcandre.lureau@redhat.com
Cc: Stefan Berger <stefanb@linux.ibm.com>
Subject: [PATCH 2/2] backends/tpm: Send TPM2_Shutdown upon VM reset
Date: Fri, 27 May 2022 13:30:58 -0400	[thread overview]
Message-ID: <20220527173058.226210-3-stefanb@linux.ibm.com> (raw)
In-Reply-To: <20220527173058.226210-1-stefanb@linux.ibm.com>

Send a TPM2_Shutdown(TPM2_SU_CLEAR) command to the TPM emulator when the
VM is reset. However, this is only necessary for a TPM 2 and only if the
TPM2_Shutdown command has not been sent by the VM as the last command as
it would do under normal circumstances. Further, it also doesn't need to
be sent if the VM was just started.

This fixes a bug where well-timed VM resets may trigger the TPM 2's
dictionary attack lockout logic due to the TPM 2 not having received a
TPM2_Shutdown command when it was reset.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2087538
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 backends/tpm/tpm_emulator.c | 35 +++++++++++++++++++++++++++++++++++
 backends/tpm/tpm_int.h      |  3 +++
 backends/tpm/trace-events   |  1 +
 3 files changed, 39 insertions(+)

diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 89ecb04a2a..c928d7abd1 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -389,8 +389,43 @@ err_exit:
     return -1;
 }
 
+static void tpm_emulator_send_tpm2_shutdown(TPMEmulator *tpm_emu)
+{
+    const struct tpm2_shutdown {
+        struct tpm_req_hdr hdr;
+        uint16_t shutdownType;
+    } tpm2_shutdown_clear = {
+        .hdr = {
+            .tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
+            .len = cpu_to_be32(sizeof(tpm2_shutdown_clear)),
+            .ordinal = cpu_to_be32(TPM2_CC_Shutdown),
+        },
+        .shutdownType = cpu_to_be16(TPM2_SU_CLEAR),
+    };
+    Error *local_err = NULL;
+    uint8_t result[10];
+
+    trace_tpm_emulator_send_tpm2_shutdown(tpm_emu->last_command);
+
+    if (tpm_emulator_unix_tx_bufs(tpm_emu, (uint8_t *)&tpm2_shutdown_clear,
+                                  sizeof(tpm2_shutdown_clear),
+                                  result, sizeof(result),
+                                  NULL, &local_err) < 0) {
+        error_report_err(local_err);
+    }
+}
+
 static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
 {
+    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
+
+    /* In case of VM reset we may need to send a TPM2_Shutdown command */
+    if (tpm_emu->tpm_version == TPM_VERSION_2_0 &&
+        tpm_emu->last_command != TPM_ORDINAL_NONE &&
+        tpm_emu->last_command != TPM2_CC_Shutdown) {
+        tpm_emulator_send_tpm2_shutdown(tpm_emu);
+    }
+
     return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
 }
 
diff --git a/backends/tpm/tpm_int.h b/backends/tpm/tpm_int.h
index ba6109306e..2730d4ff02 100644
--- a/backends/tpm/tpm_int.h
+++ b/backends/tpm/tpm_int.h
@@ -64,6 +64,7 @@ struct tpm_resp_hdr {
 /* TPM2 defines */
 #define TPM2_ST_NO_SESSIONS       0x8001
 
+#define TPM2_CC_Shutdown          0x00000145
 #define TPM2_CC_ReadClock         0x00000181
 #define TPM2_CC_GetCapability     0x0000017a
 
@@ -71,6 +72,8 @@ struct tpm_resp_hdr {
 
 #define TPM2_PT_MAX_COMMAND_SIZE  0x11e
 
+#define TPM2_SU_CLEAR             0x0
+
 #define TPM_RC_INSUFFICIENT       0x9a
 #define TPM_RC_FAILURE            0x101
 #define TPM_RC_LOCALITY           0x907
diff --git a/backends/tpm/trace-events b/backends/tpm/trace-events
index 3298766dd7..cd16d41804 100644
--- a/backends/tpm/trace-events
+++ b/backends/tpm/trace-events
@@ -31,3 +31,4 @@ tpm_emulator_set_state_blobs_error(const char *msg) "error while setting state b
 tpm_emulator_set_state_blobs_done(void) "Done setting state blobs"
 tpm_emulator_pre_save(void) ""
 tpm_emulator_inst_init(void) ""
+tpm_emulator_send_tpm2_shutdown(uint32_t ord) "Sending TPM2_Shutdown(TPM2_SU_CLEAR); last ordinal from VM was: 0x%08x"
-- 
2.35.3



  parent reply	other threads:[~2022-05-27 17:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-27 17:30 [PATCH 0/2] backend/tpm: Resolve issue with TPM 2 DA lockout Stefan Berger
2022-05-27 17:30 ` [PATCH 1/2] backends/tpm: Record the last command sent to the TPM Stefan Berger
2022-05-27 17:30 ` Stefan Berger [this message]
2022-05-27 19:24 ` [PATCH 0/2] backend/tpm: Resolve issue with TPM 2 DA lockout Marc-André Lureau
2022-05-27 19:31   ` Stefan Berger
2022-05-28 17:23     ` Stefan Berger
2022-05-30  7:49       ` Marc-André Lureau
2022-05-30 16:41         ` Stefan Berger

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=20220527173058.226210-3-stefanb@linux.ibm.com \
    --to=stefanb@linux.ibm.com \
    --cc=marcandre.lureau@redhat.com \
    --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).