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