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