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