All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/6] image: add a stage pre-load
@ 2021-11-12  9:27 Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 1/6] lib: allow to build asn1 decoder and oid registry in SPL Philippe Reynes
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Philippe Reynes @ 2021-11-12  9:27 UTC (permalink / raw)
  To: sjg, mr.nuke.me, joel.peshkin; +Cc: u-boot, Philippe Reynes

This serie adds a stage pre-load before launching an image.
This stage is used to read a header before the image and
this header contains the signature of the full image.
So u-boot may check the full image before using any
data of the image.

Changelog:
v2:
- move the code to image-pre-load
- add support of stage pre-load for spl
- add support of stage pre-load on spl_ram

Philippe Reynes (6):
  lib: allow to build asn1 decoder and oid registry in SPL
  lib: crypto: allow to build crypyo in SPL
  lib: rsa: allow rsa verify with pkey in SPL
  common: image: add a stage pre-load
  cmd: bootm: add a stage pre-load
  common: spl: fit_ram: allow to use image pre load

 cmd/Kconfig             |   9 ++
 cmd/bootm.c             |   2 +-
 common/Kconfig.boot     |  33 +++++
 common/Makefile         |   1 +
 common/bootm.c          |  33 +++++
 common/image-pre-load.c | 291 ++++++++++++++++++++++++++++++++++++++++
 common/spl/spl_ram.c    |  21 ++-
 include/image.h         |  10 ++
 lib/Kconfig             |   6 +
 lib/Makefile            |   9 +-
 lib/crypto/Kconfig      |  15 +++
 lib/crypto/Makefile     |  19 ++-
 lib/rsa/Kconfig         |   8 ++
 13 files changed, 446 insertions(+), 11 deletions(-)
 create mode 100644 common/image-pre-load.c

-- 
2.17.1


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

* [RFC PATCH v2 1/6] lib: allow to build asn1 decoder and oid registry in SPL
  2021-11-12  9:27 [RFC PATCH v2 0/6] image: add a stage pre-load Philippe Reynes
@ 2021-11-12  9:27 ` Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 2/6] lib: crypto: allow to build crypyo " Philippe Reynes
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Reynes @ 2021-11-12  9:27 UTC (permalink / raw)
  To: sjg, mr.nuke.me, joel.peshkin; +Cc: u-boot, Philippe Reynes

This commit adds the options:
- SPL_ASN1_DECODER
- SPL_OID_REGISTRY

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
 lib/Kconfig  | 6 ++++++
 lib/Makefile | 7 +++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/lib/Kconfig b/lib/Kconfig
index 70bf8e7a46..ebff84f113 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -758,11 +758,17 @@ config ASN1_DECODER
 	help
 	  Enable asn1 decoder library.
 
+config SPL_ASN1_DECODER
+	bool
+
 config OID_REGISTRY
 	bool
 	help
 	  Enable fast lookup object identifier registry.
 
+config SPL_OID_REGISTRY
+	bool
+
 config SMBIOS_PARSER
 	bool "SMBIOS parser"
 	help
diff --git a/lib/Makefile b/lib/Makefile
index 5ddbc77ed6..900e684d62 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -17,7 +17,6 @@ obj-$(CONFIG_OF_LIVE) += of_live.o
 obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
 obj-$(CONFIG_ARCH_AT91) += at91/
 obj-$(CONFIG_OPTEE_LIB) += optee/
-obj-$(CONFIG_ASN1_DECODER) += asn1_decoder.o
 obj-y += crypto/
 
 obj-$(CONFIG_AES) += aes.o
@@ -67,6 +66,7 @@ obj-$(CONFIG_SHA1) += sha1.o
 obj-$(CONFIG_SHA256) += sha256.o
 obj-$(CONFIG_SHA512) += sha512.o
 obj-$(CONFIG_CRYPT_PW) += crypt/
+obj-$(CONFIG_$(SPL_)ASN1_DECODER) += asn1_decoder.o
 
 obj-$(CONFIG_$(SPL_)ZLIB) += zlib/
 obj-$(CONFIG_$(SPL_)ZSTD) += zstd/
@@ -128,9 +128,9 @@ obj-$(CONFIG_$(SPL_TPL_)STRTO) += strto.o
 else
 # Main U-Boot always uses the full printf support
 obj-y += vsprintf.o strto.o
-obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
 obj-$(CONFIG_SSCANF) += sscanf.o
 endif
+obj-$(CONFIG_$(SPL_)OID_REGISTRY) += oid_registry.o
 
 obj-y += abuf.o
 obj-y += date.o
@@ -141,6 +141,9 @@ obj-$(CONFIG_LIB_ELF) += elf.o
 # Build a fast OID lookup registry from include/linux/oid_registry.h
 #
 $(obj)/oid_registry.o: $(obj)/oid_registry_data.c
+ifdef CONFIG_SPL_BUILD
+CFLAGS_oid_registry.o += -I$(obj)
+endif
 
 $(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \
 			    $(srctree)/scripts/build_OID_registry
-- 
2.17.1


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

* [RFC PATCH v2 2/6] lib: crypto: allow to build crypyo in SPL
  2021-11-12  9:27 [RFC PATCH v2 0/6] image: add a stage pre-load Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 1/6] lib: allow to build asn1 decoder and oid registry in SPL Philippe Reynes
@ 2021-11-12  9:27 ` Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 3/6] lib: rsa: allow rsa verify with pkey " Philippe Reynes
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Reynes @ 2021-11-12  9:27 UTC (permalink / raw)
  To: sjg, mr.nuke.me, joel.peshkin; +Cc: u-boot, Philippe Reynes

