Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bootutil: Add compressed image flags and TLV, fix misc. bugs in bootutil #2028

Merged
merged 7 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions boot/bootutil/include/bootutil/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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");

Expand Down
38 changes: 37 additions & 1 deletion boot/bootutil/src/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions boot/bootutil/src/swap_scratch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
27 changes: 27 additions & 0 deletions boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions boot/zephyr/include/mcuboot_config/mcuboot_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions docs/release-notes.d/zephyr-compression.md
Original file line number Diff line number Diff line change
@@ -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
Loading