[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging] vtpmmgr: Support GetRandom passthrough on TPM 2.0



commit 64d00dd126b3dfa4370805f1dc3d7c1ddb6a130d
Author:     Jason Andryuk <jandryuk@xxxxxxxxx>
AuthorDate: Thu May 6 09:59:19 2021 -0400
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Mon May 10 14:50:27 2021 +0100

    vtpmmgr: Support GetRandom passthrough on TPM 2.0
    
    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@xxxxxxxxx>
    Reviewed-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
    Reviewed by: Daniel P. Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>
---
 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
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.