Utility to Import external RSA pem key into TPM
[aaf/sshsm.git] / TPM2-Plugin / lib / tpm2_tcti_ldr.c
1 //**********************************************************************;
2 // Copyright (c) 2018, Intel Corporation
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 // THE POSSIBILITY OF SUCH DAMAGE.
26 //**********************************************************************;
27
28 #include <limits.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <dlfcn.h>
32
33 #include <tss2/tss2_sys.h>
34
35 #include "log.h"
36 #include "tpm2_tcti_ldr.h"
37
38 static void *handle;
39 static const TSS2_TCTI_INFO *info;
40
41 void tpm2_tcti_ldr_unload(void) {
42     if (handle) {
43 #ifndef DISABLE_DLCLOSE
44         dlclose(handle);
45 #endif
46         handle = NULL;
47         info = NULL;
48     }
49 }
50
51 const TSS2_TCTI_INFO *tpm2_tcti_ldr_getinfo(void) {
52     return info;
53 }
54
55 bool tpm2_tcti_ldr_is_tcti_present(const char *name) {
56
57     char path[PATH_MAX];
58     snprintf(path, sizeof(path), "libtss2-tcti-%s.so", name);
59
60     void *handle = dlopen (path, RTLD_LAZY);
61     if (handle) {
62         dlclose(handle);
63     }
64
65     return handle != NULL;
66 }
67
68 TSS2_TCTI_CONTEXT *tpm2_tcti_ldr_load(const char *path, const char *opts) {
69
70     TSS2_TCTI_CONTEXT *tcti_ctx = NULL;
71
72     if (handle) {
73         LOG_ERR("Attempting to load multiple tcti's simultaneously is not supported!");
74         return NULL;
75     }
76
77     /*
78      * Try what they gave us, if it doesn't load up, try
79      * libtss2-tcti-xxx.so replacing xxx with what they gave us.
80      */
81     handle = dlopen (path, RTLD_LAZY);
82     if (!handle) {
83
84         char buf[PATH_MAX];
85         size_t size = snprintf(buf, sizeof(buf), "libtss2-tcti-%s.so", path);
86         if (size >= sizeof(buf)) {
87             LOG_ERR("Truncated friendly name conversion, got: \"%s\", made: \"%s\"",
88                     path, buf);
89             return NULL;
90         }
91
92         handle = dlopen (buf, RTLD_LAZY);
93         if (!handle) {
94             LOG_ERR("Could not dlopen library: \"%s\"", buf);
95             return NULL;
96         }
97     }
98
99     TSS2_TCTI_INFO_FUNC infofn = (TSS2_TCTI_INFO_FUNC)dlsym(handle, TSS2_TCTI_INFO_SYMBOL);
100     if (!infofn) {
101         LOG_ERR("Symbol \"%s\"not found in library: \"%s\"",
102                 TSS2_TCTI_INFO_SYMBOL, path);
103         goto err;
104     }
105
106     info = infofn();
107
108     TSS2_TCTI_INIT_FUNC init = info->init;
109
110     size_t size;
111     TSS2_RC rc = init(NULL, &size, opts);
112     if (rc != TPM2_RC_SUCCESS) {
113         LOG_ERR("tcti init setup routine failed for library: \"%s\""
114                 " options: \"%s\"", path, opts);
115         goto err;
116     }
117
118     tcti_ctx = (TSS2_TCTI_CONTEXT*) calloc(1, size);
119     if (tcti_ctx == NULL) {
120         LOG_ERR("oom");
121         goto err;
122     }
123
124     rc = init(tcti_ctx, &size, opts);
125     if (rc != TPM2_RC_SUCCESS) {
126         LOG_ERR("tcti init allocation routine failed for library: \"%s\""
127                 " options: \"%s\"", path, opts);
128         goto err;
129     }
130
131     return tcti_ctx;
132
133 err:
134     free(tcti_ctx);
135     dlclose(handle);
136     return NULL;
137 }