This commit adds the options:
- SPL_ASYMMETRIC_KEY_TYPE
- SPL_ASYMMETRIC_PUBLIC_KEY_SUBTYPE
- SPL_RSA_PUBLIC_KEY_PARSER

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
 lib/Makefile        |  2 +-
 lib/crypto/Kconfig  | 15 +++++++++++++++
 lib/crypto/Makefile | 19 +++++++++++++------
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 900e684d62..df70917b49 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -17,7 +17,6 @@ obj-$(CONFIG_OF_LIVE) += of_live.o
 obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
 obj-$(CONFIG_ARCH_AT91) += at91/
 obj-$(CONFIG_OPTEE_LIB) += optee/
-obj-y += crypto/
 
 obj-$(CONFIG_AES) += aes.o
 obj-$(CONFIG_AES) += aes/
@@ -57,6 +56,7 @@ obj-$(CONFIG_TPM_V1) += tpm-v1.o
 obj-$(CONFIG_TPM_V2) += tpm-v2.o
 endif
 
+obj-y += crypto/
 obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi/
 obj-$(CONFIG_$(SPL_)MD5) += md5.o
 obj-$(CONFIG_ECDSA) += ecdsa/
diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
index 6369bafac0..9351865f2c 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -8,6 +8,10 @@ menuconfig ASYMMETRIC_KEY_TYPE
 
 if ASYMMETRIC_KEY_TYPE
 
+config SPL_ASYMMETRIC_KEY_TYPE
+	bool "Asymmetric (public-key cryptographic) key Support within SPL"
+	depends on SPL
+
 config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 	bool "Asymmetric public-key crypto algorithm subtype"
 	help
@@ -16,6 +20,10 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 	  appropriate hash algorithms (such as SHA-1) must be available.
 	  ENOPKG will be reported if the requisite algorithm is unavailable.
 
+config SPL_ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+	bool "Asymmetric public-key crypto algorithm subtype within SPL"
+	depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+
 config RSA_PUBLIC_KEY_PARSER
 	bool "RSA public key parser"
 	depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
@@ -27,6 +35,13 @@ config RSA_PUBLIC_KEY_PARSER
 	  public key data and provides the ability to instantiate a public
 	  key.
 
+config SPL_RSA_PUBLIC_KEY_PARSER
+	bool "RSA public key parser within SPL"
+	depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+	select SPL_ASN1_DECODER
+	select ASN1_COMPILER
+	select SPL_OID_REGISTRY
+
 config X509_CERTIFICATE_PARSER
 	bool "X.509 certificate parser"
 	depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
index f3a414525d..6792b1d4f0 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -3,27 +3,34 @@
 # Makefile for asymmetric cryptographic keys
 #
 
-obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
+obj-$(CONFIG_$(SPL_)ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
 
 asymmetric_keys-y := asymmetric_type.o
 
-obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
+obj-$(CONFIG_$(SPL_)ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
 
 #
 # RSA public key parser
 #
-obj-$(CONFIG_RSA_PUBLIC_KEY_PARSER) += rsa_public_key.o
+obj-$(CONFIG_$(SPL_)RSA_PUBLIC_KEY_PARSER) += rsa_public_key.o
 rsa_public_key-y := \
 	rsapubkey.asn1.o \
 	rsa_helper.o
 
 $(obj)/rsapubkey.asn1.o: $(obj)/rsapubkey.asn1.c $(obj)/rsapubkey.asn1.h
+ifdef CONFIG_SPL_BUILD
+CFLAGS_rsapubkey.asn1.o += -I$(obj)
+endif
+
 $(obj)/rsa_helper.o: $(obj)/rsapubkey.asn1.h
+ifdef CONFIG_SPL_BUILD
+CFLAGS_rsa_helper.o += -I$(obj)
+endif
 
 #
 # X.509 Certificate handling
 #
-obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
+obj-$(CONFIG_$(SPL_)X509_CERTIFICATE_PARSER) += x509_key_parser.o
 x509_key_parser-y := \
 	x509.asn1.o \
 	x509_akid.asn1.o \
@@ -40,11 +47,11 @@ $(obj)/x509_akid.asn1.o: $(obj)/x509_akid.asn1.c $(obj)/x509_akid.asn1.h
 #
 # PKCS#7 message handling
 #
-obj-$(CONFIG_PKCS7_MESSAGE_PARSER) += pkcs7_message.o
+obj-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER) += pkcs7_message.o
 pkcs7_message-y := \
 	pkcs7.asn1.o \
 	pkcs7_parser.o
-obj-$(CONFIG_PKCS7_VERIFY) += pkcs7_verify.o
+obj-$(CONFIG_$(SPL_)PKCS7_VERIFY) += pkcs7_verify.o
 
 $(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h
 $(obj)/pkcs7.asn1.o: $(obj)/pkcs7.asn1.c $(obj)/pkcs7.asn1.h
-- 
2.17.1


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

* [RFC PATCH v2 3/6] lib: rsa: allow rsa verify with pkey in SPL
  2021-11-12  9:27 [RFC PATCH v2 0/6] image: add a stage pre-load Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 1/6] lib: allow to build asn1 decoder and oid registry in SPL Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 2/6] lib: crypto: allow to build crypyo " Philippe Reynes
@ 2021-11-12  9:27 ` Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 4/6] common: image: add a stage pre-load Philippe Reynes
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Reynes @ 2021-11-12  9:27 UTC (permalink / raw)
  To: sjg, mr.nuke.me, joel.peshkin; +Cc: u-boot, Philippe Reynes

This commit adds the option SPL_RSA_VERIFY_WITH_PKEY.

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
 lib/rsa/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig
index 469596abe7..608d51c428 100644
--- a/lib/rsa/Kconfig
+++ b/lib/rsa/Kconfig
@@ -46,6 +46,14 @@ config RSA_VERIFY_WITH_PKEY
 	  directly specified in image_sign_info, where all the necessary
 	  key properties will be calculated on the fly in verification code.
 
+config SPL_RSA_VERIFY_WITH_PKEY
+	bool "Execute RSA verification without key parameters from FDT within SPL"
+	depends on SPL
+	select SPL_RSA_VERIFY
+	select SPL_ASYMMETRIC_KEY_TYPE
+	select SPL_ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+	select SPL_RSA_PUBLIC_KEY_PARSER
+
 config RSA_SOFTWARE_EXP
 	bool "Enable driver for RSA Modular Exponentiation in software"
 	depends on DM
-- 
2.17.1


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

* [RFC PATCH v2 4/6] common: image: add a stage pre-load
  2021-11-12  9:27 [RFC PATCH v2 0/6] image: add a stage pre-load Philippe Reynes
                   ` (2 preceding siblings ...)
  2021-11-12  9:27 ` [RFC PATCH v2 3/6] lib: rsa: allow rsa verify with pkey " Philippe Reynes
@ 2021-11-12  9:27 ` Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 5/6] cmd: bootm: " Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 6/6] common: spl: fit_ram: allow to use image pre load Philippe Reynes
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Reynes @ 2021-11-12  9:27 UTC (permalink / raw)
  To: sjg, mr.nuke.me, joel.peshkin; +Cc: u-boot, Philippe Reynes

