Exemple #1
0
int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
			ulong addr)
{
	int cfg_noffset;
	void *fit_hdr;
	int noffset;

	debug("*  %s: using config '%s' from image at 0x%08lx\n",
	      prop_name, images->fit_uname_cfg, addr);

	/* Check whether configuration has this property defined */
	fit_hdr = map_sysmem(addr, 0);
	cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
	if (cfg_noffset < 0) {
		debug("*  %s: no such config\n", prop_name);
		return -ENOENT;
	}

	noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
	if (noffset < 0) {
		debug("*  %s: no '%s' in config\n", prop_name, prop_name);
		return -ENOLINK;
	}

	return noffset;
}
static int sec_firmware_get_data(const void *sec_firmware_img,
				const void **data, size_t *size)
{
	int conf_node_off, fw_node_off;
	char *conf_node_name = NULL;
	char *desc;
	int ret;

	conf_node_name = SEC_FIRMEWARE_FIT_CNF_NAME;

	conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name);
	if (conf_node_off < 0) {
		printf("SEC Firmware: %s: no such config\n", conf_node_name);
		return -ENOENT;
	}

	fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off,
			SEC_FIRMWARE_FIT_IMAGE);
	if (fw_node_off < 0) {
		printf("SEC Firmware: No '%s' in config\n",
		       SEC_FIRMWARE_FIT_IMAGE);
		return -ENOLINK;
	}

	/* Verify secure firmware image */
	if (!(fit_image_verify(sec_firmware_img, fw_node_off))) {
		printf("SEC Firmware: Bad firmware image (bad CRC)\n");
		return -EINVAL;
	}

	if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) {
		printf("SEC Firmware: Can't get %s subimage data/size",
		       SEC_FIRMWARE_FIT_IMAGE);
		return -ENOENT;
	}

	ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc);
	if (ret)
		printf("SEC Firmware: Can't get description\n");
	else
		printf("%s\n", desc);

	return ret;
}
Exemple #3
0
/*
 * Get PFE firmware from FIT image
 *
 * @param data pointer to PFE firmware
 * @param size pointer to size of the firmware
 * @param fw_name pfe firmware name, either class or tmu
 *
 * @return 0 on success, a negative value on error
 */
static int pfe_get_fw(const void **data,
		      size_t *size, char *fw_name)
{
	int conf_node_off, fw_node_off;
	char *conf_node_name = NULL;
	char *desc;
	int ret = 0;

	conf_node_name = PFE_FIRMEWARE_FIT_CNF_NAME;

	conf_node_off = fit_conf_get_node(pfe_fit_addr, conf_node_name);
	if (conf_node_off < 0) {
		printf("PFE Firmware: %s: no such config\n", conf_node_name);
		return -ENOENT;
	}

	fw_node_off = fit_conf_get_prop_node(pfe_fit_addr, conf_node_off,
					     fw_name);
	if (fw_node_off < 0) {
		printf("PFE Firmware: No '%s' in config\n",
		       fw_name);
		return -ENOLINK;
	}

	if (!(fit_image_verify(pfe_fit_addr, fw_node_off))) {
		printf("PFE Firmware: Bad firmware image (bad CRC)\n");
		return -EINVAL;
	}

	if (fit_image_get_data(pfe_fit_addr, fw_node_off, data, size)) {
		printf("PFE Firmware: Can't get %s subimage data/size",
		       fw_name);
		return -ENOENT;
	}

	ret = fit_get_desc(pfe_fit_addr, fw_node_off, &desc);
	if (ret)
		printf("PFE Firmware: Can't get description\n");
	else
		printf("%s\n", desc);

	return ret;
}
Exemple #4
0
int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
		   const char **fit_unamep, const char **fit_uname_configp,
		   int arch, int image_type, int bootstage_id,
		   enum fit_load_op load_op, ulong *datap, ulong *lenp)
{
	int cfg_noffset, noffset;
	const char *fit_uname;
	const char *fit_uname_config;
	const void *fit;
	const void *buf;
	size_t size;
	int type_ok, os_ok;
	ulong load, data, len;
	int ret;

