spl: implement CRC check on U-Boot uImage
authorSimon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Sun, 10 Feb 2019 20:34:37 +0000 (21:34 +0100)
committerTom Rini <trini@konsulko.com>
Tue, 19 Feb 2019 13:55:43 +0000 (08:55 -0500)
SPL currently does not check uImage CRCs when loading U-Boot.

This patch adds checking the uImage CRC when SPL loads U-Boot. It does
this by reusing the existing config option SPL_CRC32_SUPPORT to allow
leaving out the CRC check on boards where the additional code size or
boot time is a problem (adding the CRC check currently adds ~1.4 kByte
to flash).

The SPL_CRC32_SUPPORT config option now gets enabled by default if SPL
support for legacy images is enabled to check the CRC on all boards
that don't actively take countermeasures.

Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
common/spl/Kconfig
common/spl/spl.c
include/spl.h

index 85edd5a61f83ffb4dfb6959e348108e621dc79e1..206c24076da8f1a0a2a818a86f0545a1f025668c 100644 (file)
@@ -100,6 +100,16 @@ config SPL_LEGACY_IMAGE_SUPPORT
          is y. If this is not set, SPL will move on to other available
          boot media to find a suitable image.
 
+config SPL_LEGACY_IMAGE_CRC_CHECK
+       bool "Check CRC of Legacy images"
+       depends on SPL_LEGACY_IMAGE_SUPPORT
+       select SPL_CRC32_SUPPORT
+       help
+         Enable this to check the CRC of Legacy images. While this increases
+         reliability, it affects both code size and boot duration.
+         If disabled, Legacy images are booted if the image magic and size
+         are correct, without further integrity checks.
+
 config SPL_SYS_MALLOC_SIMPLE
        bool
        prompt "Only use malloc_simple functions in the SPL"
@@ -236,13 +246,13 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE
 
 config SPL_CRC32_SUPPORT
        bool "Support CRC32"
-       depends on SPL_FIT
+       default y if SPL_LEGACY_IMAGE_SUPPORT
        help
-         Enable this to support CRC32 in FIT images within SPL. This is a
-         32-bit checksum value that can be used to verify images. This is
-         the least secure type of checksum, suitable for detected
-         accidental image corruption. For secure applications you should
-         consider SHA1 or SHA256.
+         Enable this to support CRC32 in uImages or FIT images within SPL.
+         This is a 32-bit checksum value that can be used to verify images.
+         For FIT images, this is the least secure type of checksum, suitable
+         for detected accidental image corruption. For secure applications you
+         should consider SHA1 or SHA256.
 
 config SPL_MD5_SUPPORT
        bool "Support MD5"
index 35120b6efd1a7ce4cc08d67a181aab529de9cd99..2e2af1b28ee51205045442fae3160b534f754a10 100644 (file)
@@ -239,6 +239,14 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
 #ifdef CONFIG_SPL_LEGACY_IMAGE_SUPPORT
                u32 header_size = sizeof(struct image_header);
 
+#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
+               /* check uImage header CRC */
+               if (!image_check_hcrc(header)) {
+                       puts("SPL: Image header CRC check failed!\n");
+                       return -EINVAL;
+               }
+#endif
+
                if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) {
                        /*
                         * On some system (e.g. powerpc), the load-address and
@@ -256,6 +264,13 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
                        spl_image->size = image_get_data_size(header) +
                                header_size;
                }
+#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
+               /* store uImage data length and CRC to check later */
+               spl_image->dcrc_data = image_get_load(header);
+               spl_image->dcrc_length = image_get_data_size(header);
+               spl_image->dcrc = image_get_dcrc(header);
+#endif
+
                spl_image->os = image_get_os(header);
                spl_image->name = image_get_name(header);
                debug(SPL_TPL_PROMPT
@@ -495,12 +510,25 @@ static struct spl_image_loader *spl_ll_find_loader(uint boot_device)
 static int spl_load_image(struct spl_image_info *spl_image,
                          struct spl_image_loader *loader)
 {
+       int ret;
        struct spl_boot_device bootdev;
 
        bootdev.boot_device = loader->boot_device;
        bootdev.boot_device_name = NULL;
 
-       return loader->load_image(spl_image, &bootdev);
+       ret = loader->load_image(spl_image, &bootdev);
+#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
+       if (!ret && spl_image->dcrc_length) {
+               /* check data crc */
+               ulong dcrc = crc32_wd(0, (unsigned char *)spl_image->dcrc_data,
+                                     spl_image->dcrc_length, CHUNKSZ_CRC32);
+               if (dcrc != spl_image->dcrc) {
+                       puts("SPL: Image data CRC check failed!\n");
+                       ret = -EINVAL;
+               }
+       }
+#endif
+       return ret;
 }
 
 /**
index c82f2fd033653dddc2a26198c0040a268b321024..f09909e189ba9314d321e79d807f9a66c92ce5c1 100644 (file)
@@ -74,6 +74,11 @@ struct spl_image_info {
        u32 size;
        u32 flags;
        void *arg;
+#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
+       ulong dcrc_data;
+       ulong dcrc_length;
+       ulong dcrc;
+#endif
 };
 
 /*