This commit adds a stage pre-load that could
check or modify an image.

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

The stage use a node /image/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
- signature-size : size of the signature (in the header)
- mandatory : set to yes if this sig is mandatory
- public-key (madatory) : 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>
---
 common/Kconfig.boot     |  33 +++++
 common/Makefile         |   1 +
 common/image-pre-load.c | 291 ++++++++++++++++++++++++++++++++++++++++
 include/image.h         |   9 ++
 4 files changed, 334 insertions(+)
 create mode 100644 common/image-pre-load.c

diff --git a/common/Kconfig.boot b/common/Kconfig.boot
index a8d4be23a9..916fdde71f 100644
--- a/common/Kconfig.boot
+++ b/common/Kconfig.boot
@@ -958,6 +958,39 @@ config AUTOBOOT_MENU_SHOW
 
 endmenu
 
+menu "Image support"
+
+config IMAGE_PRE_LOAD
+	bool "Image pre-load support"
+	help
+	  Enable image pre-load support
+
+config SPL_IMAGE_PRE_LOAD
+	bool "Image pre-load support within SPL"
+	depends on SPL && IMAGE_PRE_LOAD
+	help
+	  Enable image pre-load support in SPL
+
+config IMAGE_PRE_LOAD_SIG
+	bool "Image pre-load signature support"
+	depends on IMAGE_PRE_LOAD
+	select FIT_SIGNATURE
+	select RSA
+	select RSA_VERIFY_WITH_PKEY
+	help
+	  Enable image pre-load signature support
+
+config SPL_IMAGE_PRE_LOAD_SIG
+	bool "Image pre-load signature support witin SPL"
+	depends on SPL_IMAGE_PRE_LOAD && IMAGE_PRE_LOAD_SIG
+	select SPL_FIT_SIGNATURE
+	select SPL_RSA
+	select SPL_RSA_VERIFY_WITH_PKEY
+	help
+	  Enable image pre-load signature support in SPL
+
+endmenu
+
 config USE_BOOTARGS
 	bool "Enable boot arguments"
 	help
diff --git a/common/Makefile b/common/Makefile
index e7839027b6..9b322e3ae4 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -102,6 +102,7 @@ endif
 endif
 
 obj-y += image.o image-board.o
+obj-$(CONFIG_$(SPL_TPL_)IMAGE_PRE_LOAD) += image-pre-load.o
 obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o
 obj-$(CONFIG_ANDROID_AB) += android_ab.o
 obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
