xref: /arm-trusted-firmware/lib/fconf/fconf_cot_getter.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <stddef.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <mbedtls/version.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #include <common/fdt_wrappers.h>
13*91f16700Schasinglulu #include <common/tbbr/cot_def.h>
14*91f16700Schasinglulu #include <drivers/auth/auth_mod.h>
15*91f16700Schasinglulu #include <lib/fconf/fconf.h>
16*91f16700Schasinglulu #include <lib/object_pool.h>
17*91f16700Schasinglulu #include <libfdt.h>
18*91f16700Schasinglulu 
19*91f16700Schasinglulu #include <tools_share/tbbr_oid.h>
20*91f16700Schasinglulu 
21*91f16700Schasinglulu /* static structures used during authentication process */
22*91f16700Schasinglulu static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
23*91f16700Schasinglulu 			AUTH_PARAM_SIG, 0);
24*91f16700Schasinglulu static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
25*91f16700Schasinglulu 			AUTH_PARAM_SIG_ALG, 0);
26*91f16700Schasinglulu static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
27*91f16700Schasinglulu 			AUTH_PARAM_RAW_DATA, 0);
28*91f16700Schasinglulu 
29*91f16700Schasinglulu /* pointers to an array of CoT descriptors */
30*91f16700Schasinglulu static const auth_img_desc_t *cot_desc[MAX_NUMBER_IDS];
31*91f16700Schasinglulu /* array of CoT descriptors */
32*91f16700Schasinglulu static auth_img_desc_t auth_img_descs[MAX_NUMBER_IDS];
33*91f16700Schasinglulu 
34*91f16700Schasinglulu /* array of authentication methods structures */
35*91f16700Schasinglulu static auth_method_desc_t auth_methods[MAX_NUMBER_IDS * AUTH_METHOD_NUM];
36*91f16700Schasinglulu static OBJECT_POOL_ARRAY(auth_methods_pool, auth_methods);
37*91f16700Schasinglulu 
38*91f16700Schasinglulu /* array of authentication params structures */
39*91f16700Schasinglulu static auth_param_desc_t auth_params[MAX_NUMBER_IDS * COT_MAX_VERIFIED_PARAMS];
40*91f16700Schasinglulu static OBJECT_POOL_ARRAY(auth_params_pool, auth_params);
41*91f16700Schasinglulu 
42*91f16700Schasinglulu /* array of authentication param type structures */
43*91f16700Schasinglulu static auth_param_type_desc_t auth_param_type_descs[MAX_NUMBER_IDS];
44*91f16700Schasinglulu static OBJECT_POOL_ARRAY(auth_param_type_descs_pool, auth_param_type_descs);
45*91f16700Schasinglulu 
46*91f16700Schasinglulu /*
47*91f16700Schasinglulu  * array of OIDs
48*91f16700Schasinglulu  * Object IDs are used to search hash, pk, counter values in certificate.
49*91f16700Schasinglulu  * As per binding we have below 2 combinations:
50*91f16700Schasinglulu  * 1. Certificates are validated using nv-cntr and pk
51*91f16700Schasinglulu  * 2. Raw images are authenticated using hash
52*91f16700Schasinglulu  * Hence in worst case, there are maximum 2 OIDs per image/certificate
53*91f16700Schasinglulu  */
54*91f16700Schasinglulu static unsigned char oids[(MAX_NUMBER_IDS * 2)][MAX_OID_NAME_LEN];
55*91f16700Schasinglulu static OBJECT_POOL_ARRAY(oid_pool, oids);
56*91f16700Schasinglulu 
57*91f16700Schasinglulu /* An array of auth buffer which holds hashes and pk
58*91f16700Schasinglulu  * ToDo: Size decided with the current number of images and
59*91f16700Schasinglulu  * certificates which are available in CoT. Size of these buffers bound to
60*91f16700Schasinglulu  * increase in the future on the addition of images/certificates.
61*91f16700Schasinglulu  */
62*91f16700Schasinglulu static unsigned char hash_auth_bufs[20][HASH_DER_LEN];
63*91f16700Schasinglulu static OBJECT_POOL_ARRAY(hash_auth_buf_pool, hash_auth_bufs);
64*91f16700Schasinglulu static unsigned char pk_auth_bufs[12][PK_DER_LEN];
65*91f16700Schasinglulu static OBJECT_POOL_ARRAY(pk_auth_buf_pool, pk_auth_bufs);
66*91f16700Schasinglulu 
67*91f16700Schasinglulu /*******************************************************************************
68*91f16700Schasinglulu  * update_parent_auth_data() - Update authentication data structure
69*91f16700Schasinglulu  * @auth_desc[in]:	Pointer to the auth image descriptor
70*91f16700Schasinglulu  * @type_desc[in]:	Pointer to authentication parameter
71*91f16700Schasinglulu  * @auth_buf_size[in]:	Buffer size to hold pk or hash
72*91f16700Schasinglulu  *
73*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
74*91f16700Schasinglulu  ******************************************************************************/
75*91f16700Schasinglulu static int update_parent_auth_data(const auth_img_desc_t *auth_desc,
76*91f16700Schasinglulu 				   auth_param_type_desc_t *type_desc,
77*91f16700Schasinglulu 				   unsigned int auth_buf_size)
78*91f16700Schasinglulu {
79*91f16700Schasinglulu 	unsigned int i;
80*91f16700Schasinglulu 	auth_param_desc_t *auth_data = &auth_desc->authenticated_data[0];
81*91f16700Schasinglulu 	unsigned char *auth_buf;
82*91f16700Schasinglulu 
83*91f16700Schasinglulu 	for (i = 0U; i < COT_MAX_VERIFIED_PARAMS; i++) {
84*91f16700Schasinglulu 		if (auth_data[i].type_desc == type_desc) {
85*91f16700Schasinglulu 			return 0;
86*91f16700Schasinglulu 		}
87*91f16700Schasinglulu 		if (auth_data[i].type_desc == NULL) {
88*91f16700Schasinglulu 			break;
89*91f16700Schasinglulu 		}
90*91f16700Schasinglulu 	}
91*91f16700Schasinglulu 
92*91f16700Schasinglulu 	if (auth_buf_size == HASH_DER_LEN) {
93*91f16700Schasinglulu 		auth_buf = pool_alloc(&hash_auth_buf_pool);
94*91f16700Schasinglulu 	} else if (auth_buf_size == PK_DER_LEN) {
95*91f16700Schasinglulu 		auth_buf = pool_alloc(&pk_auth_buf_pool);
96*91f16700Schasinglulu 	} else {
97*91f16700Schasinglulu 		return -1;
98*91f16700Schasinglulu 	}
99*91f16700Schasinglulu 
100*91f16700Schasinglulu 	if (i < COT_MAX_VERIFIED_PARAMS) {
101*91f16700Schasinglulu 		auth_data[i].type_desc = type_desc;
102*91f16700Schasinglulu 		auth_data[i].data.ptr = auth_buf;
103*91f16700Schasinglulu 		auth_data[i].data.len = auth_buf_size;
104*91f16700Schasinglulu 	} else {
105*91f16700Schasinglulu 		ERROR("Out of authentication data array\n");
106*91f16700Schasinglulu 		return -1;
107*91f16700Schasinglulu 	}
108*91f16700Schasinglulu 
109*91f16700Schasinglulu 	return 0;
110*91f16700Schasinglulu }
111*91f16700Schasinglulu 
112*91f16700Schasinglulu /*******************************************************************************
113*91f16700Schasinglulu  * get_auth_param_type_desc() - Get pointer of authentication parameter
114*91f16700Schasinglulu  * @img_id[in]:		Image Id
115*91f16700Schasinglulu  * @type_desc[out]:	Pointer to authentication parameter
116*91f16700Schasinglulu  * @buf_size[out]:	Buffer size which hold hash/pk
117*91f16700Schasinglulu  *
118*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
119*91f16700Schasinglulu  ******************************************************************************/
120*91f16700Schasinglulu static int get_auth_param_type_desc(unsigned int img_id,
121*91f16700Schasinglulu 				    auth_param_type_desc_t **type_desc,
122*91f16700Schasinglulu 				    unsigned int *buf_size)
123*91f16700Schasinglulu {
124*91f16700Schasinglulu 	auth_method_desc_t *img_auth_method = NULL;
125*91f16700Schasinglulu 	img_type_t type = auth_img_descs[img_id].img_type;
126*91f16700Schasinglulu 
127*91f16700Schasinglulu 	if (type == IMG_CERT) {
128*91f16700Schasinglulu 		img_auth_method =
129*91f16700Schasinglulu 		&auth_img_descs[img_id].img_auth_methods[AUTH_METHOD_SIG];
130*91f16700Schasinglulu 		*type_desc = img_auth_method->param.sig.pk;
131*91f16700Schasinglulu 		*buf_size = PK_DER_LEN;
132*91f16700Schasinglulu 	} else if (type == IMG_RAW) {
133*91f16700Schasinglulu 		img_auth_method =
134*91f16700Schasinglulu 		&auth_img_descs[img_id].img_auth_methods[AUTH_METHOD_HASH];
135*91f16700Schasinglulu 		*type_desc = img_auth_method->param.hash.hash;
136*91f16700Schasinglulu 		*buf_size = HASH_DER_LEN;
137*91f16700Schasinglulu 	} else {
138*91f16700Schasinglulu 		return -1;
139*91f16700Schasinglulu 	}
140*91f16700Schasinglulu 
141*91f16700Schasinglulu 	return 0;
142*91f16700Schasinglulu }
143*91f16700Schasinglulu 
144*91f16700Schasinglulu /*******************************************************************************
145*91f16700Schasinglulu  * set_auth_method() - Update global auth image descriptors with authentication
146*91f16700Schasinglulu  *			method data
147*91f16700Schasinglulu  * @auth_method_type[in]:	Type of authentication method
148*91f16700Schasinglulu  * @oid[in]:			Object Idetifier for pk/hash search
149*91f16700Schasinglulu  * @auth_method[in]:		Pointer to authentication method to set
150*91f16700Schasinglulu  ******************************************************************************/
151*91f16700Schasinglulu static void set_auth_method(auth_method_type_t auth_method_type, char *oid,
152*91f16700Schasinglulu 			    auth_method_desc_t *auth_method)
153*91f16700Schasinglulu {
154*91f16700Schasinglulu 	auth_param_type_t auth_param_type = AUTH_PARAM_NONE;
155*91f16700Schasinglulu 	auth_param_type_desc_t *auth_param_type_desc;
156*91f16700Schasinglulu 
157*91f16700Schasinglulu 	assert(auth_method != NULL);
158*91f16700Schasinglulu 
159*91f16700Schasinglulu 	auth_param_type_desc = pool_alloc(&auth_param_type_descs_pool);
160*91f16700Schasinglulu 	auth_method->type = auth_method_type;
161*91f16700Schasinglulu 
162*91f16700Schasinglulu 	if (auth_method_type == AUTH_METHOD_SIG) {
163*91f16700Schasinglulu 		auth_param_type = AUTH_PARAM_PUB_KEY;
164*91f16700Schasinglulu 		auth_method->param.sig.sig = &sig;
165*91f16700Schasinglulu 		auth_method->param.sig.alg = &sig_alg;
166*91f16700Schasinglulu 		auth_method->param.sig.data = &raw_data;
167*91f16700Schasinglulu 		auth_method->param.sig.pk = auth_param_type_desc;
168*91f16700Schasinglulu 	} else if (auth_method_type == AUTH_METHOD_HASH) {
169*91f16700Schasinglulu 		auth_param_type = AUTH_PARAM_HASH;
170*91f16700Schasinglulu 		auth_method->param.hash.data = &raw_data;
171*91f16700Schasinglulu 		auth_method->param.hash.hash = auth_param_type_desc;
172*91f16700Schasinglulu 	} else if (auth_method_type == AUTH_METHOD_NV_CTR) {
173*91f16700Schasinglulu 		auth_param_type = AUTH_PARAM_NV_CTR;
174*91f16700Schasinglulu 		auth_method->param.nv_ctr.cert_nv_ctr = auth_param_type_desc;
175*91f16700Schasinglulu 		auth_method->param.nv_ctr.plat_nv_ctr = auth_param_type_desc;
176*91f16700Schasinglulu 	}
177*91f16700Schasinglulu 
178*91f16700Schasinglulu 	auth_param_type_desc->type = auth_param_type;
179*91f16700Schasinglulu 	auth_param_type_desc->cookie = (void *)oid;
180*91f16700Schasinglulu }
181*91f16700Schasinglulu 
182*91f16700Schasinglulu /*******************************************************************************
183*91f16700Schasinglulu  * get_oid() -	get object identifier from device tree
184*91f16700Schasinglulu  * @dtb[in]:	Pointer to the device tree blob in memory
185*91f16700Schasinglulu  * @node[in]:	Offset of the node
186*91f16700Schasinglulu  * @prop[in]:	Property to read from the given node
187*91f16700Schasinglulu  * @oid[out]:	Object Indentifier of key/hash/nv-counter in certificate
188*91f16700Schasinglulu  *
189*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
190*91f16700Schasinglulu  ******************************************************************************/
191*91f16700Schasinglulu static int get_oid(const void *dtb, int node, const char *prop, char **oid)
192*91f16700Schasinglulu {
193*91f16700Schasinglulu 	uint32_t phandle;
194*91f16700Schasinglulu 	int rc;
195*91f16700Schasinglulu 
196*91f16700Schasinglulu 	rc = fdt_read_uint32(dtb, node, prop, &phandle);
197*91f16700Schasinglulu 	if (rc < 0) {
198*91f16700Schasinglulu 		return rc;
199*91f16700Schasinglulu 	}
200*91f16700Schasinglulu 
201*91f16700Schasinglulu 	node = fdt_node_offset_by_phandle(dtb, phandle);
202*91f16700Schasinglulu 	if (node < 0) {
203*91f16700Schasinglulu 		return node;
204*91f16700Schasinglulu 	}
205*91f16700Schasinglulu 
206*91f16700Schasinglulu 	*oid = pool_alloc(&oid_pool);
207*91f16700Schasinglulu 	rc = fdtw_read_string(dtb, node, "oid", *oid, MAX_OID_NAME_LEN);
208*91f16700Schasinglulu 
209*91f16700Schasinglulu 	return rc;
210*91f16700Schasinglulu }
211*91f16700Schasinglulu 
212*91f16700Schasinglulu /*******************************************************************************
213*91f16700Schasinglulu  * populate_and_set_auth_methods() -  Populate auth method parameters from
214*91f16700Schasinglulu  *			device tree and set authentication method
215*91f16700Schasinglulu  *			structure.
216*91f16700Schasinglulu  * @dtb[in]:		Pointer to the device tree blob in memory
217*91f16700Schasinglulu  * @node[in]:		Offset of the node
218*91f16700Schasinglulu  * @img_id[in]:		Image identifier
219*91f16700Schasinglulu  * @type[in]:		Type of image
220*91f16700Schasinglulu  * @root_certificate[in]:Root certificate (authenticated by ROTPK)
221*91f16700Schasinglulu  *
222*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
223*91f16700Schasinglulu  ******************************************************************************/
224*91f16700Schasinglulu static int populate_and_set_auth_methods(const void *dtb, int node,
225*91f16700Schasinglulu 					 unsigned int img_id, img_type_t type,
226*91f16700Schasinglulu 					 bool root_certificate)
227*91f16700Schasinglulu {
228*91f16700Schasinglulu 	auth_method_type_t auth_method_type = AUTH_METHOD_NONE;
229*91f16700Schasinglulu 	int rc;
230*91f16700Schasinglulu 	char *oid = NULL;
231*91f16700Schasinglulu 
232*91f16700Schasinglulu 	auth_method_desc_t *auth_method = pool_alloc_n(&auth_methods_pool,
233*91f16700Schasinglulu 					AUTH_METHOD_NUM);
234*91f16700Schasinglulu 
235*91f16700Schasinglulu 	/*
236*91f16700Schasinglulu 	 * This is as per binding document where certificates are
237*91f16700Schasinglulu 	 * verified by signature and images are verified by hash.
238*91f16700Schasinglulu 	 */
239*91f16700Schasinglulu 	if (type == IMG_CERT) {
240*91f16700Schasinglulu 		if (root_certificate) {
241*91f16700Schasinglulu 			oid = NULL;
242*91f16700Schasinglulu 		} else {
243*91f16700Schasinglulu 			rc = get_oid(dtb, node, "signing-key", &oid);
244*91f16700Schasinglulu 			if (rc < 0) {
245*91f16700Schasinglulu 				ERROR("FCONF: Can't read %s property\n",
246*91f16700Schasinglulu 					"signing-key");
247*91f16700Schasinglulu 				return rc;
248*91f16700Schasinglulu 			}
249*91f16700Schasinglulu 		}
250*91f16700Schasinglulu 		auth_method_type = AUTH_METHOD_SIG;
251*91f16700Schasinglulu 	} else if (type == IMG_RAW) {
252*91f16700Schasinglulu 		rc = get_oid(dtb, node, "hash", &oid);
253*91f16700Schasinglulu 		if (rc < 0) {
254*91f16700Schasinglulu 			ERROR("FCONF: Can't read %s property\n",
255*91f16700Schasinglulu 				"hash");
256*91f16700Schasinglulu 			return rc;
257*91f16700Schasinglulu 		}
258*91f16700Schasinglulu 		auth_method_type = AUTH_METHOD_HASH;
259*91f16700Schasinglulu 	} else {
260*91f16700Schasinglulu 		return -1;
261*91f16700Schasinglulu 	}
262*91f16700Schasinglulu 
263*91f16700Schasinglulu 	set_auth_method(auth_method_type, oid,
264*91f16700Schasinglulu 			&auth_method[auth_method_type]);
265*91f16700Schasinglulu 
266*91f16700Schasinglulu 	/* Retrieve the optional property */
267*91f16700Schasinglulu 	rc = get_oid(dtb, node, "antirollback-counter", &oid);
268*91f16700Schasinglulu 	if (rc == 0) {
269*91f16700Schasinglulu 		auth_method_type = AUTH_METHOD_NV_CTR;
270*91f16700Schasinglulu 		set_auth_method(auth_method_type, oid,
271*91f16700Schasinglulu 				&auth_method[auth_method_type]);
272*91f16700Schasinglulu 	}
273*91f16700Schasinglulu 
274*91f16700Schasinglulu 	auth_img_descs[img_id].img_auth_methods = &auth_method[0];
275*91f16700Schasinglulu 
276*91f16700Schasinglulu 	return 0;
277*91f16700Schasinglulu }
278*91f16700Schasinglulu 
279*91f16700Schasinglulu /*******************************************************************************
280*91f16700Schasinglulu  * get_parent_img_id() - Get parent image id for given child node
281*91f16700Schasinglulu  * @dtb[in]:		Pointer to the device tree blob in memory
282*91f16700Schasinglulu  * @node[in]:		Offset of the child node
283*91f16700Schasinglulu  * @parent_img_id[out]:	Image id of parent
284*91f16700Schasinglulu  *
285*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
286*91f16700Schasinglulu  ******************************************************************************/
287*91f16700Schasinglulu static int get_parent_img_id(const void *dtb, int node,
288*91f16700Schasinglulu 			     unsigned int *parent_img_id)
289*91f16700Schasinglulu {
290*91f16700Schasinglulu 	uint32_t phandle;
291*91f16700Schasinglulu 	int err;
292*91f16700Schasinglulu 
293*91f16700Schasinglulu 	err = fdt_read_uint32(dtb, node, "parent", &phandle);
294*91f16700Schasinglulu 	if (err < 0) {
295*91f16700Schasinglulu 		ERROR("FCONF: Could not read %s property in node\n",
296*91f16700Schasinglulu 			"parent");
297*91f16700Schasinglulu 		return err;
298*91f16700Schasinglulu 	}
299*91f16700Schasinglulu 
300*91f16700Schasinglulu 	node = fdt_node_offset_by_phandle(dtb, phandle);
301*91f16700Schasinglulu 	if (node < 0) {
302*91f16700Schasinglulu 		ERROR("FCONF: Failed to locate node using its phandle\n");
303*91f16700Schasinglulu 		return node;
304*91f16700Schasinglulu 	}
305*91f16700Schasinglulu 
306*91f16700Schasinglulu 	err = fdt_read_uint32(dtb, node, "image-id", parent_img_id);
307*91f16700Schasinglulu 	if (err < 0) {
308*91f16700Schasinglulu 		ERROR("FCONF: Could not read %s property in node\n",
309*91f16700Schasinglulu 			"image-id");
310*91f16700Schasinglulu 	}
311*91f16700Schasinglulu 
312*91f16700Schasinglulu 	return err;
313*91f16700Schasinglulu }
314*91f16700Schasinglulu 
315*91f16700Schasinglulu /*******************************************************************************
316*91f16700Schasinglulu  * set_desc_data() - Update data in descriptor's structure
317*91f16700Schasinglulu  * @dtb[in]:	Pointer to the device tree blob in memory
318*91f16700Schasinglulu  * @node[in]:	Offset of the node
319*91f16700Schasinglulu  * @type[in]:	Type of image (RAW/CERT)
320*91f16700Schasinglulu  *
321*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
322*91f16700Schasinglulu  ******************************************************************************/
323*91f16700Schasinglulu static int set_desc_data(const void *dtb, int node, img_type_t type)
324*91f16700Schasinglulu {
325*91f16700Schasinglulu 	int rc;
326*91f16700Schasinglulu 	bool root_certificate = false;
327*91f16700Schasinglulu 	unsigned int img_id, parent_img_id;
328*91f16700Schasinglulu 
329*91f16700Schasinglulu 	rc = fdt_read_uint32(dtb, node, "image-id", &img_id);
330*91f16700Schasinglulu 	if (rc < 0) {
331*91f16700Schasinglulu 		ERROR("FCONF: Can't find property %s in node\n",
332*91f16700Schasinglulu 			"image-id");
333*91f16700Schasinglulu 		return rc;
334*91f16700Schasinglulu 	}
335*91f16700Schasinglulu 
336*91f16700Schasinglulu 	if (fdt_getprop(dtb, node, "root-certificate",
337*91f16700Schasinglulu 					NULL) != NULL) {
338*91f16700Schasinglulu 		root_certificate = true;
339*91f16700Schasinglulu 	}
340*91f16700Schasinglulu 
341*91f16700Schasinglulu 	if (!root_certificate) {
342*91f16700Schasinglulu 		rc = get_parent_img_id(dtb, node, &parent_img_id);
343*91f16700Schasinglulu 		if (rc < 0) {
344*91f16700Schasinglulu 			return rc;
345*91f16700Schasinglulu 		}
346*91f16700Schasinglulu 		auth_img_descs[img_id].parent = &auth_img_descs[parent_img_id];
347*91f16700Schasinglulu 	}
348*91f16700Schasinglulu 
349*91f16700Schasinglulu 	auth_img_descs[img_id].img_id = img_id;
350*91f16700Schasinglulu 	auth_img_descs[img_id].img_type = type;
351*91f16700Schasinglulu 
352*91f16700Schasinglulu 	rc = populate_and_set_auth_methods(dtb, node, img_id, type,
353*91f16700Schasinglulu 				root_certificate);
354*91f16700Schasinglulu 	if (rc < 0) {
355*91f16700Schasinglulu 		return rc;
356*91f16700Schasinglulu 	}
357*91f16700Schasinglulu 
358*91f16700Schasinglulu 	if (type == IMG_CERT) {
359*91f16700Schasinglulu 		auth_param_desc_t *auth_param =
360*91f16700Schasinglulu 			pool_alloc_n(&auth_params_pool,
361*91f16700Schasinglulu 					COT_MAX_VERIFIED_PARAMS);
362*91f16700Schasinglulu 		auth_img_descs[img_id].authenticated_data = &auth_param[0];
363*91f16700Schasinglulu 	}
364*91f16700Schasinglulu 
365*91f16700Schasinglulu 	cot_desc[img_id] = &auth_img_descs[img_id];
366*91f16700Schasinglulu 
367*91f16700Schasinglulu 	return rc;
368*91f16700Schasinglulu }
369*91f16700Schasinglulu 
370*91f16700Schasinglulu /*******************************************************************************
371*91f16700Schasinglulu  * populate_manifest_descs() - Populate CoT descriptors and update global
372*91f16700Schasinglulu  *			       certificate structures
373*91f16700Schasinglulu  * @dtb[in]:	Pointer to the device tree blob in memory
374*91f16700Schasinglulu  *
375*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
376*91f16700Schasinglulu  ******************************************************************************/
377*91f16700Schasinglulu static int populate_manifest_descs(const void *dtb)
378*91f16700Schasinglulu {
379*91f16700Schasinglulu 	int node, child;
380*91f16700Schasinglulu 	int rc;
381*91f16700Schasinglulu 
382*91f16700Schasinglulu 	/*
383*91f16700Schasinglulu 	 * Assert the node offset points to "arm, cert-descs"
384*91f16700Schasinglulu 	 * compatible property
385*91f16700Schasinglulu 	 */
386*91f16700Schasinglulu 	const char *compatible_str = "arm, cert-descs";
387*91f16700Schasinglulu 
388*91f16700Schasinglulu 	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
389*91f16700Schasinglulu 	if (node < 0) {
390*91f16700Schasinglulu 		ERROR("FCONF: Can't find %s compatible in node\n",
391*91f16700Schasinglulu 			compatible_str);
392*91f16700Schasinglulu 		return node;
393*91f16700Schasinglulu 	}
394*91f16700Schasinglulu 
395*91f16700Schasinglulu 	fdt_for_each_subnode(child, dtb, node) {
396*91f16700Schasinglulu 		rc = set_desc_data(dtb, child, IMG_CERT);
397*91f16700Schasinglulu 		if (rc < 0) {
398*91f16700Schasinglulu 			return rc;
399*91f16700Schasinglulu 		}
400*91f16700Schasinglulu 	}
401*91f16700Schasinglulu 
402*91f16700Schasinglulu 	return 0;
403*91f16700Schasinglulu }
404*91f16700Schasinglulu 
405*91f16700Schasinglulu /*******************************************************************************
406*91f16700Schasinglulu  * populate_image_descs() - Populate CoT descriptors and update global
407*91f16700Schasinglulu  *			    image descriptor structures.
408*91f16700Schasinglulu  * @dtb[in]:	Pointer to the device tree blob in memory
409*91f16700Schasinglulu  *
410*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
411*91f16700Schasinglulu  ******************************************************************************/
412*91f16700Schasinglulu static int populate_image_descs(const void *dtb)
413*91f16700Schasinglulu {
414*91f16700Schasinglulu 	int node, child;
415*91f16700Schasinglulu 	int rc;
416*91f16700Schasinglulu 
417*91f16700Schasinglulu 	/*
418*91f16700Schasinglulu 	 * Assert the node offset points to "arm, img-descs"
419*91f16700Schasinglulu 	 * compatible property
420*91f16700Schasinglulu 	 */
421*91f16700Schasinglulu 	const char *compatible_str = "arm, img-descs";
422*91f16700Schasinglulu 
423*91f16700Schasinglulu 	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
424*91f16700Schasinglulu 	if (node < 0) {
425*91f16700Schasinglulu 		ERROR("FCONF: Can't find %s compatible in node\n",
426*91f16700Schasinglulu 			compatible_str);
427*91f16700Schasinglulu 		return node;
428*91f16700Schasinglulu 	}
429*91f16700Schasinglulu 
430*91f16700Schasinglulu 	fdt_for_each_subnode(child, dtb, node) {
431*91f16700Schasinglulu 		rc = set_desc_data(dtb, child, IMG_RAW);
432*91f16700Schasinglulu 		if (rc < 0) {
433*91f16700Schasinglulu 			return rc;
434*91f16700Schasinglulu 		}
435*91f16700Schasinglulu 	}
436*91f16700Schasinglulu 
437*91f16700Schasinglulu 	return 0;
438*91f16700Schasinglulu }
439*91f16700Schasinglulu 
440*91f16700Schasinglulu /*******************************************************************************
441*91f16700Schasinglulu  * fconf_populate_cot_descs() - Populate CoT descriptors and update global
442*91f16700Schasinglulu  *				structures
443*91f16700Schasinglulu  * @config[in]:	Pointer to the device tree blob in memory
444*91f16700Schasinglulu  *
445*91f16700Schasinglulu  * Return 0 on success or an error value otherwise.
446*91f16700Schasinglulu  ******************************************************************************/
447*91f16700Schasinglulu static int fconf_populate_cot_descs(uintptr_t config)
448*91f16700Schasinglulu {
449*91f16700Schasinglulu 	auth_param_type_desc_t *type_desc = NULL;
450*91f16700Schasinglulu 	unsigned int auth_buf_size = 0U;
451*91f16700Schasinglulu 	int rc;
452*91f16700Schasinglulu 
453*91f16700Schasinglulu 	/* As libfdt uses void *, we can't avoid this cast */
454*91f16700Schasinglulu 	const void *dtb = (void *)config;
455*91f16700Schasinglulu 
456*91f16700Schasinglulu 	/* populate manifest descs information */
457*91f16700Schasinglulu 	rc = populate_manifest_descs(dtb);
458*91f16700Schasinglulu 	if (rc < 0) {
459*91f16700Schasinglulu 		ERROR("FCONF: population of %s descs failed %d\n",
460*91f16700Schasinglulu 			"manifest", rc);
461*91f16700Schasinglulu 		return rc;
462*91f16700Schasinglulu 	}
463*91f16700Schasinglulu 
464*91f16700Schasinglulu 	/* populate image descs information */
465*91f16700Schasinglulu 	rc = populate_image_descs(dtb);
466*91f16700Schasinglulu 	if (rc < 0) {
467*91f16700Schasinglulu 		ERROR("FCONF: population of %s descs failed %d\n",
468*91f16700Schasinglulu 			"images", rc);
469*91f16700Schasinglulu 		return rc;
470*91f16700Schasinglulu 	}
471*91f16700Schasinglulu 
472*91f16700Schasinglulu 	/* update parent's authentication data */
473*91f16700Schasinglulu 	for (unsigned int i = 0U; i < MAX_NUMBER_IDS; i++) {
474*91f16700Schasinglulu 		if (auth_img_descs[i].parent != NULL) {
475*91f16700Schasinglulu 			rc = get_auth_param_type_desc(i,
476*91f16700Schasinglulu 						&type_desc,
477*91f16700Schasinglulu 						&auth_buf_size);
478*91f16700Schasinglulu 			if (rc < 0) {
479*91f16700Schasinglulu 				ERROR("FCONF: failed to get auth data %d\n",
480*91f16700Schasinglulu 					rc);
481*91f16700Schasinglulu 				return rc;
482*91f16700Schasinglulu 			}
483*91f16700Schasinglulu 
484*91f16700Schasinglulu 			rc = update_parent_auth_data(auth_img_descs[i].parent,
485*91f16700Schasinglulu 						type_desc,
486*91f16700Schasinglulu 						auth_buf_size);
487*91f16700Schasinglulu 			if (rc < 0) {
488*91f16700Schasinglulu 				ERROR("FCONF: auth data update failed %d\n",
489*91f16700Schasinglulu 					rc);
490*91f16700Schasinglulu 				return rc;
491*91f16700Schasinglulu 			}
492*91f16700Schasinglulu 		}
493*91f16700Schasinglulu 	}
494*91f16700Schasinglulu 
495*91f16700Schasinglulu 	return rc;
496*91f16700Schasinglulu }
497*91f16700Schasinglulu 
498*91f16700Schasinglulu FCONF_REGISTER_POPULATOR(TB_FW, cot_desc, fconf_populate_cot_descs);
499*91f16700Schasinglulu REGISTER_COT(cot_desc);
500