1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************
3 * Copyright (c) 2017-2018, Intel Corporation
4 *
5 * All rights reserved.
6 ***********************************************************************/
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <errno.h>
12 #include <inttypes.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include "tss2_tcti_device.h"
18 #include "tss2_tcti_mssim.h"
19 #include "tss2_tcti_swtpm.h"
20 #ifdef TCTI_FUZZING
21 #include "tss2_tcti_fuzzing.h"
22 #endif /* TCTI_FUZZING */
23
24 #include "context-util.h"
25 #include "tss2-tcti/tcti-mssim.h"
26 #include "tss2-tcti/tcti-swtpm.h"
27
28 #ifdef TCTI_DEVICE
29 /*
30 * Initialize a TSS2_TCTI_CONTEXT for the device TCTI.
31 */
32 TSS2_TCTI_CONTEXT *
tcti_device_init(char const * device_path)33 tcti_device_init(char const *device_path)
34 {
35 size_t size;
36 TSS2_RC rc;
37 TSS2_TCTI_CONTEXT *tcti_ctx;
38
39 rc = Tss2_Tcti_Device_Init(NULL, &size, 0);
40 if (rc != TSS2_RC_SUCCESS) {
41 fprintf(stderr,
42 "Failed to get allocation size for device tcti context: "
43 "0x%x\n", rc);
44 return NULL;
45 }
46 tcti_ctx = (TSS2_TCTI_CONTEXT *) calloc(1, size);
47 if (tcti_ctx == NULL) {
48 fprintf(stderr,
49 "Allocation for device TCTI context failed: %s\n",
50 strerror(errno));
51 return NULL;
52 }
53 rc = Tss2_Tcti_Device_Init(tcti_ctx, &size, device_path);
54 if (rc != TSS2_RC_SUCCESS) {
55 fprintf(stderr, "Failed to initialize device TCTI context: 0x%x\n", rc);
56 free(tcti_ctx);
57 return NULL;
58 }
59 return tcti_ctx;
60 }
61 #endif /* TCTI_DEVICE */
62
63 #ifdef TCTI_MSSIM
64 /*
65 * Initialize a socket TCTI instance using the provided options structure.
66 * The hostname and port are the only configuration options used.
67 * The caller is returned a TCTI context structure that is allocated by this
68 * function. This structure must be freed by the caller.
69 */
70 TSS2_TCTI_CONTEXT *
tcti_socket_init(char const * host,uint16_t port)71 tcti_socket_init(char const *host, uint16_t port)
72 {
73 size_t size;
74 TSS2_RC rc;
75 TSS2_TCTI_CONTEXT *tcti_ctx;
76 char conf_str[TCTI_MSSIM_CONF_MAX] = { 0 };
77
78 snprintf(conf_str, TCTI_MSSIM_CONF_MAX, "host=%s,port=%" PRIu16, host, port);
79 rc = Tss2_Tcti_Mssim_Init(NULL, &size, conf_str);
80 if (rc != TSS2_RC_SUCCESS) {
81 fprintf(stderr, "Faled to get allocation size for tcti context: "
82 "0x%x\n", rc);
83 return NULL;
84 }
85 tcti_ctx = (TSS2_TCTI_CONTEXT *) calloc(1, size);
86 if (tcti_ctx == NULL) {
87 fprintf(stderr, "Allocation for tcti context failed: %s\n",
88 strerror(errno));
89 return NULL;
90 }
91 rc = Tss2_Tcti_Mssim_Init(tcti_ctx, &size, conf_str);
92 if (rc != TSS2_RC_SUCCESS) {
93 fprintf(stderr, "Failed to initialize tcti context: 0x%x\n", rc);
94 free(tcti_ctx);
95 return NULL;
96 }
97 return tcti_ctx;
98 }
99 #endif /* TCTI_MSSIM */
100
101 #ifdef TCTI_SWTPM
102 /*
103 * Initialize a socket TCTI instance using the provided options structure.
104 * The hostname and port are the only configuration options used.
105 * The caller is returned a TCTI context structure that is allocated by this
106 * function. This structure must be freed by the caller.
107 */
108 TSS2_TCTI_CONTEXT *
tcti_swtpm_init(char const * host,uint16_t port)109 tcti_swtpm_init(char const *host, uint16_t port)
110 {
111 size_t size;
112 TSS2_RC rc;
113 TSS2_TCTI_CONTEXT *tcti_ctx;
114 char conf_str[TCTI_SWTPM_CONF_MAX] = { 0 };
115
116 snprintf(conf_str, TCTI_SWTPM_CONF_MAX, "host=%s,port=%" PRIu16, host, port);
117 rc = Tss2_Tcti_Swtpm_Init(NULL, &size, conf_str);
118 if (rc != TSS2_RC_SUCCESS) {
119 fprintf(stderr, "Faled to get allocation size for tcti context: "
120 "0x%x\n", rc);
121 return NULL;
122 }
123 tcti_ctx = (TSS2_TCTI_CONTEXT *) calloc(1, size);
124 if (tcti_ctx == NULL) {
125 fprintf(stderr, "Allocation for tcti context failed: %s\n",
126 strerror(errno));
127 return NULL;
128 }
129 rc = Tss2_Tcti_Swtpm_Init(tcti_ctx, &size, conf_str);
130 if (rc != TSS2_RC_SUCCESS) {
131 fprintf(stderr, "Failed to initialize tcti context: 0x%x\n", rc);
132 free(tcti_ctx);
133 return NULL;
134 }
135 return tcti_ctx;
136 }
137 #endif /* TCTI_SWTPM */
138
139 #ifdef TCTI_FUZZING
140 /*
141 * Initialize a fuzzing TCTI instance using the provided options structure.
142 * The fuzzing_lengths.log file is the only configuration option used.
143 * The caller is returned a TCTI context structure that is allocated by this
144 * function. This structure must be freed by the caller.
145 */
146 TSS2_TCTI_CONTEXT *
tcti_fuzzing_init()147 tcti_fuzzing_init()
148 {
149 size_t size;
150 TSS2_RC rc;
151 TSS2_TCTI_CONTEXT *tcti_ctx;
152
153 rc = Tss2_Tcti_Fuzzing_Init(NULL, &size, NULL);
154 if (rc != TSS2_RC_SUCCESS) {
155 fprintf(stderr, "Faled to get allocation size for tcti context: "
156 "0x%x\n", rc);
157 return NULL;
158 }
159 tcti_ctx = (TSS2_TCTI_CONTEXT *) calloc(1, size);
160 if (tcti_ctx == NULL) {
161 fprintf(stderr, "Allocation for tcti context failed: %s\n",
162 strerror(errno));
163 return NULL;
164 }
165 rc = Tss2_Tcti_Fuzzing_Init(tcti_ctx, &size, NULL);
166 if (rc != TSS2_RC_SUCCESS) {
167 fprintf(stderr, "Failed to initialize tcti context: 0x%x\n", rc);
168 free(tcti_ctx);
169 return NULL;
170 }
171 return tcti_ctx;
172 }
173 #endif /* TCTI_FUZZING */
174
175 /*
176 * Initialize a SYS context using the TCTI context provided by the caller.
177 * This function allocates memory for the SYS context and returns it to the
178 * caller. This memory must be freed by the caller.
179 */
180 TSS2_SYS_CONTEXT *
sys_init_from_tcti_ctx(TSS2_TCTI_CONTEXT * tcti_ctx)181 sys_init_from_tcti_ctx(TSS2_TCTI_CONTEXT * tcti_ctx)
182 {
183 TSS2_SYS_CONTEXT *sys_ctx;
184 TSS2_RC rc;
185 size_t size;
186 TSS2_ABI_VERSION abi_version = {
187 .tssCreator = 1,
188 .tssFamily = 2,
189 .tssLevel = 1,
190 .tssVersion = 108,
191 };
192
193 size = Tss2_Sys_GetContextSize(0);
194 sys_ctx = (TSS2_SYS_CONTEXT *) calloc(1, size);
195 if (sys_ctx == NULL) {
196 fprintf(stderr,
197 "Failed to allocate 0x%zx bytes for the SYS context\n", size);
198 return NULL;
199 }
200 rc = Tss2_Sys_Initialize(sys_ctx, size, tcti_ctx, &abi_version);
201 if (rc != TSS2_RC_SUCCESS) {
202 fprintf(stderr, "Failed to initialize SYS context: 0x%x\n", rc);
203 free(sys_ctx);
204 return NULL;
205 }
206 return sys_ctx;
207 }
208
209 /*
210 * Initialize a SYS context to use a socket TCTI. Get configuration data from
211 * the provided structure.
212 */
213 TSS2_SYS_CONTEXT *
sys_init_from_opts(test_opts_t * options)214 sys_init_from_opts(test_opts_t * options)
215 {
216 TSS2_TCTI_CONTEXT *tcti_ctx;
217 TSS2_SYS_CONTEXT *sys_ctx;
218
219 tcti_ctx = tcti_init_from_opts(options);
220 if (tcti_ctx == NULL)
221 return NULL;
222 sys_ctx = sys_init_from_tcti_ctx(tcti_ctx);
223 if (sys_ctx == NULL)
224 return NULL;
225 return sys_ctx;
226 }
227
228 /*
229 * Initialize a TSS2_TCTI_CONTEXT using whatever TCTI data is in the options
230 * structure. This is a mechanism that allows the calling application to be
231 * mostly ignorant of which TCTI they're creating / initializing.
232 */
233 TSS2_TCTI_CONTEXT *
tcti_init_from_opts(test_opts_t * options)234 tcti_init_from_opts(test_opts_t * options)
235 {
236 switch (options->tcti_type) {
237 #ifdef TCTI_DEVICE
238 case DEVICE_TCTI:
239 return tcti_device_init(options->device_file);
240 #endif /* TCTI_DEVICE */
241 #ifdef TCTI_MSSIM
242 case SOCKET_TCTI:
243 return tcti_socket_init(options->socket_address, options->socket_port);
244 #endif /* TCTI_MSSIM */
245 #ifdef TCTI_SWTPM
246 case SWTPM_TCTI:
247 return tcti_swtpm_init(options->socket_address, options->socket_port);
248 #endif /* TCTI_SWTPM */
249 #ifdef TCTI_FUZZING
250 case FUZZING_TCTI:
251 return tcti_fuzzing_init();
252 #endif /* TCTI_FUZZING */
253 default:
254 return NULL;
255 }
256 }
257
258 /*
259 * Teardown / Finalize TCTI context and free memory.
260 */
261 void
tcti_teardown(TSS2_TCTI_CONTEXT * tcti_context)262 tcti_teardown(TSS2_TCTI_CONTEXT * tcti_context)
263 {
264 if (tcti_context) {
265 Tss2_Tcti_Finalize(tcti_context);
266 free(tcti_context);
267 }
268 }
269
270 /*
271 * Teardown and free the resources associated with a SYS context structure.
272 */
273 void
sys_teardown(TSS2_SYS_CONTEXT * sys_context)274 sys_teardown(TSS2_SYS_CONTEXT * sys_context)
275 {
276 Tss2_Sys_Finalize(sys_context);
277 free(sys_context);
278 }
279
280 /*
281 * Teardown and free the resources associated with a SYS context structure.
282 * This includes tearing down the TCTI as well.
283 */
284 void
sys_teardown_full(TSS2_SYS_CONTEXT * sys_context)285 sys_teardown_full(TSS2_SYS_CONTEXT * sys_context)
286 {
287 TSS2_TCTI_CONTEXT *tcti_context = NULL;
288 TSS2_RC rc;
289
290 rc = Tss2_Sys_GetTctiContext(sys_context, &tcti_context);
291 if (rc != TSS2_RC_SUCCESS)
292 return;
293
294 sys_teardown(sys_context);
295 tcti_teardown(tcti_context);
296 }
297