diff --git a/common/image-pre-load.c b/common/image-pre-load.c
new file mode 100644
index 0000000000..6ed21c3f51
--- /dev/null
+++ b/common/image-pre-load.c
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Philippe Reynes <philippe.reynes@softathome.com>
+ */
+
+#include <common.h>
+#include <asm/global_data.h>
+DECLARE_GLOBAL_DATA_PTR;
+#include <image.h>
+#include <mapmem.h>
+
+#define IMAGE_PRE_LOAD_SIG_MAGIC		0x55425348
+#define IMAGE_PRE_LOAD_SIG_OFFSET_MAGIC		0
+#define IMAGE_PRE_LOAD_SIG_OFFSET_IMG_LEN	4
+#define IMAGE_PRE_LOAD_SIG_OFFSET_SIG		8
+
+#define IMAGE_PRE_LOAD_PATH			"/image/pre-load/sig"
+#define IMAGE_PRE_LOAD_PROP_HEADER_SIZE		"header-size"
+#define IMAGE_PRE_LOAD_PROP_ALGO_NAME		"algo-name"
+#define IMAGE_PRE_LOAD_PROP_PADDING_NAME	"padding-name"
+#define IMAGE_PRE_LOAD_PROP_SIG_SIZE		"signature-size"
+#define IMAGE_PRE_LOAD_PROP_PUBLIC_KEY		"public-key"
+#define IMAGE_PRE_LOAD_PROP_MANDATORY		"mandatory"
+
+#ifndef CONFIG_SYS_BOOTM_LEN
+/* use 8MByte as default max gunzip size */
+#define CONFIG_SYS_BOOTM_LEN	0x800000
+#endif
+
+struct image_sig_header {
+	u32 magic;
+	u32 size;
+	u8 *sig;
+};
+
+struct image_sig_info {
+	ulong header_size;
+	char *algo_name;
+	char *padding_name;
+	u8 *key;
+	int key_len;
+	u32 sig_size;
+	int mandatory;
+};
+
+ulong image_load_offset;
+
+/*
+ * This function gathers information about the signature check
+ * that could be done before launching the image.
+ *
+ * return:
+ * -1 => an error has occurred
+ *  0 => OK
+ *  1 => no setup
+ */
+static int image_pre_load_sig_setup(struct image_sig_info *info)
+{
+	const void *algo_name, *padding_name, *key, *mandatory;
+	const u32 *header_size, *sig_size;
+	int key_len;
+	int node, ret = 0;
+
+	if (!info) {
+		printf("ERROR: info is NULL for image pre-load sig check\n");
+		ret = -1;
+		goto out;
+	}
+
+	memset(info, 0, sizeof(*info));
+
+	node = fdt_path_offset(gd_fdt_blob(), IMAGE_PRE_LOAD_PATH);
+	if (node < 0) {
+		printf("INFO: no info for image pre-load sig check\n");
+		ret = 1;
+		goto out;
+	}
+
+	header_size = fdt_getprop(gd_fdt_blob(), node,
+				  IMAGE_PRE_LOAD_PROP_HEADER_SIZE, NULL);
+	if (!header_size) {
+		printf("ERROR: no header-size for image pre-load sig check\n");
+		ret = -1;
+		goto out;
+	}
+
+	algo_name = fdt_getprop(gd_fdt_blob(), node,
+				IMAGE_PRE_LOAD_PROP_ALGO_NAME, NULL);
+	if (!algo_name) {
+		printf("ERROR: no algo_name for image pre-load sig check\n");
+		ret = -1;
+		goto out;
+	}
+
+	padding_name = fdt_getprop(gd_fdt_blob(), node,
+				   IMAGE_PRE_LOAD_PROP_PADDING_NAME, NULL);
+	if (!padding_name) {
+		printf("INFO: no padding_name provided, so using pkcs-1.5\n");
+		padding_name = "pkcs-1.5";
+	}
+
+	sig_size = fdt_getprop(gd_fdt_blob(), node,
+			       IMAGE_PRE_LOAD_PROP_SIG_SIZE, NULL);
+	if (!sig_size) {
+		printf("ERROR: no signature-size for image pre-load sig check\n");
+		ret = -1;
+		goto out;
+	}
+
+	key = fdt_getprop(gd_fdt_blob(), node,
+			  IMAGE_PRE_LOAD_PROP_PUBLIC_KEY, &key_len);
+	if (!key) {
+		printf("ERROR: no key for image 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;
+	info->sig_size		= fdt32_to_cpu(*sig_size);
+
+	mandatory = fdt_getprop(gd_fdt_blob(), node,
+				IMAGE_PRE_LOAD_PROP_MANDATORY, NULL);
+	if (mandatory && !strcmp((char *)mandatory, "yes"))
+		info->mandatory = 1;
+
+ out:
+	return ret;
+}
+
+static int image_pre_load_sig_get_header_u32(struct image_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 image pre-load sig\n");
+		ret = -1;
+		goto out;
+	}
+
+	tmp = header + offset;
+	*value = be32_to_cpu(*tmp);
+
+	unmap_sysmem(header);
+
+ out:
+	return ret;
+}
+
+static int image_pre_load_sig_get_magic(struct image_sig_info *info,
+					ulong addr, u32 *magic)
+{
+	int ret;
+
+	ret = image_pre_load_sig_get_header_u32(info, addr,
+						IMAGE_PRE_LOAD_SIG_OFFSET_MAGIC, magic);
+
+	return ret;
+}
+
+static int image_pre_load_sig_get_img_len(struct image_sig_info *info,
+					  ulong addr, u32 *len)
+{
+	int ret;
+
+	ret = image_pre_load_sig_get_header_u32(info, addr,
+						IMAGE_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;
+	}
+
+	if (*len == 0) {
+		printf("ERROR: size of image (%u) is zero\n", *len);
+		ret = -1;
+		goto out;
+	}
+
+ out:
+	return ret;
+}
+
+static int image_pre_load_sig_check(struct image_sig_info *info, ulong addr, int img_len)
+{
+	void *image;
+	struct image_sign_info sig_info;
+	struct image_region reg;
+	u32 sig_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;
+
+	sig = (uint8_t *)image + IMAGE_PRE_LOAD_SIG_OFFSET_SIG;
+	sig_len = info->sig_size;
+
+	ret = sig_info.crypto->verify(&sig_info, &reg, 1, sig, sig_len);
+	if (ret) {
+		printf("ERROR: signature check has failed (err=%d)\n", ret);
+		ret = -1;
+		goto out_unmap;
+	}
+
+	printf("INFO: signature check has succeed\n");
+
+out_unmap:
+	unmap_sysmem(image);
+
+ out:
+	return ret;
+}
+
+int image_pre_load_sig(ulong addr)
+{
+	struct image_sig_info info;
+	u32 magic, img_len;
+	int ret;
+
+	ret = image_pre_load_sig_setup(&info);
+	if (ret < 0)
+		goto out;
+	if (ret > 0) {
+		ret = 0;
+		goto out;
+	}
+
+	ret = image_pre_load_sig_get_magic(&info, addr, &magic);
+	if (ret < 0)
+		goto out;
+
+	if (magic != IMAGE_PRE_LOAD_SIG_MAGIC) {
+		if (info.mandatory) {
+			printf("ERROR: signature is mandatory\n");
+			ret = -1;
+		}
+		goto out;
+	}
+
+	ret = image_pre_load_sig_get_img_len(&info, addr, &img_len);
+	if (ret < 0)
+		goto out;
+
+	ret = image_pre_load_sig_check(&info, addr, img_len);
+
+	if (!ret)
+		image_load_offset += info.header_size;
+
+ out:
+	return ret;
+}
+
+int image_pre_load(ulong addr)
+{
+	int ret = 0;
+
+	image_load_offset = 0;
+
+	if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD_SIG))
+		ret = image_pre_load_sig(addr);
+
+	return ret;
+}
diff --git a/include/image.h b/include/image.h
index fd662e74b4..5f83e4c747 100644
--- a/include/image.h
+++ b/include/image.h
@@ -48,6 +48,7 @@ struct fdt_region;
 extern ulong image_load_addr;		/* Default Load Address */
 extern ulong image_save_addr;		/* Default Save Address */
 extern ulong image_save_size;		/* Default Save Size */
