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 @@ -1,69 +1,107 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2023 Beckhoff Automation GmbH & Co. KG * Author: Corvin Köhne */ #include #include #include #include #include #include #include #include "config.h" #include "tpm_device.h" #include "tpm_emul.h" 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) { struct tpm_passthru *tpm; const char *path; tpm = calloc(1, sizeof(struct tpm_passthru)); if (tpm == NULL) { warnx("%s: failed to allocate tpm passthru", __func__); return (ENOMEM); } path = get_config_value_node(nvl, "path"); tpm->fd = open(path, O_RDWR); if (tpm->fd < 0) { warnx("%s: unable to open tpm device \"%s\"", __func__, path); return (ENOENT); } *sc = tpm; 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) { struct tpm_passthru *tpm; tpm = sc; if (tpm == NULL) return; if (tpm->fd >= 0) close(tpm->fd); free(tpm); } 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);