blob: 26564e25a0ce2edf76413c8592f2fc430b2eb631 [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 "tss2_esys.h"
29#include "esys_mu.h"
30
31#include "esys_iutil.h"
Juergen Reppff821bd2017-12-11 15:21:42 +010032#define LOGMODULE esys
Philip Triccaa7c51ce2018-03-10 18:28:25 -080033#include "util/log.h"
Juergen Reppff821bd2017-12-11 15:21:42 +010034
35/** Serialization of an ESYS_TR into a byte buffer.
36 *
37 * Serialize the metadata of an ESYS_TR object into a byte buffer such that it
38 * can be stored on disk for later use by a different program or context.
39 * The serialized object can be deserialized suing Esys_TR_Deserialize.
Juergen Repp506c4732018-04-26 11:15:50 +020040 * @param esys_context [in,out] The ESYS_CONTEXT.
41 * @param esys_handle [in] The ESYS_TR object to serialize.
42 * @param buffer [out] The buffer containing the serialized metadata.
43 * (caller-callocated) Shall be freed using free().
44 * @param buffer_size [out] The size of the buffer parameter.
Juergen Reppff821bd2017-12-11 15:21:42 +010045 * @retval TSS2_RC_SUCCESS on Success.
Juergen Repp506c4732018-04-26 11:15:50 +020046 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
47 * ESYS_CONTEXT.
48 * @retval TSS2_ESYS_RC_MEMORY if the buffer for marshaling the object can't
49 * be allocated.
50 * @retval TSS2_ESYS_RC_BAD_VALUE For invalid ESYS data to be marshaled.
51 * @retval TSS2_RCs produced by lower layers of the software stack.
Juergen Reppff821bd2017-12-11 15:21:42 +010052 */
53TSS2_RC
54Esys_TR_Serialize(ESYS_CONTEXT * esys_context,
55 ESYS_TR esys_handle, uint8_t ** buffer, size_t * buffer_size)
56{
57 TSS2_RC r = TSS2_RC_SUCCESS;
58 RSRC_NODE_T *esys_object;
59 size_t offset = 0;
Juergen Repp219fda52018-02-23 11:14:47 +010060 *buffer_size = 0;
Juergen Reppff821bd2017-12-11 15:21:42 +010061
62 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
63 return_if_error(r, "Get resource object");
Juergen Reppb8324672018-02-23 11:15:39 +010064
Juergen Repp47120322018-05-03 12:21:30 +020065 r = iesys_MU_IESYS_RESOURCE_Marshal(&esys_object->rsrc, NULL, SIZE_MAX,
66 buffer_size);
Juergen Reppff821bd2017-12-11 15:21:42 +010067 return_if_error(r, "Marshal resource object");
Juergen Reppb8324672018-02-23 11:15:39 +010068
Juergen Reppff821bd2017-12-11 15:21:42 +010069 *buffer = malloc(*buffer_size);
70 return_if_null(*buffer, "Buffer could not be allocated",
71 TSS2_ESYS_RC_MEMORY);
Juergen Reppb8324672018-02-23 11:15:39 +010072
Juergen Repp47120322018-05-03 12:21:30 +020073 r = iesys_MU_IESYS_RESOURCE_Marshal(&esys_object->rsrc, *buffer,
74 *buffer_size, &offset);
Juergen Reppff821bd2017-12-11 15:21:42 +010075 return_if_error(r, "Marshal resource object");
Juergen Reppb8324672018-02-23 11:15:39 +010076
Juergen Reppff821bd2017-12-11 15:21:42 +010077 return TSS2_RC_SUCCESS;
78};
79
80/** Deserialization of an ESYS_TR from a byte buffer.
81 *
82 * Deserialize the metadata of an ESYS_TR object from a byte buffer that was
83 * stored on disk for later use by a different program or context.
84 * An object can be serialized suing Esys_TR_Serialize.
Juergen Repp506c4732018-04-26 11:15:50 +020085 * @param esys_context [in,out] The ESYS_CONTEXT.
86 * @param esys_handle [in] The ESYS_TR object to serialize.
87 * @param buffer [out] The buffer containing the serialized metadata.
88 * (caller-callocated) Shall be freed using free().
89 * @param buffer_size [out] The size of the buffer parameter.
90 * @retval TSS2_RC_SUCCESS on Success.
91 * @retval TSS2_ESYS_RC_MEMORY if the object can not be allocated.
92 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if the buffer for unmarshaling.
93 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
94 * @retval TSS2_RCs produced by lower layers of the software stack.
Juergen Reppff821bd2017-12-11 15:21:42 +010095 */
96TSS2_RC
97Esys_TR_Deserialize(ESYS_CONTEXT * esys_context,
98 uint8_t const *buffer,
99 size_t buffer_size, ESYS_TR * esys_handle)
100{
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200101 TSS2_RC r;
102
Juergen Reppff821bd2017-12-11 15:21:42 +0100103 RSRC_NODE_T *esys_object;
104 size_t offset = 0;
105
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200106 _ESYS_ASSERT_NON_NULL(esys_context);
Juergen Reppff821bd2017-12-11 15:21:42 +0100107 r = esys_CreateResourceObject(esys_context, *esys_handle, &esys_object);
108 return_if_error(r, "Get resource object");
Juergen Reppb8324672018-02-23 11:15:39 +0100109
Juergen Repp47120322018-05-03 12:21:30 +0200110 r = iesys_MU_IESYS_RESOURCE_Unmarshal(buffer, buffer_size, &offset,
111 &esys_object->rsrc);
Juergen Reppff821bd2017-12-11 15:21:42 +0100112 return_if_error(r, "Unmarshal resource object");
Juergen Reppb8324672018-02-23 11:15:39 +0100113
Juergen Reppff821bd2017-12-11 15:21:42 +0100114 return TSS2_RC_SUCCESS;
115}
116
dantpmf6ef2472018-04-06 15:21:59 -0700117/** Start synchronous creation of an ESYS_TR object from TPM metadata.
Juergen Reppff821bd2017-12-11 15:21:42 +0100118 *
119 * This function starts the asynchronous retrieval of metadata from the TPM in
120 * order to create a new ESYS_TR object.
Juergen Repp506c4732018-04-26 11:15:50 +0200121 * @param esys_context [in,out] The ESYS_CONTEXT
122 * @param tpm_handle [in] The handle of the TPM object to represent as ESYS_TR.
123 * @param shandle1 [in,out] A session for securing the TPM command (optional).
124 * @param shandle2 [in,out] A session for securing the TPM command (optional).
125 * @param shandle3 [in,out] A session for securing the TPM command (optional).
126 * @retval TSS2_RC_SUCCESS on success
127 * @retval ESYS_RC_SUCCESS if the function call was a success.
128 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
129 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
130 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
131 * internal operations or return parameters.
132 * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
133 * the 'decrypt' attribute bit set.
134 * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
135 * the 'encrypt' attribute bit set.
136 * @retval TSS2_ESYS_RC_NO_DECRYPT_PARAM: if one of the sessions has the
137 * 'decrypt' attribute set and the command does not support encryption
138 * of the first command parameter.
139 * @retval TSS2_RCs produced by lower layers of the software stack may be
140 * returned to the caller unaltered unless handled internally.
Juergen Reppff821bd2017-12-11 15:21:42 +0100141 */
142TSS2_RC
143Esys_TR_FromTPMPublic_Async(ESYS_CONTEXT * esys_context,
144 TPM2_HANDLE tpm_handle,
145 ESYS_TR shandle1,
146 ESYS_TR shandle2, ESYS_TR shandle3)
147{
148 TSS2_RC r;
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200149 _ESYS_ASSERT_NON_NULL(esys_context);
Juergen Reppff821bd2017-12-11 15:21:42 +0100150 ESYS_TR esys_handle = esys_context->esys_handle_cnt++;
151 RSRC_NODE_T *esysHandleNode = NULL;
152 r = esys_CreateResourceObject(esys_context, esys_handle, &esysHandleNode);
153 goto_if_error(r, "Error create resource", error_cleanup);
Juergen Reppb8324672018-02-23 11:15:39 +0100154
Juergen Reppff821bd2017-12-11 15:21:42 +0100155 esysHandleNode->rsrc.handle = tpm_handle;
156 esys_context->esys_handle = esys_handle;
157
158 if (tpm_handle >= TPM2_NV_INDEX_FIRST && tpm_handle <= TPM2_NV_INDEX_LAST) {
159 esys_context->in.NV_ReadPublic.nvIndex = esys_handle;
Juergen Reppadd438d2018-04-09 10:00:19 +0200160 r = Esys_NV_ReadPublic_Async(esys_context, esys_handle, shandle1,
Juergen Reppff821bd2017-12-11 15:21:42 +0100161 shandle2, shandle3);
162 goto_if_error(r, "Error NV_ReadPublic", error_cleanup);
Juergen Reppb8324672018-02-23 11:15:39 +0100163
Juergen Reppff821bd2017-12-11 15:21:42 +0100164 } else {
165 esys_context->in.ReadPublic.objectHandle = esys_handle;
Juergen Reppadd438d2018-04-09 10:00:19 +0200166 r = Esys_ReadPublic_Async(esys_context, esys_handle, shandle1, shandle2,
Juergen Reppff821bd2017-12-11 15:21:42 +0100167 shandle3);
168 goto_if_error(r, "Error ReadPublic", error_cleanup);
169 }
170 return r;
171 error_cleanup:
172 Esys_TR_Close(esys_context, &esys_handle);
173 return r;
174}
175
dantpmf6ef2472018-04-06 15:21:59 -0700176/** Finish asynchronous creation of an ESYS_TR object from TPM metadata.
Juergen Repp506c4732018-04-26 11:15:50 +0200177 *
Juergen Reppff821bd2017-12-11 15:21:42 +0100178 * This function finishes the asynchronous retrieval of metadata from the TPM in
179 * order to create a new ESYS_TR object.
Juergen Repp506c4732018-04-26 11:15:50 +0200180 * @param esys_context [in,out] The ESYS_CONTEXT
181 * @param object [out] The newly created ESYS_TR metadata object.
182 * @retval TSS2_RC_SUCCESS on success
183 * @retval ESYS_RC_SUCCESS if the function call was a success.
184 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
185 * pointers or required output handle references are NULL.
186 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
187 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
188 * internal operations or return parameters.
189 * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
190 * operation already pending.
191 * @retval TSS2_ESYS_RC_TRY_AGAIN: if the timeout counter expires before the
192 * TPM response is received.
193 * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
194 * at least contain the tag, response length, and response code.
195 * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
196 * @retval TSS2_RCs produced by lower layers of the software stack may be
197 * returned to the caller unaltered unless handled internally.
Juergen Reppff821bd2017-12-11 15:21:42 +0100198 */
199TSS2_RC
Juergen Repp506c4732018-04-26 11:15:50 +0200200Esys_TR_FromTPMPublic_Finish(ESYS_CONTEXT * esys_context, ESYS_TR * object)
Juergen Reppff821bd2017-12-11 15:21:42 +0100201{
202 TSS2_RC r = TSS2_RC_SUCCESS;
203 ESYS_TR objectHandle = esys_context->esys_handle;
204 RSRC_NODE_T *objectHandleNode;
205
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200206 _ESYS_ASSERT_NON_NULL(esys_context);
Juergen Reppff821bd2017-12-11 15:21:42 +0100207 r = esys_GetResourceObject(esys_context, objectHandle, &objectHandleNode);
208 goto_if_error(r, "get resource", error_cleanup);
Juergen Reppb8324672018-02-23 11:15:39 +0100209
Juergen Reppff821bd2017-12-11 15:21:42 +0100210 if (objectHandleNode->rsrc.handle >= TPM2_NV_INDEX_FIRST
211 && objectHandleNode->rsrc.handle <= TPM2_NV_INDEX_LAST) {
212 TPM2B_NV_PUBLIC *nvPublic;
213 TPM2B_NAME *nvName;
Juergen Reppadd438d2018-04-09 10:00:19 +0200214 r = Esys_NV_ReadPublic_Finish(esys_context, &nvPublic, &nvName);
Andreas Fuchsb82f6da2018-04-12 13:43:04 +0200215 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
216 LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
217 " => resubmitting command", r);
218 return r;
219 }
Juergen Reppff821bd2017-12-11 15:21:42 +0100220 goto_if_error(r, "Error NV_ReadPublic", error_cleanup);
Juergen Reppb8324672018-02-23 11:15:39 +0100221
Juergen Reppff821bd2017-12-11 15:21:42 +0100222 objectHandleNode->rsrc.rsrcType = IESYSC_NV_RSRC;
223 objectHandleNode->rsrc.name = *nvName;
224 objectHandleNode->rsrc.misc.rsrc_nv_pub = *nvPublic;
225 SAFE_FREE(nvPublic);
226 SAFE_FREE(nvName);
227 } else {
228 TPM2B_PUBLIC *public;
229 TPM2B_NAME *name = NULL;
230 TPM2B_NAME *qualifiedName = NULL;
Juergen Reppadd438d2018-04-09 10:00:19 +0200231 r = Esys_ReadPublic_Finish(esys_context, &public, &name,
Juergen Reppff821bd2017-12-11 15:21:42 +0100232 &qualifiedName);
Andreas Fuchsb82f6da2018-04-12 13:43:04 +0200233 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
234 LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
235 " => resubmitting command", r);
236 return r;
237 }
Juergen Reppb8324672018-02-23 11:15:39 +0100238 goto_if_error(r, "Error ReadPublic", error_cleanup);
239
240 objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
Juergen Reppff821bd2017-12-11 15:21:42 +0100241 objectHandleNode->rsrc.name = *name;
242 objectHandleNode->rsrc.misc.rsrc_key_pub = *public;
243 SAFE_FREE(public);
244 SAFE_FREE(name);
245 SAFE_FREE(qualifiedName);
246 }
Juergen Repp506c4732018-04-26 11:15:50 +0200247 *object = objectHandle;
Juergen Reppff821bd2017-12-11 15:21:42 +0100248 return TSS2_RC_SUCCESS;
249
250 error_cleanup:
251 Esys_TR_Close(esys_context, &objectHandle);
252 return r;
253}
254
255/** Creation of an ESYS_TR object from TPM metadata.
256 *
dantpmf6ef2472018-04-06 15:21:59 -0700257 * This function can be used to create ESYS_TR object for Tpm Resources that are
Juergen Reppff821bd2017-12-11 15:21:42 +0100258 * not created or loaded (e.g. using ESys_CreatePrimary or ESys_Load) but
259 * pre-exist inside the TPM. Examples are NV-Indices or persistent object.
260 *
261 * Note: For PCRs and hierarchies, please use the global ESYS_TR identifiers.
262 * Note: If a session is provided the TPM is queried for the metadata twice.
263 * First without a session to retrieve some metadata then with the session where
264 * this metadata is used in the session HMAC calculation and thereby verified.
265 *
266 * Since man in the middle attacks should be prevented as much as possible it is
267 * recommended to pass a session.
Juergen Repp506c4732018-04-26 11:15:50 +0200268 * @param esys_context [in,out] The ESYS_CONTEXT
269 * @param tpm_handle [in] The handle of the TPM object to represent as ESYS_TR.
270 * @param shandle1 [in,out] A session for securing the TPM command (optional).
271 * @param shandle2 [in,out] A session for securing the TPM command (optional).
272 * @param shandle3 [in,out] A session for securing the TPM command (optional).
273 * @param object [out] The newly created ESYS_TR metadata object.
274 * @retval TSS2_RC_SUCCESS on success
275 * @retval ESYS_RC_SUCCESS if the function call was a success.
276 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
277 * pointers or required output handle references are NULL.
278 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
279 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
280 * internal operations or return parameters.
281 * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
282 * operation already pending.
283 * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
284 * at least contain the tag, response length, and response code.
285 * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
286 * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
287 * the 'decrypt' attribute bit set.
288 * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
289 * the 'encrypt' attribute bit set.
290 * @retval TSS2_ESYS_RC_NO_DECRYPT_PARAM: if one of the sessions has the
291 * 'decrypt' attribute set and the command does not support encryption
292 * of the first command parameter.
293 * @retval TSS2_RCs produced by lower layers of the software stack may be
294 * returned to the caller unaltered unless handled internally.
Juergen Reppff821bd2017-12-11 15:21:42 +0100295 */
296TSS2_RC
297Esys_TR_FromTPMPublic(ESYS_CONTEXT * esys_context,
298 TPM2_HANDLE tpm_handle,
299 ESYS_TR shandle1,
300 ESYS_TR shandle2, ESYS_TR shandle3, ESYS_TR * object)
301{
302 TSS2_RC r;
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200303
304 _ESYS_ASSERT_NON_NULL(esys_context);
Andreas Fuchsb82f6da2018-04-12 13:43:04 +0200305 r = Esys_TR_FromTPMPublic_Async(esys_context, tpm_handle,
306 shandle1, shandle2, shandle3);
307 return_if_error(r, "Error TR FromTPMPublic");
Juergen Reppb8324672018-02-23 11:15:39 +0100308
Andreas Fuchsb82f6da2018-04-12 13:43:04 +0200309 /* Set the timeout to indefinite for now, since we want _Finish to block */
310 int32_t timeouttmp = esys_context->timeout;
311 esys_context->timeout = -1;
312 /*
313 * Now we call the finish function, until return code is not equal to
314 * from TSS2_BASE_RC_TRY_AGAIN.
315 * Note that the finish function may return TSS2_RC_TRY_AGAIN, even if we
316 * have set the timeout to -1. This occurs for example if the TPM requests
317 * a retransmission of the command via TPM2_RC_YIELDED.
318 */
319 do {
320 r = Esys_TR_FromTPMPublic_Finish(esys_context, object);
321 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
322 LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
323 " => resubmitting command", r);
324 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
Juergen Reppb8324672018-02-23 11:15:39 +0100325
Andreas Fuchsb82f6da2018-04-12 13:43:04 +0200326 /* Restore the timeout value to the original value */
327 esys_context->timeout = timeouttmp;
328 return_if_error(r, "Error TR FromTPMPublic");
329
Juergen Reppff821bd2017-12-11 15:21:42 +0100330 return r;
331}
332
333/** Close an ESYS_TR without removing it from the TPM.
334 *
335 * This function deletes an ESYS_TR object from an ESYS_CONTEXT without deleting
336 * it from the TPM. This is useful for NV-Indices or persistent keys, after
337 * Esys_TR_Serialize has been called. Transient objects should be deleted using
338 * Esys_FlushContext.
Juergen Repp506c4732018-04-26 11:15:50 +0200339 * @param esys_context [in,out] The ESYS_CONTEXT
340 * @param object [out] ESYS_TR metadata object to be deleted from ESYS_CONTEXT.
341 * @retval TSS2_RC_SUCCESS on Success.
342 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
343 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
344 * ESYS_CONTEXT.
Juergen Reppff821bd2017-12-11 15:21:42 +0100345 */
346TSS2_RC
347Esys_TR_Close(ESYS_CONTEXT * esys_context, ESYS_TR * object)
348{
Andreas Fuchs1c48e2b2018-03-08 11:25:12 +0100349 RSRC_NODE_T *node;
350 RSRC_NODE_T **update_ptr;
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200351
352 _ESYS_ASSERT_NON_NULL(esys_context);
Andreas Fuchs1c48e2b2018-03-08 11:25:12 +0100353 for (node = esys_context->rsrc_list,
354 update_ptr = &esys_context->rsrc_list;
355 node != NULL;
356 update_ptr = &node->next, node = node->next) {
357 if (node->esys_handle == *object) {
358 *update_ptr = node->next;
359 SAFE_FREE(node);
Juergen Reppff821bd2017-12-11 15:21:42 +0100360 *object = ESYS_TR_NONE;
361 return TSS2_RC_SUCCESS;
362 }
363 }
364 LOG_ERROR("Error: Esys handle does not exist (%x).", TSS2_ESYS_RC_BAD_TR);
365 return TSS2_ESYS_RC_BAD_TR;
366}
367
368/** Set the authorization value of an ESYS_TR.
369 *
370 * Authorization values are associated with ESYS_TR Tpm Resource object. They
371 * are then picked up whenever an authorization is needed.
372 *
373 * Note: The authorization value is not stored in the metadata during
374 * Esys_TR_Serialize. Therefor Esys_TR_SetAuth needs to be called again after
375 * every Esys_TR_Deserialize.
Juergen Repp506c4732018-04-26 11:15:50 +0200376 * @param esys_context [in,out] The ESYS_CONTEXT.
377 * @param esys_handle [in,out] The ESYS_TR for which to set the auth value.
378 * @param authValue [in] The auth value to set for the ESYS_TR.
379 * @retval TSS2_RC_SUCCESS on Success.
380 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
381 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
382 * ESYS_CONTEXT.
Juergen Reppff821bd2017-12-11 15:21:42 +0100383 */
384TSS2_RC
385Esys_TR_SetAuth(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
386 TPM2B_AUTH const *authValue)
387{
Juergen Reppff821bd2017-12-11 15:21:42 +0100388 RSRC_NODE_T *esys_object;
389 TSS2_RC r;
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200390 _ESYS_ASSERT_NON_NULL(esys_context);
Juergen Reppff821bd2017-12-11 15:21:42 +0100391 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
392 if (r != TPM2_RC_SUCCESS)
393 return r;
394 esys_object->auth = *authValue;
395 return TSS2_RC_SUCCESS;
396}
397
398/** Retrieve the TPM public name of an Esys_TR object.
399 *
400 * Some operations (i.e. Esys_PolicyNameHash) require the name of a TPM object
401 * to be passed. Esys_TR_GetName provides this name to the caller.
Juergen Repp506c4732018-04-26 11:15:50 +0200402 * @param esys_context [in,out] The ESYS_CONTEXT.
403 * @param esys_handle [in,out] The ESYS_TR for which to retrieve the name.
404 * @param name [out] The name of the object (caller-allocated; use free()).
405 * @retval TSS2_RC_SUCCESS on Success.
406 * @retval TSS2_ESYS_RC_MEMORY if needed memory can't be allocated.
407 * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
408 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
409 * @retval TSS2_SYS_RC_* for SAPI errors.
Juergen Reppff821bd2017-12-11 15:21:42 +0100410 */
411TSS2_RC
412Esys_TR_GetName(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
413 TPM2B_NAME ** name)
414{
415 RSRC_NODE_T *esys_object;
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200416 TSS2_RC r;
417 _ESYS_ASSERT_NON_NULL(esys_context);
418
419 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
Andreas Fuchs1c48e2b2018-03-08 11:25:12 +0100420 return_if_error(r, "Object not found");
Juergen Reppb8324672018-02-23 11:15:39 +0100421
Juergen Reppff821bd2017-12-11 15:21:42 +0100422 *name = malloc(sizeof(TPM2B_NAME));
423 if (*name == NULL) {
424 LOG_ERROR("Error: out of memory");
425 return TSS2_ESYS_RC_MEMORY;
426 }
427 if (esys_object->rsrc.rsrcType == IESYSC_KEY_RSRC) {
428 r = iesys_get_name(&esys_object->rsrc.misc.rsrc_key_pub, *name);
429 goto_if_error(r, "Error get name", error_cleanup);
Juergen Reppb8324672018-02-23 11:15:39 +0100430
Juergen Reppff821bd2017-12-11 15:21:42 +0100431 } else {
432 if (esys_object->rsrc.rsrcType == IESYSC_NV_RSRC) {
433 r = iesys_nv_get_name(&esys_object->rsrc.misc.rsrc_nv_pub, *name);
434 goto_if_error(r, "Error get name", error_cleanup);
Juergen Reppb8324672018-02-23 11:15:39 +0100435
Juergen Reppff821bd2017-12-11 15:21:42 +0100436 } else {
437 size_t offset = 0;
Juergen Repp23840302018-04-10 13:44:45 +0200438 r = Tss2_MU_TPM2_HANDLE_Marshal(esys_object->rsrc.handle,
439 &(*name)->name[0], sizeof(TPM2_HANDLE),
440 &offset);
441 goto_if_error(r, "Error get name", error_cleanup);
Juergen Reppff821bd2017-12-11 15:21:42 +0100442 (*name)->size = offset;
443 }
444 }
445 return r;
446 error_cleanup:
447 SAFE_FREE(name);
448 return r;
449}
450
451
452/** Retrieve the Session Attributes of the ESYS_TR session.
453 *
454 * Sessions possess attributes, such as whether they shall continue of be
455 * flushed after the next command, or whether they are used to encrypt
456 * parameters.
457 * Note: this function only applies to ESYS_TR objects that represent sessions.
Juergen Repp506c4732018-04-26 11:15:50 +0200458 * @param esys_context [in,out] The ESYS_CONTEXT.
459 * @param esys_handle [in,out] The ESYS_TR of the session.
460 * @param flags [out] The attributes of the session.
461 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
462 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
463 * ESYS_CONTEXT or ESYS_TR object is not a session object.
Juergen Reppff821bd2017-12-11 15:21:42 +0100464 */
465TSS2_RC
466Esys_TRSess_GetAttributes(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
467 TPMA_SESSION * flags)
468{
469 RSRC_NODE_T *esys_object;
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200470
471 _ESYS_ASSERT_NON_NULL(esys_context);
Juergen Reppff821bd2017-12-11 15:21:42 +0100472 TSS2_RC r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
473 return_if_error(r, "Object not found");
Juergen Reppb8324672018-02-23 11:15:39 +0100474
Juergen Reppff821bd2017-12-11 15:21:42 +0100475 if (esys_object->rsrc.rsrcType != IESYSC_SESSION_RSRC)
476 return_error(TSS2_ESYS_RC_BAD_TR, "Object is not a session object");
477 *flags = esys_object->rsrc.misc.rsrc_session.sessionAttributes;
478 return TSS2_RC_SUCCESS;
479}
480
481/** Set session attributes
482 *
dantpmf6ef2472018-04-06 15:21:59 -0700483 * Set or unset a session's attributes according to the provided flags and mask.
Juergen Reppff821bd2017-12-11 15:21:42 +0100484 * @verbatim new_attributes = old_attributes & ~mask | flags & mask @endverbatim
485 * Note: this function only applies to ESYS_TR objects that represent sessions.
Juergen Repp506c4732018-04-26 11:15:50 +0200486 * @param esys_context [in,out] The ESYS_CONTEXT.
487 * @param esys_handle [in,out] The ESYS_TR of the session.
488 * @param flags [in] The flags to be set or unset for the session.
489 * @param mask [in] The mask for the flags to be set or unset.
490 * @retval TSS2_RC_SUCCESS on Success.
491 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
492 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
493 * ESYS_CONTEXT or ESYS_TR object is not a session object.
Juergen Reppff821bd2017-12-11 15:21:42 +0100494 */
495TSS2_RC
496Esys_TRSess_SetAttributes(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
497 TPMA_SESSION flags, TPMA_SESSION mask)
498{
499 RSRC_NODE_T *esys_object;
Andreas Fuchs8071f1d2018-04-26 16:57:38 +0200500
501 _ESYS_ASSERT_NON_NULL(esys_context);
Juergen Reppff821bd2017-12-11 15:21:42 +0100502 TSS2_RC r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
503 return_if_error(r, "Object not found");
Juergen Reppb8324672018-02-23 11:15:39 +0100504
Juergen Reppff821bd2017-12-11 15:21:42 +0100505 if (esys_object->rsrc.rsrcType != IESYSC_SESSION_RSRC)
506 return_error(TSS2_ESYS_RC_BAD_TR, "Object is not a session object");
507 esys_object->rsrc.misc.rsrc_session.sessionAttributes =
508 (esys_object->rsrc.misc.rsrc_session.
509 sessionAttributes & ~mask) | (flags & mask);
510 return TSS2_RC_SUCCESS;
511}
Andreas Fuchs2a67f9e2018-05-25 09:40:19 +0200512
513/** Retrieve the TPM nonce of an Esys_TR session object.
514 *
515 * Some operations (i.e. Esys_PolicySigned) require the nonce returned by the
516 * TPM during Esys_StartauthSession. This function provides this nonce to the
517 * caller.
518 * @param esys_context [in,out] The ESYS_CONTEXT.
519 * @param esys_handle [in,out] The ESYS_TRsess for which to retrieve the nonce.
520 * @param nonceTPM [out] The nonce of the object (callee-allocated; use free()).
521 * @retval TSS2_RC_SUCCESS on Success.
522 * @retval TSS2_ESYS_RC_MEMORY if needed memory can't be allocated.
523 * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
524 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
525 * @retval TSS2_SYS_RC_* for SAPI errors.
526 */
527TSS2_RC
528Esys_TRSess_GetNonceTPM(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
529 TPM2B_NONCE **nonceTPM)
530{
531 RSRC_NODE_T *esys_object;
532 TSS2_RC r;
533 _ESYS_ASSERT_NON_NULL(esys_context);
534 _ESYS_ASSERT_NON_NULL(nonceTPM);
535
536 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
537 return_if_error(r, "Object not found");
538
539 *nonceTPM = calloc(1, sizeof(**nonceTPM));
540 if (*nonceTPM == NULL) {
541 LOG_ERROR("Error: out of memory");
542 return TSS2_ESYS_RC_MEMORY;
543 }
544 if (esys_object->rsrc.rsrcType != IESYSC_SESSION_RSRC) {
545 r = TSS2_ESYS_RC_BAD_TR;
546 goto_if_error(r, "NonceTPM for non-session object requested.",
547 error_cleanup);
548
549 }
550 **nonceTPM = esys_object->rsrc.misc.rsrc_session.nonceTPM;
551
552 return r;
553 error_cleanup:
554 SAFE_FREE(*nonceTPM);
555 return r;
556}