+extern ulong image_load_offset;	/* Default Load Address Offset */
 
 /* An invalid size, meaning that the image size is not known */
 #define IMAGE_SIZE_INVAL	(-1UL)
@@ -1289,6 +1290,14 @@ struct crypto_algo *image_get_crypto_algo(const char *full_name);
  */
 struct padding_algo *image_get_padding_algo(const char *name);
 
+/**
+ * image_pre_load() - Manage pre load header
+ *
+ * @param addr		Address of the image
+ * @return: 0 on success, -ve on error
+ */
+int image_pre_load(ulong addr);
+
 /**
  * fit_image_verify_required_sigs() - Verify signatures marked as 'required'
  *
-- 
2.17.1


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

* [RFC PATCH v2 5/6] cmd: bootm: add a stage pre-load
  2021-11-12  9:27 [RFC PATCH v2 0/6] image: add a stage pre-load Philippe Reynes
                   ` (3 preceding siblings ...)
  2021-11-12  9:27 ` [RFC PATCH v2 4/6] common: image: add a stage pre-load Philippe Reynes
@ 2021-11-12  9:27 ` Philippe Reynes
  2021-11-12  9:27 ` [RFC PATCH v2 6/6] common: spl: fit_ram: allow to use image pre load Philippe Reynes
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Reynes @ 2021-11-12  9:27 UTC (permalink / raw)
  To: sjg, mr.nuke.me, joel.peshkin; +Cc: u-boot, Philippe Reynes

This commit adds a stage pre-load to the command
bootm. Right now, this stage may be used to read
a header and check the signature of the full
image.

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

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 5b30b13e43..b20a346acf 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 92468d09a1..acfb8eedde 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 4482f84b40..4803c577cc 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -87,6 +87,33 @@ 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;
+}
+
+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 = image_pre_load(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[])
 {
@@ -677,6 +704,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);
 
@@ -866,6 +896,9 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
 					      &fit_uname_config,
 					      &fit_uname_kernel);
 
+	if (CONFIG_IS_ENABLED(CMD_BOOTM_PRE_LOAD))
+		img_addr += image_load_offset;
+
 	bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
 
 	/* check image type, for FIT images get FIT kernel node */
