-
Notifications
You must be signed in to change notification settings - Fork 708
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Stand alone tool that extracts compressed stream from signed.bin, decompresses it and compares against uncompressed application binary. Signed-off-by: Mateusz Michalek <[email protected]>
- Loading branch information
1 parent
b778ad9
commit 06020ca
Showing
2 changed files
with
140 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
Independent LZMA test | ||
--------------------- | ||
|
||
This tool finds and extracts compressed stream, decompresses it and verifies if | ||
decompressed one is identical as before compression. | ||
|
||
Building and running: | ||
|
||
change directory to the top of the repos: | ||
|
||
cd $ZEPHYR_BASE | ||
cd .. | ||
|
||
build tool: | ||
|
||
g++ bootloader/mcuboot/samples/compression_test/independent_cmp.c -o indcmp | ||
|
||
build example application: | ||
|
||
west build -b nrf54l15dk/nrf54l15/cpuapp -p | ||
-s zephyr/samples/hello_world/ -- | ||
-DSB_CONFIG_BOOTLOADER_MCUBOOT=y | ||
-DSB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y | ||
-DSB_CONFIG_MCUBOOT_COMPRESSED_IMAGE_SUPPORT=y | ||
|
||
|
||
compare application image with the one carried by signed binary: | ||
|
||
./indcmp build/hello_world/zephyr/zephyr.signed.bin | ||
build/hello_world/zephyr/zephyr.bin | ||
|
||
note: order of arguments matter. Compressed goes first. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
#include <unistd.h> | ||
#include <fcntl.h> | ||
#include <cstdint> | ||
#include <cstdio> | ||
#include <cstdlib> | ||
|
||
#define EXPECTED_MAGIC 0x96f3b83d | ||
#define LZMA_HEADER_SIZE 2 | ||
#define FLAG_LZMA2 0x400 | ||
#define FLAG_ARM_THUMB 0x800 | ||
|
||
struct __attribute__((__packed__)) image_header { | ||
uint32_t magic; | ||
uint32_t unused0; | ||
uint16_t hdr_size; | ||
uint16_t unused1; | ||
uint32_t img_size; | ||
uint32_t flags; | ||
}; | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
if (argc != 3) { | ||
printf("needs 2 parameters: signed image file and application binary file\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
int app_fd = open(argv[2], O_NONBLOCK); | ||
|
||
if (app_fd < 0) { | ||
printf("Opening signed image failed.\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
int signed_fd = open(argv[1], O_NONBLOCK); | ||
|
||
if (signed_fd < 0) { | ||
printf("Opening signed image failed.\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
system("mkdir -p tmp; rm -rf tmp/stream*"); | ||
struct image_header ih; | ||
size_t rc = pread(signed_fd, &ih, sizeof(struct image_header), 0); | ||
|
||
if (ih.magic != EXPECTED_MAGIC) { | ||
printf("Expected magic value at the start of signed image.\n\r"); | ||
printf("Input files in wrong order?\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
if (!ih.flags & FLAG_LZMA2) { | ||
printf("Signed image is not compressed with LZMA2.\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
int lzma_stream_size = ih.img_size - LZMA_HEADER_SIZE; | ||
int lzma_stream_offset = ih.hdr_size + LZMA_HEADER_SIZE; | ||
uint8_t *lzma_buf = (uint8_t *)malloc(lzma_stream_size); | ||
|
||
rc = pread(signed_fd, lzma_buf, lzma_stream_size, lzma_stream_offset); | ||
if (rc != lzma_stream_size) { | ||
printf("Error while reading compressed stream from signed image.\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
int lzma_fd = creat("tmp/stream.lzma", 0600); | ||
|
||
write(lzma_fd, lzma_buf, lzma_stream_size); | ||
close(lzma_fd); | ||
if (ih.flags & FLAG_ARM_THUMB) { | ||
system("unlzma --armthumb --lzma2 --format=raw --suffix=.lzma tmp/stream.lzma"); | ||
} else { | ||
system("unlzma --lzma2 --format=raw --suffix=.lzma tmp/stream.lzma"); | ||
} | ||
int unlzma_fd = open("tmp/stream", O_NONBLOCK); | ||
int unlzma_size = lseek(unlzma_fd, 0L, SEEK_END); | ||
int app_size = lseek(app_fd, 0L, SEEK_END); | ||
|
||
if (app_size != unlzma_size) { | ||
printf("Decompressed stream size and application size mismatch.\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
uint8_t *unlzma_buf = (uint8_t *)malloc(unlzma_size); | ||
uint8_t *app_buf = (uint8_t *)malloc(app_size); | ||
|
||
rc = pread(app_fd, app_buf, app_size, 0); | ||
if (rc != app_size) { | ||
printf("Error while loading application binary.\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
rc = pread(unlzma_fd, unlzma_buf, unlzma_size, 0); | ||
if (rc != unlzma_size) { | ||
printf("Error while loading decompressed stream.\n\r"); | ||
return EXIT_FAILURE; | ||
} | ||
for (int i = 0; i < app_size; i++) { | ||
if (app_buf[i] != unlzma_buf[i]) { | ||
printf("Diff at %d\r\n", i); | ||
return EXIT_FAILURE; | ||
} | ||
} | ||
close(unlzma_fd); | ||
close(app_fd); | ||
printf("All checks OK.\n\r"); | ||
return 0; | ||
} |