xref: /aosp_15_r20/external/tpm2-tss/src/tss2-fapi/ifapi_policy_execute.c (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
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 = &current_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, &current_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 = &current_policy->callbacks;
325 
326         /* Authorize NV object. */
327         r = cb->cbauth(&current_policy->name,
328                        &current_policy->object_handle,
329                        &current_policy->auth_handle,
330                        &current_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                                     &current_policy->nonceTPM);
408         return_if_error(r, "Get TPM nonce.");
409 
410         /* Concatenate objects needed for the authorization hash */
411         memcpy(&current_policy->buffer[offset], &current_policy->nonceTPM->buffer[0],
412                current_policy->nonceTPM->size);
413         offset += current_policy->nonceTPM->size;
414         memset(&current_policy->buffer[offset], 0, sizeof(INT32));
415         offset += sizeof(INT32);
416         memcpy(&current_policy->buffer[offset], &policy->cpHashA.buffer[0],
417                policy->cpHashA.size);
418         offset += policy->cpHashA.size;
419         memcpy(&current_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 = &current_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, &current_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, &current_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 = &current_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, &current_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 = &current_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, &current_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(&current_policy->name,
726                        &current_policy->object_handle,
727                        &current_policy->auth_handle,
728                        &current_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 = &current_policy->callbacks;
796         /* Callback for the object authorization. */
797         r = cb->cbauth(&policy->objectName,
798                        &current_policy->object_handle,
799                        &current_policy->auth_handle,
800                    &current_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                                     &current_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                                       &current_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                                 &current_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 = &current_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