]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/tpm_emul_passthru.c
MFV: zlib 1.3
[FreeBSD/FreeBSD.git] / usr.sbin / bhyve / tpm_emul_passthru.c
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
21 struct tpm_passthru {
22         int fd;
23 };
24
25 struct tpm_resp_hdr {
26         uint16_t tag;
27         uint32_t len;
28         uint32_t errcode;
29 } __packed;
30
31 static int
32 tpm_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
55 static int
56 tpm_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
86 static void
87 tpm_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
101 static 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 };
107 TPM_EMUL_SET(tpm_emul_passthru);