All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 1/2] cmd: bootm: add a stage pre-load
@ 2021-03-30 16:26 Philippe Reynes
  2021-03-30 16:26 ` [RFC][PATCH 2/2] configs: sandbox: enable stage pre-load for bootm Philippe Reynes
  2021-03-30 17:50 ` [RFC][PATCH 1/2] cmd: bootm: add a stage pre-load Alex G.
  0 siblings, 2 replies; 4+ messages in thread
From: Philippe Reynes @ 2021-03-30 16:26 UTC (permalink / raw)
  To: u-boot

This commit adds a stage pre-load that could
check or modify the image provided to the bootm
command.

For the moment, only a header with a signature is
supported. This header has this format:
- magic : 4 bytes
- image size : 4 bytes
- sig size : 4 bytes
- signature : n bytes
- padding : up to header size

The stage use a node /bootm/pre-load/sig to
get some information:
- header-size (mandatory) : size of the header
- algo-name (mandatory) : name of the algo used to sign
- padding-name : name of padding used to sign
- mandatory : set to yes if this sig is mandatory
- public-key : value of the public key

Before running the image, the stage pre-load check
the signature provided in the header.

This is an initial support, later we could add the
support of:
- ciphering
- uncompressing
- ...

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
 cmd/Kconfig     |   9 ++
 cmd/bootm.c     |   2 +-
 common/bootm.c  | 258 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/image.h |   1 +
 4 files changed, 269 insertions(+), 1 deletion(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index eff238cb38..086d2b7b74 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -194,6 +194,15 @@ config CMD_BOOTM
 	help
 	  Boot an application image from the memory.
 
+config CMD_BOOTM_PRE_LOAD
+       bool "enable pre-load on bootm"
+       depends on CMD_BOOTM
+       default n
+       help
+         Enable support of stage pre-load for the bootm command.
+	 This stage allow to check of modifty the image provided
+	 to the bootm command.
+
 config BOOTM_EFI
 	bool "Support booting UEFI FIT images"
 	depends on CMD_BOOTEFI && CMD_BOOTM && FIT
diff --git a/cmd/bootm.c b/cmd/bootm.c
index 81c6b93978..7a6299d8d8 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -126,7 +126,7 @@ int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 	}
 
 	return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START |
-		BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
+		BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOTHER |
 		BOOTM_STATE_LOADOS |
 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
 		BOOTM_STATE_RAMDISK |
diff --git a/common/bootm.c b/common/bootm.c
index defaed8426..37b1340023 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -42,6 +42,12 @@
 
 #define IH_INITRD_ARCH IH_ARCH_DEFAULT
 
+#define BOOTM_PRE_LOAD_SIG_MAGIC		0x55425348
+#define BOOTM_PRE_LOAD_SIG_OFFSET_MAGIC		0
+#define BOOTM_PRE_LOAD_SIG_OFFSET_IMG_LEN	4
+#define BOOTM_PRE_LOAD_SIG_OFFSET_SIG_LEN	8
+#define BOOTM_PRE_LOAD_SIG_OFFSET_SIG		12
+
 #ifndef USE_HOSTCC
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -87,6 +93,255 @@ static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc,
 	return 0;
 }
 