diff --git a/include/image.h b/include/image.h
index 5f83e4c747..42fb01ab07 100644
--- a/include/image.h
+++ b/include/image.h
@@ -351,6 +351,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;
 
 #if defined(CONFIG_LMB) && !defined(USE_HOSTCC)
-- 
2.17.1


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

* [RFC PATCH v2 6/6] common: spl: fit_ram: allow to use image pre load
  2021-11-12  9:27 [RFC PATCH v2 0/6] image: add a stage pre-load Philippe Reynes
                   ` (4 preceding siblings ...)
  2021-11-12  9:27 ` [RFC PATCH v2 5/6] cmd: bootm: " Philippe Reynes
@ 2021-11-12  9:27 ` Philippe Reynes
  5 siblings, 0 replies; 7+ messages in thread
From: Philippe Reynes @ 2021-11-12  9:27 UTC (permalink / raw)
  To: sjg, mr.nuke.me, joel.peshkin; +Cc: u-boot, Philippe Reynes

This commit add the support of image pre load in spl or tpl
when loading an image from ram.

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
 common/spl/spl_ram.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c
index df9f3a4d00..c8c7155a93 100644
--- a/common/spl/spl_ram.c
+++ b/common/spl/spl_ram.c
@@ -24,9 +24,17 @@
 static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
 			       ulong count, void *buf)
 {
+	ulong addr;
+
 	debug("%s: sector %lx, count %lx, buf %lx\n",
 	      __func__, sector, count, (ulong)buf);
-	memcpy(buf, (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + sector), count);
+
+	addr = (ulong)CONFIG_SPL_LOAD_FIT_ADDRESS + sector;
+	if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD))
+		addr += image_load_offset;
+
+	memcpy(buf, (void *)addr, count);
+
 	return count;
 }
 
@@ -37,6 +45,17 @@ static int spl_ram_load_image(struct spl_image_info *spl_image,
 
 	header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS;
 
+	if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)) {
+		unsigned long addr = (unsigned long)header;
+		int ret = image_pre_load(addr);
+
+		if (ret)
+			return ret;
+
+		addr += image_load_offset;
+		header = (struct image_header *)addr;
+	}
+
 #if CONFIG_IS_ENABLED(DFU)
 	if (bootdev->boot_device == BOOT_DEVICE_DFU)
 		spl_dfu_cmd(0, "dfu_alt_info_ram", "ram", "0");
-- 
2.17.1


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

end of thread, other threads:[~2021-11-12  9:29 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-12  9:27 [RFC PATCH v2 0/6] image: add a stage pre-load Philippe Reynes
2021-11-12  9:27 ` [RFC PATCH v2 1/6] lib: allow to build asn1 decoder and oid registry in SPL Philippe Reynes
2021-11-12  9:27 ` [RFC PATCH v2 2/6] lib: crypto: allow to build crypyo " Philippe Reynes
2021-11-12  9:27 ` [RFC PATCH v2 3/6] lib: rsa: allow rsa verify with pkey " Philippe Reynes
2021-11-12  9:27 ` [RFC PATCH v2 4/6] common: image: add a stage pre-load Philippe Reynes
2021-11-12  9:27 ` [RFC PATCH v2 5/6] cmd: bootm: " Philippe Reynes
2021-11-12  9:27 ` [RFC PATCH v2 6/6] common: spl: fit_ram: allow to use image pre load Philippe Reynes

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.