Unverified Commit e753821e authored by Maxime Ripard's avatar Maxime Ripard
Browse files

fel: Check the U-Boot's CRC instead of its size



The current code checks that the transferred size is matching the size
reported in the image header.

Unfortunately, the transferred image might be padded, which doesn't change
anything at the functional level, but will make that check trigger since
the actual image will be smaller than the transferred data.

Change that logic to first check that the transferred size isn't less that
the header image size, which will still be an error, and then check for the
CRC of the image itself. This will prove to be an more robust integrity
check than what we have right now anyway.

The CRC used in the image header is the CRC32 algorithm, that is
implemented in the zlib, which is installed on most devices on the planet,
so we can just use that implementation instead of rolling our own.
Tested-by: default avatarFrank Kunz <mailinglists@kunz-im-inter.net>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
parent b1bbc431
...@@ -118,6 +118,11 @@ sunxi-fexc: fexc.h script.h script.c \ ...@@ -118,6 +118,11 @@ sunxi-fexc: fexc.h script.h script.c \
LIBUSB = libusb-1.0 LIBUSB = libusb-1.0
LIBUSB_CFLAGS ?= `pkg-config --cflags $(LIBUSB)` LIBUSB_CFLAGS ?= `pkg-config --cflags $(LIBUSB)`
LIBUSB_LIBS ?= `pkg-config --libs $(LIBUSB)` LIBUSB_LIBS ?= `pkg-config --libs $(LIBUSB)`
ZLIB = zlib
ZLIB_CFLAGS ?= `pkg-config --cflags $(ZLIB)`
ZLIB_LIBS ?= `pkg-config --libs $(ZLIB)`
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
# Windows lacks mman.h / mmap() # Windows lacks mman.h / mmap()
DEFAULT_CFLAGS += -DNO_MMAP DEFAULT_CFLAGS += -DNO_MMAP
...@@ -132,7 +137,8 @@ SOC_INFO := soc_info.c soc_info.h ...@@ -132,7 +137,8 @@ SOC_INFO := soc_info.c soc_info.h
FEL_LIB := fel_lib.c fel_lib.h FEL_LIB := fel_lib.c fel_lib.h
sunxi-fel: fel.c thunks/fel-to-spl-thunk.h $(PROGRESS) $(SOC_INFO) $(FEL_LIB) sunxi-fel: fel.c thunks/fel-to-spl-thunk.h $(PROGRESS) $(SOC_INFO) $(FEL_LIB)
$(CC) $(HOST_CFLAGS) $(LIBUSB_CFLAGS) $(LDFLAGS) -o $@ $(filter %.c,$^) $(LIBS) $(LIBUSB_LIBS) $(CC) $(HOST_CFLAGS) $(LIBUSB_CFLAGS) $(ZLIB_CFLAGS) $(LDFLAGS) -o $@ \
$(filter %.c,$^) $(LIBS) $(LIBUSB_LIBS) $(ZLIB_LIBS)
sunxi-nand-part: nand-part-main.c nand-part.c nand-part-a10.h nand-part-a20.h sunxi-nand-part: nand-part-main.c nand-part.c nand-part-a10.h nand-part-a20.h
$(CC) $(HOST_CFLAGS) -c -o nand-part-main.o nand-part-main.c $(CC) $(HOST_CFLAGS) -c -o nand-part-main.o nand-part-main.c
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <zlib.h>
#include <sys/stat.h> #include <sys/stat.h>
static bool verbose = false; /* If set, makes the 'fel' tool more talkative */ static bool verbose = false; /* If set, makes the 'fel' tool more talkative */
...@@ -785,21 +786,16 @@ void aw_fel_write_uboot_image(feldev_handle *dev, uint8_t *buf, size_t len) ...@@ -785,21 +786,16 @@ void aw_fel_write_uboot_image(feldev_handle *dev, uint8_t *buf, size_t len)
uint32_t data_size = be32toh(hdr.ih_size); /* Image Data Size */ uint32_t data_size = be32toh(hdr.ih_size); /* Image Data Size */
uint32_t load_addr = be32toh(hdr.ih_load); /* Data Load Address */ uint32_t load_addr = be32toh(hdr.ih_load); /* Data Load Address */
if (data_size != len - HEADER_SIZE) if (data_size > len - HEADER_SIZE)
pr_fatal("U-Boot image data size mismatch: " pr_fatal("U-Boot image data trucated: "
"expected %zu, got %u\n", len - HEADER_SIZE, data_size); "expected %zu bytes, got %u\n",
len - HEADER_SIZE, data_size);
/* TODO: Verify image data integrity using the checksum field ih_dcrc,
* available from be32toh(buf32[6]) uint32_t dcrc = be32toh(hdr.ih_dcrc);
* uint32_t computed_dcrc = crc32(0, buf + HEADER_SIZE, data_size);
* However, this requires CRC routines that mimic their U-Boot if (dcrc != computed_dcrc)
* counterparts, namely image_check_dcrc() in ${U-BOOT}/common/image.c pr_fatal("U-Boot data CRC mismatch: expected %x, got %x\n",
* and crc_wd() in ${U-BOOT}/lib/crc32.c dcrc, computed_dcrc);
*
* It should be investigated if existing CRC routines in sunxi-tools
* could be factored out and reused for this purpose - e.g. calc_crc32()
* from nand-part-main.c
*/
/* If we get here, we're "good to go" (i.e. actually write the data) */ /* If we get here, we're "good to go" (i.e. actually write the data) */
pr_info("Writing image \"%.*s\", %u bytes @ 0x%08X.\n", pr_info("Writing image \"%.*s\", %u bytes @ 0x%08X.\n",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment