1*758e9fbaSOystein Eftevaag /* SPDX-License-Identifier: BSD-2-Clause */
2*758e9fbaSOystein Eftevaag /*******************************************************************************
3*758e9fbaSOystein Eftevaag * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
4*758e9fbaSOystein Eftevaag * Copyright 2019, Intel Corporation
5*758e9fbaSOystein Eftevaag * All rights reserved.
6*758e9fbaSOystein Eftevaag *******************************************************************************/
7*758e9fbaSOystein Eftevaag
8*758e9fbaSOystein Eftevaag #ifdef HAVE_CONFIG_H
9*758e9fbaSOystein Eftevaag #include <config.h>
10*758e9fbaSOystein Eftevaag #endif
11*758e9fbaSOystein Eftevaag
12*758e9fbaSOystein Eftevaag #include <stdlib.h>
13*758e9fbaSOystein Eftevaag #include <errno.h>
14*758e9fbaSOystein Eftevaag #include <string.h>
15*758e9fbaSOystein Eftevaag #include <inttypes.h>
16*758e9fbaSOystein Eftevaag #include <dlfcn.h>
17*758e9fbaSOystein Eftevaag #include <limits.h>
18*758e9fbaSOystein Eftevaag #include <stdio.h>
19*758e9fbaSOystein Eftevaag
20*758e9fbaSOystein Eftevaag #include "tss2_tcti.h"
21*758e9fbaSOystein Eftevaag #include "tctildr-interface.h"
22*758e9fbaSOystein Eftevaag #include "tctildr.h"
23*758e9fbaSOystein Eftevaag #define LOGMODULE tcti
24*758e9fbaSOystein Eftevaag #include "util/log.h"
25*758e9fbaSOystein Eftevaag
26*758e9fbaSOystein Eftevaag #define ARRAY_SIZE(X) (sizeof(X)/sizeof(X[0]))
27*758e9fbaSOystein Eftevaag
28*758e9fbaSOystein Eftevaag struct {
29*758e9fbaSOystein Eftevaag char *file;
30*758e9fbaSOystein Eftevaag char *conf;
31*758e9fbaSOystein Eftevaag char *description;
32*758e9fbaSOystein Eftevaag } tctis[] = {
33*758e9fbaSOystein Eftevaag {
34*758e9fbaSOystein Eftevaag .file = "libtss2-tcti-default.so",
35*758e9fbaSOystein Eftevaag .description = "Access libtss2-tcti-default.so",
36*758e9fbaSOystein Eftevaag },
37*758e9fbaSOystein Eftevaag {
38*758e9fbaSOystein Eftevaag .file = "libtss2-tcti-tabrmd.so.0",
39*758e9fbaSOystein Eftevaag .description = "Access libtss2-tcti-tabrmd.so",
40*758e9fbaSOystein Eftevaag },
41*758e9fbaSOystein Eftevaag {
42*758e9fbaSOystein Eftevaag .file = "libtss2-tcti-device.so.0",
43*758e9fbaSOystein Eftevaag .conf = "/dev/tpmrm0",
44*758e9fbaSOystein Eftevaag .description = "Access libtss2-tcti-device.so.0 with /dev/tpmrm0",
45*758e9fbaSOystein Eftevaag },
46*758e9fbaSOystein Eftevaag {
47*758e9fbaSOystein Eftevaag .file = "libtss2-tcti-device.so.0",
48*758e9fbaSOystein Eftevaag .conf = "/dev/tpm0",
49*758e9fbaSOystein Eftevaag .description = "Access libtss2-tcti-device.so.0 with /dev/tpm0",
50*758e9fbaSOystein Eftevaag },
51*758e9fbaSOystein Eftevaag {
52*758e9fbaSOystein Eftevaag .file = "libtss2-tcti-mssim.so.0",
53*758e9fbaSOystein Eftevaag .description = "Access to libtss2-tcti-mssim.so",
54*758e9fbaSOystein Eftevaag },
55*758e9fbaSOystein Eftevaag };
56*758e9fbaSOystein Eftevaag
57*758e9fbaSOystein Eftevaag const TSS2_TCTI_INFO*
info_from_handle(void * dlhandle)58*758e9fbaSOystein Eftevaag info_from_handle (void *dlhandle)
59*758e9fbaSOystein Eftevaag {
60*758e9fbaSOystein Eftevaag TSS2_TCTI_INFO_FUNC info_func;
61*758e9fbaSOystein Eftevaag
62*758e9fbaSOystein Eftevaag if (dlhandle == NULL)
63*758e9fbaSOystein Eftevaag return NULL;
64*758e9fbaSOystein Eftevaag
65*758e9fbaSOystein Eftevaag info_func = dlsym (dlhandle, TSS2_TCTI_INFO_SYMBOL);
66*758e9fbaSOystein Eftevaag if (info_func == NULL) {
67*758e9fbaSOystein Eftevaag LOG_ERROR ("Failed to get reference to TSS2_TCTI_INFO_SYMBOL: %s",
68*758e9fbaSOystein Eftevaag dlerror());
69*758e9fbaSOystein Eftevaag return NULL;
70*758e9fbaSOystein Eftevaag }
71*758e9fbaSOystein Eftevaag
72*758e9fbaSOystein Eftevaag return info_func ();
73*758e9fbaSOystein Eftevaag }
74*758e9fbaSOystein Eftevaag TSS2_RC
handle_from_name(const char * file,void ** handle)75*758e9fbaSOystein Eftevaag handle_from_name(const char *file,
76*758e9fbaSOystein Eftevaag void **handle)
77*758e9fbaSOystein Eftevaag {
78*758e9fbaSOystein Eftevaag char file_xfrm [PATH_MAX] = { 0, };
79*758e9fbaSOystein Eftevaag size_t size;
80*758e9fbaSOystein Eftevaag
81*758e9fbaSOystein Eftevaag if (handle == NULL) {
82*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_REFERENCE;
83*758e9fbaSOystein Eftevaag }
84*758e9fbaSOystein Eftevaag *handle = dlopen(file, RTLD_NOW);
85*758e9fbaSOystein Eftevaag if (*handle != NULL) {
86*758e9fbaSOystein Eftevaag return TSS2_RC_SUCCESS;
87*758e9fbaSOystein Eftevaag } else {
88*758e9fbaSOystein Eftevaag LOG_DEBUG("Could not load TCTI file: \"%s\": %s", file, dlerror());
89*758e9fbaSOystein Eftevaag }
90*758e9fbaSOystein Eftevaag /* 'name' alone didn't work, try libtss2-tcti-<name>.so.0 */
91*758e9fbaSOystein Eftevaag size = snprintf(file_xfrm,
92*758e9fbaSOystein Eftevaag sizeof (file_xfrm),
93*758e9fbaSOystein Eftevaag TCTI_NAME_TEMPLATE_0,
94*758e9fbaSOystein Eftevaag file);
95*758e9fbaSOystein Eftevaag if (size >= sizeof (file_xfrm)) {
96*758e9fbaSOystein Eftevaag LOG_ERROR("TCTI name truncated in transform.");
97*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_VALUE;
98*758e9fbaSOystein Eftevaag }
99*758e9fbaSOystein Eftevaag *handle = dlopen(file_xfrm, RTLD_NOW);
100*758e9fbaSOystein Eftevaag if (*handle != NULL) {
101*758e9fbaSOystein Eftevaag return TSS2_RC_SUCCESS;
102*758e9fbaSOystein Eftevaag } else {
103*758e9fbaSOystein Eftevaag LOG_DEBUG("Could not load TCTI file \"%s\": %s", file, dlerror());
104*758e9fbaSOystein Eftevaag }
105*758e9fbaSOystein Eftevaag /* libtss2-tcti-<name>.so.0 didn't work, try libtss2-tcti-<name>.so */
106*758e9fbaSOystein Eftevaag size = snprintf(file_xfrm,
107*758e9fbaSOystein Eftevaag sizeof (file_xfrm),
108*758e9fbaSOystein Eftevaag TCTI_NAME_TEMPLATE,
109*758e9fbaSOystein Eftevaag file);
110*758e9fbaSOystein Eftevaag if (size >= sizeof (file_xfrm)) {
111*758e9fbaSOystein Eftevaag LOG_ERROR("TCTI name truncated in transform.");
112*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_VALUE;
113*758e9fbaSOystein Eftevaag }
114*758e9fbaSOystein Eftevaag *handle = dlopen(file_xfrm, RTLD_NOW);
115*758e9fbaSOystein Eftevaag if (*handle == NULL) {
116*758e9fbaSOystein Eftevaag LOG_DEBUG("Failed to load TCTI for name \"%s\": %s", file, dlerror());
117*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_NOT_SUPPORTED;
118*758e9fbaSOystein Eftevaag }
119*758e9fbaSOystein Eftevaag
120*758e9fbaSOystein Eftevaag return TSS2_RC_SUCCESS;
121*758e9fbaSOystein Eftevaag }
122*758e9fbaSOystein Eftevaag TSS2_RC
tcti_from_file(const char * file,const char * conf,TSS2_TCTI_CONTEXT ** tcti,void ** dlhandle)123*758e9fbaSOystein Eftevaag tcti_from_file(const char *file,
124*758e9fbaSOystein Eftevaag const char* conf,
125*758e9fbaSOystein Eftevaag TSS2_TCTI_CONTEXT **tcti,
126*758e9fbaSOystein Eftevaag void **dlhandle)
127*758e9fbaSOystein Eftevaag {
128*758e9fbaSOystein Eftevaag TSS2_RC r;
129*758e9fbaSOystein Eftevaag void *handle;
130*758e9fbaSOystein Eftevaag TSS2_TCTI_INFO_FUNC infof;
131*758e9fbaSOystein Eftevaag
132*758e9fbaSOystein Eftevaag LOG_TRACE("Attempting to load TCTI file: %s", file);
133*758e9fbaSOystein Eftevaag if (tcti == NULL) {
134*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_REFERENCE;
135*758e9fbaSOystein Eftevaag }
136*758e9fbaSOystein Eftevaag r = handle_from_name(file, &handle);
137*758e9fbaSOystein Eftevaag if (r != TSS2_RC_SUCCESS) {
138*758e9fbaSOystein Eftevaag return r;
139*758e9fbaSOystein Eftevaag }
140*758e9fbaSOystein Eftevaag
141*758e9fbaSOystein Eftevaag infof = (TSS2_TCTI_INFO_FUNC) dlsym(handle, TSS2_TCTI_INFO_SYMBOL);
142*758e9fbaSOystein Eftevaag if (infof == NULL) {
143*758e9fbaSOystein Eftevaag LOG_ERROR("Info not found in TCTI file: %s", file);
144*758e9fbaSOystein Eftevaag dlclose(handle);
145*758e9fbaSOystein Eftevaag return TSS2_ESYS_RC_BAD_REFERENCE;
146*758e9fbaSOystein Eftevaag }
147*758e9fbaSOystein Eftevaag
148*758e9fbaSOystein Eftevaag r = tcti_from_info(infof, conf, tcti);
149*758e9fbaSOystein Eftevaag if (r != TSS2_RC_SUCCESS) {
150*758e9fbaSOystein Eftevaag LOG_ERROR("Could not initialize TCTI file: %s", file);
151*758e9fbaSOystein Eftevaag dlclose(handle);
152*758e9fbaSOystein Eftevaag return r;
153*758e9fbaSOystein Eftevaag }
154*758e9fbaSOystein Eftevaag
155*758e9fbaSOystein Eftevaag if (dlhandle)
156*758e9fbaSOystein Eftevaag *dlhandle = handle;
157*758e9fbaSOystein Eftevaag
158*758e9fbaSOystein Eftevaag LOG_DEBUG("Initialized TCTI file: %s", file);
159*758e9fbaSOystein Eftevaag
160*758e9fbaSOystein Eftevaag return TSS2_RC_SUCCESS;
161*758e9fbaSOystein Eftevaag }
162*758e9fbaSOystein Eftevaag TSS2_RC
get_info_default(const TSS2_TCTI_INFO ** info,void ** dlhandle)163*758e9fbaSOystein Eftevaag get_info_default(const TSS2_TCTI_INFO **info,
164*758e9fbaSOystein Eftevaag void **dlhandle)
165*758e9fbaSOystein Eftevaag {
166*758e9fbaSOystein Eftevaag void *handle = NULL;
167*758e9fbaSOystein Eftevaag const TSS2_TCTI_INFO *info_src;
168*758e9fbaSOystein Eftevaag char *name = NULL;
169*758e9fbaSOystein Eftevaag TSS2_RC rc = TSS2_TCTI_RC_GENERAL_FAILURE;
170*758e9fbaSOystein Eftevaag
171*758e9fbaSOystein Eftevaag LOG_DEBUG("%s", __func__);
172*758e9fbaSOystein Eftevaag if (info == NULL || dlhandle == NULL) {
173*758e9fbaSOystein Eftevaag LOG_ERROR("parameters cannot be NULL");
174*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_REFERENCE;
175*758e9fbaSOystein Eftevaag }
176*758e9fbaSOystein Eftevaag #ifdef ESYS_TCTI_DEFAULT_MODULE
177*758e9fbaSOystein Eftevaag name = ESYS_TCTI_DEFAULT_MODULE;
178*758e9fbaSOystein Eftevaag LOG_DEBUG("name: %s", name);
179*758e9fbaSOystein Eftevaag rc = handle_from_name (name, &handle);
180*758e9fbaSOystein Eftevaag if (rc != TSS2_RC_SUCCESS)
181*758e9fbaSOystein Eftevaag return rc;
182*758e9fbaSOystein Eftevaag else if (handle == NULL)
183*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_IO_ERROR;
184*758e9fbaSOystein Eftevaag #else
185*758e9fbaSOystein Eftevaag size_t i;
186*758e9fbaSOystein Eftevaag for (i = 0; i < ARRAY_SIZE(tctis); i++) {
187*758e9fbaSOystein Eftevaag name = tctis[i].file;
188*758e9fbaSOystein Eftevaag LOG_DEBUG("name: %s", name);
189*758e9fbaSOystein Eftevaag if (name == NULL) {
190*758e9fbaSOystein Eftevaag continue;
191*758e9fbaSOystein Eftevaag }
192*758e9fbaSOystein Eftevaag rc = handle_from_name (name, &handle);
193*758e9fbaSOystein Eftevaag if (rc != TSS2_RC_SUCCESS || handle == NULL) {
194*758e9fbaSOystein Eftevaag LOG_DEBUG("Failed to get handle for TCTI with name: %s", name);
195*758e9fbaSOystein Eftevaag continue;
196*758e9fbaSOystein Eftevaag }
197*758e9fbaSOystein Eftevaag
198*758e9fbaSOystein Eftevaag break;
199*758e9fbaSOystein Eftevaag }
200*758e9fbaSOystein Eftevaag #endif /* ESYS_TCTI_DEFAULT_MODULE */
201*758e9fbaSOystein Eftevaag
202*758e9fbaSOystein Eftevaag info_src = info_from_handle (handle);
203*758e9fbaSOystein Eftevaag if (info_src != NULL) {
204*758e9fbaSOystein Eftevaag *info = info_src;
205*758e9fbaSOystein Eftevaag } else {
206*758e9fbaSOystein Eftevaag tctildr_finalize_data (&handle);
207*758e9fbaSOystein Eftevaag rc = TSS2_TCTI_RC_GENERAL_FAILURE;
208*758e9fbaSOystein Eftevaag }
209*758e9fbaSOystein Eftevaag *dlhandle = handle;
210*758e9fbaSOystein Eftevaag
211*758e9fbaSOystein Eftevaag return rc;
212*758e9fbaSOystein Eftevaag }
213*758e9fbaSOystein Eftevaag
214*758e9fbaSOystein Eftevaag TSS2_RC
tctildr_get_default(TSS2_TCTI_CONTEXT ** tcticontext,void ** dlhandle)215*758e9fbaSOystein Eftevaag tctildr_get_default(TSS2_TCTI_CONTEXT ** tcticontext, void **dlhandle)
216*758e9fbaSOystein Eftevaag {
217*758e9fbaSOystein Eftevaag if (tcticontext == NULL) {
218*758e9fbaSOystein Eftevaag LOG_ERROR("tcticontext must not be NULL");
219*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_REFERENCE;
220*758e9fbaSOystein Eftevaag }
221*758e9fbaSOystein Eftevaag *tcticontext = NULL;
222*758e9fbaSOystein Eftevaag #ifdef ESYS_TCTI_DEFAULT_MODULE
223*758e9fbaSOystein Eftevaag
224*758e9fbaSOystein Eftevaag #ifdef ESYS_TCTI_DEFAULT_CONFIG
225*758e9fbaSOystein Eftevaag const char *config = ESYS_TCTI_DEFAULT_CONFIG;
226*758e9fbaSOystein Eftevaag #else /* ESYS_TCTI_DEFAULT_CONFIG */
227*758e9fbaSOystein Eftevaag const char *config = NULL;
228*758e9fbaSOystein Eftevaag #endif /* ESYS_TCTI_DEFAULT_CONFIG */
229*758e9fbaSOystein Eftevaag
230*758e9fbaSOystein Eftevaag LOG_DEBUG("Attempting to initialize TCTI defined during compilation: %s:%s",
231*758e9fbaSOystein Eftevaag ESYS_TCTI_DEFAULT_MODULE, config);
232*758e9fbaSOystein Eftevaag return tcti_from_file(ESYS_TCTI_DEFAULT_MODULE, config, tcticontext,
233*758e9fbaSOystein Eftevaag dlhandle);
234*758e9fbaSOystein Eftevaag
235*758e9fbaSOystein Eftevaag #else /* ESYS_TCTI_DEFAULT_MODULE */
236*758e9fbaSOystein Eftevaag
237*758e9fbaSOystein Eftevaag TSS2_RC r;
238*758e9fbaSOystein Eftevaag size_t i;
239*758e9fbaSOystein Eftevaag
240*758e9fbaSOystein Eftevaag for (i = 0; i < ARRAY_SIZE(tctis); i++) {
241*758e9fbaSOystein Eftevaag LOG_DEBUG("Attempting to connect using standard TCTI: %s",
242*758e9fbaSOystein Eftevaag tctis[i].description);
243*758e9fbaSOystein Eftevaag r = tcti_from_file(tctis[i].file, tctis[i].conf, tcticontext,
244*758e9fbaSOystein Eftevaag dlhandle);
245*758e9fbaSOystein Eftevaag if (r == TSS2_RC_SUCCESS)
246*758e9fbaSOystein Eftevaag return TSS2_RC_SUCCESS;
247*758e9fbaSOystein Eftevaag LOG_DEBUG("Failed to load standard TCTI number %zu", i);
248*758e9fbaSOystein Eftevaag }
249*758e9fbaSOystein Eftevaag
250*758e9fbaSOystein Eftevaag LOG_ERROR("No standard TCTI could be loaded");
251*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_IO_ERROR;
252*758e9fbaSOystein Eftevaag
253*758e9fbaSOystein Eftevaag #endif /* ESYS_TCTI_DEFAULT_MODULE */
254*758e9fbaSOystein Eftevaag }
255*758e9fbaSOystein Eftevaag TSS2_RC
info_from_name(const char * name,const TSS2_TCTI_INFO ** info,void ** data)256*758e9fbaSOystein Eftevaag info_from_name (const char *name,
257*758e9fbaSOystein Eftevaag const TSS2_TCTI_INFO **info,
258*758e9fbaSOystein Eftevaag void **data)
259*758e9fbaSOystein Eftevaag {
260*758e9fbaSOystein Eftevaag TSS2_RC rc;
261*758e9fbaSOystein Eftevaag
262*758e9fbaSOystein Eftevaag if (data == NULL || info == NULL)
263*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_REFERENCE;
264*758e9fbaSOystein Eftevaag rc = handle_from_name (name, data);
265*758e9fbaSOystein Eftevaag if (rc != TSS2_RC_SUCCESS)
266*758e9fbaSOystein Eftevaag return rc;
267*758e9fbaSOystein Eftevaag *info = (TSS2_TCTI_INFO*)info_from_handle (*data);
268*758e9fbaSOystein Eftevaag if (*info == NULL) {
269*758e9fbaSOystein Eftevaag tctildr_finalize_data (data);
270*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_IO_ERROR;
271*758e9fbaSOystein Eftevaag }
272*758e9fbaSOystein Eftevaag return rc;
273*758e9fbaSOystein Eftevaag }
274*758e9fbaSOystein Eftevaag TSS2_RC
tctildr_get_info(const char * name,const TSS2_TCTI_INFO ** info,void ** data)275*758e9fbaSOystein Eftevaag tctildr_get_info(const char *name,
276*758e9fbaSOystein Eftevaag const TSS2_TCTI_INFO **info,
277*758e9fbaSOystein Eftevaag void **data)
278*758e9fbaSOystein Eftevaag {
279*758e9fbaSOystein Eftevaag if (info == NULL) {
280*758e9fbaSOystein Eftevaag LOG_ERROR("info must not be NULL");
281*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_REFERENCE;
282*758e9fbaSOystein Eftevaag }
283*758e9fbaSOystein Eftevaag if (name != NULL) {
284*758e9fbaSOystein Eftevaag return info_from_name (name, info, data);
285*758e9fbaSOystein Eftevaag } else {
286*758e9fbaSOystein Eftevaag return get_info_default (info, data);
287*758e9fbaSOystein Eftevaag }
288*758e9fbaSOystein Eftevaag }
289*758e9fbaSOystein Eftevaag TSS2_RC
tctildr_get_tcti(const char * name,const char * conf,TSS2_TCTI_CONTEXT ** tcti,void ** data)290*758e9fbaSOystein Eftevaag tctildr_get_tcti(const char *name,
291*758e9fbaSOystein Eftevaag const char* conf,
292*758e9fbaSOystein Eftevaag TSS2_TCTI_CONTEXT **tcti,
293*758e9fbaSOystein Eftevaag void **data)
294*758e9fbaSOystein Eftevaag {
295*758e9fbaSOystein Eftevaag LOG_DEBUG("name: \"%s\", conf: \"%s\"", name, conf);
296*758e9fbaSOystein Eftevaag if (tcti == NULL) {
297*758e9fbaSOystein Eftevaag LOG_ERROR("tcticontext must not be NULL");
298*758e9fbaSOystein Eftevaag return TSS2_TCTI_RC_BAD_REFERENCE;
299*758e9fbaSOystein Eftevaag }
300*758e9fbaSOystein Eftevaag *tcti = NULL;
301*758e9fbaSOystein Eftevaag if (name == NULL) {
302*758e9fbaSOystein Eftevaag return tctildr_get_default (tcti, data);
303*758e9fbaSOystein Eftevaag }
304*758e9fbaSOystein Eftevaag
305*758e9fbaSOystein Eftevaag return tcti_from_file (name, conf, tcti, data);
306*758e9fbaSOystein Eftevaag }
307*758e9fbaSOystein Eftevaag
308*758e9fbaSOystein Eftevaag void
tctildr_finalize_data(void ** data)309*758e9fbaSOystein Eftevaag tctildr_finalize_data (void **data)
310*758e9fbaSOystein Eftevaag {
311*758e9fbaSOystein Eftevaag if (data != NULL && *data != NULL) {
312*758e9fbaSOystein Eftevaag dlclose(*data);
313*758e9fbaSOystein Eftevaag *data = NULL;
314*758e9fbaSOystein Eftevaag }
315*758e9fbaSOystein Eftevaag }
316