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