blob: fd57e74d2c5a00f5d5b7706dff0d50beced7cfb5 [file] [log] [blame]
Peter Huewed5a36f62018-06-12 00:59:26 +02001/* SPDX-License-Identifier: BSD-2 */
Juergen Reppad4c2302018-02-27 23:32:51 +01002/*******************************************************************************
3 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
4 * All rights reserved.
Juergen Reppad4c2302018-02-27 23:32:51 +01005 ******************************************************************************/
6
Philip Tricca910f17c2018-03-15 12:38:37 -07007#include "tss2_mu.h"
8#include "tss2_sys.h"
Philip Tricca8ffd3c42018-03-09 16:27:24 -08009#include "tss2_esys.h"
Juergen Repped6e6e22018-03-19 17:34:32 +010010
11#include "esys_types.h"
Juergen Reppad4c2302018-02-27 23:32:51 +010012#include "esys_iutil.h"
13#include "esys_mu.h"
Juergen Reppad4c2302018-02-27 23:32:51 +010014#define LOGMODULE esys
Philip Triccaa7c51ce2018-03-10 18:28:25 -080015#include "util/log.h"
Juergen Reppad4c2302018-02-27 23:32:51 +010016
Juergen Reppadd438d2018-04-09 10:00:19 +020017/** Store command parameters inside the ESYS_CONTEXT for use during _Finish */
Juergen Reppad4c2302018-02-27 23:32:51 +010018static void store_input_parameters (
19 ESYS_CONTEXT *esysContext,
20 ESYS_TR keyHandle,
21 const TPM2B_MAX_BUFFER *inData,
22 TPMI_YES_NO decrypt,
23 TPMI_ALG_SYM_MODE mode,
24 const TPM2B_IV *ivIn)
25{
26 esysContext->in.EncryptDecrypt2.keyHandle = keyHandle;
27 esysContext->in.EncryptDecrypt2.decrypt = decrypt;
28 esysContext->in.EncryptDecrypt2.mode = mode;
29 if (inData == NULL) {
30 esysContext->in.EncryptDecrypt2.inData = NULL;
31 } else {
32 esysContext->in.EncryptDecrypt2.inDataData = *inData;
33 esysContext->in.EncryptDecrypt2.inData =
34 &esysContext->in.EncryptDecrypt2.inDataData;
35 }
36 if (ivIn == NULL) {
37 esysContext->in.EncryptDecrypt2.ivIn = NULL;
38 } else {
39 esysContext->in.EncryptDecrypt2.ivInData = *ivIn;
40 esysContext->in.EncryptDecrypt2.ivIn =
41 &esysContext->in.EncryptDecrypt2.ivInData;
42 }
43}
44
45/** One-Call function for TPM2_EncryptDecrypt2
46 *
47 * This function invokes the TPM2_EncryptDecrypt2 command in a one-call
48 * variant. This means the function will block until the TPM response is
49 * available. All input parameters are const. The memory for non-simple output
50 * parameters is allocated by the function implementation.
51 *
52 * @param[in,out] esysContext The ESYS_CONTEXT.
Juergen Reppf7e5bd32018-04-26 11:11:32 +020053 * @param[in] keyHandle The symmetric key used for the operation.
54 * @param[in] shandle1 Session handle for authorization of keyHandle
55 * @param[in] shandle2 Second session handle.
56 * @param[in] shandle3 Third session handle.
57 * @param[in] inData The data to be encrypted/decrypted.
58 * @param[in] decrypt If YES, then the operation is decryption; if NO, the
59 * operation is encryption.
60 * @param[in] mode Symmetric mode.
61 * @param[in] ivIn An initial value as required by the algorithm.
62 * @param[out] outData Encrypted or decrypted output.
63 * (callee-allocated)
64 * @param[out] ivOut Chaining value to use for IV in next round.
65 * (callee-allocated)
Juergen Reppc3cf4b62018-08-22 15:27:59 +020066 * @retval TSS2_RC_SUCCESS if the function call was a success.
Juergen Reppf7e5bd32018-04-26 11:11:32 +020067 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
68 * pointers or required output handle references are NULL.
69 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
70 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
71 * internal operations or return parameters.
72 * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
73 * operation already pending.
74 * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
75 * at least contain the tag, response length, and response code.
76 * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
Juergen Reppc3cf4b62018-08-22 15:27:59 +020077 * @retval TSS2_ESYS_RC_RSP_AUTH_FAILED: if the response HMAC from the TPM
78 did not verify.
Juergen Reppf7e5bd32018-04-26 11:11:32 +020079 * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
80 * the 'decrypt' attribute bit set.
81 * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
82 * the 'encrypt' attribute bit set.
Juergen Repp66989272018-09-04 11:13:06 +020083 * @retval TSS2_ESYS_RC_BAD_TR: if any of the ESYS_TR objects are unknown
84 * to the ESYS_CONTEXT or are of the wrong type or if required
85 * ESYS_TR objects are ESYS_TR_NONE.
Juergen Reppf7e5bd32018-04-26 11:11:32 +020086 * @retval TSS2_RCs produced by lower layers of the software stack may be
87 * returned to the caller unaltered unless handled internally.
Juergen Reppad4c2302018-02-27 23:32:51 +010088 */
89TSS2_RC
90Esys_EncryptDecrypt2(
91 ESYS_CONTEXT *esysContext,
92 ESYS_TR keyHandle,
93 ESYS_TR shandle1,
94 ESYS_TR shandle2,
95 ESYS_TR shandle3,
96 const TPM2B_MAX_BUFFER *inData,
97 TPMI_YES_NO decrypt,
98 TPMI_ALG_SYM_MODE mode,
99 const TPM2B_IV *ivIn,
100 TPM2B_MAX_BUFFER **outData,
101 TPM2B_IV **ivOut)
102{
Juergen Repp3b7b41b2018-03-19 15:58:04 +0100103 TSS2_RC r;
Juergen Reppad4c2302018-02-27 23:32:51 +0100104
Juergen Repp66989272018-09-04 11:13:06 +0200105 r = Esys_EncryptDecrypt2_Async(esysContext, keyHandle, shandle1, shandle2,
106 shandle3, inData, decrypt, mode, ivIn);
Juergen Reppad4c2302018-02-27 23:32:51 +0100107 return_if_error(r, "Error in async function");
108
Juergen Reppadd438d2018-04-09 10:00:19 +0200109 /* Set the timeout to indefinite for now, since we want _Finish to block */
Juergen Reppad4c2302018-02-27 23:32:51 +0100110 int32_t timeouttmp = esysContext->timeout;
111 esysContext->timeout = -1;
112 /*
113 * Now we call the finish function, until return code is not equal to
114 * from TSS2_BASE_RC_TRY_AGAIN.
115 * Note that the finish function may return TSS2_RC_TRY_AGAIN, even if we
116 * have set the timeout to -1. This occurs for example if the TPM requests
117 * a retransmission of the command via TPM2_RC_YIELDED.
118 */
119 do {
Juergen Repp66989272018-09-04 11:13:06 +0200120 r = Esys_EncryptDecrypt2_Finish(esysContext, outData, ivOut);
Juergen Reppad4c2302018-02-27 23:32:51 +0100121 /* This is just debug information about the reattempt to finish the
122 command */
123 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
124 LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32
125 " => resubmitting command", r);
126 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
127
128 /* Restore the timeout value to the original value */
129 esysContext->timeout = timeouttmp;
130 return_if_error(r, "Esys Finish");
131
132 return TSS2_RC_SUCCESS;
133}
134
135/** Asynchronous function for TPM2_EncryptDecrypt2
136 *
137 * This function invokes the TPM2_EncryptDecrypt2 command in a asynchronous
138 * variant. This means the function will return as soon as the command has been
139 * sent downwards the stack to the TPM. All input parameters are const.
Juergen Reppadd438d2018-04-09 10:00:19 +0200140 * In order to retrieve the TPM's response call Esys_EncryptDecrypt2_Finish.
Juergen Reppad4c2302018-02-27 23:32:51 +0100141 *
142 * @param[in,out] esysContext The ESYS_CONTEXT.
Juergen Reppf7e5bd32018-04-26 11:11:32 +0200143 * @param[in] keyHandle The symmetric key used for the operation.
144 * @param[in] shandle1 Session handle for authorization of keyHandle
145 * @param[in] shandle2 Second session handle.
146 * @param[in] shandle3 Third session handle.
147 * @param[in] inData The data to be encrypted/decrypted.
148 * @param[in] decrypt If YES, then the operation is decryption; if NO, the
149 * operation is encryption.
150 * @param[in] mode Symmetric mode.
151 * @param[in] ivIn An initial value as required by the algorithm.
152 * @retval ESYS_RC_SUCCESS if the function call was a success.
153 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
154 * pointers or required output handle references are NULL.
155 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
156 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
157 * internal operations or return parameters.
158 * @retval TSS2_RCs produced by lower layers of the software stack may be
159 returned to the caller unaltered unless handled internally.
160 * @retval TSS2_ESYS_RC_MULTIPLE_DECRYPT_SESSIONS: if more than one session has
161 * the 'decrypt' attribute bit set.
162 * @retval TSS2_ESYS_RC_MULTIPLE_ENCRYPT_SESSIONS: if more than one session has
163 * the 'encrypt' attribute bit set.
Juergen Repp66989272018-09-04 11:13:06 +0200164 * @retval TSS2_ESYS_RC_BAD_TR: if any of the ESYS_TR objects are unknown
165 * to the ESYS_CONTEXT or are of the wrong type or if required
166 * ESYS_TR objects are ESYS_TR_NONE.
Juergen Reppad4c2302018-02-27 23:32:51 +0100167 */
168TSS2_RC
Juergen Reppadd438d2018-04-09 10:00:19 +0200169Esys_EncryptDecrypt2_Async(
Juergen Reppad4c2302018-02-27 23:32:51 +0100170 ESYS_CONTEXT *esysContext,
171 ESYS_TR keyHandle,
172 ESYS_TR shandle1,
173 ESYS_TR shandle2,
174 ESYS_TR shandle3,
175 const TPM2B_MAX_BUFFER *inData,
176 TPMI_YES_NO decrypt,
177 TPMI_ALG_SYM_MODE mode,
178 const TPM2B_IV *ivIn)
179{
Juergen Repp3b7b41b2018-03-19 15:58:04 +0100180 TSS2_RC r;
Andreas Fuchs15bbb672018-03-27 13:21:13 +0200181 LOG_TRACE("context=%p, keyHandle=%"PRIx32 ", inData=%p,"
182 "decrypt=%02"PRIx8", mode=%04"PRIx16", ivIn=%p",
183 esysContext, keyHandle, inData, decrypt, mode,
184 ivIn);
Andreas Fuchsc5a73eb2018-03-19 16:01:00 +0100185 TSS2L_SYS_AUTH_COMMAND auths;
Juergen Reppad4c2302018-02-27 23:32:51 +0100186 RSRC_NODE_T *keyHandleNode;
187
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100188 /* Check context, sequence correctness and set state to error for now */
Juergen Reppad4c2302018-02-27 23:32:51 +0100189 if (esysContext == NULL) {
190 LOG_ERROR("esyscontext is NULL.");
191 return TSS2_ESYS_RC_BAD_REFERENCE;
192 }
193 r = iesys_check_sequence_async(esysContext);
194 if (r != TSS2_RC_SUCCESS)
195 return r;
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100196 esysContext->state = _ESYS_STATE_INTERNALERROR;
Juergen Reppad4c2302018-02-27 23:32:51 +0100197
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100198 /* Check and store input parameters */
dantpmf6ef2472018-04-06 15:21:59 -0700199 r = check_session_feasibility(shandle1, shandle2, shandle3, 1);
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100200 return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
Juergen Repp66989272018-09-04 11:13:06 +0200201 store_input_parameters(esysContext, keyHandle, inData, decrypt, mode, ivIn);
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100202
203 /* Retrieve the metadata objects for provided handles */
Juergen Reppad4c2302018-02-27 23:32:51 +0100204 r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100205 return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
206
207 /* Initial invocation of SAPI to prepare the command buffer with parameters */
Juergen Reppad4c2302018-02-27 23:32:51 +0100208 r = Tss2_Sys_EncryptDecrypt2_Prepare(esysContext->sys,
Juergen Repp66989272018-09-04 11:13:06 +0200209 (keyHandleNode == NULL) ? TPM2_RH_NULL
210 : keyHandleNode->rsrc.handle, inData,
211 decrypt, mode, ivIn);
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100212 return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
Juergen Reppad4c2302018-02-27 23:32:51 +0100213
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100214 /* Calculate the cpHash Values */
215 r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
216 return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
Juergen Reppad4c2302018-02-27 23:32:51 +0100217 iesys_compute_session_value(esysContext->session_tab[0],
218 &keyHandleNode->rsrc.name, &keyHandleNode->auth);
219 iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
220 iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
Juergen Reppad4c2302018-02-27 23:32:51 +0100221
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100222 /* Generate the auth values and set them in the SAPI command buffer */
223 r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
Juergen Repp66989272018-09-04 11:13:06 +0200224 return_state_if_error(r, _ESYS_STATE_INIT,
225 "Error in computation of auth values");
226
Juergen Reppad4c2302018-02-27 23:32:51 +0100227 esysContext->authsCount = auths.count;
228 r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100229 return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
Juergen Reppad4c2302018-02-27 23:32:51 +0100230
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100231 /* Trigger execution and finish the async invocation */
Juergen Reppad4c2302018-02-27 23:32:51 +0100232 r = Tss2_Sys_ExecuteAsync(esysContext->sys);
Juergen Repp66989272018-09-04 11:13:06 +0200233 return_state_if_error(r, _ESYS_STATE_INTERNALERROR,
234 "Finish (Execute Async)");
Juergen Reppad4c2302018-02-27 23:32:51 +0100235
236 esysContext->state = _ESYS_STATE_SENT;
237
238 return r;
239}
240
241/** Asynchronous finish function for TPM2_EncryptDecrypt2
242 *
243 * This function returns the results of a TPM2_EncryptDecrypt2 command
Juergen Reppadd438d2018-04-09 10:00:19 +0200244 * invoked via Esys_EncryptDecrypt2_Finish. All non-simple output parameters
Juergen Reppad4c2302018-02-27 23:32:51 +0100245 * are allocated by the function's implementation. NULL can be passed for every
246 * output parameter if the value is not required.
247 *
248 * @param[in,out] esysContext The ESYS_CONTEXT.
Juergen Reppf7e5bd32018-04-26 11:11:32 +0200249 * @param[out] outData Encrypted or decrypted output.
250 * (callee-allocated)
251 * @param[out] ivOut Chaining value to use for IV in next round.
252 * (callee-allocated)
Juergen Reppad4c2302018-02-27 23:32:51 +0100253 * @retval TSS2_RC_SUCCESS on success
Juergen Reppf7e5bd32018-04-26 11:11:32 +0200254 * @retval ESYS_RC_SUCCESS if the function call was a success.
255 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext or required input
256 * pointers or required output handle references are NULL.
257 * @retval TSS2_ESYS_RC_BAD_CONTEXT: if esysContext corruption is detected.
258 * @retval TSS2_ESYS_RC_MEMORY: if the ESAPI cannot allocate enough memory for
259 * internal operations or return parameters.
260 * @retval TSS2_ESYS_RC_BAD_SEQUENCE: if the context has an asynchronous
261 * operation already pending.
262 * @retval TSS2_ESYS_RC_TRY_AGAIN: if the timeout counter expires before the
263 * TPM response is received.
264 * @retval TSS2_ESYS_RC_INSUFFICIENT_RESPONSE: if the TPM's response does not
Juergen Reppc3cf4b62018-08-22 15:27:59 +0200265 * at least contain the tag, response length, and response code.
266 * @retval TSS2_ESYS_RC_RSP_AUTH_FAILED: if the response HMAC from the TPM did
267 * not verify.
Juergen Reppf7e5bd32018-04-26 11:11:32 +0200268 * @retval TSS2_ESYS_RC_MALFORMED_RESPONSE: if the TPM's response is corrupted.
269 * @retval TSS2_RCs produced by lower layers of the software stack may be
270 * returned to the caller unaltered unless handled internally.
Juergen Reppad4c2302018-02-27 23:32:51 +0100271 */
272TSS2_RC
Juergen Reppadd438d2018-04-09 10:00:19 +0200273Esys_EncryptDecrypt2_Finish(
Juergen Reppad4c2302018-02-27 23:32:51 +0100274 ESYS_CONTEXT *esysContext,
275 TPM2B_MAX_BUFFER **outData,
276 TPM2B_IV **ivOut)
277{
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100278 TSS2_RC r;
Andreas Fuchs15bbb672018-03-27 13:21:13 +0200279 LOG_TRACE("context=%p, outData=%p, ivOut=%p",
280 esysContext, outData, ivOut);
281
Juergen Reppad4c2302018-02-27 23:32:51 +0100282 if (esysContext == NULL) {
283 LOG_ERROR("esyscontext is NULL.");
284 return TSS2_ESYS_RC_BAD_REFERENCE;
285 }
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100286
287 /* Check for correct sequence and set sequence to irregular for now */
Juergen Reppad4c2302018-02-27 23:32:51 +0100288 if (esysContext->state != _ESYS_STATE_SENT) {
289 LOG_ERROR("Esys called in bad sequence.");
290 return TSS2_ESYS_RC_BAD_SEQUENCE;
291 }
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100292 esysContext->state = _ESYS_STATE_INTERNALERROR;
293
294 /* Allocate memory for response parameters */
Juergen Reppad4c2302018-02-27 23:32:51 +0100295 if (outData != NULL) {
296 *outData = calloc(sizeof(TPM2B_MAX_BUFFER), 1);
297 if (*outData == NULL) {
298 return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
299 }
300 }
301 if (ivOut != NULL) {
302 *ivOut = calloc(sizeof(TPM2B_IV), 1);
303 if (*ivOut == NULL) {
304 goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
305 }
306 }
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100307
308 /*Receive the TPM response and handle resubmissions if necessary. */
Juergen Reppad4c2302018-02-27 23:32:51 +0100309 r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
310 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
311 LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100312 esysContext->state = _ESYS_STATE_SENT;
Juergen Reppad4c2302018-02-27 23:32:51 +0100313 goto error_cleanup;
314 }
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100315 /* This block handle the resubmission of TPM commands given a certain set of
316 * TPM response codes. */
Juergen Reppad4c2302018-02-27 23:32:51 +0100317 if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
318 LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
319 "resubmission: %" PRIx32, r);
Andreas Fuchs631d7e62018-03-19 10:54:56 +0100320 if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100321 LOG_WARNING("Maximum number of (re)submissions has been reached.");
322 esysContext->state = _ESYS_STATE_INIT;
Juergen Reppad4c2302018-02-27 23:32:51 +0100323 goto error_cleanup;
324 }
325 esysContext->state = _ESYS_STATE_RESUBMISSION;
Juergen Reppadd438d2018-04-09 10:00:19 +0200326 r = Esys_EncryptDecrypt2_Async(esysContext,
Juergen Repp66989272018-09-04 11:13:06 +0200327 esysContext->in.EncryptDecrypt2.keyHandle,
328 esysContext->session_type[0],
329 esysContext->session_type[1],
330 esysContext->session_type[2],
331 esysContext->in.EncryptDecrypt2.inData,
332 esysContext->in.EncryptDecrypt2.decrypt,
333 esysContext->in.EncryptDecrypt2.mode,
334 esysContext->in.EncryptDecrypt2.ivIn);
Juergen Reppad4c2302018-02-27 23:32:51 +0100335 if (r != TSS2_RC_SUCCESS) {
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100336 LOG_WARNING("Error attempting to resubmit");
337 /* We do not set esysContext->state here but inherit the most recent
338 * state of the _async function. */
Juergen Reppad4c2302018-02-27 23:32:51 +0100339 goto error_cleanup;
340 }
341 r = TSS2_ESYS_RC_TRY_AGAIN;
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100342 LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
Juergen Reppad4c2302018-02-27 23:32:51 +0100343 goto error_cleanup;
344 }
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100345 /* The following is the "regular error" handling. */
Juergen Repp033da112018-07-10 13:06:18 +0200346 if (iesys_tpm_error(r)) {
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100347 LOG_WARNING("Received TPM Error");
348 esysContext->state = _ESYS_STATE_INIT;
349 goto error_cleanup;
350 } else if (r != TSS2_RC_SUCCESS) {
351 LOG_ERROR("Received a non-TPM Error");
352 esysContext->state = _ESYS_STATE_INTERNALERROR;
Juergen Reppad4c2302018-02-27 23:32:51 +0100353 goto error_cleanup;
354 }
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100355
Juergen Reppad4c2302018-02-27 23:32:51 +0100356 /*
357 * Now the verification of the response (hmac check) and if necessary the
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100358 * parameter decryption have to be done.
Juergen Reppad4c2302018-02-27 23:32:51 +0100359 */
360 r = iesys_check_response(esysContext);
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100361 goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
Juergen Repp66989272018-09-04 11:13:06 +0200362 error_cleanup);
363
Juergen Reppad4c2302018-02-27 23:32:51 +0100364 /*
365 * After the verification of the response we call the complete function
366 * to deliver the result.
367 */
368 r = Tss2_Sys_EncryptDecrypt2_Complete(esysContext->sys,
Juergen Repp66989272018-09-04 11:13:06 +0200369 (outData != NULL) ? *outData : NULL,
370 (ivOut != NULL) ? *ivOut : NULL);
371 goto_state_if_error(r, _ESYS_STATE_INTERNALERROR,
372 "Received error from SAPI unmarshaling" ,
373 error_cleanup);
374
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100375 esysContext->state = _ESYS_STATE_INIT;
Juergen Reppad4c2302018-02-27 23:32:51 +0100376
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100377 return TSS2_RC_SUCCESS;
Juergen Reppad4c2302018-02-27 23:32:51 +0100378
379error_cleanup:
380 if (outData != NULL)
381 SAFE_FREE(*outData);
382 if (ivOut != NULL)
383 SAFE_FREE(*ivOut);
Andreas Fuchs4d9961e2018-03-20 15:51:48 +0100384
Juergen Reppad4c2302018-02-27 23:32:51 +0100385 return r;
386}