1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
4 * All rights reserved.
5 ******************************************************************************/
6
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include "tss2_esys.h"
12 #include "esys_mu.h"
13
14 #include "esys_iutil.h"
15 #define LOGMODULE esys
16 #include "util/log.h"
17 #include "util/aux_util.h"
18
19 /** Serialization of an ESYS_TR into a byte buffer.
20 *
21 * Serialize the metadata of an ESYS_TR object into a byte buffer such that it
22 * can be stored on disk for later use by a different program or context.
23 * The serialized object can be deserialized suing Esys_TR_Deserialize.
24 * @param esys_context [in,out] The ESYS_CONTEXT.
25 * @param esys_handle [in] The ESYS_TR object to serialize.
26 * @param buffer [out] The buffer containing the serialized metadata.
27 * (caller-callocated) Shall be freed using free().
28 * @param buffer_size [out] The size of the buffer parameter.
29 * @retval TSS2_RC_SUCCESS on Success.
30 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
31 * ESYS_CONTEXT.
32 * @retval TSS2_ESYS_RC_MEMORY if the buffer for marshaling the object can't
33 * be allocated.
34 * @retval TSS2_ESYS_RC_BAD_VALUE For invalid ESYS data to be marshaled.
35 * @retval TSS2_RCs produced by lower layers of the software stack.
36 */
37 TSS2_RC
Esys_TR_Serialize(ESYS_CONTEXT * esys_context,ESYS_TR esys_handle,uint8_t ** buffer,size_t * buffer_size)38 Esys_TR_Serialize(ESYS_CONTEXT * esys_context,
39 ESYS_TR esys_handle, uint8_t ** buffer, size_t * buffer_size)
40 {
41 TSS2_RC r = TSS2_RC_SUCCESS;
42 RSRC_NODE_T *esys_object;
43 size_t offset = 0;
44 *buffer_size = 0;
45
46 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
47 return_if_error(r, "Get resource object");
48
49 r = iesys_MU_IESYS_RESOURCE_Marshal(&esys_object->rsrc, NULL, SIZE_MAX,
50 buffer_size);
51 return_if_error(r, "Marshal resource object");
52
53 *buffer = malloc(*buffer_size);
54 return_if_null(*buffer, "Buffer could not be allocated",
55 TSS2_ESYS_RC_MEMORY);
56
57 r = iesys_MU_IESYS_RESOURCE_Marshal(&esys_object->rsrc, *buffer,
58 *buffer_size, &offset);
59 return_if_error(r, "Marshal resource object");
60
61 return TSS2_RC_SUCCESS;
62 };
63
64 /** Deserialization of an ESYS_TR from a byte buffer.
65 *
66 * Deserialize the metadata of an ESYS_TR object from a byte buffer that was
67 * stored on disk for later use by a different program or context.
68 * An object can be serialized suing Esys_TR_Serialize.
69 * @param esys_context [in,out] The ESYS_CONTEXT.
70 * @param esys_handle [in] The ESYS_TR object to serialize.
71 * @param buffer [out] The buffer containing the serialized metadata.
72 * (caller-callocated) Shall be freed using free().
73 * @param buffer_size [out] The size of the buffer parameter.
74 * @retval TSS2_RC_SUCCESS on Success.
75 * @retval TSS2_ESYS_RC_MEMORY if the object can not be allocated.
76 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if the buffer for unmarshaling.
77 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
78 * @retval TSS2_RCs produced by lower layers of the software stack.
79 */
80 TSS2_RC
Esys_TR_Deserialize(ESYS_CONTEXT * esys_context,uint8_t const * buffer,size_t buffer_size,ESYS_TR * esys_handle)81 Esys_TR_Deserialize(ESYS_CONTEXT * esys_context,
82 uint8_t const *buffer,
83 size_t buffer_size, ESYS_TR * esys_handle)
84 {
85 TSS2_RC r;
86
87 RSRC_NODE_T *esys_object;
88 size_t offset = 0;
89
90 _ESYS_ASSERT_NON_NULL(esys_context);
91 *esys_handle = esys_context->esys_handle_cnt++;
92 r = esys_CreateResourceObject(esys_context, *esys_handle, &esys_object);
93 return_if_error(r, "Get resource object");
94
95 r = iesys_MU_IESYS_RESOURCE_Unmarshal(buffer, buffer_size, &offset,
96 &esys_object->rsrc);
97 return_if_error(r, "Unmarshal resource object");
98
99 return TSS2_RC_SUCCESS;
100 }
101
102 /** Start synchronous creation of an ESYS_TR object from TPM metadata.
103 *
104 * This function starts the asynchronous retrieval of metadata from the TPM in
105 * order to create a new ESYS_TR object.
106 * @param esys_context [in,out] The ESYS_CONTEXT
107 * @param tpm_handle [in] The handle of the TPM object to represent as ESYS_TR.
108 * @param shandle1 [in,out] A session for securing the TPM command (optional).
109 * @param shandle2 [in,out] A session for securing the TPM command (optional).
110 * @param shandle3 [in,out] A session for securing the TPM command (optional).
111 * @retval TSS2_RC_SUCCESS on success
112 * @retval ESYS_RC_SUCCESS if the function call was a success.
113 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
114 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
115 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
116 * internal operations or return parameters.
117 * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
118 * the 'decrypt' attribute bit set.
119 * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
120 * the 'encrypt' attribute bit set.
121 * @retval TSS2_ESYS_RC_NO_DECRYPT_PARAM: if one of the sessions has the
122 * 'decrypt' attribute set and the command does not support encryption
123 * of the first command parameter.
124 * @retval TSS2_RCs produced by lower layers of the software stack may be
125 * returned to the caller unaltered unless handled internally.
126 */
127 TSS2_RC
Esys_TR_FromTPMPublic_Async(ESYS_CONTEXT * esys_context,TPM2_HANDLE tpm_handle,ESYS_TR shandle1,ESYS_TR shandle2,ESYS_TR shandle3)128 Esys_TR_FromTPMPublic_Async(ESYS_CONTEXT * esys_context,
129 TPM2_HANDLE tpm_handle,
130 ESYS_TR shandle1,
131 ESYS_TR shandle2, ESYS_TR shandle3)
132 {
133 TSS2_RC r;
134 _ESYS_ASSERT_NON_NULL(esys_context);
135 ESYS_TR esys_handle = esys_context->esys_handle_cnt++;
136 RSRC_NODE_T *esysHandleNode = NULL;
137 r = esys_CreateResourceObject(esys_context, esys_handle, &esysHandleNode);
138 goto_if_error(r, "Error create resource", error_cleanup);
139
140 esysHandleNode->rsrc.handle = tpm_handle;
141 esys_context->esys_handle = esys_handle;
142
143 if (tpm_handle >= TPM2_NV_INDEX_FIRST && tpm_handle <= TPM2_NV_INDEX_LAST) {
144 r = Esys_NV_ReadPublic_Async(esys_context, esys_handle, shandle1,
145 shandle2, shandle3);
146 goto_if_error(r, "Error NV_ReadPublic", error_cleanup);
147
148 } else if(tpm_handle >> TPM2_HR_SHIFT == TPM2_HT_LOADED_SESSION
149 || tpm_handle >> TPM2_HR_SHIFT == TPM2_HT_SAVED_SESSION) {
150 // no readpublic call for loaded or saved sessions.
151 r = TSS2_RC_SUCCESS;
152 } else {
153 r = Esys_ReadPublic_Async(esys_context, esys_handle, shandle1, shandle2,
154 shandle3);
155 goto_if_error(r, "Error ReadPublic", error_cleanup);
156 }
157 return r;
158 error_cleanup:
159 Esys_TR_Close(esys_context, &esys_handle);
160 return r;
161 }
162
163 /** Finish asynchronous creation of an ESYS_TR object from TPM metadata.
164 *
165 * This function finishes the asynchronous retrieval of metadata from the TPM in
166 * order to create a new ESYS_TR object.
167 * @param esys_context [in,out] The ESYS_CONTEXT
168 * @param object [out] The newly created ESYS_TR metadata object.
169 * @retval TSS2_RC_SUCCESS on success
170 * @retval ESYS_RC_SUCCESS if the function call was a success.
171 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
172 * pointers or required output handle references are NULL.
173 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
174 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
175 * internal operations or return parameters.
176 * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
177 * operation already pending.
178 * @retval TSS2_ESYS_RC_TRY_AGAIN: if the timeout counter expires before the
179 * TPM response is received.
180 * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
181 * at least contain the tag, response length, and response code.
182 * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
183 * @retval TSS2_RCs produced by lower layers of the software stack may be
184 * returned to the caller unaltered unless handled internally.
185 */
186 TSS2_RC
Esys_TR_FromTPMPublic_Finish(ESYS_CONTEXT * esys_context,ESYS_TR * object)187 Esys_TR_FromTPMPublic_Finish(ESYS_CONTEXT * esys_context, ESYS_TR * object)
188 {
189 TSS2_RC r = TSS2_RC_SUCCESS;
190 ESYS_TR objectHandle = ESYS_TR_NONE;
191 RSRC_NODE_T *objectHandleNode;
192
193 _ESYS_ASSERT_NON_NULL(esys_context);
194
195 objectHandle = esys_context->esys_handle;
196
197 r = esys_GetResourceObject(esys_context, objectHandle, &objectHandleNode);
198 goto_if_error(r, "get resource", error_cleanup);
199
200 if (objectHandleNode->rsrc.handle >= TPM2_NV_INDEX_FIRST
201 && objectHandleNode->rsrc.handle <= TPM2_NV_INDEX_LAST) {
202 TPM2B_NV_PUBLIC *nvPublic;
203 TPM2B_NAME *nvName;
204 r = Esys_NV_ReadPublic_Finish(esys_context, &nvPublic, &nvName);
205 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
206 LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
207 " => resubmitting command", r);
208 return r;
209 }
210 goto_if_error(r, "Error NV_ReadPublic", error_cleanup);
211
212 objectHandleNode->rsrc.rsrcType = IESYSC_NV_RSRC;
213 objectHandleNode->rsrc.name = *nvName;
214 objectHandleNode->rsrc.misc.rsrc_nv_pub = *nvPublic;
215 SAFE_FREE(nvPublic);
216 SAFE_FREE(nvName);
217 } else if(objectHandleNode->rsrc.handle >> TPM2_HR_SHIFT == TPM2_HT_LOADED_SESSION
218 || objectHandleNode->rsrc.handle >> TPM2_HR_SHIFT == TPM2_HT_SAVED_SESSION) {
219 objectHandleNode->rsrc.rsrcType = IESYSC_DEGRADED_SESSION_RSRC;
220 } else {
221 TPM2B_PUBLIC *public;
222 TPM2B_NAME *name = NULL;
223 TPM2B_NAME *qualifiedName = NULL;
224 r = Esys_ReadPublic_Finish(esys_context, &public, &name,
225 &qualifiedName);
226 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
227 LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
228 " => resubmitting command", r);
229 return r;
230 }
231 goto_if_error(r, "Error ReadPublic", error_cleanup);
232
233 objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
234 objectHandleNode->rsrc.name = *name;
235 objectHandleNode->rsrc.misc.rsrc_key_pub = *public;
236 SAFE_FREE(public);
237 SAFE_FREE(name);
238 SAFE_FREE(qualifiedName);
239 }
240 *object = objectHandle;
241 return TSS2_RC_SUCCESS;
242
243 error_cleanup:
244 Esys_TR_Close(esys_context, &objectHandle);
245 return r;
246 }
247
248 /** Creation of an ESYS_TR object from TPM metadata.
249 *
250 * This function can be used to create ESYS_TR object for Tpm Resources that are
251 * not created or loaded (e.g. using ESys_CreatePrimary or ESys_Load) but
252 * pre-exist inside the TPM. Examples are NV-Indices or persistent object.
253 *
254 * Note: For PCRs and hierarchies, please use the global ESYS_TR identifiers.
255 * Note: If a session is provided the TPM is queried for the metadata twice.
256 * First without a session to retrieve some metadata then with the session where
257 * this metadata is used in the session HMAC calculation and thereby verified.
258 *
259 * Since man in the middle attacks should be prevented as much as possible it is
260 * recommended to pass a session.
261 * @param esys_context [in,out] The ESYS_CONTEXT
262 * @param tpm_handle [in] The handle of the TPM object to represent as ESYS_TR.
263 * @param shandle1 [in,out] A session for securing the TPM command (optional).
264 * @param shandle2 [in,out] A session for securing the TPM command (optional).
265 * @param shandle3 [in,out] A session for securing the TPM command (optional).
266 * @param object [out] The newly created ESYS_TR metadata object.
267 * @retval TSS2_RC_SUCCESS on success
268 * @retval ESYS_RC_SUCCESS if the function call was a success.
269 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
270 * pointers or required output handle references are NULL.
271 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
272 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
273 * internal operations or return parameters.
274 * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
275 * operation already pending.
276 * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
277 * at least contain the tag, response length, and response code.
278 * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
279 * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
280 * the 'decrypt' attribute bit set.
281 * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
282 * the 'encrypt' attribute bit set.
283 * @retval TSS2_ESYS_RC_NO_DECRYPT_PARAM: if one of the sessions has the
284 * 'decrypt' attribute set and the command does not support encryption
285 * of the first command parameter.
286 * @retval TSS2_RCs produced by lower layers of the software stack may be
287 * returned to the caller unaltered unless handled internally.
288 */
289 TSS2_RC
Esys_TR_FromTPMPublic(ESYS_CONTEXT * esys_context,TPM2_HANDLE tpm_handle,ESYS_TR shandle1,ESYS_TR shandle2,ESYS_TR shandle3,ESYS_TR * object)290 Esys_TR_FromTPMPublic(ESYS_CONTEXT * esys_context,
291 TPM2_HANDLE tpm_handle,
292 ESYS_TR shandle1,
293 ESYS_TR shandle2, ESYS_TR shandle3, ESYS_TR * object)
294 {
295 TSS2_RC r;
296
297 _ESYS_ASSERT_NON_NULL(esys_context);
298 r = Esys_TR_FromTPMPublic_Async(esys_context, tpm_handle,
299 shandle1, shandle2, shandle3);
300 return_if_error(r, "Error TR FromTPMPublic");
301
302 /* Set the timeout to indefinite for now, since we want _Finish to block */
303 int32_t timeouttmp = esys_context->timeout;
304 esys_context->timeout = -1;
305 /*
306 * Now we call the finish function, until return code is not equal to
307 * from TSS2_BASE_RC_TRY_AGAIN.
308 * Note that the finish function may return TSS2_RC_TRY_AGAIN, even if we
309 * have set the timeout to -1. This occurs for example if the TPM requests
310 * a retransmission of the command via TPM2_RC_YIELDED.
311 */
312 do {
313 r = Esys_TR_FromTPMPublic_Finish(esys_context, object);
314 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
315 LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
316 " => resubmitting command", r);
317 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
318
319 /* Restore the timeout value to the original value */
320 esys_context->timeout = timeouttmp;
321 return_if_error(r, "Error TR FromTPMPublic");
322
323 return r;
324 }
325
326 /** Close an ESYS_TR without removing it from the TPM.
327 *
328 * This function deletes an ESYS_TR object from an ESYS_CONTEXT without deleting
329 * it from the TPM. This is useful for NV-Indices or persistent keys, after
330 * Esys_TR_Serialize has been called. Transient objects should be deleted using
331 * Esys_FlushContext.
332 * @param esys_context [in,out] The ESYS_CONTEXT
333 * @param object [out] ESYS_TR metadata object to be deleted from ESYS_CONTEXT.
334 * @retval TSS2_RC_SUCCESS on Success.
335 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
336 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
337 * ESYS_CONTEXT.
338 */
339 TSS2_RC
Esys_TR_Close(ESYS_CONTEXT * esys_context,ESYS_TR * object)340 Esys_TR_Close(ESYS_CONTEXT * esys_context, ESYS_TR * object)
341 {
342 RSRC_NODE_T *node;
343 RSRC_NODE_T **update_ptr;
344
345 _ESYS_ASSERT_NON_NULL(esys_context);
346 for (node = esys_context->rsrc_list,
347 update_ptr = &esys_context->rsrc_list;
348 node != NULL;
349 update_ptr = &node->next, node = node->next) {
350 if (node->esys_handle == *object) {
351 *update_ptr = node->next;
352 SAFE_FREE(node);
353 *object = ESYS_TR_NONE;
354 return TSS2_RC_SUCCESS;
355 }
356 }
357 LOG_ERROR("Error: Esys handle does not exist (%x).", TSS2_ESYS_RC_BAD_TR);
358 return TSS2_ESYS_RC_BAD_TR;
359 }
360
361 /** Set the authorization value of an ESYS_TR.
362 *
363 * Authorization values are associated with ESYS_TR Tpm Resource object. They
364 * are then picked up whenever an authorization is needed.
365 *
366 * Note: The authorization value is not stored in the metadata during
367 * Esys_TR_Serialize. Therefor Esys_TR_SetAuth needs to be called again after
368 * every Esys_TR_Deserialize.
369 * @param esys_context [in,out] The ESYS_CONTEXT.
370 * @param esys_handle [in,out] The ESYS_TR for which to set the auth value.
371 * @param authValue [in] The auth value to set for the ESYS_TR or NULL to zero
372 * the auth.
373 * @retval TSS2_RC_SUCCESS on Success.
374 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
375 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
376 * ESYS_CONTEXT.
377 */
378 TSS2_RC
Esys_TR_SetAuth(ESYS_CONTEXT * esys_context,ESYS_TR esys_handle,TPM2B_AUTH const * authValue)379 Esys_TR_SetAuth(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
380 TPM2B_AUTH const *authValue)
381 {
382 RSRC_NODE_T *esys_object;
383 TSS2_RC r;
384 _ESYS_ASSERT_NON_NULL(esys_context);
385 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
386 if (r != TPM2_RC_SUCCESS)
387 return r;
388
389 if (authValue == NULL) {
390 esys_object->auth.size = 0;
391 } else {
392 if (authValue->size > sizeof(TPMU_HA)) {
393 return_error(TSS2_ESYS_RC_BAD_SIZE, "Bad size for auth value.");
394 }
395 esys_object->auth = *authValue;
396 }
397 return TSS2_RC_SUCCESS;
398 }
399
400 /** Retrieve the TPM public name of an Esys_TR object.
401 *
402 * Some operations (i.e. Esys_PolicyNameHash) require the name of a TPM object
403 * to be passed. Esys_TR_GetName provides this name to the caller.
404 * @param esys_context [in,out] The ESYS_CONTEXT.
405 * @param esys_handle [in,out] The ESYS_TR for which to retrieve the name.
406 * @param name [out] The name of the object (caller-allocated; use free()).
407 * @retval TSS2_RC_SUCCESS on Success.
408 * @retval TSS2_ESYS_RC_MEMORY if needed memory can't be allocated.
409 * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
410 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
411 * @retval TSS2_SYS_RC_* for SAPI errors.
412 */
413 TSS2_RC
Esys_TR_GetName(ESYS_CONTEXT * esys_context,ESYS_TR esys_handle,TPM2B_NAME ** name)414 Esys_TR_GetName(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
415 TPM2B_NAME ** name)
416 {
417 RSRC_NODE_T *esys_object;
418 TSS2_RC r;
419 _ESYS_ASSERT_NON_NULL(esys_context);
420
421 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
422 return_if_error(r, "Object not found");
423
424 *name = malloc(sizeof(TPM2B_NAME));
425 if (*name == NULL) {
426 LOG_ERROR("Error: out of memory");
427 return TSS2_ESYS_RC_MEMORY;
428 }
429 if (esys_object->rsrc.rsrcType == IESYSC_KEY_RSRC) {
430 r = iesys_get_name(&esys_object->rsrc.misc.rsrc_key_pub, *name);
431 goto_if_error(r, "Error get name", error_cleanup);
432
433 } else {
434 if (esys_object->rsrc.rsrcType == IESYSC_NV_RSRC) {
435 r = iesys_nv_get_name(&esys_object->rsrc.misc.rsrc_nv_pub, *name);
436 goto_if_error(r, "Error get name", error_cleanup);
437
438 } else {
439 size_t offset = 0;
440 r = Tss2_MU_TPM2_HANDLE_Marshal(esys_object->rsrc.handle,
441 &(*name)->name[0], sizeof(TPM2_HANDLE),
442 &offset);
443 goto_if_error(r, "Error get name", error_cleanup);
444 (*name)->size = offset;
445 }
446 }
447 return r;
448 error_cleanup:
449 SAFE_FREE(*name);
450 return r;
451 }
452
453
454 /** Retrieve the Session Attributes of the ESYS_TR session.
455 *
456 * Sessions possess attributes, such as whether they shall continue of be
457 * flushed after the next command, or whether they are used to encrypt
458 * parameters.
459 * Note: this function only applies to ESYS_TR objects that represent sessions.
460 * @param esys_context [in,out] The ESYS_CONTEXT.
461 * @param esys_handle [in,out] The ESYS_TR of the session.
462 * @param flags [out] The attributes of the session.
463 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
464 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
465 * ESYS_CONTEXT or ESYS_TR object is not a session object.
466 */
467 TSS2_RC
Esys_TRSess_GetAttributes(ESYS_CONTEXT * esys_context,ESYS_TR esys_handle,TPMA_SESSION * flags)468 Esys_TRSess_GetAttributes(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
469 TPMA_SESSION * flags)
470 {
471 RSRC_NODE_T *esys_object;
472
473 _ESYS_ASSERT_NON_NULL(esys_context);
474 TSS2_RC r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
475 return_if_error(r, "Object not found");
476
477 if (esys_object->rsrc.rsrcType != IESYSC_SESSION_RSRC)
478 return_error(TSS2_ESYS_RC_BAD_TR, "Object is not a session object");
479 *flags = esys_object->rsrc.misc.rsrc_session.sessionAttributes;
480 return TSS2_RC_SUCCESS;
481 }
482
483 /** Set session attributes
484 *
485 * Set or unset a session's attributes according to the provided flags and mask.
486 * @verbatim new_attributes = old_attributes & ~mask | flags & mask @endverbatim
487 * Note: this function only applies to ESYS_TR objects that represent sessions.
488 * @param esys_context [in,out] The ESYS_CONTEXT.
489 * @param esys_handle [in,out] The ESYS_TR of the session.
490 * @param flags [in] The flags to be set or unset for the session.
491 * @param mask [in] The mask for the flags to be set or unset.
492 * @retval TSS2_RC_SUCCESS on Success.
493 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
494 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
495 * ESYS_CONTEXT or ESYS_TR object is not a session object.
496 */
497 TSS2_RC
Esys_TRSess_SetAttributes(ESYS_CONTEXT * esys_context,ESYS_TR esys_handle,TPMA_SESSION flags,TPMA_SESSION mask)498 Esys_TRSess_SetAttributes(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
499 TPMA_SESSION flags, TPMA_SESSION mask)
500 {
501 RSRC_NODE_T *esys_object;
502
503 _ESYS_ASSERT_NON_NULL(esys_context);
504 TSS2_RC r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
505 return_if_error(r, "Object not found");
506
507 return_if_null(esys_object, "Object not found", TSS2_ESYS_RC_BAD_VALUE);
508
509 if (esys_object->rsrc.rsrcType != IESYSC_SESSION_RSRC)
510 return_error(TSS2_ESYS_RC_BAD_TR, "Object is not a session object");
511 esys_object->rsrc.misc.rsrc_session.sessionAttributes =
512 (esys_object->rsrc.misc.rsrc_session.
513 sessionAttributes & ~mask) | (flags & mask);
514 return TSS2_RC_SUCCESS;
515 }
516
517 /** Retrieve the TPM nonce of an Esys_TR session object.
518 *
519 * Some operations (i.e. Esys_PolicySigned) require the nonce returned by the
520 * TPM during Esys_StartauthSession. This function provides this nonce to the
521 * caller.
522 * @param esys_context [in,out] The ESYS_CONTEXT.
523 * @param esys_handle [in,out] The ESYS_TRsess for which to retrieve the nonce.
524 * @param nonceTPM [out] The nonce of the object (callee-allocated; use free()).
525 * @retval TSS2_RC_SUCCESS on Success.
526 * @retval TSS2_ESYS_RC_MEMORY if needed memory can't be allocated.
527 * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
528 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
529 * @retval TSS2_SYS_RC_* for SAPI errors.
530 */
531 TSS2_RC
Esys_TRSess_GetNonceTPM(ESYS_CONTEXT * esys_context,ESYS_TR esys_handle,TPM2B_NONCE ** nonceTPM)532 Esys_TRSess_GetNonceTPM(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
533 TPM2B_NONCE **nonceTPM)
534 {
535 RSRC_NODE_T *esys_object;
536 TSS2_RC r;
537 _ESYS_ASSERT_NON_NULL(esys_context);
538 _ESYS_ASSERT_NON_NULL(nonceTPM);
539
540 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
541 return_if_error(r, "Object not found");
542
543 *nonceTPM = calloc(1, sizeof(**nonceTPM));
544 if (*nonceTPM == NULL) {
545 LOG_ERROR("Error: out of memory");
546 return TSS2_ESYS_RC_MEMORY;
547 }
548 if (esys_object->rsrc.rsrcType != IESYSC_SESSION_RSRC) {
549 goto_error(r, TSS2_ESYS_RC_BAD_TR,
550 "NonceTPM for non-session object requested.",
551 error_cleanup);
552
553 }
554 **nonceTPM = esys_object->rsrc.misc.rsrc_session.nonceTPM;
555
556 return r;
557 error_cleanup:
558 SAFE_FREE(*nonceTPM);
559 return r;
560 }
561
562 /** Retrieves the associated TPM2_HANDLE from an ESYS_TR object.
563 *
564 * Retrieves the TPM2_HANDLE for an associated ESYS_TR object for use with the
565 * SAPI API or comparisons against raw TPM2_HANDLES from commands like
566 * TPM2_GetCapability or use of various handle bitwise comparisons. For example
567 * the mask TPM2_HR_NV_INDEX.
568 *
569 * @param esys_context [in,out] The ESYS_CONTEXT.
570 * @param esys_handle [in] The ESYS_TR object to retrieve the TPM2_HANDLE from.
571 * @param tpm_handle [out] The TPM2_HANDLE retrieved from the ESYS_TR object.
572 * @retval TSS2_RC_SUCCESS on Success.
573 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
574 * ESYS_CONTEXT or is ESYS_TR_NONE.
575 * @retval TSS2_ESYS_RC_BAD_VALUE if an unknown handle < ESYS_TR_MIN_OBJECT is
576 * passed.
577 * @retval TSS2_ESYS_RC_BAD_REFERENCE For invalid ESYS_CONTEXT.
578 */
579 TSS2_RC
Esys_TR_GetTpmHandle(ESYS_CONTEXT * esys_context,ESYS_TR esys_handle,TPM2_HANDLE * tpm_handle)580 Esys_TR_GetTpmHandle(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
581 TPM2_HANDLE * tpm_handle)
582 {
583 TSS2_RC r = TSS2_RC_SUCCESS;
584 RSRC_NODE_T *esys_object;
585
586 _ESYS_ASSERT_NON_NULL(esys_context);
587 _ESYS_ASSERT_NON_NULL(tpm_handle);
588
589 if (esys_handle == ESYS_TR_NONE) {
590 return TSS2_ESYS_RC_BAD_TR;
591 }
592
593 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
594 return_if_error(r, "Get resource object");
595
596 *tpm_handle = esys_object->rsrc.handle;
597
598 return TSS2_RC_SUCCESS;
599 };
600
601 /** Retrieve whether auth value is required from a Esys_TR session object.
602 *
603 * This function can be used to determin whether PoliyPassword or
604 * PlolicyAuthValue are used for a session.
605 * @param esys_context [in,out] The ESYS_CONTEXT.
606 * @param esys_handle [in,out] The ESYS_TRsess for which to retrieve the nonce.
607 * @param neeed [out] The boolean indicating whether auth value will be
608 * needed.
609 * @retval TSS2_RC_SUCCESS on Success.
610 * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
611 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
612 * @retval TSS2_SYS_RC_* for SAPI errors.
613 */
614 TSS2_RC
Esys_TRSess_GetAuthRequired(ESYS_CONTEXT * esys_context,ESYS_TR esys_handle,TPMI_YES_NO * auth_needed)615 Esys_TRSess_GetAuthRequired(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
616 TPMI_YES_NO *auth_needed)
617 {
618 RSRC_NODE_T *esys_object;
619 TSS2_RC r;
620 _ESYS_ASSERT_NON_NULL(esys_context);
621
622 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
623 return_if_error(r, "Object not found");
624
625 if (esys_object->rsrc.rsrcType != IESYSC_SESSION_RSRC) {
626 return_if_error(TSS2_ESYS_RC_BAD_TR,
627 "Auth value needed for non-session object requested.");
628 }
629
630 if (esys_object->rsrc.misc.rsrc_session.type_policy_session == POLICY_AUTH ||
631 esys_object->rsrc.misc.rsrc_session.type_policy_session == POLICY_PASSWORD)
632 *auth_needed = TPM2_YES;
633 else
634 *auth_needed = TPM2_NO;
635 return TSS2_RC_SUCCESS;
636
637 }
638