static int fit_config_check_sig(const void *fit, int noffset,
				int required_keynode, int conf_noffset,
				char **err_msgp)
{
	char * const exc_prop[] = {"data", "data-size", "data-position"};
	const char *prop, *end, *name;
	struct image_sign_info info;
	const uint32_t *strings;
	const char *config_name;
	uint8_t *fit_value;
	int fit_value_len;
	bool found_config;
	int max_regions;
	int i, prop_len;
	char path[200];
	int count;

	config_name = fit_get_name(fit, conf_noffset, NULL);
	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;
	}

	if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') {
		*err_msgp = "hashed-nodes property must be null-terminated";
		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);
	found_config = false;
	for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) {
		debug("   '%s'\n", name);
		node_inc[i] = (char *)name;
		if (!strncmp(FIT_CONFS_PATH, name, strlen(FIT_CONFS_PATH)) &&
		    name[sizeof(FIT_CONFS_PATH) - 1] == '/' &&
		    !strcmp(name + sizeof(FIT_CONFS_PATH), config_name)) {
			debug("      (found config node %s)", config_name);
			found_config = true;
		}
	}
	if (!found_config) {
		*err_msgp = "Selected config not in hashed nodes";
		return -1;
	}

	/*
	 * 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) {
		/*
		 * The strings region offset must be a static 0x0.
		 * This is set in tool/image-host.c
		 */
		fdt_regions[count].offset = fdt_off_dt_strings(fit);
		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.crypto->verify(&info, region, count, fit_value,
				fit_value_len)) {
		*err_msgp = "Verification failed";
		return -1;
	}

	return 0;
}
static int fit_config_check_sig(const void *fit, int noffset,
				int required_keynode, int conf_noffset,
				char **err_msgp)
{
	char * const exc_prop[] = {"data", "data-size", "data-position"};
	const char *prop, *end, *name;
	struct image_sign_info info;
	const uint32_t *strings;
	const char *config_name;
	uint8_t *fit_value;
	int fit_value_len;
	bool found_config;
	int max_regions;
	int i, prop_len;
	char path[200];
	int count;

	config_name = fit_get_name(fit, conf_noffset, NULL);
	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;
	}

	 
	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;
	}

	if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') {
		*err_msgp = "hashed-nodes property must be null-terminated";
		return -1;
	}

	 
	if (count > IMAGE_MAX_HASHED_NODES) {
		*err_msgp = "Number of hashed nodes exceeds maximum";
		return -1;
	}

	 
	char *node_inc[count];

	debug("Hash nodes (%d):\n", count);
	found_config = false;
	for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) {
		debug("   '%s'\n", name);
		node_inc[i] = (char *)name;
		if (!strncmp(FIT_CONFS_PATH, name, strlen(FIT_CONFS_PATH)) &&
		    name[sizeof(FIT_CONFS_PATH) - 1] == '/' &&
		    !strcmp(name + sizeof(FIT_CONFS_PATH), config_name)) {
			debug("      (found config node %s)", config_name);
			found_config = true;
		}
	}
	if (!found_config) {
		*err_msgp = "Selected config not in hashed nodes";
		return -1;
	}

	 
	max_regions = 20 + count * 7;
	struct fdt_region fdt_regions[max_regions];

	 
	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;
	}

	 
	strings = fdt_getprop(fit, noffset, "hashed-strings", NULL);
	if (strings) {
		 
		fdt_regions[count].offset = fdt_off_dt_strings(fit);
		fdt_regions[count].size = fdt32_to_cpu(strings[1]);
		count++;
	}

	 
	struct image_region region[count];

	fit_region_make_list(fit, fdt_regions, count, region);
	if (info.crypto->verify(&info, region, count, fit_value,
				fit_value_len)) {
		*err_msgp = "Verification failed";
		return -1;
	}

	return 0;
}