[PATCH 2/2] tools: socfpgaimage: update padding flow

Ley Foon Tan ley.foon.tan at intel.com
Wed Jan 6 07:04:37 CET 2021


The existing socfpgaimage always pads the image to the maximum size of
OCRAM size. This will break in the encryption flow where it expects the
image to be un-padded. The encryption tool will do the encryption for
the whole image and append the signature key at end of the image.
The signature key will append to beyond the size of OCRAM if the image
is padded with the maximum size before encryption.

Move the padding step from socfpgaimage to Makefile and pads with objcopy
command.

socfpgaimage will pad the image with 16 bytes aligned (including CRC word),
this is a requirement in encryption flow.

Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
---
 Makefile             |  5 ++++-
 tools/socfpgaimage.c | 41 ++++++++++++++++++++++++++++-------------
 2 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/Makefile b/Makefile
index 679e4a603a28..e7ff15d419c4 100644
--- a/Makefile
+++ b/Makefile
@@ -1583,7 +1583,10 @@ u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE
 
 ifneq ($(CONFIG_ARCH_SOCFPGA),)
 quiet_cmd_gensplx4 = GENSPLX4 $@
-cmd_gensplx4 = cat	spl/u-boot-spl.sfp spl/u-boot-spl.sfp	\
+cmd_gensplx4 = $(OBJCOPY) -I binary -O binary --gap-fill=0x0		\
+			--pad-to=$(CONFIG_SPL_PAD_TO)			\
+			spl/u-boot-spl.sfp spl/u-boot-spl.sfp &&        \
+		cat	spl/u-boot-spl.sfp spl/u-boot-spl.sfp		\
 			spl/u-boot-spl.sfp spl/u-boot-spl.sfp > $@ || rm -f $@
 spl/u-boot-splx4.sfp: spl/u-boot-spl.sfp FORCE
 	$(call if_changed,gensplx4)
diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c
index 5808b383e9cb..bacd31b98b8a 100644
--- a/tools/socfpgaimage.c
+++ b/tools/socfpgaimage.c
@@ -61,6 +61,7 @@
 
 #define HEADER_OFFSET	0x40
 #define VALIDATION_WORD	0x31305341
+#define IMAGE_ALIGN	16
 
 /* Minimum and default entry point offset */
 #define ENTRY_POINT_OFFSET	0x14
@@ -97,7 +98,7 @@ static unsigned int sfp_hdr_size(uint8_t ver)
 	return 0;
 }
 
-static unsigned int sfp_pad_size(uint8_t ver)
+static unsigned int sfp_max_size(uint8_t ver)
 {
 	if (ver == 0)
 		return sizeof(buffer_v0);
@@ -106,6 +107,12 @@ static unsigned int sfp_pad_size(uint8_t ver)
 	return 0;
 }
 
+static unsigned int sfp_aligned_len(uint32_t size)
+{
+	/* Add 4 bytes for CRC and align to 16 bytes */
+	return ALIGN(size + sizeof(unsigned int), IMAGE_ALIGN);
+}
+
 /*
  * The header checksum is just a very simple checksum over
  * the header area.
@@ -208,22 +215,24 @@ static int sfp_sign_buffer(uint8_t *buf, uint8_t ver, uint8_t flags,
 			   struct image_tool_params *params)
 {
 	uint32_t calc_crc;
+	uint32_t crc_off;
 
 	/* Align the length up */
-	len = ALIGN(len, 4);
+	len = sfp_aligned_len(len);
 
-	/* Build header, adding 4 bytes to length to hold the CRC32. */
-	sfp_build_header(buf + HEADER_OFFSET, ver, flags, len + 4, params);
+	/* Build header */
+	sfp_build_header(buf + HEADER_OFFSET, ver, flags, len, params);
 
 	/* Calculate and apply the CRC */
-	calc_crc = ~pbl_crc32(0, (char *)buf, len);
+	crc_off = len - 4; /* at last 4 bytes of image */
+	calc_crc = ~pbl_crc32(0, (char *)buf, crc_off);
 
-	*((uint32_t *)(buf + len)) = cpu_to_le32(calc_crc);
+	*((uint32_t *)(buf + crc_off)) = cpu_to_le32(calc_crc);
 
 	if (!pad_64k)
 		return len + 4;
 
-	return sfp_pad_size(ver);
+	return sfp_max_size(ver);
 }
 
 /* Verify that the buffer looks sane */
@@ -240,7 +249,7 @@ static int sfp_verify_buffer(const uint8_t *buf)
 		return -1;
 	}
 
-	if (len < HEADER_OFFSET || len > sfp_pad_size(ver)) {
+	if (len < HEADER_OFFSET || len > sfp_max_size(ver)) {
 		debug("Invalid header length (%i)\n", len);
 		return -1;
 	}
@@ -367,19 +376,25 @@ static int socfpgaimage_check_image_types_v1(uint8_t type)
  * To work in with the mkimage framework, we do some ugly stuff...
  *
  * First, socfpgaimage_vrec_header() is called.
- * We prepend a fake header big enough to make the file sfp_pad_size().
+ * We prepend a fake header big enough to include crc32 and align image to 16
+ * bytes.
  * This gives us enough space to do what we want later.
  *
  * Next, socfpgaimage_set_header() is called.
  * We fix up the buffer by moving the image to the start of the buffer.
- * We now have some room to do what we need (add CRC and padding).
+ * We now have some room to do what we need (add CRC).
  */
 
 static int data_size;
 
 static int sfp_fake_header_size(unsigned int size, uint8_t ver)
 {
-	return sfp_pad_size(ver) - size;
+	unsigned int align_size;
+
+	align_size = sfp_aligned_len(size);
+
+	/* extra bytes needed */
+	return align_size - size;
 }
 
 static int sfp_vrec_header(struct image_tool_params *params,
@@ -389,7 +404,7 @@ static int sfp_vrec_header(struct image_tool_params *params,
 
 	if (params->datafile &&
 	    stat(params->datafile, &sbuf) == 0 &&
-	    sbuf.st_size <= (sfp_pad_size(ver) - sizeof(uint32_t))) {
+	    sbuf.st_size <= (sfp_max_size(ver) - sizeof(uint32_t))) {
 		data_size = sbuf.st_size;
 		tparams->header_size = sfp_fake_header_size(data_size, ver);
 	}
@@ -417,7 +432,7 @@ static void sfp_set_header(void *ptr, unsigned char ver,
 	/*
 	 * This function is called after vrec_header() has been called.
 	 * At this stage we have the sfp_fake_header_size() dummy bytes
-	 * followed by data_size image bytes. Total = sfp_pad_size().
+	 * followed by data_size image bytes.
 	 * We need to fix the buffer by moving the image bytes back to
 	 * the beginning of the buffer, then actually do the signing stuff...
 	 */
-- 
2.19.0



More information about the U-Boot mailing list