1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2018-2019, 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 <string.h>
12 #include <stdlib.h>
13
14 #include "tss2_mu.h"
15 #include "fapi_util.h"
16 #include "fapi_crypto.h"
17 //#include "fapi_policy.h"
18 #include "ifapi_policy_execute.h"
19 #include "ifapi_helpers.h"
20 #include "ifapi_json_deserialize.h"
21 #include "tpm_json_deserialize.h"
22 #include "ifapi_policy_callbacks.h"
23 #define LOGMODULE fapi
24 #include "util/log.h"
25 #include "util/aux_util.h"
26
27 /** Copy the policy digests from a branch list to a digest list.
28 *
29 * @param[in] branches The list of policy branches.
30 * @param[in] current_hash_alg The hash algorithm used for computation.
31 * @param[out] digest_list The list of policies computed for every branch.
32 * @retval TSS2_RC_SUCCESS on success.
33 * @retval TSS2_FAPI_RC_BAD_VALUE If no appropriate digest was found in
34 * the branch list.
35 */
36 static TSS2_RC
compute_or_digest_list(TPML_POLICYBRANCHES * branches,TPMI_ALG_HASH current_hash_alg,TPML_DIGEST * digest_list)37 compute_or_digest_list(
38 TPML_POLICYBRANCHES *branches,
39 TPMI_ALG_HASH current_hash_alg,
40 TPML_DIGEST *digest_list)
41 {
42 size_t i;
43 size_t digest_idx, hash_size;
44 bool digest_found = false;
45
46 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
47 return_error2(TSS2_FAPI_RC_BAD_VALUE,
48 "Unsupported hash algorithm (%" PRIu16 ")",
49 current_hash_alg);
50 }
51 /* Determine digest values with appropriate hash alg */
52 TPML_DIGEST_VALUES *branch_digests = &branches->authorizations[0].policyDigests;
53 for (i = 0; i < branch_digests->count; i++) {
54 if (branch_digests->digests[i].hashAlg == current_hash_alg) {
55 digest_idx = i;
56 digest_found = true;
57 break;
58 }
59 }
60 if (!digest_found) {
61 return_error(TSS2_FAPI_RC_BAD_VALUE, "No digest found for hash alg");
62 }
63
64 digest_list->count = branches->count;
65 for (i = 0; i < branches->count; i++) {
66 if (i > 7) {
67 return_error(TSS2_FAPI_RC_BAD_VALUE, "Too much or branches.");
68 }
69 digest_list->digests[i].size = hash_size;
70 memcpy(&digest_list->digests[i].buffer[0],
71 &branches->authorizations[i].policyDigests.
72 digests[digest_idx].digest, hash_size);
73 LOGBLOB_DEBUG(&digest_list->digests[i].buffer[0],
74 digest_list->digests[i].size, "Compute digest list");
75 }
76 return TSS2_RC_SUCCESS;
77 }
78
79 /** Add a new authorization to a policy.
80 *
81 * The the signed hash computed from the policy digest and the policyRef together with
82 * the public key of the key used for signing will be stored in the policy.
83 *
84 * @param[in,out] policy The policy to be authorized.
85 * @param[in] authorization The structure with the signature, the policyRef and
86 * the public key.
87 *
88 * @retval TSS2_RC_SUCCESS on success.
89 * @retval TSS2_FAPI_RC_MEMORY If the memory for the authorization list cannot be
90 * allocated.
91 */
92 TSS2_RC
ifapi_extend_authorization(TPMS_POLICY * policy,TPMS_POLICYAUTHORIZATION * authorization)93 ifapi_extend_authorization(
94 TPMS_POLICY *policy,
95 TPMS_POLICYAUTHORIZATION *authorization)
96 {
97 TPML_POLICYAUTHORIZATIONS *save = NULL;
98 size_t n = 0;
99 size_t i;
100
101 if (policy->policyAuthorizations) {
102 /* Extend old authorizations */
103 n = policy->policyAuthorizations->count;
104 save = policy->policyAuthorizations;
105 policy->policyAuthorizations =
106 malloc((n + 1) * sizeof(TPMS_POLICYAUTHORIZATION)
107 + sizeof(TPML_POLICYAUTHORIZATIONS));
108 return_if_null(policy->policyAuthorizations->authorizations,
109 "Out of memory.", TSS2_FAPI_RC_MEMORY);
110
111 for (i = 0; i < n; i++)
112 policy->policyAuthorizations->authorizations[i] =
113 save->authorizations[i];
114 policy->policyAuthorizations->authorizations[n] = *authorization;
115 policy->policyAuthorizations->count = n + 1;
116 SAFE_FREE(save);
117 } else {
118 /* No old authorizations exits */
119 policy->policyAuthorizations = malloc(sizeof(TPMS_POLICYAUTHORIZATION)
120 + sizeof(TPML_POLICYAUTHORIZATIONS));
121 return_if_null(policy->policyAuthorizations->authorizations,
122 "Out of memory.", TSS2_FAPI_RC_MEMORY);
123
124 policy->policyAuthorizations->count = 1;
125 policy->policyAuthorizations->authorizations[0] = *authorization;
126 }
127 return TSS2_RC_SUCCESS;
128 }
129 /** Compute the index for the current digest list and clear the digest.
130 *
131 * The list entry with the appropriate hash algorithm will be searched.
132 * The found digest will be set to zero.
133 *
134 * @param[in,out] digest_values The list of policy digests and corresponding
135 * hash algorithms.
136 * @param[in] hashAlg The hash algorithm to be searched.
137 * @param[out] idx The index of the found digest.
138 * @retval TSS2_RC_SUCCESS on success.
139 * @retval TSS2_FAPI_RC_BAD_VALUE If no appropriate digest was found in
140 * the digest list.
141 */
142 TSS2_RC
get_policy_digest_idx(TPML_DIGEST_VALUES * digest_values,TPMI_ALG_HASH hashAlg,size_t * idx)143 get_policy_digest_idx(TPML_DIGEST_VALUES *digest_values, TPMI_ALG_HASH hashAlg,
144 size_t *idx)
145 {
146 size_t i;
147 for (i = 0; i < digest_values->count; i++) {
148 /* Check whether current hashAlg is appropriate. */
149 if (digest_values->digests[i].hashAlg == hashAlg) {
150 *idx = i;
151 return TSS2_RC_SUCCESS;
152 }
153 }
154
155 if (i >= TPM2_NUM_PCR_BANKS) {
156 return_error(TSS2_FAPI_RC_BAD_VALUE, "Table overflow");
157 }
158 digest_values->digests[i].hashAlg = hashAlg;
159 memset(&digest_values->digests[i].digest, 0, sizeof(TPMU_HA));
160 *idx = i;
161 digest_values->count += 1;
162 return TSS2_RC_SUCCESS;
163 }
164
165 /** Execute policy PCR.
166 *
167 * This command is used to cause conditional gating of a policy based on PCR.
168 *
169 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
170 * policy command.
171 * @param[in,out] policy The PCR policy which will be executed. The policy
172 * digest will be added to the policy.
173 * @param[in] current_hash_alg The hash algorithm wich will be used for
174 * policy computation.
175 * @param[in,out] current_policy The policy context which stores the state
176 * of the policy execution.
177 * @retval TSS2_RC_SUCCESS on success.
178 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
179 * this function needs to be called again.
180 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
181 * operation already pending.
182 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
183 */
184 static TSS2_RC
execute_policy_pcr(ESYS_CONTEXT * esys_ctx,TPMS_POLICYPCR * policy,TPMI_ALG_HASH current_hash_alg,IFAPI_POLICY_EXEC_CTX * current_policy)185 execute_policy_pcr(
186 ESYS_CONTEXT *esys_ctx,
187 TPMS_POLICYPCR *policy,
188 TPMI_ALG_HASH current_hash_alg,
189 IFAPI_POLICY_EXEC_CTX *current_policy)
190 {
191 TSS2_RC r = TSS2_RC_SUCCESS;
192 TPML_PCR_SELECTION pcr_selection;
193 TPM2B_DIGEST pcr_digest;
194
195 LOG_TRACE("call");
196
197 switch (current_policy->state) {
198 statecase(current_policy->state, POLICY_EXECUTE_INIT)
199 /* Compute PCR selection and pcr digest */
200 r = ifapi_compute_policy_digest(policy->pcrs, &pcr_selection,
201 current_hash_alg, &pcr_digest);
202 return_if_error(r, "Compute policy digest and selection.");
203
204 LOGBLOB_DEBUG(&pcr_digest.buffer[0], pcr_digest.size, "PCR Digest");
205
206 /* Prepare the policy execution. */
207 r = Esys_PolicyPCR_Async(esys_ctx,
208 current_policy->session,
209 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
210 &pcr_digest, &pcr_selection);
211 return_if_error(r, "Execute PolicyPCR.");
212 fallthrough;
213
214 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
215 /* Finalize the policy execution if possible. */
216 r = Esys_PolicyPCR_Finish(esys_ctx);
217 try_again_or_error(r, "Execute PolicyPCR_Finish.");
218
219 current_policy->state = POLICY_EXECUTE_INIT;
220 return r;
221
222 statecasedefault(current_policy->state);
223 }
224 return r;
225 }
226
227 /** Execute policy duplicate.
228 *
229 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
230 * policy command.
231 * @param[in,out] policy The duplicate policy which will be executed. The policy
232 * digest will be added to the policy.
233 * @param[in] current_hash_alg The hash algorithm wich will be used for
234 * policy computation.
235 * @param[in,out] current_policy The policy context which stores the state
236 * of the policy execution.
237 * @retval TSS2_RC_SUCCESS on success.
238 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
239 * this function needs to be called again.
240 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
241 * operation already pending.
242 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
243 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
244 */
245 static TSS2_RC
execute_policy_duplicate(ESYS_CONTEXT * esys_ctx,TPMS_POLICYDUPLICATIONSELECT * policy,IFAPI_POLICY_EXEC_CTX * current_policy)246 execute_policy_duplicate(
247 ESYS_CONTEXT *esys_ctx,
248 TPMS_POLICYDUPLICATIONSELECT *policy,
249 IFAPI_POLICY_EXEC_CTX *current_policy)
250 {
251 TSS2_RC r = TSS2_RC_SUCCESS;
252
253 LOG_TRACE("call");
254
255 switch (current_policy->state) {
256 statecase(current_policy->state, POLICY_EXECUTE_INIT)
257 ifapi_policyeval_EXEC_CB *cb = ¤t_policy->callbacks;
258 r = cb->cbdup(&policy->objectName, cb->cbdup_userdata);
259 return_if_error(r, "Get name for policy duplicate select.");
260
261 /* Prepare the policy execution. */
262 r = Esys_PolicyDuplicationSelect_Async(esys_ctx,
263 current_policy->session,
264 ESYS_TR_NONE, ESYS_TR_NONE,
265 ESYS_TR_NONE,
266 &policy->objectName,
267 &policy->newParentName,
268 policy->includeObject);
269 return_if_error(r, "Execute PolicyDuplicatonSelect_Async.");
270 fallthrough;
271
272 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
273 /* Finalize the policy execution if possible. */
274 r = Esys_PolicyDuplicationSelect_Finish(esys_ctx);
275 try_again_or_error(r, "Execute PolicyDuplicationselect_Finish.");
276
277 current_policy->state = POLICY_EXECUTE_INIT;
278 return r;
279
280 statecasedefault(current_policy->state);
281 }
282 return r;
283 }
284
285 /** Execute policy NV.
286 *
287 * A policy based on the contents of an NV Index will be executed. The
288 * NV authorization is done by a callback. For an example callback
289 * implementation see ifapi_policyeval_cbauth()
290 *
291 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
292 * policy command.
293 * @param[in,out] policy The NV policy which will be executed. The policy
294 * digest will be added to the policy.
295 * @param[in] current_hash_alg The hash algorithm wich will be used for
296 * policy computation.
297 * @param[in,out] current_policy The policy context which stores the state
298 * of the policy execution.
299 * @retval TSS2_RC_SUCCESS on success.
300 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
301 * this function needs to be called again.
302 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
303 * operation already pending.
304 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
305 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
306 */
307 static TSS2_RC
execute_policy_nv(ESYS_CONTEXT * esys_ctx,TPMS_POLICYNV * policy,IFAPI_POLICY_EXEC_CTX * current_policy)308 execute_policy_nv(
309 ESYS_CONTEXT *esys_ctx,
310 TPMS_POLICYNV *policy,
311 IFAPI_POLICY_EXEC_CTX *current_policy)
312 {
313 TSS2_RC r = TSS2_RC_SUCCESS;
314
315 LOG_TRACE("call");
316
317 switch (current_policy->state) {
318 statecase(current_policy->state, POLICY_EXECUTE_INIT)
319 r = ifapi_nv_get_name(&policy->nvPublic, ¤t_policy->name);
320 return_if_error(r, "Compute NV name");
321 fallthrough;
322
323 statecase(current_policy->state, POLICY_AUTH_CALLBACK)
324 ifapi_policyeval_EXEC_CB *cb = ¤t_policy->callbacks;
325
326 /* Authorize NV object. */
327 r = cb->cbauth(¤t_policy->name,
328 ¤t_policy->object_handle,
329 ¤t_policy->auth_handle,
330 ¤t_policy->auth_session, cb->cbauth_userdata);
331 return_try_again(r);
332 return_if_error(r, "Execute authorized policy.");
333
334 /* Prepare the policy execution. */
335 r = Esys_PolicyNV_Async(esys_ctx,
336 current_policy->object_handle,
337 current_policy->auth_handle,
338 current_policy->session,
339 current_policy->auth_session, ESYS_TR_NONE, ESYS_TR_NONE,
340 &policy->operandB, policy->offset,
341 policy->operation);
342 return_if_error(r, "Execute PolicyNV_Async.");
343 fallthrough;
344
345 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
346 /* Finalize the policy execution if possible. */
347 r = Esys_PolicyNV_Finish(esys_ctx);
348 try_again_or_error(r, "Execute PolicyNV_Finish.");
349
350 current_policy->state = POLICY_EXECUTE_INIT;
351 return r;
352
353 statecasedefault(current_policy->state);
354 }
355 return r;
356 }
357
358 /** Execute policy for signature based authorization.
359 *
360 * A signed authorization is included in this policy. The authorization hash
361 * of the policy data will be signed via a callback. For an example callback
362 * implementation see ifapi_sign_buffer()
363 *
364 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
365 * policy command.
366 * @param[in,out] policy The policy to be signed which will be executed. The policy
367 * digest will be added to the policy.
368 * @param[in] current_hash_alg The hash algorithm wich will be used for
369 * policy computation.
370 * @param[in,out] current_policy The policy context which stores the state
371 * of the policy execution.
372 * @retval TSS2_RC_SUCCESS on success.
373 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
374 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
375 * this function needs to be called again.
376 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
377 * operation already pending.
378 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
379 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
380 * is not set.
381 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
382 */
383 static TSS2_RC
execute_policy_signed(ESYS_CONTEXT * esys_ctx,TPMS_POLICYSIGNED * policy,IFAPI_POLICY_EXEC_CTX * current_policy)384 execute_policy_signed(
385 ESYS_CONTEXT *esys_ctx,
386 TPMS_POLICYSIGNED *policy,
387 IFAPI_POLICY_EXEC_CTX *current_policy)
388 {
389 TSS2_RC r = TSS2_RC_SUCCESS;
390 size_t offset = 0;
391 //TPMT_SIGNATURE signature_tpm;
392 size_t signature_size;
393 uint8_t *signature_ossl = NULL;
394
395 LOG_TRACE("call");
396
397 switch (current_policy->state) {
398 statecase(current_policy->state, POLICY_EXECUTE_INIT);
399 current_policy->pem_key = NULL;
400 current_policy->object_handle = ESYS_TR_NONE;
401 current_policy->buffer_size = sizeof(INT32) + sizeof(TPM2B_NONCE)
402 + policy->cpHashA.size + policy->policyRef.size;
403 current_policy->buffer = malloc(current_policy->buffer_size);
404 return_if_null(current_policy->buffer, "Out of memory.", TSS2_FAPI_RC_MEMORY);
405
406 r = Esys_TRSess_GetNonceTPM(esys_ctx, current_policy->session,
407 ¤t_policy->nonceTPM);
408 return_if_error(r, "Get TPM nonce.");
409
410 /* Concatenate objects needed for the authorization hash */
411 memcpy(¤t_policy->buffer[offset], ¤t_policy->nonceTPM->buffer[0],
412 current_policy->nonceTPM->size);
413 offset += current_policy->nonceTPM->size;
414 memset(¤t_policy->buffer[offset], 0, sizeof(INT32));
415 offset += sizeof(INT32);
416 memcpy(¤t_policy->buffer[offset], &policy->cpHashA.buffer[0],
417 policy->cpHashA.size);
418 offset += policy->cpHashA.size;
419 memcpy(¤t_policy->buffer[offset], &policy->policyRef.buffer[0],
420 policy->policyRef.size);
421 offset += policy->policyRef.size;
422 current_policy->buffer_size = offset;
423 fallthrough;
424
425 statecase(current_policy->state, POLICY_EXECUTE_CALLBACK);
426 ifapi_policyeval_EXEC_CB *cb = ¤t_policy->callbacks;
427 int pem_key_size;
428 TPM2B_PUBLIC tpm_public;
429
430 /* Recreate pem key from tpm public key */
431 if (!current_policy->pem_key) {
432 tpm_public.publicArea = policy->keyPublic;
433 tpm_public.size = 0;
434 r = ifapi_pub_pem_key_from_tpm(&tpm_public, ¤t_policy->pem_key,
435 &pem_key_size);
436 return_if_error(r, "Convert TPM public key into PEM key.");
437 }
438
439 /* Callback for signing the autorization hash. */
440 r = cb->cbsign(current_policy->pem_key, policy->publicKeyHint,
441 policy->keyPEMhashAlg, current_policy->buffer,
442 current_policy->buffer_size,
443 &signature_ossl, &signature_size,
444 cb->cbsign_userdata);
445 SAFE_FREE(current_policy->pem_key);
446 SAFE_FREE(current_policy->buffer);
447 try_again_or_error_goto(r, "Execute policy signature callback.", cleanup);
448
449 /* Convert signature into TPM format */
450 r = ifapi_der_sig_to_tpm(&policy->keyPublic, signature_ossl,
451 signature_size, policy->keyPEMhashAlg,
452 &policy->signature_tpm);
453 goto_if_error2(r, "Convert der signature into TPM format", cleanup);
454
455 SAFE_FREE(signature_ossl);
456
457 TPM2B_PUBLIC inPublic;
458 inPublic.size = 0;
459 inPublic.publicArea = policy->keyPublic;
460
461 /* Prepare the loading of the external public key, user for verificaton. */
462 r = Esys_LoadExternal_Async(esys_ctx,
463 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
464 NULL, &inPublic, TPM2_RH_OWNER);
465 goto_if_error(r, "LoadExternal_Async", cleanup);
466 fallthrough;
467
468 statecase(current_policy->state, POLICY_LOAD_KEY);
469 r = Esys_LoadExternal_Finish(esys_ctx, ¤t_policy->object_handle);
470 try_again_or_error(r, "Load external key.");
471
472 /* Prepare the policy execution. */
473 r = Esys_PolicySigned_Async(esys_ctx,
474 current_policy->object_handle,
475 current_policy->session,
476 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
477 current_policy->nonceTPM,
478 &policy->cpHashA,
479 &policy->policyRef, 0, &policy->signature_tpm);
480 SAFE_FREE(current_policy->nonceTPM);
481 goto_if_error(r, "Execute PolicySigned.", cleanup);
482 fallthrough;
483
484 statecase(current_policy->state, POLICY_EXECUTE_FINISH);
485 /* Finalize the policy execution if possible. */
486 r = Esys_PolicySigned_Finish(esys_ctx, NULL, NULL);
487 try_again_or_error(r, "Execute PolicySigned_Finish.");
488
489 r = Esys_FlushContext_Async(esys_ctx, current_policy->object_handle);
490 goto_if_error(r, "FlushContext_Async", cleanup);
491 fallthrough;
492
493 statecase(current_policy->state, POLICY_FLUSH_KEY);
494 r = Esys_FlushContext_Finish(esys_ctx);
495 try_again_or_error(r, "Flush key finish.");
496
497 current_policy->object_handle = ESYS_TR_NONE;
498 current_policy->state = POLICY_EXECUTE_INIT;
499 return r;
500
501 statecasedefault(current_policy->state);
502 }
503 cleanup:
504 SAFE_FREE(current_policy->pem_key);
505 SAFE_FREE(signature_ossl);
506 SAFE_FREE(current_policy->buffer);
507 SAFE_FREE(current_policy->pem_key);
508 /* In error cases object might not have been flushed. */
509 if (current_policy->object_handle != ESYS_TR_NONE)
510 Esys_FlushContext(esys_ctx, current_policy->object_handle);
511 return r;
512 }
513
514 /** Execute a policy that was signed by a certain key.
515 *
516 * All policies authorized by the key stored in the policy will be
517 * retrieved and one policy will be selected via a branch selection callback
518 * (see Fapi_SetBranchCB()) if more then one policy was found.
519 * The selected policy will be executed via a callback. For an example callback
520 * implementation see ifapi_exec_auth_policy().
521 *
522 * For an example callback implementation to executie of an authorized policy
523 * ifapi_exec_auth_policy()
524 *
525 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
526 * policy command.
527 * @param[in,out] policy The policy which defines the signing key and several
528 * additional parameters (nonce, policyRef ...). The policy
529 * digest will be added to the policy.
530 * @param[in] current_hash_alg The hash algorithm wich will be used for
531 * policy computation.
532 * @param[in,out] current_policy The policy context which stores the state
533 * of the policy execution.
534 * @retval TSS2_RC_SUCCESS on success.
535 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
536 * the function.
537 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
538 * this function needs to be called again.
539 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
540 * operation already pending.
541 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occured.
542 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
543 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
544 * was not successful.
545 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
546 * is not set.
547 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
548 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
549 */
550 static TSS2_RC
execute_policy_authorize(ESYS_CONTEXT * esys_ctx,TPMS_POLICYAUTHORIZE * policy,TPMI_ALG_HASH hash_alg,IFAPI_POLICY_EXEC_CTX * current_policy)551 execute_policy_authorize(
552 ESYS_CONTEXT *esys_ctx,
553 TPMS_POLICYAUTHORIZE *policy,
554 TPMI_ALG_HASH hash_alg,
555 IFAPI_POLICY_EXEC_CTX *current_policy)
556 {
557 TSS2_RC r = TSS2_RC_SUCCESS;
558 TPM2B_PUBLIC public2b;
559 TPM2B_DIGEST aHash;
560 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext;
561 size_t hash_size;
562 size_t size;
563 TPMT_TK_VERIFIED *ticket;
564 TPM2B_NAME *tmp_name = NULL;
565
566 LOG_TRACE("call");
567 public2b.size = 0;
568 if (!(hash_size = ifapi_hash_get_digest_size(hash_alg))) {
569 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
570 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
571 hash_alg);
572 }
573 switch (current_policy->state) {
574 statecase(current_policy->state, POLICY_EXECUTE_INIT);
575 current_policy->object_handle = ESYS_TR_NONE;
576 /* Execute authorized policy. */
577 ifapi_policyeval_EXEC_CB *cb = ¤t_policy->callbacks;
578 r = cb->cbauthpol(&policy->keyPublic, hash_alg, &policy->approvedPolicy,
579 &policy->signature, cb->cbauthpol_userdata);
580 return_try_again(r);
581 goto_if_error(r, "Execute authorized policy.", cleanup);
582
583 public2b.size = 0;
584 public2b.publicArea = policy->keyPublic;
585 r = Esys_LoadExternal_Async(esys_ctx,
586 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
587 NULL, &public2b, TPM2_RH_OWNER);
588 goto_if_error(r, "LoadExternal_Async", cleanup);
589 fallthrough;
590
591 statecase(current_policy->state, POLICY_LOAD_KEY);
592 r = Esys_LoadExternal_Finish(esys_ctx, ¤t_policy->object_handle);
593 try_again_or_error(r, "Load external key.");
594
595 /* Save key name for policy execution */
596 r = Esys_TR_GetName(esys_ctx, current_policy->object_handle, &tmp_name);
597 return_if_error(r, "Get key name.");
598 policy->keyName = *tmp_name;
599 SAFE_FREE(tmp_name);
600
601 /* Use policyRef and policy to compute authorization hash */
602 r = ifapi_crypto_hash_start(&cryptoContext, hash_alg);
603 return_if_error(r, "crypto hash start");
604
605 HASH_UPDATE_BUFFER(cryptoContext, &policy->approvedPolicy.buffer[0],
606 hash_size, r, cleanup);
607 HASH_UPDATE_BUFFER(cryptoContext, &policy->policyRef.buffer[0],
608 policy->policyRef.size, r, cleanup);
609 r = ifapi_crypto_hash_finish(&cryptoContext,
610 (uint8_t *) &aHash.buffer[0],
611 &size);
612 return_if_error(r, "crypto hash finish");
613
614 aHash.size = size;
615 LOGBLOB_TRACE(&policy->policyRef.buffer[0], policy->policyRef.size, "policyRef");
616 LOGBLOB_TRACE(&aHash.buffer[0], aHash.size, "aHash");
617
618 /* Verify the signature retrieved from the authorized policy against
619 the computed ahash. */
620 r = Esys_VerifySignature_Async(esys_ctx, current_policy->object_handle,
621 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
622 &aHash,
623 &policy->signature);
624 goto_if_error(r, "Verify signature", cleanup);
625 fallthrough;
626
627 statecase(current_policy->state, POLICY_VERIFY);
628 r = Esys_VerifySignature_Finish(esys_ctx, &ticket);
629 try_again_or_error(r, "Load external key.");
630
631 /* Execute policy authorize */
632 policy->checkTicket = *ticket;
633 SAFE_FREE(ticket);
634 r = Esys_PolicyAuthorize_Async(esys_ctx,
635 current_policy->session,
636 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
637 &policy->approvedPolicy,
638 &policy->policyRef,
639 &policy->keyName,
640 &policy->checkTicket);
641 goto_if_error(r, "Policy Authorize", cleanup);
642 fallthrough;
643
644 statecase(current_policy->state, POLICY_EXECUTE_FINISH);
645 r = Esys_PolicyAuthorize_Finish(esys_ctx);
646 try_again_or_error(r, "Load external key.");
647
648 r = Esys_FlushContext_Async(esys_ctx, current_policy->object_handle);
649 goto_if_error(r, "FlushContext_Async", cleanup);
650 fallthrough;
651
652 statecase(current_policy->state, POLICY_FLUSH_KEY);
653 /* Flush key used for verification. */
654 r = Esys_FlushContext_Finish(esys_ctx);
655 try_again_or_error(r, "Flush key finish.");
656
657 current_policy->object_handle = ESYS_TR_NONE;
658 current_policy->state = POLICY_EXECUTE_INIT;
659 break;
660
661 statecasedefault(current_policy->state);
662 }
663 cleanup:
664 /* In error cases object might not have been flushed. */
665 if (current_policy->object_handle != ESYS_TR_NONE)
666 Esys_FlushContext(esys_ctx, current_policy->object_handle);
667
668 return r;
669 }
670
671 /** Execute a policy whose digest is stored in the NV ram.
672 *
673 * The policy will be retrieved from policy store based on the policy digest
674 * stored in NV ram.
675 * The authorization for the NV object, the policy retrieval, and the execution
676 * is done via a callback. For an example callback implementation see
677 * ifapi_exec_auth_nv_policy().
678 *
679 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
680 * policy command.
681 * @param[in,out] policy The policy which defines the policy to be authorized
682 * and the used NV object.
683 * The policy digest will be added to the policy.
684 * @param[in] current_hash_alg The hash algorithm wich will be used for
685 * policy computation.
686 * @param[in,out] current_policy The policy context which stores the state
687 * of the policy execution.
688 * @retval TSS2_RC_SUCCESS on success.
689 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
690 * this function needs to be called again.
691 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
692 * operation already pending.
693 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
694 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
695 * the function.
696 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
697 * was not successful.
698 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
699 */
700 static TSS2_RC
execute_policy_authorize_nv(ESYS_CONTEXT * esys_ctx,TPMS_POLICYAUTHORIZENV * policy,TPMI_ALG_HASH hash_alg,IFAPI_POLICY_EXEC_CTX * current_policy)701 execute_policy_authorize_nv(
702 ESYS_CONTEXT *esys_ctx,
703 TPMS_POLICYAUTHORIZENV *policy,
704 TPMI_ALG_HASH hash_alg,
705 IFAPI_POLICY_EXEC_CTX *current_policy)
706 {
707 TSS2_RC r = TSS2_RC_SUCCESS;
708 ifapi_policyeval_EXEC_CB *cb;
709
710 LOG_DEBUG("call");
711 cb = ¤t_policy->callbacks;
712
713 switch (current_policy->state) {
714 statecase(current_policy->state, POLICY_EXECUTE_INIT)
715 /* Execute the policy stored in the NV object. */
716 r = cb->cbauthnv(&policy->nvPublic, hash_alg, cb->cbauthpol_userdata);
717 try_again_or_error(r, "Execute policy authorize nv callback.");
718
719 r = ifapi_nv_get_name(&policy->nvPublic, ¤t_policy->name);
720 return_if_error(r, "Compute NV name");
721 fallthrough;
722
723 statecase(current_policy->state, POLICY_AUTH_CALLBACK)
724 /* Authorize the NV object for policy execution. */
725 r = cb->cbauth(¤t_policy->name,
726 ¤t_policy->object_handle,
727 ¤t_policy->auth_handle,
728 ¤t_policy->auth_session, cb->cbauth_userdata);
729 return_try_again(r);
730 goto_if_error(r, "Execute authorized policy.", cleanup);
731 fallthrough;
732
733 statecase(current_policy->state, POLICY_EXEC_ESYS)
734 LOG_DEBUG("**STATE** POLICY_EXEC_ESYS");
735 /* Prepare the policy execution. */
736 r = Esys_PolicyAuthorizeNV_Async(esys_ctx,
737 current_policy->auth_handle,
738 current_policy->object_handle,
739 current_policy->session,
740 current_policy->auth_session, ESYS_TR_NONE,
741 ESYS_TR_NONE);
742 goto_if_error(r, "PolicyAuthorizeNV_Async", cleanup);
743 fallthrough;
744
745 statecase(current_policy->state, POLICY_AUTH_SENT)
746 /* Finalize the policy execution if possible. */
747 r = Esys_PolicyAuthorizeNV_Finish(esys_ctx);
748 return_try_again(r);
749 goto_if_error(r, "FAPI PolicyAuthorizeNV_Finish", cleanup);
750 break;
751
752 statecasedefault(current_policy->state);
753 }
754 cleanup:
755 return r;
756 }
757
758 /** Execute a policy based on a secret-based authorization.
759 *
760 * The policy defines an object whose secret is needed for policy execution.
761 * The authorization of the object is done via a callback.
762 * For an example callback implementation see ifapi_policyeval_cbauth;().
763 *
764 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
765 * policy command.
766 * @param[in,out] policy The policy which defines the object whose secret
767 * is needed for policy execution.
768 * The policy digest will be added to the policy.
769 * @param[in] current_hash_alg The hash algorithm wich will be used for
770 * policy computation.
771 * @param[in,out] current_policy The policy context which stores the state
772 * of the policy execution.
773 * @retval TSS2_RC_SUCCESS on success.
774 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
775 * this function needs to be called again.
776 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
777 * operation already pending.
778 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
779 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
780 */
781 static TSS2_RC
execute_policy_secret(ESYS_CONTEXT * esys_ctx,TPMS_POLICYSECRET * policy,TPMI_ALG_HASH hash_alg,IFAPI_POLICY_EXEC_CTX * current_policy)782 execute_policy_secret(
783 ESYS_CONTEXT *esys_ctx,
784 TPMS_POLICYSECRET *policy,
785 TPMI_ALG_HASH hash_alg,
786 IFAPI_POLICY_EXEC_CTX *current_policy)
787 {
788 TSS2_RC r = TSS2_RC_SUCCESS;
789 (void)hash_alg;
790
791 LOG_DEBUG("call");
792
793 switch (current_policy->state) {
794 statecase(current_policy->state, POLICY_EXECUTE_INIT)
795 ifapi_policyeval_EXEC_CB *cb = ¤t_policy->callbacks;
796 /* Callback for the object authorization. */
797 r = cb->cbauth(&policy->objectName,
798 ¤t_policy->object_handle,
799 ¤t_policy->auth_handle,
800 ¤t_policy->auth_session, cb->cbauth_userdata);
801 return_try_again(r);
802 goto_if_error(r, "Authorize object callback.", cleanup);
803 fallthrough;
804
805 statecase(current_policy->state, POLICY_EXEC_ESYS)
806 r = Esys_TRSess_GetNonceTPM(esys_ctx, current_policy->session,
807 ¤t_policy->nonceTPM);
808 goto_if_error(r, "Get TPM nonce.", cleanup);
809
810 policy->nonceTPM = *(current_policy->nonceTPM);
811 SAFE_FREE(current_policy->nonceTPM);
812
813 /* Prepare the policy execution. */
814 r = Esys_PolicySecret_Async(esys_ctx,
815 current_policy->auth_handle,
816 current_policy->session,
817 current_policy->auth_session, ESYS_TR_NONE,
818 ESYS_TR_NONE, &policy->nonceTPM,
819 &policy->cpHashA, &policy->policyRef,
820 0);
821 goto_if_error(r, "PolicySecret_Async", cleanup);
822 fallthrough;
823
824 statecase(current_policy->state, POLICY_AUTH_SENT)
825 /* Finalize the policy execution if possible. */
826 r = Esys_PolicySecret_Finish(esys_ctx, NULL,
827 NULL);
828 return_try_again(r);
829 goto_if_error(r, "FAPI PolicyAuthorizeNV_Finish", cleanup);
830 break;
831
832 statecasedefault(current_policy->state);
833 }
834
835 cleanup:
836 return r;
837 }
838
839 /** Execute a policy depending on the TPM timers.
840 *
841 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
842 * policy command.
843 * @param[in,out] policy The policy which defines the values for the comparision
844 * with the TPM timers and the comparision operation.
845 * The policy digest will be added to the policy.
846 * @param[in] current_hash_alg The hash algorithm wich will be used for
847 * policy computation.
848 * @param[in,out] current_policy The policy context which stores the state
849 * of the policy execution.
850 * @retval TSS2_RC_SUCCESS on success.
851 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
852 * this function needs to be called again.
853 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
854 * operation already pending.
855 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
856 */
857 static TSS2_RC
execute_policy_counter_timer(ESYS_CONTEXT * esys_ctx,TPMS_POLICYCOUNTERTIMER * policy,IFAPI_POLICY_EXEC_CTX * current_policy)858 execute_policy_counter_timer(
859 ESYS_CONTEXT *esys_ctx,
860 TPMS_POLICYCOUNTERTIMER *policy,
861 IFAPI_POLICY_EXEC_CTX *current_policy)
862 {
863 TSS2_RC r = TSS2_RC_SUCCESS;
864
865 LOG_TRACE("call");
866
867 switch (current_policy->state) {
868 statecase(current_policy->state, POLICY_EXECUTE_INIT)
869 /* Prepare the policy execution. */
870 r = Esys_PolicyCounterTimer_Async(esys_ctx,
871 current_policy->session,
872 ESYS_TR_NONE, ESYS_TR_NONE,
873 ESYS_TR_NONE,
874 &policy->operandB,
875 policy->offset,
876 policy->operation);
877 return_if_error(r, "Execute PolicyCounter.");
878 fallthrough;
879
880 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
881 /* Finalize the policy execution if possible. */
882 r = Esys_PolicyCounterTimer_Finish(esys_ctx);
883 try_again_or_error(r, "Execute PolicyCounterTImer_Finish.");
884
885 current_policy->state = POLICY_EXECUTE_INIT;
886 return r;
887
888 statecasedefault(current_policy->state);
889 }
890 return r;
891 }
892
893 /** Execute a policy depending on physical presence.
894 *
895 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
896 * policy command.
897 * @param[in,out] policy The policy indicating that physical presence is needed.
898 * @param[in,out] current_policy The policy context which stores the state
899 * of the policy execution.
900 * @retval TSS2_RC_SUCCESS on success.
901 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
902 * this function needs to be called again.
903 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
904 * operation already pending.
905 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
906 */
907 static TSS2_RC
execute_policy_physical_presence(ESYS_CONTEXT * esys_ctx,TPMS_POLICYPHYSICALPRESENCE * policy,IFAPI_POLICY_EXEC_CTX * current_policy)908 execute_policy_physical_presence(
909 ESYS_CONTEXT *esys_ctx,
910 TPMS_POLICYPHYSICALPRESENCE *policy,
911 IFAPI_POLICY_EXEC_CTX *current_policy)
912 {
913 TSS2_RC r = TSS2_RC_SUCCESS;
914 (void)policy;
915
916 LOG_TRACE("call");
917
918 switch (current_policy->state) {
919 statecase(current_policy->state, POLICY_EXECUTE_INIT)
920 /* Prepare the policy execution. */
921 r = Esys_PolicyPhysicalPresence_Async(esys_ctx,
922 current_policy->session,
923 ESYS_TR_NONE, ESYS_TR_NONE,
924 ESYS_TR_NONE);
925 return_if_error(r, "Execute PolicyPhysicalpresence.");
926 fallthrough;
927
928 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
929 /* Finalize the policy execution if possible. */
930 r = Esys_PolicyPhysicalPresence_Finish(esys_ctx);
931 try_again_or_error(r, "Execute PolicyPhysicalPresence_Finish.");
932
933 current_policy->state = POLICY_EXECUTE_INIT;
934 return r;
935
936 statecasedefault(current_policy->state);
937 }
938 return r;
939 }
940
941 /** Execute a policy for binding a authorization value of the authorized entity.
942 *
943 * The authValue will be included in hmacKey of the session.
944
945 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
946 * policy command.
947 * @param[in,out] policy The policy indicating that a auth value is needed.
948 * @param[in,out] current_policy The policy context which stores the state
949 * of the policy execution.
950 * @retval TSS2_RC_SUCCESS on success.
951 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
952 * this function needs to be called again.
953 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
954 * operation already pending.
955 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
956 */
957 static TSS2_RC
execute_policy_auth_value(ESYS_CONTEXT * esys_ctx,TPMS_POLICYAUTHVALUE * policy,IFAPI_POLICY_EXEC_CTX * current_policy)958 execute_policy_auth_value(
959 ESYS_CONTEXT *esys_ctx,
960 TPMS_POLICYAUTHVALUE *policy,
961 IFAPI_POLICY_EXEC_CTX *current_policy)
962 {
963 TSS2_RC r = TSS2_RC_SUCCESS;
964 (void)policy;
965
966 LOG_TRACE("call");
967
968 switch (current_policy->state) {
969 statecase(current_policy->state, POLICY_EXECUTE_INIT)
970 /* Prepare the policy execution. */
971 r = Esys_PolicyAuthValue_Async(esys_ctx,
972 current_policy->session,
973 ESYS_TR_NONE, ESYS_TR_NONE,
974 ESYS_TR_NONE);
975 return_if_error(r, "Execute PolicyAuthValue.");
976 fallthrough;
977
978 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
979 /* Finalize the policy execution if possible. */
980 r = Esys_PolicyAuthValue_Finish(esys_ctx);
981 try_again_or_error(r, "Execute PolicyAuthValue_Finish.");
982
983 current_policy->state = POLICY_EXECUTE_INIT;
984 return r;
985
986 statecasedefault(current_policy->state);
987 }
988 return r;
989 }
990
991 /** Execute a policy for binding a authorization value of the authorized object.
992 *
993 * The authValue of the authorized object will be checked when the session is used
994 * for authorization..
995 *
996 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
997 * policy command.
998 * @param[in,out] policy The policy indicating that a auth value is needed.
999 * @param[in,out] current_policy The policy context which stores the state
1000 * of the policy execution.
1001 * @retval TSS2_RC_SUCCESS on success.
1002 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1003 * this function needs to be called again.
1004 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1005 * operation already pending.
1006 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1007 */
1008 static TSS2_RC
execute_policy_password(ESYS_CONTEXT * esys_ctx,TPMS_POLICYPASSWORD * policy,IFAPI_POLICY_EXEC_CTX * current_policy)1009 execute_policy_password(
1010 ESYS_CONTEXT *esys_ctx,
1011 TPMS_POLICYPASSWORD *policy,
1012 IFAPI_POLICY_EXEC_CTX *current_policy)
1013 {
1014 TSS2_RC r = TSS2_RC_SUCCESS;
1015 (void)policy;
1016
1017 LOG_TRACE("call");
1018
1019 switch (current_policy->state) {
1020 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1021 /* Prepare the policy execution. */
1022 r = Esys_PolicyPassword_Async(esys_ctx,
1023 current_policy->session,
1024 ESYS_TR_NONE, ESYS_TR_NONE,
1025 ESYS_TR_NONE);
1026 return_if_error(r, "Execute PolicyPassword.");
1027 fallthrough;
1028
1029 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1030 /* Finalize the policy execution if possible. */
1031 r = Esys_PolicyPassword_Finish(esys_ctx);
1032 try_again_or_error(r, "Execute PolicyPassword_Finish.");
1033
1034 current_policy->state = POLICY_EXECUTE_INIT;
1035 return r;
1036
1037 statecasedefault(current_policy->state);
1038 }
1039 return r;
1040 }
1041
1042 /** Execute a policy to limit an authorization to a specific command code.
1043 *
1044 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1045 * policy command.
1046 * @param[in,out] policy The policy with the command code used fo limitting.
1047 * @param[in,out] current_policy The policy context which stores the state
1048 * of the policy execution.
1049 * @retval TSS2_RC_SUCCESS on success.
1050 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1051 * this function needs to be called again.
1052 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1053 * operation already pending.
1054 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1055 */
1056 static TSS2_RC
execute_policy_command_code(ESYS_CONTEXT * esys_ctx,TPMS_POLICYCOMMANDCODE * policy,IFAPI_POLICY_EXEC_CTX * current_policy)1057 execute_policy_command_code(
1058 ESYS_CONTEXT *esys_ctx,
1059 TPMS_POLICYCOMMANDCODE *policy,
1060 IFAPI_POLICY_EXEC_CTX *current_policy)
1061 {
1062 TSS2_RC r = TSS2_RC_SUCCESS;
1063
1064 LOG_TRACE("call");
1065
1066 switch (current_policy->state) {
1067 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1068 /* Prepare the policy execution. */
1069 r = Esys_PolicyCommandCode_Async(esys_ctx,
1070 current_policy->session,
1071 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1072 policy->code);
1073 return_if_error(r, "Execute PolicyCommandCode.");
1074 fallthrough;
1075
1076 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1077 /* Finalize the policy execution if possible. */
1078 r = Esys_PolicyCommandCode_Finish(esys_ctx);
1079 try_again_or_error(r, "Execute PolicyCommandCode_Finish.");
1080
1081 current_policy->state = POLICY_EXECUTE_INIT;
1082 return r;
1083
1084 statecasedefault(current_policy->state)
1085 }
1086 return r;
1087 }
1088
1089 /** Execute a policy for binding the policy to a specific set of TPM entities.
1090 *
1091 * Up to three entity names can be defined in the policy.
1092 *
1093 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1094 * policy command.
1095 * @param[in,out] policy The policy with the entity names.
1096 * @param[in,out] current_policy The policy context which stores the state
1097 * of the policy execution.
1098 * @retval TSS2_RC_SUCCESS on success.
1099 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1100 * this function needs to be called again.
1101 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1102 * operation already pending.
1103 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1104 */
1105 static TSS2_RC
execute_policy_name_hash(ESYS_CONTEXT * esys_ctx,TPMS_POLICYNAMEHASH * policy,IFAPI_POLICY_EXEC_CTX * current_policy)1106 execute_policy_name_hash(
1107 ESYS_CONTEXT *esys_ctx,
1108 TPMS_POLICYNAMEHASH *policy,
1109 IFAPI_POLICY_EXEC_CTX *current_policy)
1110 {
1111 TSS2_RC r = TSS2_RC_SUCCESS;
1112
1113 LOG_TRACE("call");
1114
1115 switch (current_policy->state) {
1116 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1117 /* Prepare the policy execution. */
1118 r = Esys_PolicyNameHash_Async(esys_ctx,
1119 current_policy->session,
1120 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1121 &policy->nameHash);
1122 return_if_error(r, "Execute PolicyNameH.");
1123 fallthrough;
1124
1125 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1126 /* Finalize the policy execution if possible. */
1127 r = Esys_PolicyNameHash_Finish(esys_ctx);
1128 try_again_or_error(r, "Execute PolicyNameHash_Finish.");
1129
1130 current_policy->state = POLICY_EXECUTE_INIT;
1131 return r;
1132
1133 statecasedefault(current_policy->state)
1134 }
1135 return r;
1136 }
1137
1138 /** Execute a policy for binding the policy to command parameters.
1139 *
1140 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1141 * policy command.
1142 * @param[in,out] policy The policy with the cp hash.
1143 * @param[in,out] current_policy The policy context which stores the state
1144 * of the policy execution.
1145 * @retval TSS2_RC_SUCCESS on success.
1146 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1147 * this function needs to be called again.
1148 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1149 * operation already pending.
1150 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1151 */
1152 static TSS2_RC
execute_policy_cp_hash(ESYS_CONTEXT * esys_ctx,TPMS_POLICYCPHASH * policy,IFAPI_POLICY_EXEC_CTX * current_policy)1153 execute_policy_cp_hash(
1154 ESYS_CONTEXT *esys_ctx,
1155 TPMS_POLICYCPHASH *policy,
1156 IFAPI_POLICY_EXEC_CTX *current_policy)
1157 {
1158 TSS2_RC r = TSS2_RC_SUCCESS;
1159
1160 LOG_TRACE("call");
1161
1162 switch (current_policy->state) {
1163 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1164 /* Prepare the policy execution. */
1165 r = Esys_PolicyCpHash_Async(esys_ctx,
1166 current_policy->session,
1167 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1168 &policy->cpHash);
1169 return_if_error(r, "Execute PolicyNameH.");
1170
1171 fallthrough;
1172
1173 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1174 /* Finalize the policy execution if possible. */
1175 r = Esys_PolicyCpHash_Finish(esys_ctx);
1176 try_again_or_error(r, "Execute PolicyCpHash_Finish.");
1177
1178 current_policy->state = POLICY_EXECUTE_INIT;
1179 return r;
1180
1181 statecasedefault(current_policy->state);
1182 }
1183 return r;
1184 }
1185
1186 /** Execute a policy for binding the policy to a certain locality.
1187 *
1188 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1189 * policy command.
1190 * @param[in,out] policy The policy with the locality.
1191 * @param[in,out] current_policy The policy context which stores the state
1192 * of the policy execution.
1193 * @retval TSS2_RC_SUCCESS on success.
1194 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1195 * this function needs to be called again.
1196 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1197 * operation already pending.
1198 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1199 */
1200 static TSS2_RC
execute_policy_locality(ESYS_CONTEXT * esys_ctx,TPMS_POLICYLOCALITY * policy,IFAPI_POLICY_EXEC_CTX * current_policy)1201 execute_policy_locality(
1202 ESYS_CONTEXT *esys_ctx,
1203 TPMS_POLICYLOCALITY *policy,
1204 IFAPI_POLICY_EXEC_CTX *current_policy)
1205 {
1206 TSS2_RC r = TSS2_RC_SUCCESS;
1207
1208 LOG_TRACE("call");
1209
1210 switch (current_policy->state) {
1211 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1212 /* Prepare the policy execution. */
1213 r = Esys_PolicyLocality_Async(esys_ctx,
1214 current_policy->session,
1215 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1216 policy->locality);
1217 return_if_error(r, "Execute PolicyLocality.");
1218 fallthrough;
1219
1220 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1221 /* Finalize the policy execution if possible. */
1222 r = Esys_PolicyLocality_Finish(esys_ctx);
1223 try_again_or_error(r, "Execute PolicyNV_Finish.");
1224
1225 current_policy->state = POLICY_EXECUTE_INIT;
1226 return r;
1227
1228 statecasedefault(current_policy->state);
1229 }
1230 return r;
1231 }
1232
1233 /** Execute a policy for binding the policy to the NV written state.
1234 *
1235 * The state NV written yes or NV written no can be defined in the policy.
1236 *
1237 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1238 * policy command.
1239 * @param[in,out] policy The policy with the NV written switch YES or NO.
1240 * @param[in,out] current_policy The policy context which stores the state
1241 * of the policy execution.
1242 * @retval TSS2_RC_SUCCESS on success.
1243 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1244 * this function needs to be called again.
1245 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1246 * operation already pending.
1247 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1248 */
1249 static TSS2_RC
execute_policy_nv_written(ESYS_CONTEXT * esys_ctx,TPMS_POLICYNVWRITTEN * policy,IFAPI_POLICY_EXEC_CTX * current_policy)1250 execute_policy_nv_written(
1251 ESYS_CONTEXT *esys_ctx,
1252 TPMS_POLICYNVWRITTEN *policy,
1253 IFAPI_POLICY_EXEC_CTX *current_policy)
1254 {
1255 TSS2_RC r = TSS2_RC_SUCCESS;
1256
1257 LOG_TRACE("call");
1258
1259 switch (current_policy->state) {
1260 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1261 /* Prepare the policy execution. */
1262 r = Esys_PolicyNvWritten_Async(esys_ctx,
1263 current_policy->session,
1264 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1265 policy->writtenSet);
1266 return_if_error(r, "Execute PolicyNvWritten.");
1267 fallthrough;
1268
1269 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1270 /* Finalize the policy execution if possible. */
1271 r = Esys_PolicyNvWritten_Finish(esys_ctx);
1272 try_again_or_error(r, "Execute PolicyNV_Finish.");
1273
1274 current_policy->state = POLICY_EXECUTE_INIT;
1275 return r;
1276
1277 statecasedefault(current_policy->state);
1278 }
1279 return r;
1280 }
1281
1282 /** Execute a policy for binding the policy to the NV written state.
1283 *
1284 * The state NV written yes or NV written no can be defined in the policy.
1285 *
1286 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1287 * policy command.
1288 * @param[in,out] policy The policy with the NV written switch YES or NO.
1289 * @param[in,out] current_policy The policy context which stores the state
1290 * of the policy execution.
1291 * @retval TSS2_RC_SUCCESS on success.
1292 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1293 * this function needs to be called again.
1294 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1295 * operation already pending.
1296 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1297 */
1298 static TSS2_RC
execute_policy_or(ESYS_CONTEXT * esys_ctx,TPMS_POLICYOR * policy,TPMI_ALG_HASH current_hash_alg,IFAPI_POLICY_EXEC_CTX * current_policy)1299 execute_policy_or(
1300 ESYS_CONTEXT *esys_ctx,
1301 TPMS_POLICYOR *policy,
1302 TPMI_ALG_HASH current_hash_alg,
1303 IFAPI_POLICY_EXEC_CTX *current_policy)
1304 {
1305 TSS2_RC r = TSS2_RC_SUCCESS;
1306
1307 LOG_TRACE("call");
1308
1309 switch (current_policy->state) {
1310 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1311 /* Prepare the policy execution. */
1312 r = compute_or_digest_list(policy->branches, current_hash_alg,
1313 ¤t_policy->digest_list);
1314 return_if_error(r, "Compute policy or digest list.");
1315
1316 r = Esys_PolicyOR_Async(esys_ctx,
1317 current_policy->session,
1318 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1319 ¤t_policy->digest_list);
1320 return_if_error(r, "Execute PolicyPCR.");
1321 fallthrough;
1322 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1323 /* Finalize the policy execution if possible. */
1324 r = Esys_PolicyOR_Finish(esys_ctx);
1325 try_again_or_error(r, "Execute PolicyPCR_Finish.");
1326
1327 return r;
1328
1329 statecasedefault(current_policy->state);
1330 }
1331 }
1332
1333 /** Execute a policy for executing a callback during policy execution.
1334 *
1335 * The action name stored in the policy name will be passed do the callback
1336 * function. The policy action callback has to be set with the function:
1337 * Fapi_SetPolicyActionCB().
1338 *
1339 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1340 * policy command.
1341 * @param[in,out] policy The policy with action name.
1342 * @param[in,out] current_policy The policy context which stores the state
1343 * of the policy execution.
1344 * @retval TSS2_RC_SUCCESS on success.
1345 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1346 * this function needs to be called again.
1347 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1348 * operation already pending.
1349 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1350 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1351 * is not set.
1352 */
1353 static TSS2_RC
execute_policy_action(ESYS_CONTEXT * esys_ctx,TPMS_POLICYACTION * policy,IFAPI_POLICY_EXEC_CTX * current_policy)1354 execute_policy_action(
1355 ESYS_CONTEXT *esys_ctx,
1356 TPMS_POLICYACTION *policy,
1357 IFAPI_POLICY_EXEC_CTX *current_policy)
1358 {
1359 TSS2_RC r = TSS2_RC_SUCCESS;
1360 (void)(esys_ctx);
1361 LOG_TRACE("call");
1362
1363 switch (current_policy->state) {
1364 statecase(current_policy->state, POLICY_EXECUTE_INIT);
1365 ifapi_policyeval_EXEC_CB *cb = ¤t_policy->callbacks;
1366
1367 /* Execute the callback and try it again if the callback is not finished. */
1368 r = cb->cbaction(policy->action, cb->cbaction_userdata);
1369 try_again_or_error(r, "Execute policy action callback.");
1370 return r;
1371
1372 statecasedefault(current_policy->state);
1373 }
1374 }
1375
1376 /** Execute a policy element depending on the type.
1377 *
1378 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1379 * policy command.
1380 * @param[in,out] policy The policy element with the policy to be executed and
1381 * the type of the policy.
1382 * @param[in,out] current_policy The policy context which stores the state
1383 * of the policy execution.
1384 * @retval TSS2_RC_SUCCESS on success.
1385 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occured.
1386 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1387 * this function needs to be called again.
1388 */
1389 static TSS2_RC
execute_policy_element(ESYS_CONTEXT * esys_ctx,TPMT_POLICYELEMENT * policy,TPMI_ALG_HASH hash_alg,IFAPI_POLICY_EXEC_CTX * current_policy)1390 execute_policy_element(
1391 ESYS_CONTEXT *esys_ctx,
1392 TPMT_POLICYELEMENT *policy,
1393 TPMI_ALG_HASH hash_alg,
1394 IFAPI_POLICY_EXEC_CTX *current_policy)
1395 {
1396 TSS2_RC r = TSS2_RC_SUCCESS;
1397
1398 LOG_TRACE("call");
1399
1400 switch (policy->type) {
1401 case POLICYSECRET:
1402 r = execute_policy_secret(esys_ctx,
1403 &policy->element.PolicySecret,
1404 hash_alg,
1405 current_policy);
1406 try_again_or_error_goto(r, "Execute policy authorize", error);
1407 break;
1408 case POLICYPCR:
1409 r = execute_policy_pcr(esys_ctx,
1410 &policy->element.PolicyPCR,
1411 hash_alg, current_policy);
1412 try_again_or_error_goto(r, "Execute policy pcr", error);
1413 break;
1414 case POLICYAUTHVALUE:
1415 r = execute_policy_auth_value(esys_ctx,
1416 &policy->element.PolicyAuthValue,
1417 current_policy);
1418 try_again_or_error_goto(r, "Execute policy auth value", error);
1419 break;
1420 case POLICYOR:
1421 r = execute_policy_or(esys_ctx,
1422 &policy->element.PolicyOr,
1423 hash_alg, current_policy);
1424 try_again_or_error_goto(r, "Execute policy or", error);
1425 break;
1426 case POLICYSIGNED:
1427 r = execute_policy_signed(esys_ctx,
1428 &policy->element.PolicySigned,
1429 current_policy);
1430 try_again_or_error_goto(r, "Execute policy signed", error);
1431 break;
1432 case POLICYAUTHORIZE:
1433 r = execute_policy_authorize(esys_ctx,
1434 &policy->element.PolicyAuthorize,
1435 hash_alg,
1436 current_policy);
1437 try_again_or_error_goto(r, "Execute policy authorize", error);
1438 break;
1439 case POLICYAUTHORIZENV:
1440 r = execute_policy_authorize_nv(esys_ctx,
1441 &policy->element.PolicyAuthorizeNv,
1442 hash_alg,
1443 current_policy);
1444 try_again_or_error_goto(r, "Execute policy authorize", error);
1445 break;
1446 case POLICYNV:
1447 r = execute_policy_nv(esys_ctx,
1448 &policy->element.PolicyNV,
1449 current_policy);
1450 try_again_or_error_goto(r, "Execute policy nv", error);
1451 break;
1452 case POLICYDUPLICATIONSELECT:
1453 r = execute_policy_duplicate(esys_ctx,
1454 &policy->element.PolicyDuplicationSelect,
1455 current_policy);
1456 try_again_or_error_goto(r, "Execute policy duplicate", error);
1457 break;
1458 case POLICYNVWRITTEN:
1459 r = execute_policy_nv_written(esys_ctx,
1460 &policy->element.PolicyNvWritten,
1461 current_policy);
1462 try_again_or_error_goto(r, "Execute policy nv written", error);
1463 break;
1464 case POLICYLOCALITY:
1465 r = execute_policy_locality(esys_ctx,
1466 &policy->element.PolicyLocality,
1467 current_policy);
1468 try_again_or_error_goto(r, "Execute policy locality", error);
1469 break;
1470 case POLICYCOMMANDCODE:
1471 r = execute_policy_command_code(esys_ctx,
1472 &policy->element.PolicyCommandCode,
1473 current_policy);
1474 try_again_or_error_goto(r, "Execute policy command code", error);
1475 break;
1476 case POLICYNAMEHASH:
1477 r = execute_policy_name_hash(esys_ctx,
1478 &policy->element.PolicyNameHash,
1479 current_policy);
1480 try_again_or_error_goto(r, "Execute policy name hash", error);
1481 break;
1482 case POLICYCPHASH:
1483 r = execute_policy_cp_hash(esys_ctx,
1484 &policy->element.PolicyCpHash,
1485 current_policy);
1486 try_again_or_error_goto(r, "Execute policy cp hash", error);
1487 break;
1488 case POLICYPHYSICALPRESENCE:
1489 r = execute_policy_physical_presence(esys_ctx,
1490 &policy->element.PolicyPhysicalPresence,
1491 current_policy);
1492 try_again_or_error_goto(r, "Execute policy physical presence", error);
1493 break;
1494 case POLICYPASSWORD:
1495 r = execute_policy_password(esys_ctx,
1496 &policy->element.PolicyPassword,
1497 current_policy);
1498 try_again_or_error_goto(r, "Execute policy password", error);
1499 break;
1500 case POLICYCOUNTERTIMER:
1501 r = execute_policy_counter_timer(esys_ctx,
1502 &policy->element.PolicyCounterTimer,
1503 current_policy);
1504 try_again_or_error_goto(r, "Execute policy counter timer", error);
1505 break;
1506 case POLICYACTION:
1507 r = execute_policy_action(esys_ctx,
1508 &policy->element.PolicyAction,
1509 current_policy);
1510 try_again_or_error_goto(r, "Execute policy action", error);
1511 break;
1512
1513 default:
1514 return_error(TSS2_FAPI_RC_GENERAL_FAILURE,
1515 "Policy not implemented");
1516 }
1517 return r;
1518 error:
1519 return r;
1520
1521 /* All policies executed successfully */
1522 return r;
1523 }
1524
1525 /** Compute execution order for policies based on branch selection.
1526 *
1527 * To simplify asynncronous policy executiion a linked list of the policy structures
1528 * needed for execution based on the result of the branch selection callbacks
1529 * is computed.
1530 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1531 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1532 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1533 * is not set.
1534 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1535 */
1536 static TSS2_RC
compute_policy_list(IFAPI_POLICY_EXEC_CTX * pol_ctx,TPML_POLICYELEMENTS * elements)1537 compute_policy_list(
1538 IFAPI_POLICY_EXEC_CTX *pol_ctx,
1539 TPML_POLICYELEMENTS *elements)
1540 {
1541 TSS2_RC r = TSS2_RC_SUCCESS;
1542 TPML_POLICYBRANCHES *branches;
1543 TPML_POLICYELEMENTS *or_elements;
1544 size_t branch_idx, i;
1545
1546 for (i = 0; i < elements->count; i++) {
1547 if (elements->elements[i].type == POLICYOR) {
1548 branches = elements->elements[i].element.PolicyOr.branches;
1549 r = pol_ctx->callbacks.cbpolsel(branches, &branch_idx,
1550 pol_ctx->callbacks.cbpolsel_userdata);
1551 return_if_error(r, "Select policy branch.");
1552 or_elements = branches->authorizations[branch_idx].policy;
1553 r = compute_policy_list(pol_ctx, or_elements);
1554 return_if_error(r, "Compute policy digest list for policy or.");
1555 }
1556 r = append_object_to_list(&elements->elements[i], &pol_ctx->policy_elements);
1557 return_if_error(r, "Extend policy list.");
1558 }
1559 return r;
1560 }
1561
1562 /** Initialize policy element list to be executed and store policy in context.
1563 *
1564 * @param[in] pol_ctx Context for execution of a list of policy elements.
1565 * @param[in] hash_alg The hash algorithm used for the policy computation.
1566 * @param[in,out] policy The policy to be executed. Some policy elements will
1567 * be used to store computed parameters needed for policy
1568 * execution.
1569 * @retval TSS2_RC_SUCCESS on success.
1570 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for branch selection is
1571 * not defined. This callback will be needed of or policies have to be
1572 * executed.
1573 * @retval TSS2_FAPI_RC_BAD_VALUE If the computed branch index deliverd by the
1574 * callback does not identify a branch.
1575 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1576 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1577 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1578 */
1579 TSS2_RC
ifapi_policyeval_execute_prepare(IFAPI_POLICY_EXEC_CTX * pol_ctx,TPMI_ALG_HASH hash_alg,TPMS_POLICY * policy)1580 ifapi_policyeval_execute_prepare(
1581 IFAPI_POLICY_EXEC_CTX *pol_ctx,
1582 TPMI_ALG_HASH hash_alg,
1583 TPMS_POLICY *policy)
1584 {
1585 TSS2_RC r;
1586
1587 pol_ctx->policy = policy;
1588 pol_ctx->hash_alg = hash_alg;
1589 r = compute_policy_list(pol_ctx, policy->policy);
1590 return_if_error(r, "Compute list of policy elements to be executed.");
1591
1592 return TSS2_RC_SUCCESS;
1593 }
1594
1595 /** Execute all policy commands defined by a list of policy elements.
1596 *
1597 * @retval TSS2_RC_SUCCESS on success.
1598 * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
1599 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
1600 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
1601 * store.
1602 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
1603 * not successful.
1604 * @retval TSS2_FAPI_RC_BAD_TEMPLATE In a invalid policy is loaded during execution.
1605 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1606 * this function needs to be called again.
1607 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1608 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1609 * operation already pending.
1610 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1611 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1612 * during authorization.
1613 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1614 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1615 * is not set.
1616 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1617 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1618 */
1619 TSS2_RC
ifapi_policyeval_execute(ESYS_CONTEXT * esys_ctx,IFAPI_POLICY_EXEC_CTX * current_policy)1620 ifapi_policyeval_execute(
1621 ESYS_CONTEXT *esys_ctx,
1622 IFAPI_POLICY_EXEC_CTX *current_policy)
1623
1624 {
1625 TSS2_RC r = TSS2_RC_SUCCESS;
1626 NODE_OBJECT_T *current_policy_element;
1627
1628 LOG_DEBUG("call");
1629
1630 while (current_policy->policy_elements) {
1631 r = execute_policy_element(esys_ctx,
1632 (TPMT_POLICYELEMENT *)
1633 current_policy->policy_elements->object,
1634 current_policy->hash_alg,
1635 current_policy);
1636 return_try_again(r);
1637
1638 if (r != TSS2_RC_SUCCESS) {
1639 Esys_FlushContext(esys_ctx, current_policy->session);
1640 current_policy->session = ESYS_TR_NONE;
1641 ifapi_free_node_list(current_policy->policy_elements);
1642
1643 }
1644 return_if_error(r, "Execute policy.");
1645
1646 current_policy_element = current_policy->policy_elements;
1647 current_policy->policy_elements = current_policy->policy_elements->next;
1648 SAFE_FREE(current_policy_element);
1649 }
1650 return r;
1651
1652 }
1653