+static ulong bootm_data_addr(int argc, char *const argv[])
+{
+	ulong addr;
+
+	if (argc > 0)
+		addr = simple_strtoul(argv[0], NULL, 16);
+	else
+		addr = image_load_addr;
+
+	return addr;
+}
+
+struct bootm_sig_header {
+	u32 magic;
+	u32 size;
+	u8 *sig;
+};
+
+struct bootm_sig_info {
+	ulong header_size;
+	char *algo_name;
+	char *padding_name;
+	u8 *key;
+	int key_len;
+	int mandatory;
+};
+
+/*
+ * This function gather information about the signature check
+ * that could be done in the pre-load stage of bootm.
+ *
+ * return:
+ * -1 => an error has occurred
+ *  0 => OK
+ *  1 => no setup
+ */
+static int bootm_pre_load_sig_setup(struct bootm_sig_info *info)
+{
+	const void *algo_name, *padding_name, *key, *mandatory;
+	const u32 *header_size;
+	int key_len;
+	int node, ret = 0;
+
+	if (!info) {
+		printf("ERROR: info is NULL for bootm pre-load sig check\n");
+		ret = -1;
+		goto out;
+	}
+
+	memset(info, 0, sizeof(*info));
+
+	node = fdt_path_offset(gd->fdt_blob, "/bootm/pre-load/sig");
+	if (node < 0) {
+		printf("INFO: no info for bootm pre-load sig check\n");
+		ret = 1;
+		goto out;
+	}
+
+	header_size = fdt_getprop(gd->fdt_blob, node, "header-size", NULL);
+	if (!header_size) {
+		printf("ERROR: no header-size for bootm pre-load sig check\n");
+		ret = -1;
+		goto out;
+	}
+
+	algo_name = fdt_getprop(gd->fdt_blob, node, "algo-name", NULL);
+	if (!algo_name) {
+		printf("ERROR: no algo_name for bootm pre-load sig check\n");
+		ret = -1;
+		goto out;
+	}
+
+	padding_name = fdt_getprop(gd->fdt_blob, node, "padding-name", NULL);
+	if (!padding_name) {
+		printf("INFO: no padding_name provided, so using pkcs-1.5\n");
+		padding_name = "pkcs-1.5";
+	}
+
+	key = fdt_getprop(gd->fdt_blob, node, "public-key", &key_len);
+	if (!key) {
+		printf("ERROR: no key for bootm pre-load sig check\n");
+		ret = -1;
+		goto out;
+	}
+
+	info->header_size	= fdt32_to_cpu(*header_size);
+	info->algo_name		= (char *)algo_name;
+	info->padding_name	= (char *)padding_name;
+	info->key		= (uint8_t *)key;
+	info->key_len		= key_len;
+
+	mandatory = fdt_getprop(gd->fdt_blob, node, "mandatory", NULL);
+	if (mandatory && !strcmp((char *)mandatory, "yes"))
+		info->mandatory = 1;
+
+ out:
+	return ret;
+}
+
+static int bootm_pre_load_sig_get_header_u32(struct bootm_sig_info *info,
+					     ulong addr,  u32 offset,
+					     u32 *value)
+{
+	void *header;
+	u32 *tmp;
+	int ret = 0;
+
+	header = map_sysmem(addr, info->header_size);
+	if (!header) {
+		printf("ERROR: can't map header bootm pre-load sig\n");
+		ret = -1;
+		goto out;
+	}
+
+	tmp = header + offset;
+	*value = be32_to_cpu(*tmp);
+
+	unmap_sysmem(header);
+
+ out:
+	return ret;
+}
+
+static int bootm_pre_load_sig_get_magic(struct bootm_sig_info *info,
+					ulong addr, u32 *magic)
+{
+	int ret;
+
+	ret = bootm_pre_load_sig_get_header_u32(info, addr,
+						BOOTM_PRE_LOAD_SIG_OFFSET_MAGIC, magic);
+
+	return ret;
+}
+
+static int bootm_pre_load_sig_get_img_len(struct bootm_sig_info *info,
+					  ulong addr, u32 *len)
+{
+	int ret;
+
+	ret = bootm_pre_load_sig_get_header_u32(info, addr,
+						BOOTM_PRE_LOAD_SIG_OFFSET_IMG_LEN, len);
+	if (ret < 0)
+		goto out;
+
+	if (*len > CONFIG_SYS_BOOTM_LEN) {
+		printf("ERROR: size of image (%u) bigger than CONFIG_SYS_BOOTM_LEN (%u)\n",
+		       *len, CONFIG_SYS_BOOTM_LEN);
+		ret = -1;
+		goto out;
+	}
+
+ out:
+	return ret;
+}
+
+static int bootm_pre_load_sig_check(struct bootm_sig_info *info, ulong addr, int img_len)
+{
+	void *image;
+	struct image_sign_info sig_info;
+	struct image_region reg;
+	u32 sig_len, *psig_len;
+	u8 *sig;
+	int ret = 0;
+
+	image = (void *)map_sysmem(addr, info->header_size + img_len);
+	if (!image) {
+		printf("ERROR: can't map full image\n");
+		ret = -1;
+		goto out;
+	}
+
+	memset(&sig_info, '\0', sizeof(sig_info));
+	sig_info.name = info->algo_name;
+	sig_info.padding = image_get_padding_algo(info->padding_name);
+	sig_info.checksum = image_get_checksum_algo(sig_info.name);
+	sig_info.crypto = image_get_crypto_algo(sig_info.name);
+	sig_info.key = info->key;
+	sig_info.keylen = info->key_len;
+
+	reg.data = image + info->header_size;
+	reg.size = img_len;
+
+	psig_len = (uint32_t *)((uint8_t *)image + BOOTM_PRE_LOAD_SIG_OFFSET_SIG_LEN);
+	sig_len = be32_to_cpu(*psig_len);
+	sig = (uint8_t *)image + BOOTM_PRE_LOAD_SIG_OFFSET_SIG;
+
+	ret = sig_info.crypto->verify(&sig_info, &reg, 1, sig, sig_len);
+	if (ret < 0)
+		printf("ERROR: signature check has failed (err=%d)\n", ret);
+
+	memmove(image, image + info->header_size, img_len);
+
+	unmap_sysmem(image);
+
+ out:
+	return ret;
+}
+
+static int bootm_pre_load_sig(ulong addr)
+{
+	struct bootm_sig_info info;
+	u32 magic, img_len;
+	int ret;
+
+	ret = bootm_pre_load_sig_setup(&info);
+	if (ret < 0)
+		goto out;
+	if (ret > 0) {
+		ret = 0;
+		goto out;
+	}
+
+	ret = bootm_pre_load_sig_get_magic(&info, addr, &magic);
+	if (ret < 0)
+		goto out;
+
+	if (magic != BOOTM_PRE_LOAD_SIG_MAGIC) {
+		if (info.mandatory) {
+			printf("ERROR: signature is mandatory\n");
+			ret = -1;
+		}
+		goto out;
+	}
+
+	ret = bootm_pre_load_sig_get_img_len(&info, addr, &img_len);
+	if (ret < 0)
+		goto out;
+
+	ret = bootm_pre_load_sig_check(&info, addr, img_len);
+
+ out:
+	return ret;
+}
+
+static int bootm_pre_load(struct cmd_tbl *cmdtp, int flag, int argc,
+			  char *const argv[])
+{
+	ulong data_addr = bootm_data_addr(argc, argv);
+	int ret = 0;
+
+	if (CONFIG_IS_ENABLED(CMD_BOOTM_PRE_LOAD))
+		ret = bootm_pre_load_sig(data_addr);
+
+	if (ret)
+		ret = CMD_RET_FAILURE;
+
+	return ret;
+}
+
 static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
 			 char *const argv[])
 {
@@ -676,6 +931,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
 	if (states & BOOTM_STATE_START)
 		ret = bootm_start(cmdtp, flag, argc, argv);
 
+	if (!ret && (states & BOOTM_STATE_PRE_LOAD))
+		ret = bootm_pre_load(cmdtp, flag, argc, argv);
+
 	if (!ret && (states & BOOTM_STATE_FINDOS))
 		ret = bootm_find_os(cmdtp, flag, argc, argv);
 
diff --git a/include/image.h b/include/image.h
index b4b284d52b..bd72b49913 100644
--- a/include/image.h
+++ b/include/image.h
@@ -432,6 +432,7 @@ typedef struct bootm_headers {
 #define	BOOTM_STATE_OS_PREP	(0x00000100)
 #define	BOOTM_STATE_OS_FAKE_GO	(0x00000200)	/* 'Almost' run the OS */
 #define	BOOTM_STATE_OS_GO	(0x00000400)
+#define	BOOTM_STATE_PRE_LOAD	(0x00000800)
 	int		state;
 
 #ifdef CONFIG_LMB
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC][PATCH 2/2] configs: sandbox: enable stage pre-load for bootm
  2021-03-30 16:26 [RFC][PATCH 1/2] cmd: bootm: add a stage pre-load Philippe Reynes
@ 2021-03-30 16:26 ` Philippe Reynes
  2021-04-21  7:14   ` Simon Glass
  2021-03-30 17:50 ` [RFC][PATCH 1/2] cmd: bootm: add a stage pre-load Alex G.
  1 sibling, 1 reply; 4+ messages in thread
From: Philippe Reynes @ 2021-03-30 16:26 UTC (permalink / raw)
  To: u-boot

This commit enables the stage pre-load in the bootm command.

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
 configs/sandbox_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5bc90d09a8..ab0e9213f8 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -27,6 +27,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_ANDROID_AB=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
+CONFIG_CMD_BOOTM_PRE_LOAD=y
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_BOOTEFI_HELLO=y
 CONFIG_CMD_ABOOTIMG=y
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC][PATCH 1/2] cmd: bootm: add a stage pre-load
  2021-03-30 16:26 [RFC][PATCH 1/2] cmd: bootm: add a stage pre-load Philippe Reynes
  2021-03-30 16:26 ` [RFC][PATCH 2/2] configs: sandbox: enable stage pre-load for bootm Philippe Reynes
@ 2021-03-30 17:50 ` Alex G.
  1 sibling, 0 replies; 4+ messages in thread
From: Alex G. @ 2021-03-30 17:50 UTC (permalink / raw)
  To: u-boot

Hi Phillipe,

On 3/30/21 11:26 AM, Philippe Reynes wrote:
> This commit adds a stage pre-load that could
> check or modify the image provided to the bootm
> command.
> 
> For the moment, only a header with a signature is
> supported. This header has this format:
> - magic : 4 bytes
> - image size : 4 bytes
> - sig size : 4 bytes
> - signature : n bytes
> - padding : up to header size
> 
> The stage use a node /bootm/pre-load/sig to
> get some information:
> - header-size (mandatory) : size of the header
> - algo-name (mandatory) : name of the algo used to sign
> - padding-name : name of padding used to sign
> - mandatory : set to yes if this sig is mandatory
> - public-key : value of the public key
> 
> Before running the image, the stage pre-load check
> the signature provided in the header.
> 
> This is an initial support, later we could add the
> support of:
> - ciphering
> - uncompressing
> - ...

You're on the right path of what I had in mind.

One thing that we could improve is dropping the dependency on bootm. A 
FIT image could also be loaded with CONFIG_SPL_LOAD_FIT or 
CONFIG_SPL_LOAD_FIT_FULL. It would be nice to have the signature 
verification code shared with image-fit-sig.c

The decision to verify the "header signature" is done at kconfig time. 
For distinguishing between image or config node signing, the "required" 
property in the u-boot FDT is used. So it seems odd to introduce another 
mechanism instead of leveraging "required".

A nice to have: how does mkimage insert this header signature into the FIT?

Alex



> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
>   cmd/Kconfig     |   9 ++
>   cmd/bootm.c     |   2 +-
>   common/bootm.c  | 258 ++++++++++++++++++++++++++++++++++++++++++++++++
>   include/image.h |   1 +
>   4 files changed, 269 insertions(+), 1 deletion(-)
> 
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index eff238cb38..086d2b7b74 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -194,6 +194,15 @@ config CMD_BOOTM
>   	help
>   	  Boot an application image from the memory.
>   
> +config CMD_BOOTM_PRE_LOAD
> +       bool "enable pre-load on bootm"
> +       depends on CMD_BOOTM
> +       default n
> +       help
> +         Enable support of stage pre-load for the bootm command.
> +	 This stage allow to check of modifty the image provided
> +	 to the bootm command.
> +
>   config BOOTM_EFI
>   	bool "Support booting UEFI FIT images"
>   	depends on CMD_BOOTEFI && CMD_BOOTM && FIT
> diff --git a/cmd/bootm.c b/cmd/bootm.c
> index 81c6b93978..7a6299d8d8 100644
> --- a/cmd/bootm.c
> +++ b/cmd/bootm.c
> @@ -126,7 +126,7 @@ int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>   	}
>   
>   	return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START |
> -		BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
> +		BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOTHER |
>   		BOOTM_STATE_LOADOS |
>   #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
>   		BOOTM_STATE_RAMDISK |
> diff --git a/common/bootm.c b/common/bootm.c
> index defaed8426..37b1340023 100644
> --- a/common/bootm.c
> +++ b/common/bootm.c
> @@ -42,6 +42,12 @@
>   
>   #define IH_INITRD_ARCH IH_ARCH_DEFAULT
>   
> +#define BOOTM_PRE_LOAD_SIG_MAGIC		0x55425348
> +#define BOOTM_PRE_LOAD_SIG_OFFSET_MAGIC		0
> +#define BOOTM_PRE_LOAD_SIG_OFFSET_IMG_LEN	4
> +#define BOOTM_PRE_LOAD_SIG_OFFSET_SIG_LEN	8
> +#define BOOTM_PRE_LOAD_SIG_OFFSET_SIG		12
> +
>   #ifndef USE_HOSTCC
>   
>   DECLARE_GLOBAL_DATA_PTR;
> @@ -87,6 +93,255 @@ static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc,
>   	return 0;
>   }
>   
> +static ulong bootm_data_addr(int argc, char *const argv[])
> +{
> +	ulong addr;
> +
> +	if (argc > 0)
> +		addr = simple_strtoul(argv[0], NULL, 16);
> +	else
> +		addr = image_load_addr;
> +
> +	return addr;
> +}
> +
> +struct bootm_sig_header {
> +	u32 magic;
> +	u32 size;
> +	u8 *sig;
> +};
> +
> +struct bootm_sig_info {
> +	ulong header_size;
> +	char *algo_name;
> +	char *padding_name;
> +	u8 *key;
> +	int key_len;
> +	int mandatory;
> +};
> +
> +/*
> + * This function gather information about the signature check
> + * that could be done in the pre-load stage of bootm.
> + *
> + * return:
> + * -1 => an error has occurred
> + *  0 => OK
> + *  1 => no setup
> + */
> +static int bootm_pre_load_sig_setup(struct bootm_sig_info *info)
> +{
> +	const void *algo_name, *padding_name, *key, *mandatory;
> +	const u32 *header_size;
> +	int key_len;
> +	int node, ret = 0;
> +
> +	if (!info) {
> +		printf("ERROR: info is NULL for bootm pre-load sig check\n");
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	memset(info, 0, sizeof(*info));
> +
> +	node = fdt_path_offset(gd->fdt_blob, "/bootm/pre-load/sig");
> +	if (node < 0) {
> +		printf("INFO: no info for bootm pre-load sig check\n");
> +		ret = 1;
> +		goto out;
> +	}
> +
> +	header_size = fdt_getprop(gd->fdt_blob, node, "header-size", NULL);
> +	if (!header_size) {
> +		printf("ERROR: no header-size for bootm pre-load sig check\n");
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	algo_name = fdt_getprop(gd->fdt_blob, node, "algo-name", NULL);
> +	if (!algo_name) {
> +		printf("ERROR: no algo_name for bootm pre-load sig check\n");
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	padding_name = fdt_getprop(gd->fdt_blob, node, "padding-name", NULL);
> +	if (!padding_name) {
> +		printf("INFO: no padding_name provided, so using pkcs-1.5\n");
> +		padding_name = "pkcs-1.5";
> +	}
> +
> +	key = fdt_getprop(gd->fdt_blob, node, "public-key", &key_len);
> +	if (!key) {
> +		printf("ERROR: no key for bootm pre-load sig check\n");
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	info->header_size	= fdt32_to_cpu(*header_size);
> +	info->algo_name		= (char *)algo_name;
> +	info->padding_name	= (char *)padding_name;
> +	info->key		= (uint8_t *)key;
> +	info->key_len		= key_len;
> +
> +	mandatory = fdt_getprop(gd->fdt_blob, node, "mandatory", NULL);
> +	if (mandatory && !strcmp((char *)mandatory, "yes"))
> +		info->mandatory = 1;
> +
> + out:
> +	return ret;
> +}
> +
> +static int bootm_pre_load_sig_get_header_u32(struct bootm_sig_info *info,
> +					     ulong addr,  u32 offset,
> +					     u32 *value)
> +{
> +	void *header;
> +	u32 *tmp;
> +	int ret = 0;
> +
> +	header = map_sysmem(addr, info->header_size);
> +	if (!header) {
> +		printf("ERROR: can't map header bootm pre-load sig\n");
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	tmp = header + offset;
> +	*value = be32_to_cpu(*tmp);
> +
> +	unmap_sysmem(header);
> +
> + out:
> +	return ret;
> +}
> +
> +static int bootm_pre_load_sig_get_magic(struct bootm_sig_info *info,
> +					ulong addr, u32 *magic)
> +{
> +	int ret;
> +
> +	ret = bootm_pre_load_sig_get_header_u32(info, addr,
> +						BOOTM_PRE_LOAD_SIG_OFFSET_MAGIC, magic);
> +
> +	return ret;
> +}
> +
> +static int bootm_pre_load_sig_get_img_len(struct bootm_sig_info *info,
> +					  ulong addr, u32 *len)
> +{
> +	int ret;
> +
> +	ret = bootm_pre_load_sig_get_header_u32(info, addr,
> +						BOOTM_PRE_LOAD_SIG_OFFSET_IMG_LEN, len);
> +	if (ret < 0)
> +		goto out;
> +
> +	if (*len > CONFIG_SYS_BOOTM_LEN) {
> +		printf("ERROR: size of image (%u) bigger than CONFIG_SYS_BOOTM_LEN (%u)\n",
> +		       *len, CONFIG_SYS_BOOTM_LEN);
> +		ret = -1;
> +		goto out;
> +	}
> +
> + out:
> +	return ret;
> +}
> +
> +static int bootm_pre_load_sig_check(struct bootm_sig_info *info, ulong addr, int img_len)
> +{
> +	void *image;
> +	struct image_sign_info sig_info;
> +	struct image_region reg;
> +	u32 sig_len, *psig_len;
> +	u8 *sig;
> +	int ret = 0;
> +
> +	image = (void *)map_sysmem(addr, info->header_size + img_len);
> +	if (!image) {
> +		printf("ERROR: can't map full image\n");
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	memset(&sig_info, '\0', sizeof(sig_info));
> +	sig_info.name = info->algo_name;
> +	sig_info.padding = image_get_padding_algo(info->padding_name);
> +	sig_info.checksum = image_get_checksum_algo(sig_info.name);
> +	sig_info.crypto = image_get_crypto_algo(sig_info.name);
> +	sig_info.key = info->key;
> +	sig_info.keylen = info->key_len;
> +
> +	reg.data = image + info->header_size;
> +	reg.size = img_len;
> +
> +	psig_len = (uint32_t *)((uint8_t *)image + BOOTM_PRE_LOAD_SIG_OFFSET_SIG_LEN);
> +	sig_len = be32_to_cpu(*psig_len);
> +	sig = (uint8_t *)image + BOOTM_PRE_LOAD_SIG_OFFSET_SIG;
> +
> +	ret = sig_info.crypto->verify(&sig_info, &reg, 1, sig, sig_len);
> +	if (ret < 0)
> +		printf("ERROR: signature check has failed (err=%d)\n", ret);
> +
> +	memmove(image, image + info->header_size, img_len);
> +
> +	unmap_sysmem(image);
> +
> + out:
> +	return ret;
> +}
> +
> +static int bootm_pre_load_sig(ulong addr)
> +{
> +	struct bootm_sig_info info;
> +	u32 magic, img_len;
> +	int ret;
> +
> +	ret = bootm_pre_load_sig_setup(&info);
> +	if (ret < 0)
> +		goto out;
> +	if (ret > 0) {
> +		ret = 0;
> +		goto out;
> +	}
> +
> +	ret = bootm_pre_load_sig_get_magic(&info, addr, &magic);
> +	if (ret < 0)
> +		goto out;
> +
> +	if (magic != BOOTM_PRE_LOAD_SIG_MAGIC) {
> +		if (info.mandatory) {
> +			printf("ERROR: signature is mandatory\n");
> +			ret = -1;
> +		}
> +		goto out;
> +	}
> +
> +	ret = bootm_pre_load_sig_get_img_len(&info, addr, &img_len);
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = bootm_pre_load_sig_check(&info, addr, img_len);
> +
> + out:
> +	return ret;
> +}
> +
> +static int bootm_pre_load(struct cmd_tbl *cmdtp, int flag, int argc,
> +			  char *const argv[])
> +{
> +	ulong data_addr = bootm_data_addr(argc, argv);
> +	int ret = 0;
> +
> +	if (CONFIG_IS_ENABLED(CMD_BOOTM_PRE_LOAD))
> +		ret = bootm_pre_load_sig(data_addr);
> +
> +	if (ret)
> +		ret = CMD_RET_FAILURE;
> +
> +	return ret;
> +}
> +
>   static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
>   			 char *const argv[])
>   {
> @@ -676,6 +931,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
>   	if (states & BOOTM_STATE_START)
>   		ret = bootm_start(cmdtp, flag, argc, argv);
>   
> +	if (!ret && (states & BOOTM_STATE_PRE_LOAD))
> +		ret = bootm_pre_load(cmdtp, flag, argc, argv);
> +
>   	if (!ret && (states & BOOTM_STATE_FINDOS))
>   		ret = bootm_find_os(cmdtp, flag, argc, argv);
>   
> diff --git a/include/image.h b/include/image.h
> index b4b284d52b..bd72b49913 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -432,6 +432,7 @@ typedef struct bootm_headers {
>   #define	BOOTM_STATE_OS_PREP	(0x00000100)
>   #define	BOOTM_STATE_OS_FAKE_GO	(0x00000200)	/* 'Almost' run the OS */
>   #define	BOOTM_STATE_OS_GO	(0x00000400)
> +#define	BOOTM_STATE_PRE_LOAD	(0x00000800)
>   	int		state;
>   
>   #ifdef CONFIG_LMB
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC][PATCH 2/2] configs: sandbox: enable stage pre-load for bootm
  2021-03-30 16:26 ` [RFC][PATCH 2/2] configs: sandbox: enable stage pre-load for bootm Philippe Reynes
@ 2021-04-21  7:14   ` Simon Glass
  0 siblings, 0 replies; 4+ messages in thread
From: Simon Glass @ 2021-04-21  7:14 UTC (permalink / raw)
  To: u-boot

On Wed, 31 Mar 2021 at 05:26, Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> This commit enables the stage pre-load in the bootm command.
>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
>  configs/sandbox_defconfig | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-04-21  7:14 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-30 16:26 [RFC][PATCH 1/2] cmd: bootm: add a stage pre-load Philippe Reynes
2021-03-30 16:26 ` [RFC][PATCH 2/2] configs: sandbox: enable stage pre-load for bootm Philippe Reynes
2021-04-21  7:14   ` Simon Glass
2021-03-30 17:50 ` [RFC][PATCH 1/2] cmd: bootm: add a stage pre-load Alex G.

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.