1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2023 Beckhoff Automation GmbH & Co. KG 5 * Author: Corvin K��hne <corvink@FreeBSD.org> 6 */ 7 8#include <sys/types.h> 9 10#include <err.h> 11#include <errno.h> 12#include <fcntl.h> 13#include <malloc_np.h> 14#include <stdlib.h> 15#include <unistd.h> 16 17#include "config.h" 18#include "tpm_device.h" 19#include "tpm_emul.h" 20 21struct tpm_passthru { 22 int fd; 23}; 24 25struct tpm_resp_hdr { 26 uint16_t tag; 27 uint32_t len; 28 uint32_t errcode; 29} __packed; 30 31static int 32tpm_passthru_init(void **sc, nvlist_t *nvl) 33{ 34 struct tpm_passthru *tpm; 35 const char *path; 36 37 tpm = calloc(1, sizeof(struct tpm_passthru)); 38 if (tpm == NULL) { 39 warnx("%s: failed to allocate tpm passthru", __func__); 40 return (ENOMEM); 41 } 42 43 path = get_config_value_node(nvl, "path"); 44 tpm->fd = open(path, O_RDWR); 45 if (tpm->fd < 0) { 46 warnx("%s: unable to open tpm device \"%s\"", __func__, path); 47 return (ENOENT); 48 } 49 50 *sc = tpm; 51 52 return (0); 53} 54 55static int 56tpm_passthru_execute_cmd(void *sc, void *cmd, uint32_t cmd_size, void *rsp, 57 uint32_t rsp_size) 58{ 59 struct tpm_passthru *tpm; 60 ssize_t len; 61 62 if (rsp_size < (ssize_t)sizeof(struct tpm_resp_hdr)) { 63 warn("%s: rsp_size of %u is too small", __func__, rsp_size); 64 return (EINVAL); 65 } 66 67 tpm = sc; 68 69 len = write(tpm->fd, cmd, cmd_size); 70 if (len != cmd_size) { 71 warn("%s: cmd write failed (bytes written: %zd / %d)", __func__, 72 len, cmd_size); 73 return (EFAULT); 74 } 75 76 len = read(tpm->fd, rsp, rsp_size); 77 if (len < (ssize_t)sizeof(struct tpm_resp_hdr)) { 78 warn("%s: rsp read failed (bytes read: %zd / %d)", __func__, 79 len, rsp_size); 80 return (EFAULT); 81 } 82 83 return (0); 84} 85 86static void 87tpm_passthru_deinit(void *sc) 88{ 89 struct tpm_passthru *tpm; 90 91 tpm = sc; 92 if (tpm == NULL) 93 return; 94 95 if (tpm->fd >= 0) 96 close(tpm->fd); 97 98 free(tpm); 99} 100 101static const struct tpm_emul tpm_emul_passthru = { 102 .name = "passthru", 103 .init = tpm_passthru_init, 104 .deinit = tpm_passthru_deinit, 105 .execute_cmd = tpm_passthru_execute_cmd, 106}; 107TPM_EMUL_SET(tpm_emul_passthru); 108