128e9a55fSManish V Badarkhe /*
2*04ac0b3cSlaurenw-arm * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
328e9a55fSManish V Badarkhe *
428e9a55fSManish V Badarkhe * SPDX-License-Identifier: BSD-3-Clause
528e9a55fSManish V Badarkhe */
628e9a55fSManish V Badarkhe
728e9a55fSManish V Badarkhe #include <assert.h>
828e9a55fSManish V Badarkhe #include <stddef.h>
928e9a55fSManish V Badarkhe
10a8eadc51SGovindraj Raja #include <mbedtls/version.h>
11a8eadc51SGovindraj Raja
1228e9a55fSManish V Badarkhe #include <common/fdt_wrappers.h>
13a8eadc51SGovindraj Raja #include <common/tbbr/cot_def.h>
1428e9a55fSManish V Badarkhe #include <drivers/auth/auth_mod.h>
1528e9a55fSManish V Badarkhe #include <lib/fconf/fconf.h>
1628e9a55fSManish V Badarkhe #include <lib/object_pool.h>
1728e9a55fSManish V Badarkhe #include <libfdt.h>
1828e9a55fSManish V Badarkhe
1928e9a55fSManish V Badarkhe #include <tools_share/tbbr_oid.h>
2028e9a55fSManish V Badarkhe
2128e9a55fSManish V Badarkhe /* static structures used during authentication process */
2228e9a55fSManish V Badarkhe static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
2328e9a55fSManish V Badarkhe AUTH_PARAM_SIG, 0);
2428e9a55fSManish V Badarkhe static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
2528e9a55fSManish V Badarkhe AUTH_PARAM_SIG_ALG, 0);
2628e9a55fSManish V Badarkhe static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
2728e9a55fSManish V Badarkhe AUTH_PARAM_RAW_DATA, 0);
2828e9a55fSManish V Badarkhe
2928e9a55fSManish V Badarkhe /* pointers to an array of CoT descriptors */
3028e9a55fSManish V Badarkhe static const auth_img_desc_t *cot_desc[MAX_NUMBER_IDS];
3128e9a55fSManish V Badarkhe /* array of CoT descriptors */
3228e9a55fSManish V Badarkhe static auth_img_desc_t auth_img_descs[MAX_NUMBER_IDS];
3328e9a55fSManish V Badarkhe
3428e9a55fSManish V Badarkhe /* array of authentication methods structures */
3528e9a55fSManish V Badarkhe static auth_method_desc_t auth_methods[MAX_NUMBER_IDS * AUTH_METHOD_NUM];
3628e9a55fSManish V Badarkhe static OBJECT_POOL_ARRAY(auth_methods_pool, auth_methods);
3728e9a55fSManish V Badarkhe
3828e9a55fSManish V Badarkhe /* array of authentication params structures */
3928e9a55fSManish V Badarkhe static auth_param_desc_t auth_params[MAX_NUMBER_IDS * COT_MAX_VERIFIED_PARAMS];
4028e9a55fSManish V Badarkhe static OBJECT_POOL_ARRAY(auth_params_pool, auth_params);
4128e9a55fSManish V Badarkhe
4228e9a55fSManish V Badarkhe /* array of authentication param type structures */
4328e9a55fSManish V Badarkhe static auth_param_type_desc_t auth_param_type_descs[MAX_NUMBER_IDS];
4428e9a55fSManish V Badarkhe static OBJECT_POOL_ARRAY(auth_param_type_descs_pool, auth_param_type_descs);
4528e9a55fSManish V Badarkhe
4628e9a55fSManish V Badarkhe /*
4728e9a55fSManish V Badarkhe * array of OIDs
4828e9a55fSManish V Badarkhe * Object IDs are used to search hash, pk, counter values in certificate.
4928e9a55fSManish V Badarkhe * As per binding we have below 2 combinations:
5028e9a55fSManish V Badarkhe * 1. Certificates are validated using nv-cntr and pk
5128e9a55fSManish V Badarkhe * 2. Raw images are authenticated using hash
5228e9a55fSManish V Badarkhe * Hence in worst case, there are maximum 2 OIDs per image/certificate
5328e9a55fSManish V Badarkhe */
5428e9a55fSManish V Badarkhe static unsigned char oids[(MAX_NUMBER_IDS * 2)][MAX_OID_NAME_LEN];
5528e9a55fSManish V Badarkhe static OBJECT_POOL_ARRAY(oid_pool, oids);
5628e9a55fSManish V Badarkhe
5728e9a55fSManish V Badarkhe /* An array of auth buffer which holds hashes and pk
5828e9a55fSManish V Badarkhe * ToDo: Size decided with the current number of images and
5928e9a55fSManish V Badarkhe * certificates which are available in CoT. Size of these buffers bound to
6028e9a55fSManish V Badarkhe * increase in the future on the addition of images/certificates.
6128e9a55fSManish V Badarkhe */
6228e9a55fSManish V Badarkhe static unsigned char hash_auth_bufs[20][HASH_DER_LEN];
6328e9a55fSManish V Badarkhe static OBJECT_POOL_ARRAY(hash_auth_buf_pool, hash_auth_bufs);
6428e9a55fSManish V Badarkhe static unsigned char pk_auth_bufs[12][PK_DER_LEN];
6528e9a55fSManish V Badarkhe static OBJECT_POOL_ARRAY(pk_auth_buf_pool, pk_auth_bufs);
6628e9a55fSManish V Badarkhe
6728e9a55fSManish V Badarkhe /*******************************************************************************
6828e9a55fSManish V Badarkhe * update_parent_auth_data() - Update authentication data structure
6928e9a55fSManish V Badarkhe * @auth_desc[in]: Pointer to the auth image descriptor
7028e9a55fSManish V Badarkhe * @type_desc[in]: Pointer to authentication parameter
7128e9a55fSManish V Badarkhe * @auth_buf_size[in]: Buffer size to hold pk or hash
7228e9a55fSManish V Badarkhe *
7328e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
7428e9a55fSManish V Badarkhe ******************************************************************************/
update_parent_auth_data(const auth_img_desc_t * auth_desc,auth_param_type_desc_t * type_desc,unsigned int auth_buf_size)7528e9a55fSManish V Badarkhe static int update_parent_auth_data(const auth_img_desc_t *auth_desc,
7628e9a55fSManish V Badarkhe auth_param_type_desc_t *type_desc,
7728e9a55fSManish V Badarkhe unsigned int auth_buf_size)
7828e9a55fSManish V Badarkhe {
7928e9a55fSManish V Badarkhe unsigned int i;
8028e9a55fSManish V Badarkhe auth_param_desc_t *auth_data = &auth_desc->authenticated_data[0];
8128e9a55fSManish V Badarkhe unsigned char *auth_buf;
8228e9a55fSManish V Badarkhe
8328e9a55fSManish V Badarkhe for (i = 0U; i < COT_MAX_VERIFIED_PARAMS; i++) {
8428e9a55fSManish V Badarkhe if (auth_data[i].type_desc == type_desc) {
8528e9a55fSManish V Badarkhe return 0;
8628e9a55fSManish V Badarkhe }
8728e9a55fSManish V Badarkhe if (auth_data[i].type_desc == NULL) {
8828e9a55fSManish V Badarkhe break;
8928e9a55fSManish V Badarkhe }
9028e9a55fSManish V Badarkhe }
9128e9a55fSManish V Badarkhe
9228e9a55fSManish V Badarkhe if (auth_buf_size == HASH_DER_LEN) {
9328e9a55fSManish V Badarkhe auth_buf = pool_alloc(&hash_auth_buf_pool);
9428e9a55fSManish V Badarkhe } else if (auth_buf_size == PK_DER_LEN) {
9528e9a55fSManish V Badarkhe auth_buf = pool_alloc(&pk_auth_buf_pool);
9628e9a55fSManish V Badarkhe } else {
9728e9a55fSManish V Badarkhe return -1;
9828e9a55fSManish V Badarkhe }
9928e9a55fSManish V Badarkhe
10028e9a55fSManish V Badarkhe if (i < COT_MAX_VERIFIED_PARAMS) {
10128e9a55fSManish V Badarkhe auth_data[i].type_desc = type_desc;
10228e9a55fSManish V Badarkhe auth_data[i].data.ptr = auth_buf;
10328e9a55fSManish V Badarkhe auth_data[i].data.len = auth_buf_size;
10428e9a55fSManish V Badarkhe } else {
10528e9a55fSManish V Badarkhe ERROR("Out of authentication data array\n");
10628e9a55fSManish V Badarkhe return -1;
10728e9a55fSManish V Badarkhe }
10828e9a55fSManish V Badarkhe
10928e9a55fSManish V Badarkhe return 0;
11028e9a55fSManish V Badarkhe }
11128e9a55fSManish V Badarkhe
11228e9a55fSManish V Badarkhe /*******************************************************************************
11328e9a55fSManish V Badarkhe * get_auth_param_type_desc() - Get pointer of authentication parameter
11428e9a55fSManish V Badarkhe * @img_id[in]: Image Id
11528e9a55fSManish V Badarkhe * @type_desc[out]: Pointer to authentication parameter
11628e9a55fSManish V Badarkhe * @buf_size[out]: Buffer size which hold hash/pk
11728e9a55fSManish V Badarkhe *
11828e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
11928e9a55fSManish V Badarkhe ******************************************************************************/
get_auth_param_type_desc(unsigned int img_id,auth_param_type_desc_t ** type_desc,unsigned int * buf_size)12028e9a55fSManish V Badarkhe static int get_auth_param_type_desc(unsigned int img_id,
12128e9a55fSManish V Badarkhe auth_param_type_desc_t **type_desc,
12228e9a55fSManish V Badarkhe unsigned int *buf_size)
12328e9a55fSManish V Badarkhe {
12428e9a55fSManish V Badarkhe auth_method_desc_t *img_auth_method = NULL;
12528e9a55fSManish V Badarkhe img_type_t type = auth_img_descs[img_id].img_type;
12628e9a55fSManish V Badarkhe
12728e9a55fSManish V Badarkhe if (type == IMG_CERT) {
12828e9a55fSManish V Badarkhe img_auth_method =
12928e9a55fSManish V Badarkhe &auth_img_descs[img_id].img_auth_methods[AUTH_METHOD_SIG];
13028e9a55fSManish V Badarkhe *type_desc = img_auth_method->param.sig.pk;
13128e9a55fSManish V Badarkhe *buf_size = PK_DER_LEN;
13228e9a55fSManish V Badarkhe } else if (type == IMG_RAW) {
13328e9a55fSManish V Badarkhe img_auth_method =
13428e9a55fSManish V Badarkhe &auth_img_descs[img_id].img_auth_methods[AUTH_METHOD_HASH];
13528e9a55fSManish V Badarkhe *type_desc = img_auth_method->param.hash.hash;
13628e9a55fSManish V Badarkhe *buf_size = HASH_DER_LEN;
13728e9a55fSManish V Badarkhe } else {
13828e9a55fSManish V Badarkhe return -1;
13928e9a55fSManish V Badarkhe }
14028e9a55fSManish V Badarkhe
14128e9a55fSManish V Badarkhe return 0;
14228e9a55fSManish V Badarkhe }
14328e9a55fSManish V Badarkhe
14428e9a55fSManish V Badarkhe /*******************************************************************************
14528e9a55fSManish V Badarkhe * set_auth_method() - Update global auth image descriptors with authentication
14628e9a55fSManish V Badarkhe * method data
14728e9a55fSManish V Badarkhe * @auth_method_type[in]: Type of authentication method
14828e9a55fSManish V Badarkhe * @oid[in]: Object Idetifier for pk/hash search
14928e9a55fSManish V Badarkhe * @auth_method[in]: Pointer to authentication method to set
15028e9a55fSManish V Badarkhe ******************************************************************************/
set_auth_method(auth_method_type_t auth_method_type,char * oid,auth_method_desc_t * auth_method)15128e9a55fSManish V Badarkhe static void set_auth_method(auth_method_type_t auth_method_type, char *oid,
15228e9a55fSManish V Badarkhe auth_method_desc_t *auth_method)
15328e9a55fSManish V Badarkhe {
15428e9a55fSManish V Badarkhe auth_param_type_t auth_param_type = AUTH_PARAM_NONE;
15528e9a55fSManish V Badarkhe auth_param_type_desc_t *auth_param_type_desc;
15628e9a55fSManish V Badarkhe
15728e9a55fSManish V Badarkhe assert(auth_method != NULL);
15828e9a55fSManish V Badarkhe
15928e9a55fSManish V Badarkhe auth_param_type_desc = pool_alloc(&auth_param_type_descs_pool);
16028e9a55fSManish V Badarkhe auth_method->type = auth_method_type;
16128e9a55fSManish V Badarkhe
16228e9a55fSManish V Badarkhe if (auth_method_type == AUTH_METHOD_SIG) {
16328e9a55fSManish V Badarkhe auth_param_type = AUTH_PARAM_PUB_KEY;
16428e9a55fSManish V Badarkhe auth_method->param.sig.sig = &sig;
16528e9a55fSManish V Badarkhe auth_method->param.sig.alg = &sig_alg;
16628e9a55fSManish V Badarkhe auth_method->param.sig.data = &raw_data;
16728e9a55fSManish V Badarkhe auth_method->param.sig.pk = auth_param_type_desc;
16828e9a55fSManish V Badarkhe } else if (auth_method_type == AUTH_METHOD_HASH) {
16928e9a55fSManish V Badarkhe auth_param_type = AUTH_PARAM_HASH;
17028e9a55fSManish V Badarkhe auth_method->param.hash.data = &raw_data;
17128e9a55fSManish V Badarkhe auth_method->param.hash.hash = auth_param_type_desc;
17228e9a55fSManish V Badarkhe } else if (auth_method_type == AUTH_METHOD_NV_CTR) {
17328e9a55fSManish V Badarkhe auth_param_type = AUTH_PARAM_NV_CTR;
17428e9a55fSManish V Badarkhe auth_method->param.nv_ctr.cert_nv_ctr = auth_param_type_desc;
17528e9a55fSManish V Badarkhe auth_method->param.nv_ctr.plat_nv_ctr = auth_param_type_desc;
17628e9a55fSManish V Badarkhe }
17728e9a55fSManish V Badarkhe
17828e9a55fSManish V Badarkhe auth_param_type_desc->type = auth_param_type;
17928e9a55fSManish V Badarkhe auth_param_type_desc->cookie = (void *)oid;
18028e9a55fSManish V Badarkhe }
18128e9a55fSManish V Badarkhe
18228e9a55fSManish V Badarkhe /*******************************************************************************
18328e9a55fSManish V Badarkhe * get_oid() - get object identifier from device tree
18428e9a55fSManish V Badarkhe * @dtb[in]: Pointer to the device tree blob in memory
18528e9a55fSManish V Badarkhe * @node[in]: Offset of the node
18628e9a55fSManish V Badarkhe * @prop[in]: Property to read from the given node
18728e9a55fSManish V Badarkhe * @oid[out]: Object Indentifier of key/hash/nv-counter in certificate
18828e9a55fSManish V Badarkhe *
18928e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
19028e9a55fSManish V Badarkhe ******************************************************************************/
get_oid(const void * dtb,int node,const char * prop,char ** oid)19128e9a55fSManish V Badarkhe static int get_oid(const void *dtb, int node, const char *prop, char **oid)
19228e9a55fSManish V Badarkhe {
19328e9a55fSManish V Badarkhe uint32_t phandle;
19428e9a55fSManish V Badarkhe int rc;
19528e9a55fSManish V Badarkhe
19628e9a55fSManish V Badarkhe rc = fdt_read_uint32(dtb, node, prop, &phandle);
19728e9a55fSManish V Badarkhe if (rc < 0) {
19828e9a55fSManish V Badarkhe return rc;
19928e9a55fSManish V Badarkhe }
20028e9a55fSManish V Badarkhe
20128e9a55fSManish V Badarkhe node = fdt_node_offset_by_phandle(dtb, phandle);
20228e9a55fSManish V Badarkhe if (node < 0) {
20328e9a55fSManish V Badarkhe return node;
20428e9a55fSManish V Badarkhe }
20528e9a55fSManish V Badarkhe
20628e9a55fSManish V Badarkhe *oid = pool_alloc(&oid_pool);
20728e9a55fSManish V Badarkhe rc = fdtw_read_string(dtb, node, "oid", *oid, MAX_OID_NAME_LEN);
20828e9a55fSManish V Badarkhe
20928e9a55fSManish V Badarkhe return rc;
21028e9a55fSManish V Badarkhe }
21128e9a55fSManish V Badarkhe
21228e9a55fSManish V Badarkhe /*******************************************************************************
21328e9a55fSManish V Badarkhe * populate_and_set_auth_methods() - Populate auth method parameters from
21428e9a55fSManish V Badarkhe * device tree and set authentication method
21528e9a55fSManish V Badarkhe * structure.
21628e9a55fSManish V Badarkhe * @dtb[in]: Pointer to the device tree blob in memory
21728e9a55fSManish V Badarkhe * @node[in]: Offset of the node
21828e9a55fSManish V Badarkhe * @img_id[in]: Image identifier
21928e9a55fSManish V Badarkhe * @type[in]: Type of image
22028e9a55fSManish V Badarkhe * @root_certificate[in]:Root certificate (authenticated by ROTPK)
22128e9a55fSManish V Badarkhe *
22228e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
22328e9a55fSManish V Badarkhe ******************************************************************************/
populate_and_set_auth_methods(const void * dtb,int node,unsigned int img_id,img_type_t type,bool root_certificate)22428e9a55fSManish V Badarkhe static int populate_and_set_auth_methods(const void *dtb, int node,
22528e9a55fSManish V Badarkhe unsigned int img_id, img_type_t type,
22628e9a55fSManish V Badarkhe bool root_certificate)
22728e9a55fSManish V Badarkhe {
22828e9a55fSManish V Badarkhe auth_method_type_t auth_method_type = AUTH_METHOD_NONE;
22928e9a55fSManish V Badarkhe int rc;
23028e9a55fSManish V Badarkhe char *oid = NULL;
23128e9a55fSManish V Badarkhe
23228e9a55fSManish V Badarkhe auth_method_desc_t *auth_method = pool_alloc_n(&auth_methods_pool,
23328e9a55fSManish V Badarkhe AUTH_METHOD_NUM);
23428e9a55fSManish V Badarkhe
23528e9a55fSManish V Badarkhe /*
23628e9a55fSManish V Badarkhe * This is as per binding document where certificates are
23728e9a55fSManish V Badarkhe * verified by signature and images are verified by hash.
23828e9a55fSManish V Badarkhe */
23928e9a55fSManish V Badarkhe if (type == IMG_CERT) {
240*04ac0b3cSlaurenw-arm rc = get_oid(dtb, node, "signing-key", &oid);
241*04ac0b3cSlaurenw-arm if (rc < 0) {
242*04ac0b3cSlaurenw-arm /*
243*04ac0b3cSlaurenw-arm * The signing-key property is optional in root
244*04ac0b3cSlaurenw-arm * certificates, mandatory otherwise.
245*04ac0b3cSlaurenw-arm */
24628e9a55fSManish V Badarkhe if (root_certificate) {
24728e9a55fSManish V Badarkhe oid = NULL;
24828e9a55fSManish V Badarkhe } else {
24928e9a55fSManish V Badarkhe ERROR("FCONF: Can't read %s property\n",
25028e9a55fSManish V Badarkhe "signing-key");
25128e9a55fSManish V Badarkhe return rc;
25228e9a55fSManish V Badarkhe }
25328e9a55fSManish V Badarkhe }
25428e9a55fSManish V Badarkhe auth_method_type = AUTH_METHOD_SIG;
25528e9a55fSManish V Badarkhe } else if (type == IMG_RAW) {
25628e9a55fSManish V Badarkhe rc = get_oid(dtb, node, "hash", &oid);
25728e9a55fSManish V Badarkhe if (rc < 0) {
25828e9a55fSManish V Badarkhe ERROR("FCONF: Can't read %s property\n",
25928e9a55fSManish V Badarkhe "hash");
26028e9a55fSManish V Badarkhe return rc;
26128e9a55fSManish V Badarkhe }
26228e9a55fSManish V Badarkhe auth_method_type = AUTH_METHOD_HASH;
26328e9a55fSManish V Badarkhe } else {
26428e9a55fSManish V Badarkhe return -1;
26528e9a55fSManish V Badarkhe }
26628e9a55fSManish V Badarkhe
26728e9a55fSManish V Badarkhe set_auth_method(auth_method_type, oid,
26828e9a55fSManish V Badarkhe &auth_method[auth_method_type]);
26928e9a55fSManish V Badarkhe
27028e9a55fSManish V Badarkhe /* Retrieve the optional property */
27128e9a55fSManish V Badarkhe rc = get_oid(dtb, node, "antirollback-counter", &oid);
27228e9a55fSManish V Badarkhe if (rc == 0) {
27328e9a55fSManish V Badarkhe auth_method_type = AUTH_METHOD_NV_CTR;
27428e9a55fSManish V Badarkhe set_auth_method(auth_method_type, oid,
27528e9a55fSManish V Badarkhe &auth_method[auth_method_type]);
27628e9a55fSManish V Badarkhe }
27728e9a55fSManish V Badarkhe
27828e9a55fSManish V Badarkhe auth_img_descs[img_id].img_auth_methods = &auth_method[0];
27928e9a55fSManish V Badarkhe
28028e9a55fSManish V Badarkhe return 0;
28128e9a55fSManish V Badarkhe }
28228e9a55fSManish V Badarkhe
28328e9a55fSManish V Badarkhe /*******************************************************************************
28428e9a55fSManish V Badarkhe * get_parent_img_id() - Get parent image id for given child node
28528e9a55fSManish V Badarkhe * @dtb[in]: Pointer to the device tree blob in memory
28628e9a55fSManish V Badarkhe * @node[in]: Offset of the child node
28728e9a55fSManish V Badarkhe * @parent_img_id[out]: Image id of parent
28828e9a55fSManish V Badarkhe *
28928e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
29028e9a55fSManish V Badarkhe ******************************************************************************/
get_parent_img_id(const void * dtb,int node,unsigned int * parent_img_id)29128e9a55fSManish V Badarkhe static int get_parent_img_id(const void *dtb, int node,
29228e9a55fSManish V Badarkhe unsigned int *parent_img_id)
29328e9a55fSManish V Badarkhe {
29428e9a55fSManish V Badarkhe uint32_t phandle;
29528e9a55fSManish V Badarkhe int err;
29628e9a55fSManish V Badarkhe
29728e9a55fSManish V Badarkhe err = fdt_read_uint32(dtb, node, "parent", &phandle);
29828e9a55fSManish V Badarkhe if (err < 0) {
29928e9a55fSManish V Badarkhe ERROR("FCONF: Could not read %s property in node\n",
30028e9a55fSManish V Badarkhe "parent");
30128e9a55fSManish V Badarkhe return err;
30228e9a55fSManish V Badarkhe }
30328e9a55fSManish V Badarkhe
30428e9a55fSManish V Badarkhe node = fdt_node_offset_by_phandle(dtb, phandle);
30528e9a55fSManish V Badarkhe if (node < 0) {
30628e9a55fSManish V Badarkhe ERROR("FCONF: Failed to locate node using its phandle\n");
30728e9a55fSManish V Badarkhe return node;
30828e9a55fSManish V Badarkhe }
30928e9a55fSManish V Badarkhe
31028e9a55fSManish V Badarkhe err = fdt_read_uint32(dtb, node, "image-id", parent_img_id);
31128e9a55fSManish V Badarkhe if (err < 0) {
31228e9a55fSManish V Badarkhe ERROR("FCONF: Could not read %s property in node\n",
31328e9a55fSManish V Badarkhe "image-id");
31428e9a55fSManish V Badarkhe }
31528e9a55fSManish V Badarkhe
31628e9a55fSManish V Badarkhe return err;
31728e9a55fSManish V Badarkhe }
31828e9a55fSManish V Badarkhe
31928e9a55fSManish V Badarkhe /*******************************************************************************
32028e9a55fSManish V Badarkhe * set_desc_data() - Update data in descriptor's structure
32128e9a55fSManish V Badarkhe * @dtb[in]: Pointer to the device tree blob in memory
32228e9a55fSManish V Badarkhe * @node[in]: Offset of the node
32328e9a55fSManish V Badarkhe * @type[in]: Type of image (RAW/CERT)
32428e9a55fSManish V Badarkhe *
32528e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
32628e9a55fSManish V Badarkhe ******************************************************************************/
set_desc_data(const void * dtb,int node,img_type_t type)32728e9a55fSManish V Badarkhe static int set_desc_data(const void *dtb, int node, img_type_t type)
32828e9a55fSManish V Badarkhe {
32928e9a55fSManish V Badarkhe int rc;
33028e9a55fSManish V Badarkhe bool root_certificate = false;
33128e9a55fSManish V Badarkhe unsigned int img_id, parent_img_id;
33228e9a55fSManish V Badarkhe
33328e9a55fSManish V Badarkhe rc = fdt_read_uint32(dtb, node, "image-id", &img_id);
33428e9a55fSManish V Badarkhe if (rc < 0) {
33528e9a55fSManish V Badarkhe ERROR("FCONF: Can't find property %s in node\n",
33628e9a55fSManish V Badarkhe "image-id");
33728e9a55fSManish V Badarkhe return rc;
33828e9a55fSManish V Badarkhe }
33928e9a55fSManish V Badarkhe
34028e9a55fSManish V Badarkhe if (fdt_getprop(dtb, node, "root-certificate",
34128e9a55fSManish V Badarkhe NULL) != NULL) {
34228e9a55fSManish V Badarkhe root_certificate = true;
34328e9a55fSManish V Badarkhe }
34428e9a55fSManish V Badarkhe
34528e9a55fSManish V Badarkhe if (!root_certificate) {
34628e9a55fSManish V Badarkhe rc = get_parent_img_id(dtb, node, &parent_img_id);
34728e9a55fSManish V Badarkhe if (rc < 0) {
34828e9a55fSManish V Badarkhe return rc;
34928e9a55fSManish V Badarkhe }
35028e9a55fSManish V Badarkhe auth_img_descs[img_id].parent = &auth_img_descs[parent_img_id];
35128e9a55fSManish V Badarkhe }
35228e9a55fSManish V Badarkhe
35328e9a55fSManish V Badarkhe auth_img_descs[img_id].img_id = img_id;
35428e9a55fSManish V Badarkhe auth_img_descs[img_id].img_type = type;
35528e9a55fSManish V Badarkhe
35628e9a55fSManish V Badarkhe rc = populate_and_set_auth_methods(dtb, node, img_id, type,
35728e9a55fSManish V Badarkhe root_certificate);
35828e9a55fSManish V Badarkhe if (rc < 0) {
35928e9a55fSManish V Badarkhe return rc;
36028e9a55fSManish V Badarkhe }
36128e9a55fSManish V Badarkhe
36228e9a55fSManish V Badarkhe if (type == IMG_CERT) {
36328e9a55fSManish V Badarkhe auth_param_desc_t *auth_param =
36428e9a55fSManish V Badarkhe pool_alloc_n(&auth_params_pool,
36528e9a55fSManish V Badarkhe COT_MAX_VERIFIED_PARAMS);
36628e9a55fSManish V Badarkhe auth_img_descs[img_id].authenticated_data = &auth_param[0];
36728e9a55fSManish V Badarkhe }
36828e9a55fSManish V Badarkhe
36928e9a55fSManish V Badarkhe cot_desc[img_id] = &auth_img_descs[img_id];
37028e9a55fSManish V Badarkhe
37128e9a55fSManish V Badarkhe return rc;
37228e9a55fSManish V Badarkhe }
37328e9a55fSManish V Badarkhe
37428e9a55fSManish V Badarkhe /*******************************************************************************
37528e9a55fSManish V Badarkhe * populate_manifest_descs() - Populate CoT descriptors and update global
37628e9a55fSManish V Badarkhe * certificate structures
37728e9a55fSManish V Badarkhe * @dtb[in]: Pointer to the device tree blob in memory
37828e9a55fSManish V Badarkhe *
37928e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
38028e9a55fSManish V Badarkhe ******************************************************************************/
populate_manifest_descs(const void * dtb)38128e9a55fSManish V Badarkhe static int populate_manifest_descs(const void *dtb)
38228e9a55fSManish V Badarkhe {
38328e9a55fSManish V Badarkhe int node, child;
38428e9a55fSManish V Badarkhe int rc;
38528e9a55fSManish V Badarkhe
38628e9a55fSManish V Badarkhe /*
38728e9a55fSManish V Badarkhe * Assert the node offset points to "arm, cert-descs"
38828e9a55fSManish V Badarkhe * compatible property
38928e9a55fSManish V Badarkhe */
39028e9a55fSManish V Badarkhe const char *compatible_str = "arm, cert-descs";
39128e9a55fSManish V Badarkhe
39228e9a55fSManish V Badarkhe node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
39328e9a55fSManish V Badarkhe if (node < 0) {
39428e9a55fSManish V Badarkhe ERROR("FCONF: Can't find %s compatible in node\n",
39528e9a55fSManish V Badarkhe compatible_str);
39628e9a55fSManish V Badarkhe return node;
39728e9a55fSManish V Badarkhe }
39828e9a55fSManish V Badarkhe
39928e9a55fSManish V Badarkhe fdt_for_each_subnode(child, dtb, node) {
40028e9a55fSManish V Badarkhe rc = set_desc_data(dtb, child, IMG_CERT);
40128e9a55fSManish V Badarkhe if (rc < 0) {
40228e9a55fSManish V Badarkhe return rc;
40328e9a55fSManish V Badarkhe }
40428e9a55fSManish V Badarkhe }
40528e9a55fSManish V Badarkhe
40628e9a55fSManish V Badarkhe return 0;
40728e9a55fSManish V Badarkhe }
40828e9a55fSManish V Badarkhe
40928e9a55fSManish V Badarkhe /*******************************************************************************
41028e9a55fSManish V Badarkhe * populate_image_descs() - Populate CoT descriptors and update global
41128e9a55fSManish V Badarkhe * image descriptor structures.
41228e9a55fSManish V Badarkhe * @dtb[in]: Pointer to the device tree blob in memory
41328e9a55fSManish V Badarkhe *
41428e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
41528e9a55fSManish V Badarkhe ******************************************************************************/
populate_image_descs(const void * dtb)41628e9a55fSManish V Badarkhe static int populate_image_descs(const void *dtb)
41728e9a55fSManish V Badarkhe {
41828e9a55fSManish V Badarkhe int node, child;
41928e9a55fSManish V Badarkhe int rc;
42028e9a55fSManish V Badarkhe
42128e9a55fSManish V Badarkhe /*
42228e9a55fSManish V Badarkhe * Assert the node offset points to "arm, img-descs"
42328e9a55fSManish V Badarkhe * compatible property
42428e9a55fSManish V Badarkhe */
42528e9a55fSManish V Badarkhe const char *compatible_str = "arm, img-descs";
42628e9a55fSManish V Badarkhe
42728e9a55fSManish V Badarkhe node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
42828e9a55fSManish V Badarkhe if (node < 0) {
42928e9a55fSManish V Badarkhe ERROR("FCONF: Can't find %s compatible in node\n",
43028e9a55fSManish V Badarkhe compatible_str);
43128e9a55fSManish V Badarkhe return node;
43228e9a55fSManish V Badarkhe }
43328e9a55fSManish V Badarkhe
43428e9a55fSManish V Badarkhe fdt_for_each_subnode(child, dtb, node) {
43528e9a55fSManish V Badarkhe rc = set_desc_data(dtb, child, IMG_RAW);
43628e9a55fSManish V Badarkhe if (rc < 0) {
43728e9a55fSManish V Badarkhe return rc;
43828e9a55fSManish V Badarkhe }
43928e9a55fSManish V Badarkhe }
44028e9a55fSManish V Badarkhe
44128e9a55fSManish V Badarkhe return 0;
44228e9a55fSManish V Badarkhe }
44328e9a55fSManish V Badarkhe
44428e9a55fSManish V Badarkhe /*******************************************************************************
44528e9a55fSManish V Badarkhe * fconf_populate_cot_descs() - Populate CoT descriptors and update global
44628e9a55fSManish V Badarkhe * structures
44728e9a55fSManish V Badarkhe * @config[in]: Pointer to the device tree blob in memory
44828e9a55fSManish V Badarkhe *
44928e9a55fSManish V Badarkhe * Return 0 on success or an error value otherwise.
45028e9a55fSManish V Badarkhe ******************************************************************************/
fconf_populate_cot_descs(uintptr_t config)45128e9a55fSManish V Badarkhe static int fconf_populate_cot_descs(uintptr_t config)
45228e9a55fSManish V Badarkhe {
45328e9a55fSManish V Badarkhe auth_param_type_desc_t *type_desc = NULL;
45428e9a55fSManish V Badarkhe unsigned int auth_buf_size = 0U;
45528e9a55fSManish V Badarkhe int rc;
45628e9a55fSManish V Badarkhe
45728e9a55fSManish V Badarkhe /* As libfdt uses void *, we can't avoid this cast */
45828e9a55fSManish V Badarkhe const void *dtb = (void *)config;
45928e9a55fSManish V Badarkhe
46028e9a55fSManish V Badarkhe /* populate manifest descs information */
46128e9a55fSManish V Badarkhe rc = populate_manifest_descs(dtb);
46228e9a55fSManish V Badarkhe if (rc < 0) {
46328e9a55fSManish V Badarkhe ERROR("FCONF: population of %s descs failed %d\n",
46428e9a55fSManish V Badarkhe "manifest", rc);
46528e9a55fSManish V Badarkhe return rc;
46628e9a55fSManish V Badarkhe }
46728e9a55fSManish V Badarkhe
46828e9a55fSManish V Badarkhe /* populate image descs information */
46928e9a55fSManish V Badarkhe rc = populate_image_descs(dtb);
47028e9a55fSManish V Badarkhe if (rc < 0) {
47128e9a55fSManish V Badarkhe ERROR("FCONF: population of %s descs failed %d\n",
47228e9a55fSManish V Badarkhe "images", rc);
47328e9a55fSManish V Badarkhe return rc;
47428e9a55fSManish V Badarkhe }
47528e9a55fSManish V Badarkhe
47628e9a55fSManish V Badarkhe /* update parent's authentication data */
47728e9a55fSManish V Badarkhe for (unsigned int i = 0U; i < MAX_NUMBER_IDS; i++) {
47828e9a55fSManish V Badarkhe if (auth_img_descs[i].parent != NULL) {
47928e9a55fSManish V Badarkhe rc = get_auth_param_type_desc(i,
48028e9a55fSManish V Badarkhe &type_desc,
48128e9a55fSManish V Badarkhe &auth_buf_size);
48228e9a55fSManish V Badarkhe if (rc < 0) {
48328e9a55fSManish V Badarkhe ERROR("FCONF: failed to get auth data %d\n",
48428e9a55fSManish V Badarkhe rc);
48528e9a55fSManish V Badarkhe return rc;
48628e9a55fSManish V Badarkhe }
48728e9a55fSManish V Badarkhe
48828e9a55fSManish V Badarkhe rc = update_parent_auth_data(auth_img_descs[i].parent,
48928e9a55fSManish V Badarkhe type_desc,
49028e9a55fSManish V Badarkhe auth_buf_size);
49128e9a55fSManish V Badarkhe if (rc < 0) {
49228e9a55fSManish V Badarkhe ERROR("FCONF: auth data update failed %d\n",
49328e9a55fSManish V Badarkhe rc);
49428e9a55fSManish V Badarkhe return rc;
49528e9a55fSManish V Badarkhe }
49628e9a55fSManish V Badarkhe }
49728e9a55fSManish V Badarkhe }
49828e9a55fSManish V Badarkhe
49928e9a55fSManish V Badarkhe return rc;
50028e9a55fSManish V Badarkhe }
50128e9a55fSManish V Badarkhe
50228e9a55fSManish V Badarkhe FCONF_REGISTER_POPULATOR(TB_FW, cot_desc, fconf_populate_cot_descs);
50328e9a55fSManish V Badarkhe REGISTER_COT(cot_desc);
504