xref: /aosp_15_r20/external/tpm2-tss/src/tss2-fapi/api/Fapi_CreateSeal.c (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3  * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
4  * All rights reserved.
5  ******************************************************************************/
6 
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10 
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <string.h>
16 
17 #include "tss2_fapi.h"
18 #include "fapi_int.h"
19 #include "fapi_util.h"
20 #include "fapi_policy.h"
21 #include "tss2_esys.h"
22 #define LOGMODULE fapi
23 #include "util/log.h"
24 #include "util/aux_util.h"
25 
26 /** One-Call function for Fapi_CreateSeal
27  *
28  * Creates a sealed object and stores it in the FAPI metadata store. If no data
29  * is provided, the TPM generates random data to fill the sealed object.
30  *
31  * @param[in,out] context The FAPI_CONTEXT
32  * @param[in] path The path to the new sealed object
33  * @param[in] type The type of the new sealed object. May be NULL
34  * @param[in] size The size of the new sealed object. Must not be 0
35  * @param[in] policyPath The path to the policy that is associated with the new
36  *            sealed object. May be NULL
37  * @param[in] authValue The authorization value for the new sealed object. May
38  *            be NULL
39  * @param[in] data The data that is to be sealed within the new object. May be
40  *            NULL
41  *
42  * @retval TSS2_RC_SUCCESS: if the function call was a success.
43  * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, or path is NULL.
44  * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
45  * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if the parent key does not map to a
46  *         FAPI key.
47  * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath is non-NULL and does not map to
48  *         a FAPI key.
49  * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if a sealed object already exists
50  *         at path.
51  * @retval TSS2_FAPI_RC_BAD_VALUE: if the keyType is invalid.
52  * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
53  *         operation already pending.
54  * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
55  * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
56  *         internal operations or return parameters.
57  * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
58  *         config file.
59  * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
60  *         this function needs to be called again.
61  * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
62  *         is not set.
63  * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
64  */
65 TSS2_RC
Fapi_CreateSeal(FAPI_CONTEXT * context,char const * path,char const * type,size_t size,char const * policyPath,char const * authValue,uint8_t const * data)66 Fapi_CreateSeal(
67     FAPI_CONTEXT *context,
68     char    const *path,
69     char    const *type,
70     size_t         size,
71     char    const *policyPath,
72     char    const *authValue,
73     uint8_t const *data)
74 {
75     LOG_TRACE("called for context:%p", context);
76 
77     TSS2_RC r, r2;
78 
79     /* Check for NULL parameters */
80     check_not_null(context);
81     check_not_null(path);
82 
83     /* Check whether TCTI and ESYS are initialized */
84     return_if_null(context->esys, "Command can't be executed in none TPM mode.",
85                    TSS2_FAPI_RC_NO_TPM);
86 
87     /* If the async state automata of FAPI shall be tested, then we must not set
88        the timeouts of ESYS to blocking mode.
89        During testing, the mssim tcti will ensure multiple re-invocations.
90        Usually however the synchronous invocations of FAPI shall instruct ESYS
91        to block until a result is available. */
92 #ifndef TEST_FAPI_ASYNC
93     r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
94     return_if_error_reset_state(r, "Set Timeout to blocking");
95 #endif /* TEST_FAPI_ASYNC */
96 
97     r = Fapi_CreateSeal_Async(context, path, type, size, policyPath,
98                               authValue, data);
99     return_if_error_reset_state(r, "CreateSeal");
100 
101     do {
102         /* We wait for file I/O to be ready if the FAPI state automata
103            are in a file I/O state. */
104         r = ifapi_io_poll(&context->io);
105         return_if_error(r, "Something went wrong with IO polling");
106 
107         /* Repeatedly call the finish function, until FAPI has transitioned
108            through all execution stages / states of this invocation. */
109         r = Fapi_CreateSeal_Finish(context);
110     } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
111 
112     /* Reset the ESYS timeout to non-blocking, immediate response. */
113     r2 = Esys_SetTimeout(context->esys, 0);
114     return_if_error(r2, "Set Timeout to non-blocking");
115 
116     return_if_error_reset_state(r, "CreateSeal");
117 
118     LOG_TRACE("finished");
119     return TSS2_RC_SUCCESS;
120 }
121 
122 /** Asynchronous function for Fapi_CreateSeal
123  *
124  * Creates a sealed object and stores it in the FAPI metadata store. If no data
125  * is provided, the TPM generates random data to fill the sealed object.
126  *
127  * Call Fapi_CreateSeal_Finish to finish the execution of this command.
128  *
129  * @param[in,out] context The FAPI_CONTEXT
130  * @param[in] path The path to the new sealed object
131  * @param[in] type The type of the new sealed object. May be NULL
132  * @param[in] size The size of the new sealed object. Must not be 0
133  * @param[in] policyPath The path to the policy that is associated with the new
134  *            sealed object. May be NULL
135  * @param[in] authValue The authorization value for the new sealed object. May
136  *            be NULL
137  * @param[in] data The data that is to be sealed within the new object. May be
138  *            NULL
139  *
140  * @retval TSS2_RC_SUCCESS: if the function call was a success.
141  * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, or path is NULL.
142  * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
143  * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if the parent key does not map to a
144  *         FAPI key.
145  * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath is non-NULL and does not map to
146  *         a FAPI key.
147  * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if a sealed object already exists
148  *         at path.
149  * @retval TSS2_FAPI_RC_BAD_VALUE: if the keyType is invalid.
150  * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
151  *         operation already pending.
152  * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
153  * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
154  *         internal operations or return parameters.
155  * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
156  *         config file.
157  */
158 TSS2_RC
Fapi_CreateSeal_Async(FAPI_CONTEXT * context,char const * path,char const * type,size_t size,char const * policyPath,char const * authValue,uint8_t const * data)159 Fapi_CreateSeal_Async(
160     FAPI_CONTEXT *context,
161     char    const *path,
162     char    const *type,
163     size_t         size,
164     char    const *policyPath,
165     char    const *authValue,
166     uint8_t const *data)
167 {
168     LOG_TRACE("called for context:%p", context);
169     LOG_TRACE("path: %s", path);
170     LOG_TRACE("type: %s", type);
171     LOG_TRACE("size: %zi", size);
172     LOG_TRACE("policyPath: %s", policyPath);
173     LOG_TRACE("authValue: %s", authValue);
174 
175     TSS2_RC r;
176 
177     /* Check for NULL parameters */
178     check_not_null(context);
179     check_not_null(path);
180 
181     /* Reset all context-internal session state information. */
182     r = ifapi_session_init(context);
183     return_if_error(r, "Initialize CreateSeal");
184 
185     /* Copy parameters to context for use during _Finish. */
186     memset(&context->cmd.Key_Create.public_templ, 0, sizeof(IFAPI_KEY_TEMPLATE));
187     r = ifapi_key_create_prepare_sensitive(context, path, policyPath, size,
188                                            authValue, data);
189     return_if_error(r, "Key create.");
190 
191     /* Set the flags of the NV index to be created. If no type is given the empty-string
192        default type flags are set. */
193     r = ifapi_set_key_flags(type ? type : "",
194                             (policyPath && strcmp(policyPath, "") != 0) ? true : false,
195                             &context->cmd.Key_Create.public_templ);
196     return_if_error(r, "Set key flags for key");
197 
198     context->cmd.Key_Create.public_templ.public.publicArea.objectAttributes  &=
199         ~TPMA_OBJECT_SENSITIVEDATAORIGIN;
200 
201     /* Initialize the context state for this operation. */
202     context->state = CREATE_SEAL;
203 
204     LOG_TRACE("finished");
205     return TSS2_RC_SUCCESS;
206 }
207 
208 /** Asynchronous finish function for Fapi_CreateSeal
209  *
210  * This function should be called after a previous Fapi_CreateSeal.
211  *
212  * @param[in,out] context The FAPI_CONTEXT
213  *
214  * @retval TSS2_RC_SUCCESS: if the function call was a success.
215  * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
216  * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
217  * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
218  *         operation already pending.
219  * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
220  * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
221  *         internal operations or return parameters.
222  * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
223  *         complete. Call this function again later.
224  * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
225  *         the function.
226  * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
227  *         is not set.
228  * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
229  */
230 TSS2_RC
Fapi_CreateSeal_Finish(FAPI_CONTEXT * context)231 Fapi_CreateSeal_Finish(
232     FAPI_CONTEXT *context)
233 {
234     LOG_TRACE("called for context:%p", context);
235 
236     TSS2_RC r;
237 
238     /* Check for NULL parameters */
239     check_not_null(context);
240 
241     switch (context->state) {
242         statecase(context->state, CREATE_SEAL);
243             /* Create the seal object. A seal object internally is a so-called
244                KEYED_HASH object and created in the same way as a regular key.
245                Thus the function name ifapi_key_create(). */
246             r = ifapi_key_create(context, &context->cmd.Key_Create.public_templ);
247             return_try_again(r);
248             goto_if_error(r, "Key create", error_cleanup);
249             break;
250 
251         statecasedefault(context->state);
252     }
253 
254 error_cleanup:
255    /* Cleanup any intermediate results and state stored in the context. */
256     ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
257     ifapi_cleanup_ifapi_object(context->loadKey.key_object);
258     ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
259     context->state = _FAPI_STATE_INIT;
260     LOG_TRACE("finished");
261     return r;
262 }
263