diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 05e04438b..92adc605b 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -124,6 +124,7 @@ struct flash_area; * the format and size of the raw slot (compressed) * signature */ +#define IMAGE_TLV_COMP_DEC_SIZE 0x73 /* Compressed decrypted image size */ /* * vendor reserved TLVs at xxA0-xxFF, * where xx denotes the upper byte diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 64983b318..5fe0a437c 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -618,12 +618,14 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, goto out; } +LOG_ERR("check hash"); FIH_CALL(boot_fih_memequal, fih_rc, hash, buf, sizeof(hash)); if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } +LOG_ERR("image hash valid = 1"); image_hash_valid = 1; break; } @@ -678,6 +680,8 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, if (rc) { goto out; } +LOG_ERR("check signature"); + #ifndef MCUBOOT_SIGN_PURE FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), buf, len, key_id); @@ -690,6 +694,8 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_protect_tlv_size, buf, len, key_id); #endif +LOG_ERR("image signature valid = %d", valid_signature); + key_id = -1; break; } @@ -764,18 +770,22 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, image_hash_valid = 0; FIH_SET(valid_signature, FIH_FAILURE); +LOG_ERR("check decompression hash"); rc = bootutil_img_hash_decompress(enc_state, image_index, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len); if (rc) { +LOG_ERR("w1"); goto out; } rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SHA, true); if (rc) { +LOG_ERR("w2"); goto out; } if (it.tlv_end > bootutil_max_image_size(fap)) { +LOG_ERR("w3"); rc = -1; goto out; } @@ -783,24 +793,31 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, while (true) { rc = bootutil_tlv_iter_next(&it, &off, &len, &type); if (rc < 0) { +LOG_ERR("w4"); goto out; } else if (rc > 0) { +LOG_ERR("w4"); break; } if (type == IMAGE_TLV_DECOMP_SHA) { /* Verify the image hash. This must always be present. */ if (len != sizeof(hash)) { +LOG_ERR("w5"); rc = -1; goto out; } rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, sizeof(hash)); if (rc) { +LOG_ERR("w6"); goto out; } +LOG_HEXDUMP_ERR(hash, sizeof(hash), "hash"); +LOG_HEXDUMP_ERR(buf, sizeof(hash), "buf"); FIH_CALL(boot_fih_memequal, fih_rc, hash, buf, sizeof(hash)); if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { +LOG_ERR("w7"); FIH_SET(fih_rc, FIH_FAILURE); goto out; } @@ -811,9 +828,12 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, rc = !image_hash_valid; if (rc) { +LOG_ERR("w8"); goto out; } +LOG_ERR("w9"); + #ifdef EXPECTED_SIG_TLV #if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) && defined(EXPECTED_KEY_TLV) rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false); diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 8126fb316..5f2aea98f 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1029,6 +1029,7 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa #else if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { if (!boot_is_compressed_header_valid(hdr, fap, state)) { +LOG_ERR("compressed header not valid"); return false; } } @@ -1229,17 +1230,19 @@ boot_validate_slot(struct boot_loader_state *state, int slot, } #endif if (!boot_is_header_valid(hdr, fap, state)) { +LOG_ERR("header invalid"); fih_rc = FIH_FAILURE; } else { BOOT_HOOK_CALL_FIH(boot_image_check_hook, FIH_BOOT_HOOK_REGULAR, fih_rc, BOOT_CURR_IMG(state), slot); if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) { FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs); +LOG_ERR("boot image check = %d", fih_rc); } } if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) { - flash_area_erase(fap, 0, flash_area_get_size(fap)); +// flash_area_erase(fap, 0, flash_area_get_size(fap)); /* Image is invalid, erase it to prevent further unnecessary * attempts to validate and boot it. */ diff --git a/boot/bootutil/src/tlv.c b/boot/bootutil/src/tlv.c index a763c9685..bb50d4c4d 100644 --- a/boot/bootutil/src/tlv.c +++ b/boot/bootutil/src/tlv.c @@ -43,28 +43,34 @@ bootutil_tlv_iter_begin(struct image_tlv_iter *it, const struct image_header *hd struct image_tlv_info info; if (it == NULL || hdr == NULL || fap == NULL) { +printk("aa1\n"); return -1; } off_ = BOOT_TLV_OFF(hdr); if (LOAD_IMAGE_DATA(hdr, fap, off_, &info, sizeof(info))) { +printk("aa2\n"); return -1; } if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { if (hdr->ih_protect_tlv_size != info.it_tlv_tot) { +printk("aa3 %d vs %d\n", hdr->ih_protect_tlv_size, info.it_tlv_tot); return -1; } if (LOAD_IMAGE_DATA(hdr, fap, off_ + info.it_tlv_tot, &info, sizeof(info))) { +printk("aa4\n"); return -1; } } else if (hdr->ih_protect_tlv_size != 0) { +printk("aa5\n"); return -1; } if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { +printk("aa6\n"); return -1; } diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c index 0fd3d5b12..c3092b1a5 100644 --- a/boot/zephyr/decompression.c +++ b/boot/zephyr/decompression.c @@ -81,20 +81,24 @@ bool boot_is_compressed_header_valid(const struct image_header *hdr, const struc rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_size); if (rc) { +LOG_ERR("decomp size fail"); return false; } if (!boot_u32_safe_add(&size, decompressed_size, hdr->ih_hdr_size)) { +LOG_ERR("add fail"); return false; } rc = boot_size_protected_tlvs(hdr, fap, &protected_tlvs_size); if (rc) { +LOG_ERR("protected tlv size fail"); return false; } if (!boot_u32_safe_add(&size, size, protected_tlvs_size)) { +LOG_ERR("add2 fail"); return false; } @@ -134,6 +138,12 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index bootutil_sha_context sha_ctx; uint8_t flash_erased_value; +uint32_t comp_size = 0; + +rc = bootutil_get_img_decrypted_comp_size(hdr, fap, &comp_size); + +LOG_ERR("teh size: %d", comp_size); + bootutil_sha_init(&sha_ctx); #ifdef MCUBOOT_ENC_IMAGES @@ -207,6 +217,7 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index } modified_hdr.ih_protect_tlv_size = protected_tlv_size; +LOG_HEXDUMP_ERR(&modified_hdr, sizeof(modified_hdr), "hdr"); bootutil_sha_update(&sha_ctx, &modified_hdr, sizeof(modified_hdr)); read_pos = sizeof(modified_hdr); flash_erased_value = flash_area_erased_val(fap); @@ -227,8 +238,13 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index read_pos = 0; //TODO: bug in imgtool - while (read_pos < (hdr->ih_img_size - 1)) { - uint32_t copy_size = (hdr->ih_img_size - 1) - read_pos; +#if 1 + while (read_pos < comp_size) { + uint32_t copy_size = comp_size - read_pos; +#else + while (read_pos < hdr->ih_img_size) { + uint32_t copy_size = hdr->ih_img_size - read_pos; +#endif uint32_t tmp_off = 0; uint8_t offset_zero_check = 0; @@ -270,13 +286,26 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index } //TODO: bug in imgtool - if ((read_pos + tmp_off + chunk_size) >= (hdr->ih_img_size - 1)) { +#if 1 + if ((read_pos + tmp_off + chunk_size) >= comp_size) { +#else + if ((read_pos + tmp_off + chunk_size) >= hdr->ih_img_size) { +#endif last_packet = true; +LOG_HEXDUMP_ERR(&tmp_buf[tmp_off], chunk_size, "input"); +//tmp_buf[tmp_off + chunk_size + 0] = 0xb0; +//tmp_buf[tmp_off + chunk_size + 1] = 0x00; +//chunk_size += 2; } rc = compression_lzma->decompress(NULL, &tmp_buf[tmp_off], chunk_size, last_packet, &offset, &output, &output_size); + +if (last_packet == true) { +LOG_HEXDUMP_ERR(output, output_size, "output"); +} + if (rc) { BOOT_LOG_ERR("Decompression error: %d", rc); rc = BOOT_EBADSTATUS; @@ -376,12 +405,15 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index /* If there are any protected TLVs present, add them after the main decompressed image */ if (modified_hdr.ih_protect_tlv_size > 0) { +LOG_ERR("modified hdr size: %d", modified_hdr.ih_protect_tlv_size); rc = boot_sha_protected_tlvs(hdr, fap, modified_hdr.ih_protect_tlv_size, tmp_buf, tmp_buf_sz, &sha_ctx); } bootutil_sha_finish(&sha_ctx, hash_result); +LOG_ERR("rc = %d", rc); + finish: /* Clean up decompression system */ (void)compression_lzma->deinit(NULL); @@ -461,7 +493,7 @@ static int boot_copy_protected_tlvs(const struct image_header *hdr, } if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE) { + type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { /* Skip these TLVs as they are not needed */ continue; } else { @@ -570,7 +602,7 @@ static int boot_sha_protected_tlvs(const struct image_header *hdr, } if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE) { + type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { /* Skip these TLVs as they are not needed */ continue; } @@ -635,7 +667,7 @@ int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_ } if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE) { + type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { /* Exclude these TLVs as they will be copied to the unprotected area */ tlv_size -= len + sizeof(struct image_tlv); } @@ -687,7 +719,7 @@ int boot_size_unprotected_tlvs(const struct image_header *hdr, const struct flas * original ones */ continue; - } else if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV) { + } else if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV || type == IMAGE_TLV_COMP_DEC_SIZE) { /* Exclude the original unprotected TLVs for signature and hash, the length of the * signature of the compressed data might not be the same size as the signaute of the * decompressed data, as is the case when using ECDSA-P256 @@ -911,6 +943,12 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + +uint32_t comp_size = 0; + +rc = bootutil_get_img_decrypted_comp_size(hdr, fap_src, &comp_size); + + /* Setup decompression system */ #if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { @@ -991,8 +1029,13 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl /* Read in, decompress and write out data */ //TODO: bug in imgtool - while (pos < (hdr->ih_img_size - 1)) { - uint32_t copy_size = (hdr->ih_img_size - 1) - pos; +#if 1 + while (pos < comp_size) { + uint32_t copy_size = comp_size - pos; +#else + while (pos < hdr->ih_img_size) { + uint32_t copy_size = hdr->ih_img_size - pos; +#endif uint32_t tmp_off = 0; if (copy_size > buf_size) { @@ -1032,7 +1075,11 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl } //TODO: bug in imgtool - if ((pos + tmp_off + chunk_size) >= (hdr->ih_img_size - 1)) { +#if 1 + if ((pos + tmp_off + chunk_size) >= comp_size) { +#else + if ((pos + tmp_off + chunk_size) >= hdr->ih_img_size) { +#endif last_packet = true; } @@ -1276,20 +1323,24 @@ int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct fl int32_t rc; if (hdr == NULL || fap == NULL || img_decomp_size == NULL) { +LOG_ERR("qq1"); return BOOT_EBADARGS; } else if (hdr->ih_protect_tlv_size == 0) { +LOG_ERR("qq2"); return BOOT_EBADIMAGE; } rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIZE, true); if (rc) { +LOG_ERR("qq3"); return rc; } rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); if (rc != 0) { +LOG_ERR("qq4"); return -1; } @@ -1306,5 +1357,50 @@ int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct fl return BOOT_EFLASH; } +LOG_ERR("qq5?"); + return 0; +} + +#if 1 +int bootutil_get_img_decrypted_comp_size(const struct image_header *hdr, + const struct flash_area *fap, uint32_t *img_comp_size) +{ + struct image_tlv_iter it; + uint32_t off; + uint16_t len; + int32_t rc; + + if (hdr == NULL || fap == NULL || img_comp_size == NULL) { + return BOOT_EBADARGS; + } else if (hdr->ih_protect_tlv_size == 0) { + return BOOT_EBADIMAGE; + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_COMP_DEC_SIZE, true); + + if (rc) { + return rc; + } + + rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); + + if (rc != 0) { + return -1; + } + + if (len != sizeof(*img_comp_size)) { + BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); + return BOOT_EBADIMAGE; + } + + rc = LOAD_IMAGE_DATA(hdr, fap, off, img_comp_size, len); + + if (rc) { + BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + off, len, fap->fa_id, rc); + return BOOT_EFLASH; + } + return 0; } +#endif