From 3a69b0e41addb299578fcda9ea14a07df12eec18 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 22 Nov 2024 11:56:14 +0100 Subject: [PATCH] Don't fail if the image contains no base sha + Added --no-base-sha option to sign --- .../workflows/test-powerfail-simulator.yml | 8 +++ docs/Signing.md | 9 ++++ src/update_flash.c | 17 +++--- tools/keytools/sign.c | 53 ++++++++++--------- tools/test.mk | 8 +++ 5 files changed, 65 insertions(+), 30 deletions(-) diff --git a/.github/workflows/test-powerfail-simulator.yml b/.github/workflows/test-powerfail-simulator.yml index 7d2f11e05..3892dc19f 100644 --- a/.github/workflows/test-powerfail-simulator.yml +++ b/.github/workflows/test-powerfail-simulator.yml @@ -235,6 +235,14 @@ jobs: run: | tools/scripts/sim-update-powerfail-resume.sh + - name: Rebuild without SHA of base image to test compatibility + run: | + make clean && make test-sim-internal-flash-with-delta-update-no-base-sha + + - name: Run sunny day update test (DELTA with no-base-sha) + run: | + tools/scripts/sim-sunnyday-update.sh + - name: Rebuild with wrong delta base version run: | make clean && make test-sim-internal-flash-with-wrong-delta-update diff --git a/docs/Signing.md b/docs/Signing.md index c0e989b65..1f9f81822 100644 --- a/docs/Signing.md +++ b/docs/Signing.md @@ -180,6 +180,15 @@ result is stored in a file ending in `_signed_diff.bin`. The compression scheme used is Bentley–McIlroy. +Options: + * `--no-base-sha` : Avoid adding the sha of the base image to the manifest header. + By default, the sign tool appends the sha of the base image to the manifest header, + so wolfBoot will refuse to start a delta update if the sha does not match the + one of the existing image. However, this takes up 32 to 48 bytes extra in the + manifest header, so this option is available to provide compatibility on + existing installations without this feature, where the header size does not + allow to accommodate the field + #### Policy signing (for sealing/unsealing with a TPM) diff --git a/src/update_flash.c b/src/update_flash.c index dff574a01..20cc67cc0 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -340,10 +340,15 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot, delta_base_v = wolfBoot_get_diffbase_version(PART_UPDATE); if (delta_base_hash_sz != WOLFBOOT_SHA_DIGEST_SIZE) { - wolfBoot_printf("Delta update: Base hash size mismatch" - " (size: %x expected %x)\n", delta_base_hash_sz, - WOLFBOOT_SHA_DIGEST_SIZE); - return -1; + if (delta_base_hash_sz == 0) { + wolfBoot_printf("Warning: delta update: Base hash not found in image\n"); + delta_base_hash = NULL; + } else { + wolfBoot_printf("Error: delta update: Base hash size mismatch" + " (size: %x expected %x)\n", delta_base_hash_sz, + WOLFBOOT_SHA_DIGEST_SIZE); + return -1; + } } #if defined(WOLFBOOT_HASH_SHA256) @@ -375,8 +380,8 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot, wolfBoot_printf("Delta Base 0x%x != Cur 0x%x\n", cur_v, delta_base_v); ret = -1; - - } else if (!resume && memcmp(base_hash, delta_base_hash, base_hash_sz) != 0) { + } else if (!resume && delta_base_hash && + memcmp(base_hash, delta_base_hash, base_hash_sz) != 0) { /* Wrong base image digest, cannot apply delta patch */ wolfBoot_printf("Delta Base hash mismatch\n"); ret = -1; diff --git a/tools/keytools/sign.c b/tools/keytools/sign.c index 0e38485cc..77a3d4f4a 100644 --- a/tools/keytools/sign.c +++ b/tools/keytools/sign.c @@ -291,6 +291,7 @@ struct cmd_options { const char *policy_file; const char *encrypt_key_file; const char *delta_base_file; + int no_base_sha; char output_image_file[PATH_MAX]; char output_diff_file[PATH_MAX]; char output_encrypted_image_file[PATH_MAX]; @@ -1201,33 +1202,35 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz, header_append_tag(header, &header_idx, HDR_IMG_DELTA_INVERSE_SIZE, 4, &patch_inv_len); - /* Append pad bytes, so base hash is 8-byte aligned */ - ALIGN_8(header_idx); - if (!base_hash) { - fprintf(stderr, "Base hash for delta image not found.\n"); - exit(1); - } - if (CMD.hash_algo == HASH_SHA256) { - if (base_hash_sz != HDR_SHA256_LEN) { - fprintf(stderr, "Invalid base hash size for SHA256.\n"); - exit(1); - } - header_append_tag(header, &header_idx, HDR_IMG_DELTA_BASE_HASH, - HDR_SHA256_LEN, base_hash); - } else if (CMD.hash_algo == HASH_SHA384) { - if (base_hash_sz != HDR_SHA384_LEN) { - fprintf(stderr, "Invalid base hash size for SHA384.\n"); + if (!CMD.no_base_sha) { + /* Append pad bytes, so base hash is 8-byte aligned */ + ALIGN_8(header_idx); + if (!base_hash) { + fprintf(stderr, "Base hash for delta image not found.\n"); exit(1); } - header_append_tag(header, &header_idx, HDR_IMG_DELTA_BASE_HASH, - HDR_SHA384_LEN, base_hash); - } else if (CMD.hash_algo == HASH_SHA3) { - if (base_hash_sz != HDR_SHA3_384_LEN) { - fprintf(stderr, "Invalid base hash size for SHA3-384.\n"); - exit(1); + if (CMD.hash_algo == HASH_SHA256) { + if (base_hash_sz != HDR_SHA256_LEN) { + fprintf(stderr, "Invalid base hash size for SHA256.\n"); + exit(1); + } + header_append_tag(header, &header_idx, HDR_IMG_DELTA_BASE_HASH, + HDR_SHA256_LEN, base_hash); + } else if (CMD.hash_algo == HASH_SHA384) { + if (base_hash_sz != HDR_SHA384_LEN) { + fprintf(stderr, "Invalid base hash size for SHA384.\n"); + exit(1); + } + header_append_tag(header, &header_idx, HDR_IMG_DELTA_BASE_HASH, + HDR_SHA384_LEN, base_hash); + } else if (CMD.hash_algo == HASH_SHA3) { + if (base_hash_sz != HDR_SHA3_384_LEN) { + fprintf(stderr, "Invalid base hash size for SHA3-384.\n"); + exit(1); + } + header_append_tag(header, &header_idx, HDR_IMG_DELTA_BASE_HASH, + HDR_SHA3_384_LEN, base_hash); } - header_append_tag(header, &header_idx, HDR_IMG_DELTA_BASE_HASH, - HDR_SHA3_384_LEN, base_hash); } } @@ -2490,6 +2493,8 @@ int main(int argc, char** argv) else if (strcmp(argv[i], "--delta") == 0) { CMD.delta = 1; CMD.delta_base_file = argv[++i]; + } else if (strcmp(argv[i], "--no-base-sha") == 0) { + CMD.no_base_sha = 1; } else if (strcmp(argv[i], "--no-ts") == 0) { CMD.no_ts = 1; diff --git a/tools/test.mk b/tools/test.mk index 46c21781a..7ff4b3e9f 100644 --- a/tools/test.mk +++ b/tools/test.mk @@ -246,6 +246,14 @@ test-sim-internal-flash-with-delta-update: $$(($(WOLFBOOT_PARTITION_UPDATE_ADDRESS)-$(ARCH_FLASH_OFFSET))) test-app/image_v$(TEST_UPDATE_VERSION)_signed_diff.bin \ $$(($(WOLFBOOT_PARTITION_SWAP_ADDRESS)-$(ARCH_FLASH_OFFSET))) erased_sec.dd +test-sim-internal-flash-with-delta-update-no-base-sha: + make test-sim-internal-flash-with-update DELTA_UPDATE_OPTIONS="--no-base-sha --delta test-app/image_v1_signed.bin" + $(Q)$(BINASSEMBLE) internal_flash.dd \ + 0 wolfboot.bin \ + $$(($(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET))) test-app/image_v1_signed.bin \ + $$(($(WOLFBOOT_PARTITION_UPDATE_ADDRESS)-$(ARCH_FLASH_OFFSET))) test-app/image_v$(TEST_UPDATE_VERSION)_signed_diff.bin \ + $$(($(WOLFBOOT_PARTITION_SWAP_ADDRESS)-$(ARCH_FLASH_OFFSET))) erased_sec.dd + test-sim-internal-flash-with-wrong-delta-update: make test-sim-internal-flash-with-update DELTA_UPDATE_OPTIONS="--delta test-app/image_v1_signed.bin" make test-sim-internal-flash-with-update DELTA_UPDATE_OPTIONS="--delta test-app/image_v2_signed.bin" TEST_UPDATE_VERSION=3