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