diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 1f12d9512..3e03f80dd 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -71,6 +71,13 @@ struct flash_area; */ #define IMAGE_F_ROM_FIXED 0x00000100 +/* + * Flags that indicate if the image data is compressed + */ +#define IMAGE_F_COMPRESSED_LZMA1 0x00000200 +#define IMAGE_F_COMPRESSED_LZMA2 0x00000400 +#define IMAGE_F_COMPRESSED_ARM_THUMB_FLT 0x00000800 + /* * ECSDA224 is with NIST P-224 * ECSDA256 is with NIST P-256 @@ -101,6 +108,18 @@ struct flash_area; #define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */ #define IMAGE_TLV_SEC_CNT 0x50 /* security counter */ #define IMAGE_TLV_BOOT_RECORD 0x60 /* measured boot record */ +/* The following flags relate to compressed images and are for the decompressed image data */ +#define IMAGE_TLV_DECOMP_SIZE 0x70 /* Decompressed image size excluding header/TLVs */ +#define IMAGE_TLV_DECOMP_SHA 0x71 /* + * Decompressed image shaX hash, this field must match + * the format and size of the raw slot (compressed) + * shaX hash + */ +#define IMAGE_TLV_DECOMP_SIGNATURE 0x72 /* + * Decompressed image signature, this field must match + * the format and size of the raw slot (compressed) + * signature + */ /* * vendor reserved TLVs at xxA0-xxFF, * where xx denotes the upper byte @@ -160,6 +179,12 @@ struct image_tlv { #define MUST_DECRYPT(fap, idx, hdr) \ (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_ENCRYPTED(hdr)) +#define COMPRESSIONFLAGS (IMAGE_F_COMPRESSED_LZMA1 | IMAGE_F_COMPRESSED_LZMA2 \ + | IMAGE_F_COMPRESSED_ARM_THUMB_FLT) +#define IS_COMPRESSED(hdr) ((hdr)->ih_flags & COMPRESSIONFLAGS) +#define MUST_DECOMPRESS(fap, idx, hdr) \ + (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_COMPRESSED(hdr)) + _Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE, "struct image_header not required size"); diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 8663fbf2a..d780d8541 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -860,7 +860,9 @@ split_image_check(struct image_header *app_hdr, * Check that this is a valid header. Valid means that the magic is * correct, and that the sizes/offsets are "sane". Sane means that * there is no overflow on the arithmetic, and that the result fits - * within the flash area we are in. + * within the flash area we are in. Also check the flags in the image + * and class the image as invalid if flags for encryption/compression + * are present but these features are not enabled. */ static bool boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fap) @@ -875,10 +877,44 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } +#ifdef MCUBOOT_DECOMPRESS_IMAGES + if (!MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { +#else + if (1) { +#endif + if (!boot_u32_safe_add(&size, size, hdr->ih_protect_tlv_size)) { + return false; + } + } + if (size >= flash_area_get_size(fap)) { return false; } +#if !defined(MCUBOOT_ENC_IMAGES) + if (IS_ENCRYPTED(hdr)) { + return false; + } +#else + if ((hdr->ih_flags & IMAGE_F_ENCRYPTED_AES128) && + (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES256)) + { + return false; + } +#endif + +#if !defined(MCUBOOT_DECOMPRESS_IMAGES) + if (IS_COMPRESSED(hdr)) { + return false; + } +#else + if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) && + (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) + { + return false; + } +#endif + return true; } diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 2cdb91a49..2fcf76f69 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -218,12 +218,14 @@ boot_slots_compatible(struct boot_loader_state *state) #endif } +#ifndef MCUBOOT_DECOMPRESS_IMAGES if ((i != num_sectors_primary) || (j != num_sectors_secondary) || (primary_slot_sz != secondary_slot_sz)) { BOOT_LOG_WRN("Cannot upgrade: slots are not compatible"); return 0; } +#endif return 1; } diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index bf772cac7..64e23ac6d 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -729,6 +729,33 @@ config MCUBOOT_BOOT_BANNER config BOOT_BANNER_STRING default "Using Zephyr OS build" if MCUBOOT_BOOT_BANNER +config BOOT_DECOMPRESSION_SUPPORT + bool + help + Hidden symbol which should be selected if a system provided decompression support. + +if BOOT_DECOMPRESSION_SUPPORT + +menuconfig BOOT_DECOMPRESSION + bool "Decompression" + help + If enabled, will include support for compressed images being loaded to the secondary slot + which then get decompressed into the primary slot. This mode allows the secondary slot to + be smaller than primary slot which otherwise would not be allowed. + +if BOOT_DECOMPRESSION + +config BOOT_DECOMPRESSION_BUFFER_SIZE + int "Write buffer size" + range 16 16384 + default 4096 + help + The size of a secondary buffer used for writing decompressed data to the storage device. + +endif # BOOT_DECOMPRESSION + +endif # BOOT_DECOMPRESSION_SUPPORT + endmenu config MCUBOOT_DEVICE_SETTINGS diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index bb30ce298..0891a4b11 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -127,6 +127,10 @@ #define MCUBOOT_ENCRYPT_X25519 #endif +#ifdef CONFIG_BOOT_DECOMPRESSION +#define MCUBOOT_DECOMPRESS_IMAGES +#endif + #ifdef CONFIG_BOOT_BOOTSTRAP #define MCUBOOT_BOOTSTRAP 1 #endif diff --git a/docs/release-notes.d/zephyr-compression.md b/docs/release-notes.d/zephyr-compression.md new file mode 100644 index 000000000..ba9ec2a7a --- /dev/null +++ b/docs/release-notes.d/zephyr-compression.md @@ -0,0 +1,7 @@ +- Added protected TLV size to image size check in bootutil +- Added Kconfig for decompression support in Zephyr +- Added compressed image flags and TLV to bootutil +- Added support for removing images with conflicting flags in + bootutil +- Added support for removing encrypted/compressed images when + MCUboot is compiled without support for them