	fit = map_sysmem(addr, 0);
	fit_uname = fit_unamep ? *fit_unamep : NULL;
	fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
	printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
	if (!fit_check_format(fit)) {
		printf("Bad FIT %s image format!\n", prop_name);
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
		return -ENOEXEC;
	}
	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
	if (fit_uname) {
		/* get ramdisk component image node offset */
		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
		noffset = fit_image_get_node(fit, fit_uname);
	} else {
		/*
		 * no image node unit name, try to get config
		 * node first. If config unit node name is NULL
		 * fit_conf_get_node() will try to find default config node
		 */
		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
		if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
			cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
		} else {
			cfg_noffset = fit_conf_get_node(fit,
							fit_uname_config);
		}
		if (cfg_noffset < 0) {
			puts("Could not find configuration node\n");
			bootstage_error(bootstage_id +
					BOOTSTAGE_SUB_NO_UNIT_NAME);
			return -ENOENT;
		}
		fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
		printf("   Using '%s' configuration\n", fit_uname_config);
		if (image_type == IH_TYPE_KERNEL) {
			/* Remember (and possibly verify) this config */
			images->fit_uname_cfg = fit_uname_config;
			if (IMAGE_ENABLE_VERIFY && images->verify) {
				puts("   Verifying Hash Integrity ... ");
				if (!fit_config_verify(fit, cfg_noffset)) {
					puts("Bad Data Hash\n");
					bootstage_error(bootstage_id +
						BOOTSTAGE_SUB_HASH);
					return -EACCES;
				}
				puts("OK\n");
			}
			bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
		}

