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