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