xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Jason Andryuk <jandryuk@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: Jason Andryuk <jandryuk@gmail.com>,
	Daniel De Graaf <dgdegra@tycho.nsa.gov>,
	Quan Xu <quan.xu0@gmail.com>,
	Samuel Thibault <samuel.thibault@ens-lyon.org>
Subject: [PATCH v2 09/13] vtpmmgr: Support GetRandom passthrough on TPM 2.0
Date: Thu,  6 May 2021 09:59:19 -0400	[thread overview]
Message-ID: <20210506135923.161427-10-jandryuk@gmail.com> (raw)
In-Reply-To: <20210506135923.161427-1-jandryuk@gmail.com>

GetRandom passthrough currently fails when using vtpmmgr with a hardware
TPM 2.0.
vtpmmgr (8): INFO[VTPM]: Passthrough: TPM_GetRandom
vtpm (12): vtpm_cmd.c:120: Error: TPM_GetRandom() failed with error code (30)

When running on TPM 2.0 hardware, vtpmmgr needs to convert the TPM 1.2
TPM_ORD_GetRandom into a TPM2 TPM_CC_GetRandom command.  Besides the
differing ordinal, the TPM 1.2 uses 32bit sizes for the request and
response (vs. 16bit for TPM2).

Place the random output directly into the tpmcmd->resp and build the
packet around it.  This avoids bouncing through an extra buffer, but the
header has to be written after grabbing the random bytes so we have the
number of bytes to include in the size.

Signed-off-by: Jason Andryuk <jandryuk@gmail.com>

---
v2:
Add bounds and size checks
Whitespace fixup
---
 stubdom/vtpmmgr/marshal.h          | 15 ++++++++
 stubdom/vtpmmgr/vtpm_cmd_handler.c | 61 +++++++++++++++++++++++++++++-
 2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/stubdom/vtpmmgr/marshal.h b/stubdom/vtpmmgr/marshal.h
index dce19c6439..f1037a7976 100644
--- a/stubdom/vtpmmgr/marshal.h
+++ b/stubdom/vtpmmgr/marshal.h
@@ -890,6 +890,15 @@ inline int sizeof_TPM_AUTH_SESSION(const TPM_AUTH_SESSION* auth) {
 	return rv;
 }
 
+static
+inline int sizeof_TPM_RQU_HEADER(BYTE* ptr) {
+	int rv = 0;
+	rv += sizeof_UINT16(ptr);
+	rv += sizeof_UINT32(ptr);
+	rv += sizeof_UINT32(ptr);
+	return rv;
+}
+
 static
 inline BYTE* pack_TPM_RQU_HEADER(BYTE* ptr,
 		TPM_TAG tag,
@@ -920,8 +929,14 @@ inline int unpack3_TPM_RQU_HEADER(BYTE* ptr, UINT32* pos, UINT32 max,
 		unpack3_UINT32(ptr, pos, max, ord);
 }
 
+static
+inline int sizeof_TPM_RQU_GetRandom(BYTE* ptr) {
+	return sizeof_TPM_RQU_HEADER(ptr) + sizeof_UINT32(ptr);
+}
+
 #define pack_TPM_RSP_HEADER(p, t, s, r) pack_TPM_RQU_HEADER(p, t, s, r)
 #define unpack_TPM_RSP_HEADER(p, t, s, r) unpack_TPM_RQU_HEADER(p, t, s, r)
 #define unpack3_TPM_RSP_HEADER(p, l, m, t, s, r) unpack3_TPM_RQU_HEADER(p, l, m, t, s, r)
+#define sizeof_TPM_RSP_HEADER(p) sizeof_TPM_RQU_HEADER(p)
 
 #endif
diff --git a/stubdom/vtpmmgr/vtpm_cmd_handler.c b/stubdom/vtpmmgr/vtpm_cmd_handler.c
index 2ac14fae77..c879b24c13 100644
--- a/stubdom/vtpmmgr/vtpm_cmd_handler.c
+++ b/stubdom/vtpmmgr/vtpm_cmd_handler.c
@@ -47,6 +47,7 @@
 #include "vtpm_disk.h"
 #include "vtpmmgr.h"
 #include "tpm.h"
+#include "tpm2.h"
 #include "tpmrsa.h"
 #include "tcg.h"
 #include "mgmt_authority.h"
@@ -772,6 +773,64 @@ static int vtpmmgr_permcheck(struct tpm_opaque *opq)
 	return 1;
 }
 
