blob: 5858d76ecf1ccba7e58799779de21a74ab2bffbf [file] [log] [blame]
Juergen Reppff821bd2017-12-11 15:21:42 +01001/*******************************************************************************
2 * Copyright 2017, Fraunhofer SIT sponsored by Infineon Technologies AG
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 *******************************************************************************/
Juergen Repp62097182018-03-19 18:04:42 +010027
28#include <stdlib.h>
29
30#include "tss2_esys.h"
31
Juergen Reppff821bd2017-12-11 15:21:42 +010032#include "esys_iutil.h"
Juergen Repp62097182018-03-19 18:04:42 +010033#include "esys_tcti_default.h"
Juergen Reppff821bd2017-12-11 15:21:42 +010034#define LOGMODULE esys
Philip Triccaa7c51ce2018-03-10 18:28:25 -080035#include "util/log.h"
Juergen Reppff821bd2017-12-11 15:21:42 +010036
37/** Initialize an ESYS_CONTEXT for further use.
38 *
39 * Initialize an ESYS_CONTEXT that holds all the state and metadata information
40 * during an interaction with the TPM.
dantpm4f72c282018-04-05 09:14:28 -070041 * If not specified, load a TCTI in this order:
42 * Library libtss2-tcti-default.so (link to the preferred TCTI)
43 * Library libtss2-tcti-tabrmd.so (tabrmd)
44 * Device /dev/tpmrm0 (kernel resident resource manager)
45 * Device /dev/tpm0 (hardware TPM)
46 * TCP socket localhost:2321 (TPM simulator)
Juergen Repp506c4732018-04-26 11:15:50 +020047 * @param esys_context [out] The ESYS_CONTEXT.
48 * @param tcti [in] The TCTI context used to connect to the TPM (may be NULL).
49 * @param abiVersion [in,out] The abi version to check and the abi version
Juergen Reppff821bd2017-12-11 15:21:42 +010050 * supported by this implementation (may be NULL).
Juergen Repp506c4732018-04-26 11:15:50 +020051 * @retval TSS2_ESYS_RC_SUCCESS if the function call was a success.
52 * @retval TSS2_ESYS_RC_BAD_REFERENCE if esysContext is NULL.
53 * @retval TSS2_ESYS_RC_MEMORY if the ESAPI cannot allocate enough memory to
54 * create the context.
55 * @retval TSS2_RCs produced by lower layers of the software stack may be
56 * returned to the caller unaltered unless handled internally.
Juergen Reppff821bd2017-12-11 15:21:42 +010057 */
58TSS2_RC
59Esys_Initialize(ESYS_CONTEXT ** esys_context, TSS2_TCTI_CONTEXT * tcti,
60 TSS2_ABI_VERSION * abiVersion)
61{
Andreas Fuchs142cfce2018-05-02 12:05:09 +020062 TSS2_RC r;
Juergen Reppff821bd2017-12-11 15:21:42 +010063 size_t syssize;
64
65 _ESYS_ASSERT_NON_NULL(esys_context);
66 *esys_context = NULL;
67
Andreas Fuchs142cfce2018-05-02 12:05:09 +020068 /* Allocate memory for the ESYS context
69 * After this errors must jump to cleanup_return instead of returning. */
William Roberts01bdf722018-03-15 14:07:12 -070070 *esys_context = calloc(1, sizeof(ESYS_CONTEXT));
Andreas Fuchs142cfce2018-05-02 12:05:09 +020071 return_if_null(*esys_context, "Out of memory.", TSS2_ESYS_RC_MEMORY);
Juergen Reppff821bd2017-12-11 15:21:42 +010072
73 /* Allocate memory for the SYS context */
74 syssize = Tss2_Sys_GetContextSize(0);
Andreas Fuchs142cfce2018-05-02 12:05:09 +020075 (*esys_context)->sys = calloc(1, syssize);
76 goto_if_null((*esys_context)->sys, "Error: During malloc.",
77 TSS2_ESYS_RC_MEMORY, cleanup_return);
Juergen Reppff821bd2017-12-11 15:21:42 +010078
79 /* Store the application provided tcti to be return on Esys_GetTcti(). */
80 (*esys_context)->tcti_app_param = tcti;
81
82 /* If no tcti was provided, initialize the default one. */
83 if (tcti == NULL) {
Andreas Fuchs142cfce2018-05-02 12:05:09 +020084 r = get_tcti_default(&tcti);
85 goto_if_error(r, "Initialize default tcti.", cleanup_return);
Juergen Reppff821bd2017-12-11 15:21:42 +010086 }
87
88 /* Initialize the ESAPI */
Andreas Fuchs142cfce2018-05-02 12:05:09 +020089 r = Tss2_Sys_Initialize((*esys_context)->sys, syssize, tcti, abiVersion);
90 goto_if_error(r, "During syscontext initialization", cleanup_return);
Juergen Reppff821bd2017-12-11 15:21:42 +010091
92 /* Use random number for initial esys handle value to provide pseudo
93 namespace for handles */
94 (*esys_context)->esys_handle_cnt = ESYS_TR_MIN_OBJECT + (rand() % 6000000);
95
96 return TSS2_RC_SUCCESS;
97
98cleanup_return:
99 /* If we created the tcti ourselves, we must clean it up */
100 if ((*esys_context)->tcti_app_param == NULL && tcti != NULL) {
101 Tss2_Tcti_Finalize(tcti);
102 free(tcti);
103 }
104 /* No need to finalize (*esys_context)->sys only free since
105 it is the last goto in this function. */
106 free((*esys_context)->sys);
107 free(*esys_context);
108 *esys_context = NULL;
Andreas Fuchs142cfce2018-05-02 12:05:09 +0200109 return r;
Juergen Reppff821bd2017-12-11 15:21:42 +0100110}
111
112/** Finalize an ESYS_CONTEXT
113 *
114 * After interactions with the TPM the context holding the metadata needs to be
115 * freed. Since additional internal memory allocations may have happened during
116 * use of the context, it needs to be finalized correctly.
Juergen Repp506c4732018-04-26 11:15:50 +0200117 * @param esys_context [in,out] The ESYS_CONTEXT. (will be freed and set to NULL)
Juergen Reppff821bd2017-12-11 15:21:42 +0100118 */
119void
120Esys_Finalize(ESYS_CONTEXT ** esys_context)
121{
Andreas Fuchs142cfce2018-05-02 12:05:09 +0200122 TSS2_RC r;
Juergen Reppff821bd2017-12-11 15:21:42 +0100123 TSS2_TCTI_CONTEXT *tctcontext = NULL;
124
125 if (esys_context == NULL || *esys_context == NULL) {
126 LOG_WARNING("Finalizing NULL context.");
127 return;
128 }
129
130 /* Flush from TPM and free all resource objects first */
131 iesys_DeleteAllResourceObjects(*esys_context);
132
Andreas Fuchs142cfce2018-05-02 12:05:09 +0200133 /* If no tcti context was provided during initialization, then we need to
134 finalize the tcti context. So we retrieve here before finalizing the
135 SAPI context. */
Juergen Reppff821bd2017-12-11 15:21:42 +0100136 if ((*esys_context)->tcti_app_param == NULL) {
Andreas Fuchs142cfce2018-05-02 12:05:09 +0200137 r = Tss2_Sys_GetTctiContext((*esys_context)->sys, &tctcontext);
138 if (r != TSS2_RC_SUCCESS) {
139 LOG_ERROR("Internal error in Tss2_Sys_GetTctiContext.");
Juergen Reppff821bd2017-12-11 15:21:42 +0100140 tctcontext = NULL;
141 }
142 }
143
144 /* Finalize the syscontext */
145 Tss2_Sys_Finalize((*esys_context)->sys);
146 free((*esys_context)->sys);
147
Andreas Fuchs142cfce2018-05-02 12:05:09 +0200148 /* If no tcti context was provided during initialization, then we need to
149 finalize the tcti context here. */
Juergen Reppff821bd2017-12-11 15:21:42 +0100150 if (tctcontext != NULL) {
151 Tss2_Tcti_Finalize(tctcontext);
152 free(tctcontext);
153 }
154
155 /* Free esys_context */
156 free(*esys_context);
157 *esys_context = NULL;
158}
159
160/** Return the used TCTI context.
161 *
162 * If a tcti context was passed into Esys_Initialize then this tcti context is
163 * return. If NULL was passed in, then NULL will be returned.
164 * This function is useful before Esys_Finalize to retrieve the tcti context and
165 * perform a clean Tss2_Tcti_Finalize.
Juergen Repp506c4732018-04-26 11:15:50 +0200166 * @param esys_context [in] The ESYS_CONTEXT.
167 * @param tcti [out] The TCTI context used to connect to the TPM (may be NULL).
168 * @retval TSS2_RC_SUCCESS on Success.
169 * @retval TSS2_ESYS_RC_BAD_REFERENCE if esysContext or tcti is NULL.
Juergen Reppff821bd2017-12-11 15:21:42 +0100170 */
171TSS2_RC
172Esys_GetTcti(ESYS_CONTEXT * esys_context, TSS2_TCTI_CONTEXT ** tcti)
173{
174 _ESYS_ASSERT_NON_NULL(esys_context);
175 _ESYS_ASSERT_NON_NULL(tcti);
176 *tcti = esys_context->tcti_app_param;
177 return TSS2_RC_SUCCESS;
178}
179
180/** Return the poll handles of the used TCTI.
181 *
182 * The connection to the TPM is held using a TCTI. These may optionally provide
dantpmf6ef2472018-04-06 15:21:59 -0700183 * handles that can be used to poll for incoming data. This is useful when
Juergen Reppff821bd2017-12-11 15:21:42 +0100184 * using the asynchronous function of ESAPI in an event-loop model.
Juergen Repp506c4732018-04-26 11:15:50 +0200185 * @param esys_context [in] The ESYS_CONTEXT.
186 * @param handles [out] The poll handles (callee-allocated, use free())
187 * @param count [out] The number of poll handles.
188 * @retval TSS2_RC_SUCCESS on Success.
189 * @retval TSS2_ESYS_RC_BAD_REFERENCE if esysContext, handles or count is NULL.
190 * @retval TSS2_RCs produced by lower layers of the software stack.
Juergen Reppff821bd2017-12-11 15:21:42 +0100191 */
192TSS2_RC
193Esys_GetPollHandles(ESYS_CONTEXT * esys_context,
194 TSS2_TCTI_POLL_HANDLE ** handles, size_t * count)
195{
196 TSS2_RC r;
197 TSS2_TCTI_CONTEXT *tcti_context;
198
199 _ESYS_ASSERT_NON_NULL(esys_context);
200 _ESYS_ASSERT_NON_NULL(handles);
201 _ESYS_ASSERT_NON_NULL(count);
202
203 /* Get the tcti-context to use */
204 r = Tss2_Sys_GetTctiContext(esys_context->sys, &tcti_context);
Andreas Fuchs142cfce2018-05-02 12:05:09 +0200205 return_if_error(r, "Invalid SAPI or TCTI context.");
Juergen Reppff821bd2017-12-11 15:21:42 +0100206
207 /* Allocate the memory to hold the poll handles */
208 r = Tss2_Tcti_GetPollHandles(tcti_context, NULL, count);
209 return_if_error(r, "Error getting poll handle count.");
Andreas Fuchs142cfce2018-05-02 12:05:09 +0200210 *handles = calloc(*count, sizeof(TSS2_TCTI_POLL_HANDLE));
211 return_if_null(*handles, "Out of memory.", TSS2_ESYS_RC_MEMORY);
Juergen Reppff821bd2017-12-11 15:21:42 +0100212
213 /* Retrieve the poll handles */
214 r = Tss2_Tcti_GetPollHandles(tcti_context, *handles, count);
215 return_if_error(r, "Error getting poll handles.");
216 return r;
217}
218
dantpmf6ef2472018-04-06 15:21:59 -0700219/** Set the timeout of Esys asynchronous functions.
Juergen Reppff821bd2017-12-11 15:21:42 +0100220 *
dantpmf6ef2472018-04-06 15:21:59 -0700221 * Sets the timeout for the _finish() functions in the asynchronous versions of
Juergen Reppff821bd2017-12-11 15:21:42 +0100222 * the Esys commands.
Juergen Repp506c4732018-04-26 11:15:50 +0200223 * @param esys_context [in] The ESYS_CONTEXT.
224 * @param timeout [in] The timeout in ms or -1 to block indefinately.
225 * @retval TSS2_RC_SUCCESS on Success.
226 * @retval TSS2_ESYS_RC_BAD_REFERENCE if esysContext is NULL.
Juergen Reppff821bd2017-12-11 15:21:42 +0100227 */
228TSS2_RC
229Esys_SetTimeout(ESYS_CONTEXT * esys_context, int32_t timeout)
230{
231 _ESYS_ASSERT_NON_NULL(esys_context);
232 esys_context->timeout = timeout;
233 return TSS2_RC_SUCCESS;
234}