diff options
-rw-r--r-- | stubdom/vtpmmgr/marshal.h | 15 | ||||
-rw-r--r-- | stubdom/vtpmmgr/vtpm_cmd_handler.c | 61 |
2 files changed, 75 insertions, 1 deletions
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 @@ -891,6 +891,15 @@ inline int sizeof_TPM_AUTH_SESSION(const TPM_AUTH_SESSION* auth) { } 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, UINT32 size, @@ -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 |