+TPM_RESULT vtpmmgr_handle_getrandom(struct tpm_opaque *opaque,
+				    tpmcmd_t* tpmcmd)
+{
+	TPM_RESULT status = TPM_SUCCESS;
+	TPM_TAG tag;
+	UINT32 size;
+	const int max_rand_size = TCPA_MAX_BUFFER_LENGTH -
+				  sizeof_TPM_RQU_GetRandom(tpmcmd->req);
+	UINT32 rand_offset;
+	UINT32 rand_size;
+	TPM_COMMAND_CODE ord;
+	BYTE *p;
+
+	if (tpmcmd->req_len != sizeof_TPM_RQU_GetRandom(tpmcmd->req)) {
+		status = TPM_BAD_PARAMETER;
+		tag = TPM_TAG_RQU_COMMAND;
+		goto abort_egress;
+	}
+
+	p = unpack_TPM_RQU_HEADER(tpmcmd->req, &tag, &size, &ord);
+
+	if (!hw_is_tpm2()) {
+		size = TCPA_MAX_BUFFER_LENGTH;
+		TPMTRYRETURN(TPM_TransmitData(tpmcmd->req, tpmcmd->req_len,
+					      tpmcmd->resp, &size));
+		tpmcmd->resp_len = size;
+
+		return TPM_SUCCESS;
+	}
+
+	/* TPM_GetRandom req: <header><uint32 num bytes> */
+	unpack_UINT32(p, &rand_size);
+
+	/* Returning fewer bytes is acceptable per the spec. */
+	if (rand_size > max_rand_size)
+		rand_size = max_rand_size;
+
+	/* Call TPM2_GetRandom but return a TPM_GetRandom response. */
+	/* TPM_GetRandom resp: <header><uint32 num bytes><num random bytes> */
+	rand_offset = sizeof_TPM_RSP_HEADER(tpmcmd->resp) +
+		      sizeof_UINT32(tpmcmd->resp);
+
+	TPMTRYRETURN(TPM2_GetRandom(&rand_size, tpmcmd->resp + rand_offset));
+
+	p = pack_TPM_RSP_HEADER(tpmcmd->resp, TPM_TAG_RSP_COMMAND,
+				rand_offset + rand_size, status);
+	p = pack_UINT32(p, rand_size);
+	tpmcmd->resp_len = rand_offset + rand_size;
+
+	return status;
+
+abort_egress:
+	tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
+	pack_TPM_RSP_HEADER(tpmcmd->resp, tag + 3, tpmcmd->resp_len, status);
+
+	return status;
+}
+
 TPM_RESULT vtpmmgr_handle_cmd(
 		struct tpm_opaque *opaque,
 		tpmcmd_t* tpmcmd)
@@ -842,7 +901,7 @@ TPM_RESULT vtpmmgr_handle_cmd(
 		switch(ord) {
 		case TPM_ORD_GetRandom:
 			vtpmloginfo(VTPM_LOG_VTPM, "Passthrough: TPM_GetRandom\n");
-			break;
+			return vtpmmgr_handle_getrandom(opaque, tpmcmd);
 		case TPM_ORD_PcrRead:
 			vtpmloginfo(VTPM_LOG_VTPM, "Passthrough: TPM_PcrRead\n");
 			// Quotes also need to be restricted to hide PCR values
-- 
2.30.2



  parent reply	other threads:[~2021-05-06 14:00 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-06 13:59 [PATCH v2 00/13] vtpmmgr: Some fixes - still incomplete Jason Andryuk
2021-05-06 13:59 ` [PATCH v2 01/13] docs: Warn about incomplete vtpmmgr TPM 2.0 support Jason Andryuk
2021-05-06 13:59 ` [PATCH v2 02/13] vtpmmgr: Print error code to aid debugging Jason Andryuk
2021-05-06 13:59 ` [PATCH v2 03/13] stubom: newlib: Enable C99 formats for %z Jason Andryuk
2021-05-06 13:59 ` [PATCH v2 04/13] vtpmmgr: Allow specifying srk_handle for TPM2 Jason Andryuk
2021-05-06 21:35   ` Samuel Thibault
2021-05-10 11:56   ` Daniel P. Smith
2021-05-06 13:59 ` [PATCH v2 05/13] vtpmmgr: Move vtpmmgr_shutdown Jason Andryuk
2021-05-07 15:48   ` Daniel P. Smith
2021-05-06 13:59 ` [PATCH v2 06/13] vtpmmgr: Flush transient keys on shutdown Jason Andryuk
2021-05-10 12:12   ` Daniel P. Smith
2021-05-06 13:59 ` [PATCH v2 07/13] vtpmmgr: Flush all transient keys Jason Andryuk
2021-05-10 12:19   ` Daniel P. Smith
2021-05-06 13:59 ` [PATCH v2 08/13] vtpmmgr: Shutdown more gracefully Jason Andryuk
2021-05-06 14:04   ` Jason Andryuk
2021-05-10 12:42   ` Daniel P. Smith
2021-05-06 13:59 ` Jason Andryuk [this message]
2021-05-06 21:40   ` [PATCH v2 09/13] vtpmmgr: Support GetRandom passthrough on TPM 2.0 Samuel Thibault
2021-05-10 12:51   ` Daniel P. Smith
2021-05-06 13:59 ` [PATCH v2 10/13] vtpmmgr: Remove bogus cast from TPM2_GetRandom Jason Andryuk
2021-05-06 21:41   ` Samuel Thibault
2021-05-10 13:03   ` Daniel P. Smith
2021-05-06 13:59 ` [PATCH v2 11/13] vtpmmgr: Fix owner_auth & srk_auth parsing Jason Andryuk
2021-05-06 21:41   ` Samuel Thibault
2021-05-10 13:18   ` Daniel P. Smith
2021-05-06 13:59 ` [PATCH v2 12/13] vtpmmgr: Check req_len before unpacking command Jason Andryuk
2021-05-06 21:42   ` Samuel Thibault
2021-05-10 13:32   ` Daniel P. Smith
2021-05-06 13:59 ` [PATCH v2 13/13] vtpm: Correct timeout units and command duration Jason Andryuk
2021-05-06 21:52   ` Samuel Thibault
2021-05-10 13:40   ` Daniel P. Smith

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=20210506135923.161427-10-jandryuk@gmail.com \
    --to=jandryuk@gmail.com \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=quan.xu0@gmail.com \
    --cc=samuel.thibault@ens-lyon.org \
    --cc=xen-devel@lists.xenproject.org \
    --subject='Re: [PATCH v2 09/13] vtpmmgr: Support GetRandom passthrough on TPM 2.0' \
    /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

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).