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 \
LIBUSB = libusb-1.0
LIBUSB_CFLAGS ?= `pkg-config --cflags $(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)
# Windows lacks mman.h / mmap()
DEFAULT_CFLAGS += -DNO_MMAP
......@@ -132,7 +137,8 @@ SOC_INFO := soc_info.c soc_info.h
FEL_LIB := fel_lib.c fel_lib.h
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
$(CC) $(HOST_CFLAGS) -c -o nand-part-main.o nand-part-main.c
......
......@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <zlib.h>
#include <sys/stat.h>
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)
uint32_t data_size = be32toh(hdr.ih_size); /* Image Data Size */
uint32_t load_addr = be32toh(hdr.ih_load); /* Data Load Address */
if (data_size != len - HEADER_SIZE)
pr_fatal("U-Boot image data size mismatch: "
"expected %zu, got %u\n", len - HEADER_SIZE, data_size);
/* TODO: Verify image data integrity using the checksum field ih_dcrc,
* available from be32toh(buf32[6])
*
* However, this requires CRC routines that mimic their U-Boot
* counterparts, namely image_check_dcrc() in ${U-BOOT}/common/image.c
* and crc_wd() in ${U-BOOT}/lib/crc32.c
*
* 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 (data_size > len - HEADER_SIZE)
pr_fatal("U-Boot image data trucated: "
"expected %zu bytes, got %u\n",
len - HEADER_SIZE, data_size);
uint32_t dcrc = be32toh(hdr.ih_dcrc);
uint32_t computed_dcrc = crc32(0, buf + HEADER_SIZE, data_size);
if (dcrc != computed_dcrc)
pr_fatal("U-Boot data CRC mismatch: expected %x, got %x\n",
dcrc, computed_dcrc);
/* 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",
......
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