diff --git a/usr.sbin/bhyve/tpm_emul_passthru.c b/usr.sbin/bhyve/tpm_emul_passthru.c index 9d706dee7120..084d31d5fa9f 100644 --- a/usr.sbin/bhyve/tpm_emul_passthru.c +++ b/usr.sbin/bhyve/tpm_emul_passthru.c @@ -22,6 +22,12 @@ struct tpm_passthru { int fd; }; +struct tpm_resp_hdr { + uint16_t tag; + uint32_t len; + uint32_t errcode; +} __packed; + static int tpm_passthru_init(void **sc, nvlist_t *nvl) { @@ -46,6 +52,37 @@ tpm_passthru_init(void **sc, nvlist_t *nvl) return (0); } +static int +tpm_passthru_execute_cmd(void *sc, void *cmd, uint32_t cmd_size, void *rsp, + uint32_t rsp_size) +{ + struct tpm_passthru *tpm; + ssize_t len; + + if (rsp_size < (ssize_t)sizeof(struct tpm_resp_hdr)) { + warn("%s: rsp_size of %u is too small", __func__, rsp_size); + return (EINVAL); + } + + tpm = sc; + + len = write(tpm->fd, cmd, cmd_size); + if (len != cmd_size) { + warn("%s: cmd write failed (bytes written: %zd / %d)", __func__, + len, cmd_size); + return (EFAULT); + } + + len = read(tpm->fd, rsp, rsp_size); + if (len < (ssize_t)sizeof(struct tpm_resp_hdr)) { + warn("%s: rsp read failed (bytes read: %zd / %d)", __func__, + len, rsp_size); + return (EFAULT); + } + + return (0); +} + static void tpm_passthru_deinit(void *sc) { @@ -65,5 +102,6 @@ static const struct tpm_emul tpm_emul_passthru = { .name = "passthru", .init = tpm_passthru_init, .deinit = tpm_passthru_deinit, + .execute_cmd = tpm_passthru_execute_cmd, }; TPM_EMUL_SET(tpm_emul_passthru);