		noffset = fit_conf_get_prop_node(fit, cfg_noffset,
						 prop_name);
		fit_uname = fit_get_name(fit, noffset, NULL);
	}
	if (noffset < 0) {
		puts("Could not find subimage node\n");
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
		return -ENOENT;
	}

	printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);

	ret = fit_image_select(fit, noffset, images->verify);
	if (ret) {
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
		return ret;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
	if (!fit_image_check_target_arch(fit, noffset)) {
		puts("Unsupported Architecture\n");
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
		return -ENOEXEC;
	}

	if (image_type == IH_TYPE_FLATDT &&
	    !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
		puts("FDT image is compressed");
		return -EPROTONOSUPPORT;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
	type_ok = fit_image_check_type(fit, noffset, image_type) ||
		(image_type == IH_TYPE_KERNEL &&
			fit_image_check_type(fit, noffset,
					     IH_TYPE_KERNEL_NOLOAD));
	os_ok = image_type == IH_TYPE_FLATDT ||
		fit_image_check_os(fit, noffset, IH_OS_LINUX);
	if (!type_ok || !os_ok) {
		printf("No Linux %s %s Image\n", genimg_get_arch_name(arch),
		       genimg_get_type_name(image_type));
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
		return -EIO;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);

	/* get image data address and length */
	if (fit_image_get_data(fit, noffset, &buf, &size)) {
		printf("Could not find %s subimage data!\n", prop_name);
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
		return -ENOENT;
	}
	len = (ulong)size;

	/* verify that image data is a proper FDT blob */
	if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) {
		puts("Subimage data is not a FDT");
		return -ENOEXEC;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);

	/*
	 * Work-around for eldk-4.2 which gives this warning if we try to
	 * case in the unmap_sysmem() call:
	 * warning: initialization discards qualifiers from pointer target type
	 */
	{
		void *vbuf = (void *)buf;

		data = map_to_sysmem(vbuf);
	}

	if (load_op == FIT_LOAD_IGNORED) {
		/* Don't load */
	} else if (fit_image_get_load(fit, noffset, &load)) {
		if (load_op == FIT_LOAD_REQUIRED) {
			printf("Can't get %s subimage load address!\n",
			       prop_name);
			bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
			return -EBADF;
		}
	} else {
		ulong image_start, image_end;
		ulong load_end;
		void *dst;

		/*
		 * move image data to the load address,
		 * make sure we don't overwrite initial image
		 */
		image_start = addr;
		image_end = addr + fit_get_size(fit);

		load_end = load + len;
		if (image_type != IH_TYPE_KERNEL &&
		    load < image_end && load_end > image_start) {
			printf("Error: %s overwritten\n", prop_name);
			return -EXDEV;
		}

		printf("   Loading %s from 0x%08lx to 0x%08lx\n",
		       prop_name, data, load);

		dst = map_sysmem(load, len);
		memmove(dst, buf, len);
		data = load;
	}
	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);

	*datap = data;
	*lenp = len;
	if (fit_unamep)
		*fit_unamep = (char *)fit_uname;
	if (fit_uname_configp)
		*fit_uname_configp = (char *)fit_uname_config;

	return noffset;
}
Exemple #5
0
static int fit_config_get_hash_list(void *fit, int conf_noffset,
				    int sig_offset, struct strlist *node_inc)
{
	int allow_missing;
	const char *prop, *iname, *end;
	const char *conf_name, *sig_name;
	char name[200], path[200];
	int image_count;
	int ret, len;

	conf_name = fit_get_name(fit, conf_noffset, NULL);
	sig_name = fit_get_name(fit, sig_offset, NULL);

	/*
	 * Build a list of nodes we need to hash. We always need the root
	 * node and the configuration.
	 */
	strlist_init(node_inc);
	snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, conf_name);
	if (strlist_add(node_inc, "/") ||
	    strlist_add(node_inc, name))
		goto err_mem;

	/* Get a list of images that we intend to sign */
	prop = fit_config_get_image_list(fit, sig_offset, &len,
					&allow_missing);
	if (!prop)
		return 0;

	/* Locate the images */
	end = prop + len;
	image_count = 0;
	for (iname = prop; iname < end; iname += strlen(iname) + 1) {
		int noffset;
		int image_noffset;
		int hash_count;

		image_noffset = fit_conf_get_prop_node(fit, conf_noffset,
						       iname);
		if (image_noffset < 0) {
			printf("Failed to find image '%s' in  configuration '%s/%s'\n",
			       iname, conf_name, sig_name);
			if (allow_missing)
				continue;

			return -ENOENT;
		}

		ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
		if (ret < 0)
			goto err_path;
		if (strlist_add(node_inc, path))
			goto err_mem;

		snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH,
			 conf_name);

		/* Add all this image's hashes */
		hash_count = 0;
		for (noffset = fdt_first_subnode(fit, image_noffset);
		     noffset >= 0;
		     noffset = fdt_next_subnode(fit, noffset)) {
			const char *name = fit_get_name(fit, noffset, NULL);

			if (strncmp(name, FIT_HASH_NODENAME,
				    strlen(FIT_HASH_NODENAME)))
				continue;
			ret = fdt_get_path(fit, noffset, path, sizeof(path));
			if (ret < 0)
				goto err_path;
			if (strlist_add(node_inc, path))
				goto err_mem;
			hash_count++;
		}

		if (!hash_count) {
			printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
			       conf_name, sig_name, iname);
			return -ENOMSG;
		}

		image_count++;
	}

	if (!image_count) {
		printf("Failed to find any images for configuration '%s/%s'\n",
		       conf_name, sig_name);
		return -ENOMSG;
	}

	return 0;

err_mem:
	printf("Out of memory processing configuration '%s/%s'\n", conf_name,
	       sig_name);
	return -ENOMEM;

err_path:
	printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
	       iname, conf_name, sig_name, fdt_strerror(ret));
	return -ENOENT;
}