xref: /aosp_15_r20/external/tpm2-tss/src/tss2-fapi/ifapi_policyutil_execute.c (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
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_policyutil_execute.h"
20*758e9fbaSOystein Eftevaag #include "ifapi_helpers.h"
21*758e9fbaSOystein Eftevaag #include "ifapi_json_deserialize.h"
22*758e9fbaSOystein Eftevaag #include "tpm_json_deserialize.h"
23*758e9fbaSOystein Eftevaag #include "ifapi_policy_callbacks.h"
24*758e9fbaSOystein Eftevaag #include "ifapi_policyutil_execute.h"
25*758e9fbaSOystein Eftevaag #define LOGMODULE fapi
26*758e9fbaSOystein Eftevaag #include "util/log.h"
27*758e9fbaSOystein Eftevaag #include "util/aux_util.h"
28*758e9fbaSOystein Eftevaag 
29*758e9fbaSOystein Eftevaag /** Create a new policy on policy stack.
30*758e9fbaSOystein Eftevaag  *
31*758e9fbaSOystein Eftevaag  * The structures for policy and callback execution are allocated
32*758e9fbaSOystein Eftevaag  * and the callbacks are assigned.
33*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
34*758e9fbaSOystein Eftevaag  */
35*758e9fbaSOystein Eftevaag static TSS2_RC
new_policy(FAPI_CONTEXT * context,TPMS_POLICY * policy,IFAPI_POLICYUTIL_STACK ** current_policy)36*758e9fbaSOystein Eftevaag new_policy(
37*758e9fbaSOystein Eftevaag     FAPI_CONTEXT *context,
38*758e9fbaSOystein Eftevaag     TPMS_POLICY *policy,
39*758e9fbaSOystein Eftevaag     IFAPI_POLICYUTIL_STACK **current_policy)
40*758e9fbaSOystein Eftevaag {
41*758e9fbaSOystein Eftevaag     LOG_DEBUG("ADD POLICY");
42*758e9fbaSOystein Eftevaag     IFAPI_POLICY_EXEC_CTX *pol_exec_ctx;
43*758e9fbaSOystein Eftevaag     IFAPI_POLICY_EXEC_CB_CTX *pol_exec_cb_ctx;
44*758e9fbaSOystein Eftevaag 
45*758e9fbaSOystein Eftevaag     *current_policy = calloc(sizeof(IFAPI_POLICYUTIL_STACK), 1);
46*758e9fbaSOystein Eftevaag     if (!*current_policy) {
47*758e9fbaSOystein Eftevaag         return_error(TSS2_FAPI_RC_MEMORY, "Out of memory");
48*758e9fbaSOystein Eftevaag     }
49*758e9fbaSOystein Eftevaag 
50*758e9fbaSOystein Eftevaag     pol_exec_ctx = calloc(sizeof(IFAPI_POLICY_EXEC_CTX), 1);
51*758e9fbaSOystein Eftevaag     if (!pol_exec_ctx) {
52*758e9fbaSOystein Eftevaag         return_error(TSS2_FAPI_RC_MEMORY, "Out of memory");
53*758e9fbaSOystein Eftevaag     }
54*758e9fbaSOystein Eftevaag     (*current_policy)->pol_exec_ctx = pol_exec_ctx;
55*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbauth = ifapi_policyeval_cbauth;
56*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbauth_userdata = context;
57*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbpolsel = ifapi_branch_selection;
58*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbpolsel_userdata = context;
59*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbsign = ifapi_sign_buffer;
60*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbsign_userdata = context;
61*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbauthpol = ifapi_exec_auth_policy;
62*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbauthpol_userdata = context;
63*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbauthnv = ifapi_exec_auth_nv_policy;
64*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbauthnv_userdata = context;
65*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbdup = ifapi_get_duplicate_name;
66*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbdup_userdata = context;
67*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbaction = ifapi_policy_action;
68*758e9fbaSOystein Eftevaag     pol_exec_ctx->callbacks.cbaction_userdata = context;
69*758e9fbaSOystein Eftevaag 
70*758e9fbaSOystein Eftevaag     pol_exec_cb_ctx = calloc(sizeof(IFAPI_POLICY_EXEC_CB_CTX), 1);
71*758e9fbaSOystein Eftevaag     if (!pol_exec_cb_ctx) {
72*758e9fbaSOystein Eftevaag         return_error(TSS2_FAPI_RC_MEMORY, "Out of memory");
73*758e9fbaSOystein Eftevaag     }
74*758e9fbaSOystein Eftevaag     pol_exec_ctx->app_data = pol_exec_cb_ctx;
75*758e9fbaSOystein Eftevaag     pol_exec_ctx->policy = policy;
76*758e9fbaSOystein Eftevaag     if (!context->policy.policyutil_stack) {
77*758e9fbaSOystein Eftevaag         context->policy.policyutil_stack = *current_policy;
78*758e9fbaSOystein Eftevaag         context->policy.util_current_policy = *current_policy;
79*758e9fbaSOystein Eftevaag     } else {
80*758e9fbaSOystein Eftevaag         context->policy.util_current_policy->next = *current_policy;
81*758e9fbaSOystein Eftevaag         (*current_policy)->prev = context->policy.util_current_policy;
82*758e9fbaSOystein Eftevaag     }
83*758e9fbaSOystein Eftevaag     return TSS2_RC_SUCCESS;
84*758e9fbaSOystein Eftevaag }
85*758e9fbaSOystein Eftevaag 
86*758e9fbaSOystein Eftevaag /** Compute a new session which will be uses as policy session.
87*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
88*758e9fbaSOystein Eftevaag  *         this function needs to be called again.
89*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
90*758e9fbaSOystein Eftevaag  * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
91*758e9fbaSOystein Eftevaag  */
92*758e9fbaSOystein Eftevaag static TSS2_RC
create_session(FAPI_CONTEXT * context,ESYS_TR * session,TPMI_ALG_HASH hash_alg)93*758e9fbaSOystein Eftevaag create_session(
94*758e9fbaSOystein Eftevaag     FAPI_CONTEXT *context,
95*758e9fbaSOystein Eftevaag     ESYS_TR *session,
96*758e9fbaSOystein Eftevaag     TPMI_ALG_HASH hash_alg)
97*758e9fbaSOystein Eftevaag {
98*758e9fbaSOystein Eftevaag     TSS2_RC r = TSS2_RC_SUCCESS;
99*758e9fbaSOystein Eftevaag 
100*758e9fbaSOystein Eftevaag     switch (context->policy.create_session_state) {
101*758e9fbaSOystein Eftevaag     case CREATE_SESSION_INIT:
102*758e9fbaSOystein Eftevaag         r = Esys_StartAuthSession_Async(context->esys,
103*758e9fbaSOystein Eftevaag                                         context->srk_handle ? context->srk_handle : ESYS_TR_NONE,
104*758e9fbaSOystein Eftevaag                                         ESYS_TR_NONE,
105*758e9fbaSOystein Eftevaag                                         ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
106*758e9fbaSOystein Eftevaag                                         NULL,
107*758e9fbaSOystein Eftevaag                                         TPM2_SE_POLICY,
108*758e9fbaSOystein Eftevaag                                         &context->profiles.default_profile.session_symmetric,
109*758e9fbaSOystein Eftevaag                                         hash_alg);
110*758e9fbaSOystein Eftevaag 
111*758e9fbaSOystein Eftevaag         return_if_error(r, "Creating session.");
112*758e9fbaSOystein Eftevaag 
113*758e9fbaSOystein Eftevaag         context->policy.create_session_state = WAIT_FOR_CREATE_SESSION;
114*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_TRY_AGAIN;
115*758e9fbaSOystein Eftevaag 
116*758e9fbaSOystein Eftevaag     case WAIT_FOR_CREATE_SESSION:
117*758e9fbaSOystein Eftevaag         r = Esys_StartAuthSession_Finish(context->esys, session);
118*758e9fbaSOystein Eftevaag         if (r != TSS2_RC_SUCCESS)
119*758e9fbaSOystein Eftevaag             return r;
120*758e9fbaSOystein Eftevaag         context->policy.create_session_state = CREATE_SESSION_INIT;
121*758e9fbaSOystein Eftevaag         break;
122*758e9fbaSOystein Eftevaag 
123*758e9fbaSOystein Eftevaag     default:
124*758e9fbaSOystein Eftevaag         context->state = _FAPI_STATE_INTERNALERROR;
125*758e9fbaSOystein Eftevaag         goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid state for create session.",
126*758e9fbaSOystein Eftevaag                    cleanup);
127*758e9fbaSOystein Eftevaag     }
128*758e9fbaSOystein Eftevaag 
129*758e9fbaSOystein Eftevaag cleanup:
130*758e9fbaSOystein Eftevaag     return r;
131*758e9fbaSOystein Eftevaag }
132*758e9fbaSOystein Eftevaag 
133*758e9fbaSOystein Eftevaag /** Cleanup the current policy and adapt the policy stack.
134*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
135*758e9fbaSOystein Eftevaag  */
136*758e9fbaSOystein Eftevaag static TSS2_RC
clear_current_policy(FAPI_CONTEXT * context)137*758e9fbaSOystein Eftevaag clear_current_policy(FAPI_CONTEXT *context)
138*758e9fbaSOystein Eftevaag {
139*758e9fbaSOystein Eftevaag     LOG_DEBUG("CLEAR POLICY");
140*758e9fbaSOystein Eftevaag     IFAPI_POLICYUTIL_STACK *prev_pol;
141*758e9fbaSOystein Eftevaag     if (!context->policy.util_current_policy) {
142*758e9fbaSOystein Eftevaag         return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "No current policy.");
143*758e9fbaSOystein Eftevaag     }
144*758e9fbaSOystein Eftevaag     prev_pol = context->policy.util_current_policy->prev;
145*758e9fbaSOystein Eftevaag 
146*758e9fbaSOystein Eftevaag     SAFE_FREE(context->policy.util_current_policy->pol_exec_ctx->app_data);
147*758e9fbaSOystein Eftevaag     SAFE_FREE(context->policy.util_current_policy->pol_exec_ctx);
148*758e9fbaSOystein Eftevaag     SAFE_FREE(context->policy.util_current_policy);
149*758e9fbaSOystein Eftevaag 
150*758e9fbaSOystein Eftevaag     if (!prev_pol) {
151*758e9fbaSOystein Eftevaag         context->policy.policyutil_stack = NULL;
152*758e9fbaSOystein Eftevaag     } else {
153*758e9fbaSOystein Eftevaag         prev_pol->next = NULL;
154*758e9fbaSOystein Eftevaag     }
155*758e9fbaSOystein Eftevaag     return TSS2_RC_SUCCESS;
156*758e9fbaSOystein Eftevaag }
157*758e9fbaSOystein Eftevaag 
158*758e9fbaSOystein Eftevaag /** Cleanup the policy stack.
159*758e9fbaSOystein Eftevaag   *
160*758e9fbaSOystein Eftevaag   * Will be used if an error occurs.
161*758e9fbaSOystein Eftevaag   */
162*758e9fbaSOystein Eftevaag static void
clear_all_policies(FAPI_CONTEXT * context)163*758e9fbaSOystein Eftevaag clear_all_policies(FAPI_CONTEXT *context)
164*758e9fbaSOystein Eftevaag {
165*758e9fbaSOystein Eftevaag     LOG_DEBUG("CLEAR ALL POLICIES");
166*758e9fbaSOystein Eftevaag 
167*758e9fbaSOystein Eftevaag     IFAPI_POLICYUTIL_STACK *policy = context->policy.policyutil_stack;
168*758e9fbaSOystein Eftevaag     IFAPI_POLICYUTIL_STACK *next_policy;
169*758e9fbaSOystein Eftevaag 
170*758e9fbaSOystein Eftevaag     while (policy) {
171*758e9fbaSOystein Eftevaag         next_policy = policy->next;
172*758e9fbaSOystein Eftevaag         SAFE_FREE(policy->pol_exec_ctx->app_data);
173*758e9fbaSOystein Eftevaag         if (policy->pol_exec_ctx->session)
174*758e9fbaSOystein Eftevaag             Esys_FlushContext(context->esys, policy->pol_exec_ctx->session);
175*758e9fbaSOystein Eftevaag         SAFE_FREE(policy->pol_exec_ctx);
176*758e9fbaSOystein Eftevaag         ;
177*758e9fbaSOystein Eftevaag         SAFE_FREE(policy);
178*758e9fbaSOystein Eftevaag         policy = next_policy;
179*758e9fbaSOystein Eftevaag     }
180*758e9fbaSOystein Eftevaag     context->policy.policyutil_stack = NULL;
181*758e9fbaSOystein Eftevaag }
182*758e9fbaSOystein Eftevaag 
183*758e9fbaSOystein Eftevaag /** Prepare the execution of a new policy on policy stack.
184*758e9fbaSOystein Eftevaag  *
185*758e9fbaSOystein Eftevaag  * The context for the  policy utility, the policy execution and the needed
186*758e9fbaSOystein Eftevaag  * callbacks is initialized.
187*758e9fbaSOystein Eftevaag  * The policy execution will be prepared. In this step the list of policies
188*758e9fbaSOystein Eftevaag  * to be executed will be computed.
189*758e9fbaSOystein Eftevaag  * @param[in,out] context The fapi context with the pointer to the policy stack.
190*758e9fbaSOystein Eftevaag  * @param[in] hash_alg The hash algorithm used for the policy computation.
191*758e9fbaSOystein Eftevaag  * @param[in,out] policy The policy to be executed. Some policy elements will
192*758e9fbaSOystein Eftevaag  *                be used to store computed parameters needed for policy
193*758e9fbaSOystein Eftevaag  *                execution.
194*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS on success.
195*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for branch selection is
196*758e9fbaSOystein Eftevaag  *         not defined. This callback will be needed of or policies have to be
197*758e9fbaSOystein Eftevaag  *         executed.
198*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_VALUE If the computed branch index deliverd by the
199*758e9fbaSOystein Eftevaag  *         callback does not identify a branch.
200*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_REFERENCE If no context is passed.
201*758e9fbaSOystein Eftevaag  *
202*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
203*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
204*758e9fbaSOystein Eftevaag  * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
205*758e9fbaSOystein Eftevaag  */
206*758e9fbaSOystein Eftevaag TSS2_RC
ifapi_policyutil_execute_prepare(FAPI_CONTEXT * context,TPMI_ALG_HASH hash_alg,TPMS_POLICY * policy)207*758e9fbaSOystein Eftevaag ifapi_policyutil_execute_prepare(
208*758e9fbaSOystein Eftevaag     FAPI_CONTEXT *context,
209*758e9fbaSOystein Eftevaag     TPMI_ALG_HASH hash_alg,
210*758e9fbaSOystein Eftevaag     TPMS_POLICY *policy)
211*758e9fbaSOystein Eftevaag {
212*758e9fbaSOystein Eftevaag     TSS2_RC r;
213*758e9fbaSOystein Eftevaag     IFAPI_POLICYUTIL_STACK *current_policy;
214*758e9fbaSOystein Eftevaag 
215*758e9fbaSOystein Eftevaag     return_if_null(context, "Bad context.", TSS2_FAPI_RC_BAD_REFERENCE);
216*758e9fbaSOystein Eftevaag 
217*758e9fbaSOystein Eftevaag     r = new_policy(context, policy, &current_policy);
218*758e9fbaSOystein Eftevaag     goto_if_error(r, "Create new policy.", error);
219*758e9fbaSOystein Eftevaag 
220*758e9fbaSOystein Eftevaag     r = ifapi_policyeval_execute_prepare(current_policy->pol_exec_ctx, hash_alg, policy);
221*758e9fbaSOystein Eftevaag     goto_if_error(r, "Prepare policy execution.", error);
222*758e9fbaSOystein Eftevaag 
223*758e9fbaSOystein Eftevaag     return r;
224*758e9fbaSOystein Eftevaag 
225*758e9fbaSOystein Eftevaag error:
226*758e9fbaSOystein Eftevaag     while (context->policy.policyutil_stack) {
227*758e9fbaSOystein Eftevaag         clear_all_policies(context);
228*758e9fbaSOystein Eftevaag     }
229*758e9fbaSOystein Eftevaag     SAFE_FREE(current_policy);
230*758e9fbaSOystein Eftevaag     return r;
231*758e9fbaSOystein Eftevaag }
232*758e9fbaSOystein Eftevaag /** State machine to Execute the TPM policy commands needed for the current policy.
233*758e9fbaSOystein Eftevaag  *
234*758e9fbaSOystein Eftevaag  * In the first step a session will be created if no session is passed.
235*758e9fbaSOystein Eftevaag  * In the second step the policy engine will execute the policy.
236*758e9fbaSOystein Eftevaag  *
237*758e9fbaSOystein Eftevaag  * @param[in,out] context The fapi context with the pointer to the policy stack.
238*758e9fbaSOystein Eftevaag  * @param[in,out] session The policy session to be extended or if the value is
239*758e9fbaSOystein Eftevaag  *                equal zero or ESYS_TR_NONE a new created session will been
240*758e9fbaSOystein Eftevaag  *                be stored in this parameter.
241*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS on success.
242*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
243*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
244*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
245*758e9fbaSOystein Eftevaag  *         store.
246*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
247*758e9fbaSOystein Eftevaag  *         not successful.
248*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_TEMPLATE In a invalid policy is loaded during execution.
249*758e9fbaSOystein Eftevaag  * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for policy
250*758e9fbaSOystein Eftevaag  *         execution fails.
251*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
252*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
253*758e9fbaSOystein Eftevaag  *         this function needs to be called again.
254*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
255*758e9fbaSOystein Eftevaag  *         operation already pending.
256*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
257*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
258*758e9fbaSOystein Eftevaag  *         during authorization.
259*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
260*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
261*758e9fbaSOystein Eftevaag  *         is not set.
262*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
263*758e9fbaSOystein Eftevaag  * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
264*758e9fbaSOystein Eftevaag  */
265*758e9fbaSOystein Eftevaag TSS2_RC
ifapi_policyutil_execute(FAPI_CONTEXT * context,ESYS_TR * session)266*758e9fbaSOystein Eftevaag ifapi_policyutil_execute(FAPI_CONTEXT *context, ESYS_TR *session)
267*758e9fbaSOystein Eftevaag {
268*758e9fbaSOystein Eftevaag     TSS2_RC r;
269*758e9fbaSOystein Eftevaag     IFAPI_POLICYUTIL_STACK *pol_util_ctx;
270*758e9fbaSOystein Eftevaag     TPMI_ALG_HASH hash_alg;
271*758e9fbaSOystein Eftevaag 
272*758e9fbaSOystein Eftevaag     if (context->policy.util_current_policy) {
273*758e9fbaSOystein Eftevaag         pol_util_ctx = context->policy.util_current_policy->next;
274*758e9fbaSOystein Eftevaag         context->policy.util_current_policy = context->policy.util_current_policy->next;
275*758e9fbaSOystein Eftevaag     } else {
276*758e9fbaSOystein Eftevaag         pol_util_ctx = context->policy.policyutil_stack;
277*758e9fbaSOystein Eftevaag         context->policy.util_current_policy = pol_util_ctx;
278*758e9fbaSOystein Eftevaag     }
279*758e9fbaSOystein Eftevaag     LOG_TRACE("Util context: %p", pol_util_ctx);
280*758e9fbaSOystein Eftevaag 
281*758e9fbaSOystein Eftevaag     if (!pol_util_ctx) {
282*758e9fbaSOystein Eftevaag         return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "No policy util stack.");
283*758e9fbaSOystein Eftevaag     }
284*758e9fbaSOystein Eftevaag 
285*758e9fbaSOystein Eftevaag     switch (pol_util_ctx->state) {
286*758e9fbaSOystein Eftevaag         statecase(pol_util_ctx->state, POLICY_UTIL_INIT);
287*758e9fbaSOystein Eftevaag             LOG_DEBUG("Util session: %x", pol_util_ctx->policy_session);
288*758e9fbaSOystein Eftevaag             if (*session == ESYS_TR_NONE  || *session == 0) {
289*758e9fbaSOystein Eftevaag                 /* Create a new  policy session for the current policy execution */
290*758e9fbaSOystein Eftevaag                 hash_alg = pol_util_ctx->pol_exec_ctx->hash_alg;
291*758e9fbaSOystein Eftevaag                 r = create_session(context, &pol_util_ctx->policy_session,
292*758e9fbaSOystein Eftevaag                                   hash_alg);
293*758e9fbaSOystein Eftevaag                 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
294*758e9fbaSOystein Eftevaag                     context->policy.util_current_policy = pol_util_ctx->prev;
295*758e9fbaSOystein Eftevaag                     return TSS2_FAPI_RC_TRY_AGAIN;
296*758e9fbaSOystein Eftevaag                 }
297*758e9fbaSOystein Eftevaag                 goto_if_error(r, "Create policy session", error);
298*758e9fbaSOystein Eftevaag 
299*758e9fbaSOystein Eftevaag                 pol_util_ctx->pol_exec_ctx->session = pol_util_ctx->policy_session;
300*758e9fbaSOystein Eftevaag             } else {
301*758e9fbaSOystein Eftevaag                 pol_util_ctx->pol_exec_ctx->session = *session;
302*758e9fbaSOystein Eftevaag             }
303*758e9fbaSOystein Eftevaag             fallthrough;
304*758e9fbaSOystein Eftevaag 
305*758e9fbaSOystein Eftevaag         statecase(pol_util_ctx->state, POLICY_UTIL_EXEC_POLICY);
306*758e9fbaSOystein Eftevaag             r = ifapi_policyeval_execute(context->esys,
307*758e9fbaSOystein Eftevaag                                          pol_util_ctx->pol_exec_ctx);
308*758e9fbaSOystein Eftevaag             if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
309*758e9fbaSOystein Eftevaag                 context->policy.util_current_policy = pol_util_ctx->prev;
310*758e9fbaSOystein Eftevaag                 return TSS2_FAPI_RC_TRY_AGAIN;
311*758e9fbaSOystein Eftevaag             }
312*758e9fbaSOystein Eftevaag             goto_if_error(r, "Execute policy.", error);
313*758e9fbaSOystein Eftevaag 
314*758e9fbaSOystein Eftevaag             break;
315*758e9fbaSOystein Eftevaag 
316*758e9fbaSOystein Eftevaag         statecasedefault(pol_util_ctx->state);
317*758e9fbaSOystein Eftevaag     }
318*758e9fbaSOystein Eftevaag     *session = pol_util_ctx->policy_session;
319*758e9fbaSOystein Eftevaag 
320*758e9fbaSOystein Eftevaag     pol_util_ctx = pol_util_ctx->prev;
321*758e9fbaSOystein Eftevaag 
322*758e9fbaSOystein Eftevaag     r = clear_current_policy(context);
323*758e9fbaSOystein Eftevaag     goto_if_error(r, "Clear policy.", error);
324*758e9fbaSOystein Eftevaag 
325*758e9fbaSOystein Eftevaag     context->policy.util_current_policy = pol_util_ctx;
326*758e9fbaSOystein Eftevaag 
327*758e9fbaSOystein Eftevaag     LOG_TRACE("success");
328*758e9fbaSOystein Eftevaag     return r;
329*758e9fbaSOystein Eftevaag 
330*758e9fbaSOystein Eftevaag error:
331*758e9fbaSOystein Eftevaag     while (context->policy.policyutil_stack) {
332*758e9fbaSOystein Eftevaag         clear_all_policies(context);
333*758e9fbaSOystein Eftevaag     }
334*758e9fbaSOystein Eftevaag     return r;
335*758e9fbaSOystein Eftevaag }
336