static int fit_config_get_data(void *fit, int conf_noffset, int noffset, struct image_region **regionp, int *region_countp, char **region_propp, int *region_proplen) { char * const exc_prop[] = {"data"}; struct strlist node_inc; struct image_region *region; struct fdt_region fdt_regions[100]; const char *conf_name, *sig_name; char path[200]; int count, i; char *region_prop; int ret, len; conf_name = fit_get_name(fit, conf_noffset, NULL); sig_name = fit_get_name(fit, conf_noffset, NULL); debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name); /* Get a list of nodes we want to hash */ ret = fit_config_get_hash_list(fit, conf_noffset, noffset, &node_inc); if (ret) return ret; /* Get a list of regions to hash */ count = fdt_find_regions(fit, node_inc.strings, node_inc.count, exc_prop, ARRAY_SIZE(exc_prop), fdt_regions, ARRAY_SIZE(fdt_regions), path, sizeof(path), 1); if (count < 0) { printf("Failed to hash configuration '%s/%s': %s\n", conf_name, sig_name, fdt_strerror(ret)); return -EIO; } if (count == 0) { printf("No data to hash for configuration '%s/%s': %s\n", conf_name, sig_name, fdt_strerror(ret)); return -EINVAL; } /* Build our list of data blocks */ region = fit_region_make_list(fit, fdt_regions, count, NULL); if (!region) { printf("Out of memory hashing configuration '%s/%s'\n", conf_name, sig_name); return -ENOMEM; } /* Create a list of all hashed properties */ debug("Hash nodes:\n"); for (i = len = 0; i < node_inc.count; i++) { debug(" %s\n", node_inc.strings[i]); len += strlen(node_inc.strings[i]) + 1; } region_prop = malloc(len); if (!region_prop) { printf("Out of memory setting up regions for configuration '%s/%s'\n", conf_name, sig_name); return -ENOMEM; } for (i = len = 0; i < node_inc.count; len += strlen(node_inc.strings[i]) + 1, i++) strcpy(region_prop + len, node_inc.strings[i]); strlist_free(&node_inc); *region_countp = count; *regionp = region; *region_propp = region_prop; *region_proplen = len; return 0; }
int fit_config_check_sig(const void *fit, int noffset, int required_keynode, char **err_msgp) { char * const exc_prop[] = {"data"}; const char *prop, *end, *name; struct image_sign_info info; const uint32_t *strings; uint8_t *fit_value; int fit_value_len; int max_regions; int i, prop_len; char path[200]; int count; debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(), fit_get_name(fit, noffset, NULL), fit_get_name(gd_fdt_blob(), required_keynode, NULL)); *err_msgp = NULL; if (fit_image_setup_verify(&info, fit, noffset, required_keynode, err_msgp)) return -1; if (fit_image_hash_get_value(fit, noffset, &fit_value, &fit_value_len)) { *err_msgp = "Can't get hash value property"; return -1; } /* Count the number of strings in the property */ prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len); end = prop ? prop + prop_len : prop; for (name = prop, count = 0; name < end; name++) if (!*name) count++; if (!count) { *err_msgp = "Can't get hashed-nodes property"; return -1; } /* Add a sanity check here since we are using the stack */ if (count > IMAGE_MAX_HASHED_NODES) { *err_msgp = "Number of hashed nodes exceeds maximum"; return -1; } /* Create a list of node names from those strings */ char *node_inc[count]; debug("Hash nodes (%d):\n", count); for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) { debug(" '%s'\n", name); node_inc[i] = (char *)name; } /* * Each node can generate one region for each sub-node. Allow for * 7 sub-nodes (hash@1, signature@1, etc.) and some extra. */ max_regions = 20 + count * 7; struct fdt_region fdt_regions[max_regions]; /* Get a list of regions to hash */ count = fdt_find_regions(fit, node_inc, count, exc_prop, ARRAY_SIZE(exc_prop), fdt_regions, max_regions - 1, path, sizeof(path), 0); if (count < 0) { *err_msgp = "Failed to hash configuration"; return -1; } if (count == 0) { *err_msgp = "No data to hash"; return -1; } if (count >= max_regions - 1) { *err_msgp = "Too many hash regions"; return -1; } /* Add the strings */ strings = fdt_getprop(fit, noffset, "hashed-strings", NULL); if (strings) { fdt_regions[count].offset = fdt_off_dt_strings(fit) + fdt32_to_cpu(strings[0]); fdt_regions[count].size = fdt32_to_cpu(strings[1]); count++; } /* Allocate the region list on the stack */ struct image_region region[count]; fit_region_make_list(fit, fdt_regions, count, region); if (info.algo->verify(&info, region, count, fit_value, fit_value_len)) { *err_msgp = "Verification failed"; return -1; } return 0; }