xref: /aosp_15_r20/external/tpm2-tss/src/tss2-fapi/ifapi_profiles.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 <stdint.h>
12*758e9fbaSOystein Eftevaag #include <stdlib.h>
13*758e9fbaSOystein Eftevaag #include <string.h>
14*758e9fbaSOystein Eftevaag 
15*758e9fbaSOystein Eftevaag #include "tss2_common.h"
16*758e9fbaSOystein Eftevaag 
17*758e9fbaSOystein Eftevaag #include "ifapi_profiles.h"
18*758e9fbaSOystein Eftevaag 
19*758e9fbaSOystein Eftevaag #include "tpm_json_deserialize.h"
20*758e9fbaSOystein Eftevaag #include "ifapi_policy_json_deserialize.h"
21*758e9fbaSOystein Eftevaag #include "ifapi_json_deserialize.h"
22*758e9fbaSOystein Eftevaag #include "ifapi_helpers.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 #include "ifapi_macros.h"
27*758e9fbaSOystein Eftevaag 
28*758e9fbaSOystein Eftevaag #define PROFILES_EXTENSION ".json"
29*758e9fbaSOystein Eftevaag #define PROFILES_PREFIX "P_"
30*758e9fbaSOystein Eftevaag 
31*758e9fbaSOystein Eftevaag static TSS2_RC
32*758e9fbaSOystein Eftevaag ifapi_profile_json_deserialize(
33*758e9fbaSOystein Eftevaag     json_object *jso,
34*758e9fbaSOystein Eftevaag     IFAPI_PROFILE *profile);
35*758e9fbaSOystein Eftevaag 
36*758e9fbaSOystein Eftevaag static TSS2_RC
37*758e9fbaSOystein Eftevaag ifapi_profile_checkpcrs(const TPML_PCR_SELECTION *pcr_profile);
38*758e9fbaSOystein Eftevaag 
39*758e9fbaSOystein Eftevaag /** Initialize the profiles information in the context in an asynchronous way
40*758e9fbaSOystein Eftevaag  *
41*758e9fbaSOystein Eftevaag  * Load the profile information from disk, fill the dictionary of loaded profiles and fill
42*758e9fbaSOystein Eftevaag  * the default profile information into the context.
43*758e9fbaSOystein Eftevaag  *
44*758e9fbaSOystein Eftevaag  * Call ifapi_profiles_initialize_finish to complete the operation.
45*758e9fbaSOystein Eftevaag  *
46*758e9fbaSOystein Eftevaag  * @param[in,out] profiles The context for the profiles information.
47*758e9fbaSOystein Eftevaag  * @param[in,out] io The input/output context being used for file I/O.
48*758e9fbaSOystein Eftevaag  * @param[in] profilesdir The directory to load profile information from.
49*758e9fbaSOystein Eftevaag  * @param[in] defaultprofile The name of the default profile to use.
50*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS on success.
51*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_REFERENCE if NULL pointers were passed in.
52*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_VALUE if the profilesdir does not exist or is empty.
53*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
54*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
55*758e9fbaSOystein Eftevaag  */
56*758e9fbaSOystein Eftevaag TSS2_RC
ifapi_profiles_initialize_async(IFAPI_PROFILES * profiles,IFAPI_IO * io,const char * profilesdir,const char * defaultprofile)57*758e9fbaSOystein Eftevaag ifapi_profiles_initialize_async(
58*758e9fbaSOystein Eftevaag     IFAPI_PROFILES *profiles,
59*758e9fbaSOystein Eftevaag     IFAPI_IO *io,
60*758e9fbaSOystein Eftevaag     const char *profilesdir,
61*758e9fbaSOystein Eftevaag     const char *defaultprofile)
62*758e9fbaSOystein Eftevaag {
63*758e9fbaSOystein Eftevaag     TSS2_RC r;
64*758e9fbaSOystein Eftevaag     char *tmp;
65*758e9fbaSOystein Eftevaag     size_t i, j;
66*758e9fbaSOystein Eftevaag     check_not_null(profiles);
67*758e9fbaSOystein Eftevaag     check_not_null(profilesdir);
68*758e9fbaSOystein Eftevaag 
69*758e9fbaSOystein Eftevaag     memset(profiles, 0, sizeof(*profiles));
70*758e9fbaSOystein Eftevaag 
71*758e9fbaSOystein Eftevaag     profiles->default_name = strdup(defaultprofile);
72*758e9fbaSOystein Eftevaag     check_oom(profiles->default_name);
73*758e9fbaSOystein Eftevaag 
74*758e9fbaSOystein Eftevaag     r = ifapi_io_dirfiles(profilesdir, &profiles->filenames, &profiles->num_profiles);
75*758e9fbaSOystein Eftevaag     return_if_error(r, "Reading profiles from profiles dir");
76*758e9fbaSOystein Eftevaag 
77*758e9fbaSOystein Eftevaag     profiles->profiles = calloc(profiles->num_profiles, sizeof(profiles->profiles[0]));
78*758e9fbaSOystein Eftevaag     check_oom(profiles->profiles);
79*758e9fbaSOystein Eftevaag 
80*758e9fbaSOystein Eftevaag     /* Clean up list of files to only include those that match our filename pattern
81*758e9fbaSOystein Eftevaag        Expand the filenames with the directory
82*758e9fbaSOystein Eftevaag        Set the names in the dictionary */
83*758e9fbaSOystein Eftevaag     for (i = 0; i < profiles->num_profiles; ) {
84*758e9fbaSOystein Eftevaag         char *ext = strstr(profiles->filenames[i], PROFILES_EXTENSION);
85*758e9fbaSOystein Eftevaag         /* Path the filename with the expected pattern */
86*758e9fbaSOystein Eftevaag         if (ext != NULL && strlen(ext) == strlen(PROFILES_EXTENSION) &&
87*758e9fbaSOystein Eftevaag                 strncmp(profiles->filenames[i], PROFILES_PREFIX, strlen(PROFILES_PREFIX)) == 0)
88*758e9fbaSOystein Eftevaag         {
89*758e9fbaSOystein Eftevaag             LOG_TRACE("Using file %s in profiles directory", profiles->filenames[i]);
90*758e9fbaSOystein Eftevaag             /* Add the profile name */
91*758e9fbaSOystein Eftevaag             profiles->profiles[i].name = strndup(profiles->filenames[i],
92*758e9fbaSOystein Eftevaag                                                  ext - profiles->filenames[i]);
93*758e9fbaSOystein Eftevaag             check_oom(profiles->profiles[i].name);
94*758e9fbaSOystein Eftevaag             /* Expand the filename with the directory */
95*758e9fbaSOystein Eftevaag             tmp = profiles->filenames[i];
96*758e9fbaSOystein Eftevaag             r = ifapi_asprintf(&profiles->filenames[i], "%s/%s", profilesdir, tmp);
97*758e9fbaSOystein Eftevaag             return_if_error(r, "Out of memory");
98*758e9fbaSOystein Eftevaag 
99*758e9fbaSOystein Eftevaag             LOG_TRACE("Added profile-entry %s for file %s based on direntry %s",
100*758e9fbaSOystein Eftevaag                       profiles->profiles[i].name, profiles->filenames[i], tmp);
101*758e9fbaSOystein Eftevaag 
102*758e9fbaSOystein Eftevaag             /* Cleanup and continue */
103*758e9fbaSOystein Eftevaag             free(tmp);
104*758e9fbaSOystein Eftevaag             i++;
105*758e9fbaSOystein Eftevaag         } else {
106*758e9fbaSOystein Eftevaag             LOG_TRACE("Skipping file %s in profiles directory", profiles->filenames[i]);
107*758e9fbaSOystein Eftevaag             free(profiles->filenames[i]);
108*758e9fbaSOystein Eftevaag             profiles->num_profiles -= 1;
109*758e9fbaSOystein Eftevaag             for (j = i; j < profiles->num_profiles; j++) {
110*758e9fbaSOystein Eftevaag                 profiles->filenames[j] = profiles->filenames[j + 1];
111*758e9fbaSOystein Eftevaag             }
112*758e9fbaSOystein Eftevaag         }
113*758e9fbaSOystein Eftevaag     }
114*758e9fbaSOystein Eftevaag 
115*758e9fbaSOystein Eftevaag     if (profiles->num_profiles == 0) {
116*758e9fbaSOystein Eftevaag         LOG_ERROR("No files found in profile dir %s that match the pattern %s*%s",
117*758e9fbaSOystein Eftevaag                   profilesdir, PROFILES_PREFIX, PROFILES_EXTENSION);
118*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
119*758e9fbaSOystein Eftevaag     }
120*758e9fbaSOystein Eftevaag #ifdef HAVE_REALLOCARRAY
121*758e9fbaSOystein Eftevaag     profiles->profiles = reallocarray(profiles->profiles, profiles->num_profiles,
122*758e9fbaSOystein Eftevaag                                       sizeof(profiles->profiles[0]));
123*758e9fbaSOystein Eftevaag     profiles->filenames = reallocarray(profiles->filenames, profiles->num_profiles,
124*758e9fbaSOystein Eftevaag                                       sizeof(profiles->filenames[0]));
125*758e9fbaSOystein Eftevaag #else /* HAVE_REALLOCARRAY */
126*758e9fbaSOystein Eftevaag     profiles->profiles = realloc(profiles->profiles, profiles->num_profiles *
127*758e9fbaSOystein Eftevaag                                       sizeof(profiles->profiles[0]));
128*758e9fbaSOystein Eftevaag     profiles->filenames = realloc(profiles->filenames, profiles->num_profiles *
129*758e9fbaSOystein Eftevaag                                       sizeof(profiles->filenames[0]));
130*758e9fbaSOystein Eftevaag #endif /* HAVE_REALLOCARRAY */
131*758e9fbaSOystein Eftevaag     /* No need for OOM checks, since num_profiles may only have become smaller */
132*758e9fbaSOystein Eftevaag 
133*758e9fbaSOystein Eftevaag     r = ifapi_io_read_async(io, profiles->filenames[profiles->profiles_idx]);
134*758e9fbaSOystein Eftevaag     return_if_error2(r, "Reading profile %s", profiles->filenames[profiles->profiles_idx]);
135*758e9fbaSOystein Eftevaag 
136*758e9fbaSOystein Eftevaag     return TSS2_RC_SUCCESS;
137*758e9fbaSOystein Eftevaag }
138*758e9fbaSOystein Eftevaag 
139*758e9fbaSOystein Eftevaag /** Initialize the profiles information in the context in an asynchronous way
140*758e9fbaSOystein Eftevaag  *
141*758e9fbaSOystein Eftevaag  * Call after ifapi_profiles_initialize_async to complete the operation.
142*758e9fbaSOystein Eftevaag  *
143*758e9fbaSOystein Eftevaag  * @param[in,out] profiles The context for the profiles information.
144*758e9fbaSOystein Eftevaag  * @param[in,out] io The input/output context being used for file I/O.
145*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS on success.
146*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_REFERENCE if NULL pointers were passed in.
147*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_VALUE if a profile could not be loaded.
148*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
149*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
150*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_TRY_AGAIN if the I/O operation is not finished yet and this function needs
151*758e9fbaSOystein Eftevaag  *         to be called again.
152*758e9fbaSOystein Eftevaag  */
153*758e9fbaSOystein Eftevaag TSS2_RC
ifapi_profiles_initialize_finish(IFAPI_PROFILES * profiles,IFAPI_IO * io)154*758e9fbaSOystein Eftevaag ifapi_profiles_initialize_finish(
155*758e9fbaSOystein Eftevaag     IFAPI_PROFILES *profiles,
156*758e9fbaSOystein Eftevaag     IFAPI_IO *io)
157*758e9fbaSOystein Eftevaag {
158*758e9fbaSOystein Eftevaag     TSS2_RC r;
159*758e9fbaSOystein Eftevaag     uint8_t *buffer;
160*758e9fbaSOystein Eftevaag     size_t i;
161*758e9fbaSOystein Eftevaag     json_object *jso;
162*758e9fbaSOystein Eftevaag     check_not_null(profiles);
163*758e9fbaSOystein Eftevaag     check_not_null(io);
164*758e9fbaSOystein Eftevaag 
165*758e9fbaSOystein Eftevaag     r = ifapi_io_read_finish(io, &buffer, NULL);
166*758e9fbaSOystein Eftevaag     return_if_error(r, "Reading profile failed");
167*758e9fbaSOystein Eftevaag 
168*758e9fbaSOystein Eftevaag     jso = json_tokener_parse((char *) buffer);
169*758e9fbaSOystein Eftevaag     free(buffer);
170*758e9fbaSOystein Eftevaag     if (jso == NULL) {
171*758e9fbaSOystein Eftevaag         LOG_ERROR("Failed to parse profile %s", profiles->filenames[profiles->profiles_idx]);
172*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
173*758e9fbaSOystein Eftevaag     }
174*758e9fbaSOystein Eftevaag 
175*758e9fbaSOystein Eftevaag     r = ifapi_profile_json_deserialize(jso,
176*758e9fbaSOystein Eftevaag             &profiles->profiles[profiles->profiles_idx].profile);
177*758e9fbaSOystein Eftevaag     json_object_put(jso);
178*758e9fbaSOystein Eftevaag     return_if_error2(r, "Parsing profile %s failed",
179*758e9fbaSOystein Eftevaag                      profiles->filenames[profiles->profiles_idx]);
180*758e9fbaSOystein Eftevaag 
181*758e9fbaSOystein Eftevaag     r = ifapi_profile_checkpcrs(&profiles->profiles[profiles->profiles_idx].profile.pcr_selection);
182*758e9fbaSOystein Eftevaag     return_if_error2(r, "Malformed profile pcr selection for profile %s",
183*758e9fbaSOystein Eftevaag                      profiles->filenames[profiles->profiles_idx]);
184*758e9fbaSOystein Eftevaag 
185*758e9fbaSOystein Eftevaag     profiles->profiles_idx += 1;
186*758e9fbaSOystein Eftevaag 
187*758e9fbaSOystein Eftevaag     if (profiles->profiles_idx < profiles->num_profiles) {
188*758e9fbaSOystein Eftevaag         r = ifapi_io_read_async(io, profiles->filenames[profiles->profiles_idx]);
189*758e9fbaSOystein Eftevaag         return_if_error2(r, "Reading profile %s", profiles->filenames[profiles->profiles_idx]);
190*758e9fbaSOystein Eftevaag 
191*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_TRY_AGAIN;
192*758e9fbaSOystein Eftevaag     }
193*758e9fbaSOystein Eftevaag 
194*758e9fbaSOystein Eftevaag     /* Get the data of the default profile into the respective variable */
195*758e9fbaSOystein Eftevaag     for (i = 0; i < profiles->num_profiles; i++) {
196*758e9fbaSOystein Eftevaag         if (strcmp(profiles->default_name, profiles->profiles[i].name) == 0) {
197*758e9fbaSOystein Eftevaag             profiles->default_profile = profiles->profiles[i].profile;
198*758e9fbaSOystein Eftevaag             break;
199*758e9fbaSOystein Eftevaag         }
200*758e9fbaSOystein Eftevaag     }
201*758e9fbaSOystein Eftevaag     if (i == profiles->num_profiles) {
202*758e9fbaSOystein Eftevaag         LOG_ERROR("Default profile %s not in the list of loaded profiles",
203*758e9fbaSOystein Eftevaag                   profiles->default_name);
204*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
205*758e9fbaSOystein Eftevaag     }
206*758e9fbaSOystein Eftevaag 
207*758e9fbaSOystein Eftevaag     for (i = 0; i < profiles->num_profiles; i++) {
208*758e9fbaSOystein Eftevaag         free(profiles->filenames[i]);
209*758e9fbaSOystein Eftevaag     }
210*758e9fbaSOystein Eftevaag     SAFE_FREE(profiles->filenames);
211*758e9fbaSOystein Eftevaag 
212*758e9fbaSOystein Eftevaag     return TSS2_RC_SUCCESS;
213*758e9fbaSOystein Eftevaag }
214*758e9fbaSOystein Eftevaag 
215*758e9fbaSOystein Eftevaag /** Return the profile data for a given profile name.
216*758e9fbaSOystein Eftevaag  *
217*758e9fbaSOystein Eftevaag  * Returns a (const, not to be free'd) pointer to the profile data for a requested profile.
218*758e9fbaSOystein Eftevaag  * If a NULL profile is requesten, then the default profile is returned.
219*758e9fbaSOystein Eftevaag  * If a keypath is passed in, then the prefix is analysed. If that keypath starts with a profile
220*758e9fbaSOystein Eftevaag  * then this profile is returned. Otherwise the default profile is returned.
221*758e9fbaSOystein Eftevaag  *
222*758e9fbaSOystein Eftevaag  * @param[in] profiles The profiles context
223*758e9fbaSOystein Eftevaag  * @param[in] name The name of the profile or the keypath
224*758e9fbaSOystein Eftevaag  * @param[out] profile The pointer to the profile data.
225*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS on success.
226*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_REFERENCE if NULL pointers were passed in.
227*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_VALUE if a profile is not found.
228*758e9fbaSOystein Eftevaag  */
229*758e9fbaSOystein Eftevaag TSS2_RC
ifapi_profiles_get(const IFAPI_PROFILES * profiles,const char * name,const IFAPI_PROFILE ** profile)230*758e9fbaSOystein Eftevaag ifapi_profiles_get(
231*758e9fbaSOystein Eftevaag     const IFAPI_PROFILES *profiles,
232*758e9fbaSOystein Eftevaag     const char *name,
233*758e9fbaSOystein Eftevaag     const IFAPI_PROFILE **profile)
234*758e9fbaSOystein Eftevaag {
235*758e9fbaSOystein Eftevaag     check_not_null(profiles);
236*758e9fbaSOystein Eftevaag     check_not_null(name);
237*758e9fbaSOystein Eftevaag     check_not_null(profile);
238*758e9fbaSOystein Eftevaag     char *split;
239*758e9fbaSOystein Eftevaag     size_t len;
240*758e9fbaSOystein Eftevaag 
241*758e9fbaSOystein Eftevaag     /* if no name or nor profile prefix is given, use the default profile */
242*758e9fbaSOystein Eftevaag     if (!name || strncmp(name, "P_", 2) != 0 || strncmp(name, "/P_", 2) != 0) {
243*758e9fbaSOystein Eftevaag         *profile = &profiles->default_profile;
244*758e9fbaSOystein Eftevaag         return TSS2_RC_SUCCESS;
245*758e9fbaSOystein Eftevaag     }
246*758e9fbaSOystein Eftevaag 
247*758e9fbaSOystein Eftevaag     /* Search for path delimiter */
248*758e9fbaSOystein Eftevaag     split = index(name, IFAPI_FILE_DELIM_CHAR);
249*758e9fbaSOystein Eftevaag 
250*758e9fbaSOystein Eftevaag     /* If the path beging with delimiters, skip over those */
251*758e9fbaSOystein Eftevaag     if (name == split) {
252*758e9fbaSOystein Eftevaag         name += 1;
253*758e9fbaSOystein Eftevaag         split = index(name, IFAPI_FILE_DELIM_CHAR);
254*758e9fbaSOystein Eftevaag     }
255*758e9fbaSOystein Eftevaag     if (split == NULL)
256*758e9fbaSOystein Eftevaag         len = strlen(name);
257*758e9fbaSOystein Eftevaag     else
258*758e9fbaSOystein Eftevaag         len = split - name;
259*758e9fbaSOystein Eftevaag 
260*758e9fbaSOystein Eftevaag     for (size_t i = 0; i < profiles->num_profiles; i++) {
261*758e9fbaSOystein Eftevaag         if (len == strlen(profiles->profiles[i].name) &&
262*758e9fbaSOystein Eftevaag                 strncmp(name, profiles->profiles[i].name, len) == 0) {
263*758e9fbaSOystein Eftevaag             *profile = &profiles->profiles[i].profile;
264*758e9fbaSOystein Eftevaag             return TSS2_RC_SUCCESS;
265*758e9fbaSOystein Eftevaag         }
266*758e9fbaSOystein Eftevaag     }
267*758e9fbaSOystein Eftevaag     LOG_ERROR("Profile %s not in the list of loaded profiles", name);
268*758e9fbaSOystein Eftevaag     return TSS2_FAPI_RC_BAD_VALUE;
269*758e9fbaSOystein Eftevaag }
270*758e9fbaSOystein Eftevaag 
271*758e9fbaSOystein Eftevaag /** Sanitizes and frees internal data structures of loaded profiles' information.
272*758e9fbaSOystein Eftevaag  *
273*758e9fbaSOystein Eftevaag  * @param[in,out] profiles The context for the profiles information.
274*758e9fbaSOystein Eftevaag  */
275*758e9fbaSOystein Eftevaag void
ifapi_profiles_finalize(IFAPI_PROFILES * profiles)276*758e9fbaSOystein Eftevaag ifapi_profiles_finalize(
277*758e9fbaSOystein Eftevaag     IFAPI_PROFILES *profiles)
278*758e9fbaSOystein Eftevaag {
279*758e9fbaSOystein Eftevaag     size_t i;
280*758e9fbaSOystein Eftevaag     if (!profiles) {
281*758e9fbaSOystein Eftevaag         LOG_ERROR("Called with bad reference");
282*758e9fbaSOystein Eftevaag         return;
283*758e9fbaSOystein Eftevaag     }
284*758e9fbaSOystein Eftevaag 
285*758e9fbaSOystein Eftevaag     SAFE_FREE(profiles->default_name);
286*758e9fbaSOystein Eftevaag 
287*758e9fbaSOystein Eftevaag     for (i = 0; i < profiles->num_profiles; i++) {
288*758e9fbaSOystein Eftevaag         IFAPI_PROFILE_ENTRY * entry = &profiles->profiles[i];
289*758e9fbaSOystein Eftevaag         SAFE_FREE(profiles->profiles[i].name);
290*758e9fbaSOystein Eftevaag 
291*758e9fbaSOystein Eftevaag         IFAPI_PROFILE * profile = &entry->profile;
292*758e9fbaSOystein Eftevaag 
293*758e9fbaSOystein Eftevaag         SAFE_FREE(profile->srk_template);
294*758e9fbaSOystein Eftevaag         SAFE_FREE(profile->ek_template);
295*758e9fbaSOystein Eftevaag 
296*758e9fbaSOystein Eftevaag         ifapi_cleanup_policy(profile->eh_policy);
297*758e9fbaSOystein Eftevaag         SAFE_FREE(profile->eh_policy);
298*758e9fbaSOystein Eftevaag 
299*758e9fbaSOystein Eftevaag         ifapi_cleanup_policy(profile->ek_policy);
300*758e9fbaSOystein Eftevaag         SAFE_FREE(profile->ek_policy);
301*758e9fbaSOystein Eftevaag 
302*758e9fbaSOystein Eftevaag         ifapi_cleanup_policy(profile->sh_policy);
303*758e9fbaSOystein Eftevaag         SAFE_FREE(profile->sh_policy);
304*758e9fbaSOystein Eftevaag     }
305*758e9fbaSOystein Eftevaag     SAFE_FREE(profiles->profiles);
306*758e9fbaSOystein Eftevaag 
307*758e9fbaSOystein Eftevaag     memset(profiles, 0, sizeof(*profiles));
308*758e9fbaSOystein Eftevaag }
309*758e9fbaSOystein Eftevaag 
310*758e9fbaSOystein Eftevaag /** Deserialize a IFAPI_KEY_PROFILE json object.
311*758e9fbaSOystein Eftevaag  *
312*758e9fbaSOystein Eftevaag  * @param[in]  jso the json object to be deserialized.
313*758e9fbaSOystein Eftevaag  * @param[out] out the deserialzed binary object.
314*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS if the function call was a success.
315*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
316*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
317*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
318*758e9fbaSOystein Eftevaag  *         object store.
319*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
320*758e9fbaSOystein Eftevaag  */
321*758e9fbaSOystein Eftevaag static TSS2_RC
ifapi_profile_json_deserialize(json_object * jso,IFAPI_PROFILE * out)322*758e9fbaSOystein Eftevaag ifapi_profile_json_deserialize(
323*758e9fbaSOystein Eftevaag     json_object *jso,
324*758e9fbaSOystein Eftevaag     IFAPI_PROFILE *out)
325*758e9fbaSOystein Eftevaag {
326*758e9fbaSOystein Eftevaag     json_object *jso2;
327*758e9fbaSOystein Eftevaag     TSS2_RC r;
328*758e9fbaSOystein Eftevaag 
329*758e9fbaSOystein Eftevaag     const TPMT_SYM_DEF session_symmetric_default = {
330*758e9fbaSOystein Eftevaag         .algorithm = TPM2_ALG_AES,
331*758e9fbaSOystein Eftevaag         .keyBits = {.aes = 128},
332*758e9fbaSOystein Eftevaag         .mode = {.aes = TPM2_ALG_CFB}
333*758e9fbaSOystein Eftevaag     };
334*758e9fbaSOystein Eftevaag 
335*758e9fbaSOystein Eftevaag     LOG_TRACE("call");
336*758e9fbaSOystein Eftevaag     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
337*758e9fbaSOystein Eftevaag 
338*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "type", &jso2)) {
339*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value");
340*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
341*758e9fbaSOystein Eftevaag     }
342*758e9fbaSOystein Eftevaag     r = ifapi_json_TPMI_ALG_PUBLIC_deserialize(jso2, &out->type);
343*758e9fbaSOystein Eftevaag     return_if_error(r, "BAD VALUE");
344*758e9fbaSOystein Eftevaag 
345*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "srk_template", &jso2)) {
346*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value");
347*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
348*758e9fbaSOystein Eftevaag     }
349*758e9fbaSOystein Eftevaag     out->srk_template = strdup(json_object_get_string(jso2));
350*758e9fbaSOystein Eftevaag     return_if_null(out->srk_template, "Out of memory.", TSS2_FAPI_RC_MEMORY);
351*758e9fbaSOystein Eftevaag 
352*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "ek_template", &jso2)) {
353*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value");
354*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
355*758e9fbaSOystein Eftevaag     }
356*758e9fbaSOystein Eftevaag     out->ek_template = strdup(json_object_get_string(jso2));
357*758e9fbaSOystein Eftevaag     return_if_null(out->ek_template, "Out of memory.", TSS2_FAPI_RC_MEMORY);
358*758e9fbaSOystein Eftevaag 
359*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "ecc_signing_scheme", &jso2)) {
360*758e9fbaSOystein Eftevaag         memset(&out->ecc_signing_scheme, 0, sizeof(TPMT_SIG_SCHEME));
361*758e9fbaSOystein Eftevaag     } else {
362*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMT_SIG_SCHEME_deserialize(jso2, &out->ecc_signing_scheme);
363*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
364*758e9fbaSOystein Eftevaag     }
365*758e9fbaSOystein Eftevaag 
366*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "rsa_signing_scheme", &jso2)) {
367*758e9fbaSOystein Eftevaag         memset(&out->rsa_signing_scheme, 0, sizeof(TPMT_SIG_SCHEME));
368*758e9fbaSOystein Eftevaag     } else {
369*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMT_SIG_SCHEME_deserialize(jso2, &out->rsa_signing_scheme);
370*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
371*758e9fbaSOystein Eftevaag     }
372*758e9fbaSOystein Eftevaag 
373*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "rsa_decrypt_scheme", &jso2)) {
374*758e9fbaSOystein Eftevaag         memset(&out->rsa_decrypt_scheme, 0, sizeof(TPMT_RSA_DECRYPT));
375*758e9fbaSOystein Eftevaag     } else {
376*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMT_RSA_DECRYPT_deserialize(jso2, &out->rsa_decrypt_scheme);
377*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
378*758e9fbaSOystein Eftevaag     }
379*758e9fbaSOystein Eftevaag 
380*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "sym_mode", &jso2)) {
381*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value");
382*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
383*758e9fbaSOystein Eftevaag     }
384*758e9fbaSOystein Eftevaag     r = ifapi_json_TPMI_ALG_SYM_MODE_deserialize(jso2, &out->sym_mode);
385*758e9fbaSOystein Eftevaag     return_if_error(r, "BAD VALUE");
386*758e9fbaSOystein Eftevaag 
387*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "sym_parameters", &jso2)) {
388*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value");
389*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
390*758e9fbaSOystein Eftevaag     }
391*758e9fbaSOystein Eftevaag     r = ifapi_json_TPMT_SYM_DEF_OBJECT_deserialize(jso2, &out->sym_parameters);
392*758e9fbaSOystein Eftevaag     return_if_error(r, "BAD VALUE");
393*758e9fbaSOystein Eftevaag 
394*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "sym_block_size", &jso2)) {
395*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value");
396*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
397*758e9fbaSOystein Eftevaag     }
398*758e9fbaSOystein Eftevaag     r = ifapi_json_UINT16_deserialize(jso2, &out->sym_block_size);
399*758e9fbaSOystein Eftevaag     return_if_error(r, "BAD VALUE");
400*758e9fbaSOystein Eftevaag 
401*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "pcr_selection", &jso2)) {
402*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value");
403*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
404*758e9fbaSOystein Eftevaag     }
405*758e9fbaSOystein Eftevaag     r = ifapi_json_TPML_PCR_SELECTION_deserialize(jso2, &out->pcr_selection);
406*758e9fbaSOystein Eftevaag     return_if_error(r, "BAD VALUE");
407*758e9fbaSOystein Eftevaag 
408*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "nameAlg", &jso2)) {
409*758e9fbaSOystein Eftevaag         LOG_ERROR("Bad value");
410*758e9fbaSOystein Eftevaag         return TSS2_FAPI_RC_BAD_VALUE;
411*758e9fbaSOystein Eftevaag     }
412*758e9fbaSOystein Eftevaag     r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->nameAlg);
413*758e9fbaSOystein Eftevaag     return_if_error(r, "BAD VALUE");
414*758e9fbaSOystein Eftevaag 
415*758e9fbaSOystein Eftevaag     if (out->type == TPM2_ALG_RSA) {
416*758e9fbaSOystein Eftevaag         if (!ifapi_get_sub_object(jso, "exponent", &jso2)) {
417*758e9fbaSOystein Eftevaag             LOG_ERROR("Bad value");
418*758e9fbaSOystein Eftevaag             return TSS2_FAPI_RC_BAD_VALUE;
419*758e9fbaSOystein Eftevaag         }
420*758e9fbaSOystein Eftevaag         r = ifapi_json_UINT32_deserialize(jso2, &out->exponent);
421*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
422*758e9fbaSOystein Eftevaag         if (!ifapi_get_sub_object(jso, "keyBits", &jso2)) {
423*758e9fbaSOystein Eftevaag             LOG_ERROR("Bad value");
424*758e9fbaSOystein Eftevaag             return TSS2_FAPI_RC_BAD_VALUE;
425*758e9fbaSOystein Eftevaag 
426*758e9fbaSOystein Eftevaag         }
427*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMI_RSA_KEY_BITS_deserialize(jso2, &out->keyBits);
428*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
429*758e9fbaSOystein Eftevaag 
430*758e9fbaSOystein Eftevaag     } else if (out->type == TPM2_ALG_ECC) {
431*758e9fbaSOystein Eftevaag         if (!ifapi_get_sub_object(jso, "curveID", &jso2)) {
432*758e9fbaSOystein Eftevaag             LOG_ERROR("Bad value");
433*758e9fbaSOystein Eftevaag             return TSS2_FAPI_RC_BAD_VALUE;
434*758e9fbaSOystein Eftevaag         }
435*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMI_ECC_CURVE_deserialize(jso2, &out->curveID);
436*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
437*758e9fbaSOystein Eftevaag     }
438*758e9fbaSOystein Eftevaag 
439*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "session_symmetric", &jso2)) {
440*758e9fbaSOystein Eftevaag         out->session_symmetric = session_symmetric_default;
441*758e9fbaSOystein Eftevaag     } else {
442*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMT_SYM_DEF_deserialize(jso2, &out->session_symmetric);
443*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
444*758e9fbaSOystein Eftevaag     }
445*758e9fbaSOystein Eftevaag 
446*758e9fbaSOystein Eftevaag     if (ifapi_get_sub_object(jso, "eh_policy", &jso2)) {
447*758e9fbaSOystein Eftevaag         out->eh_policy = calloc(1, sizeof(TPMS_POLICY));
448*758e9fbaSOystein Eftevaag         goto_if_null2(out->eh_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
449*758e9fbaSOystein Eftevaag                       cleanup);
450*758e9fbaSOystein Eftevaag 
451*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->eh_policy);
452*758e9fbaSOystein Eftevaag         goto_if_error(r, "Deserialize policy.", cleanup);
453*758e9fbaSOystein Eftevaag     }
454*758e9fbaSOystein Eftevaag 
455*758e9fbaSOystein Eftevaag     if (ifapi_get_sub_object(jso, "sh_policy", &jso2)) {
456*758e9fbaSOystein Eftevaag         out->sh_policy = calloc(1, sizeof(TPMS_POLICY));
457*758e9fbaSOystein Eftevaag         goto_if_null2(out->sh_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
458*758e9fbaSOystein Eftevaag                       cleanup);
459*758e9fbaSOystein Eftevaag 
460*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->sh_policy);
461*758e9fbaSOystein Eftevaag         goto_if_error(r, "Deserialize policy.", cleanup);
462*758e9fbaSOystein Eftevaag     }
463*758e9fbaSOystein Eftevaag 
464*758e9fbaSOystein Eftevaag     if (ifapi_get_sub_object(jso, "ek_policy", &jso2)) {
465*758e9fbaSOystein Eftevaag         out->ek_policy = calloc(1, sizeof(TPMS_POLICY));
466*758e9fbaSOystein Eftevaag         goto_if_null2(out->ek_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
467*758e9fbaSOystein Eftevaag                       cleanup);
468*758e9fbaSOystein Eftevaag 
469*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->ek_policy);
470*758e9fbaSOystein Eftevaag         goto_if_error(r, "Deserialize policy.", cleanup);
471*758e9fbaSOystein Eftevaag     }
472*758e9fbaSOystein Eftevaag 
473*758e9fbaSOystein Eftevaag     if (ifapi_get_sub_object(jso, "srk_policy", &jso2)) {
474*758e9fbaSOystein Eftevaag         out->srk_policy = calloc(1, sizeof(TPMS_POLICY));
475*758e9fbaSOystein Eftevaag         goto_if_null2(out->srk_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
476*758e9fbaSOystein Eftevaag                       cleanup);
477*758e9fbaSOystein Eftevaag 
478*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->srk_policy);
479*758e9fbaSOystein Eftevaag         goto_if_error(r, "Deserialize policy.", cleanup);
480*758e9fbaSOystein Eftevaag     }
481*758e9fbaSOystein Eftevaag 
482*758e9fbaSOystein Eftevaag     if (ifapi_get_sub_object(jso, "lockout_policy", &jso2)) {
483*758e9fbaSOystein Eftevaag         out->lockout_policy = calloc(1, sizeof(TPMS_POLICY));
484*758e9fbaSOystein Eftevaag         goto_if_null2(out->lockout_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
485*758e9fbaSOystein Eftevaag                       cleanup);
486*758e9fbaSOystein Eftevaag 
487*758e9fbaSOystein Eftevaag         r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->lockout_policy);
488*758e9fbaSOystein Eftevaag         goto_if_error(r, "Deserialize policy.", cleanup);
489*758e9fbaSOystein Eftevaag     }
490*758e9fbaSOystein Eftevaag 
491*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "newMaxTries", &jso2)) {
492*758e9fbaSOystein Eftevaag         out->newMaxTries = 5;
493*758e9fbaSOystein Eftevaag     } else {
494*758e9fbaSOystein Eftevaag         r = ifapi_json_UINT32_deserialize(jso2, &out->newMaxTries);
495*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
496*758e9fbaSOystein Eftevaag     }
497*758e9fbaSOystein Eftevaag 
498*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "newRecoveryTime", &jso2)) {
499*758e9fbaSOystein Eftevaag         out->newRecoveryTime = 1000;
500*758e9fbaSOystein Eftevaag     } else {
501*758e9fbaSOystein Eftevaag         r = ifapi_json_UINT32_deserialize(jso2, &out->newRecoveryTime);
502*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
503*758e9fbaSOystein Eftevaag     }
504*758e9fbaSOystein Eftevaag 
505*758e9fbaSOystein Eftevaag     if (!ifapi_get_sub_object(jso, "lockoutRecovery", &jso2)) {
506*758e9fbaSOystein Eftevaag         out->lockoutRecovery = 1000;
507*758e9fbaSOystein Eftevaag     } else {
508*758e9fbaSOystein Eftevaag         r = ifapi_json_UINT32_deserialize(jso2, &out->lockoutRecovery);
509*758e9fbaSOystein Eftevaag         return_if_error(r, "BAD VALUE");
510*758e9fbaSOystein Eftevaag     }
511*758e9fbaSOystein Eftevaag 
512*758e9fbaSOystein Eftevaag     LOG_TRACE("true");
513*758e9fbaSOystein Eftevaag     return TSS2_RC_SUCCESS;
514*758e9fbaSOystein Eftevaag 
515*758e9fbaSOystein Eftevaag cleanup:
516*758e9fbaSOystein Eftevaag     SAFE_FREE(out->eh_policy);
517*758e9fbaSOystein Eftevaag     return r;
518*758e9fbaSOystein Eftevaag }
519*758e9fbaSOystein Eftevaag 
520*758e9fbaSOystein Eftevaag /**
521*758e9fbaSOystein Eftevaag   * Check whether PCRs with muliple banks are defined in profile.
522*758e9fbaSOystein Eftevaag   *
523*758e9fbaSOystein Eftevaag   * This case is not allowed by FAPI.
524*758e9fbaSOystein Eftevaag   */
525*758e9fbaSOystein Eftevaag static TSS2_RC
ifapi_profile_checkpcrs(const TPML_PCR_SELECTION * pcr_profile)526*758e9fbaSOystein Eftevaag ifapi_profile_checkpcrs(const TPML_PCR_SELECTION *pcr_profile)
527*758e9fbaSOystein Eftevaag {
528*758e9fbaSOystein Eftevaag     size_t i, j, byte_idx;
529*758e9fbaSOystein Eftevaag 
530*758e9fbaSOystein Eftevaag     for (i = 0; i < pcr_profile->count - 1; i++) {
531*758e9fbaSOystein Eftevaag         for (j = i + 1; j <  pcr_profile->count; j++) {
532*758e9fbaSOystein Eftevaag             for (byte_idx = 0; byte_idx < 3; byte_idx++) {
533*758e9fbaSOystein Eftevaag                 /* Check whether a PCR register flag does occur in two different banks. */
534*758e9fbaSOystein Eftevaag                 if (pcr_profile->pcrSelections[i].pcrSelect[byte_idx] &
535*758e9fbaSOystein Eftevaag                         pcr_profile->pcrSelections[j].pcrSelect[byte_idx]) {
536*758e9fbaSOystein Eftevaag                     return_error2(TSS2_FAPI_RC_BAD_VALUE,
537*758e9fbaSOystein Eftevaag                                   "More than one bank selected for a PCR register.");
538*758e9fbaSOystein Eftevaag                 }
539*758e9fbaSOystein Eftevaag             }
540*758e9fbaSOystein Eftevaag         }
541*758e9fbaSOystein Eftevaag     }
542*758e9fbaSOystein Eftevaag     return TSS2_RC_SUCCESS;
543*758e9fbaSOystein Eftevaag }
544