Skip to content

Commit 148712e

Browse files
committed
[nrf noup] zephyr: Add support for encrypted compressed updates
nrf-squash! [nrf noup] zephyr: Add support for ARM thumb filter Adds support to the compressed image update for allowing encrypted images. Also removes the limit of having 1 updateable image Signed-off-by: Jamie McCrae <[email protected]>
1 parent e8cc9b6 commit 148712e

File tree

3 files changed

+131
-8
lines changed

3 files changed

+131
-8
lines changed

boot/bootutil/src/loader.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1612,7 +1612,7 @@ boot_copy_region(struct boot_loader_state *state,
16121612
#else
16131613
(void)state;
16141614
#endif
1615-
#ifdef MCUBOOT_DECOMPRESS_IMAGES
1615+
#if defined(MCUBOOT_DECOMPRESS_IMAGES) && !defined(MCUBOOT_ENC_IMAGES)
16161616
struct image_header *hdr;
16171617
#endif
16181618

boot/zephyr/Kconfig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -975,8 +975,7 @@ config BOOT_BANNER_STRING
975975
config BOOT_DECOMPRESSION_SUPPORT
976976
bool
977977
depends on NRF_COMPRESS && NRF_COMPRESS_DECOMPRESSION && (NRF_COMPRESS_LZMA_VERSION_LZMA1 || NRF_COMPRESS_LZMA_VERSION_LZMA2)
978-
depends on !SINGLE_APPLICATION_SLOT && !BOOT_ENCRYPT_IMAGE && BOOT_UPGRADE_ONLY
979-
depends on UPDATEABLE_IMAGE_NUMBER = 1
978+
depends on !SINGLE_APPLICATION_SLOT && BOOT_UPGRADE_ONLY
980979
default y
981980
help
982981
Hidden symbol which should be selected if a system provided decompression support.

boot/zephyr/decompression.c

Lines changed: 129 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,17 @@ bool boot_is_compressed_header_valid(const struct image_header *hdr, const struc
5858
uint32_t protected_tlvs_size;
5959
uint32_t decompressed_size;
6060

61+
primary_fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT);
62+
63+
if (primary_fa_id == fap->fa_id) {
64+
BOOT_LOG_ERR("Primary slots cannot be compressed, image: %d", BOOT_CURR_IMG(state));
65+
return false;
66+
}
67+
6168
if (BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT) == NULL) {
6269
opened_flash_area = true;
6370
}
6471

65-
primary_fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT);
6672
rc = flash_area_open(primary_fa_id, &BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
6773
assert(rc == 0);
6874

@@ -111,6 +117,55 @@ static bool is_compression_object_valid(struct nrf_compress_implementation *comp
111117
return true;
112118
}
113119

120+
#ifdef MCUBOOT_ENC_IMAGES
121+
int bootutil_get_img_decrypted_comp_size(const struct image_header *hdr,
122+
const struct flash_area *fap, uint32_t *img_comp_size)
123+
{
124+
if (hdr == NULL || fap == NULL || img_comp_size == NULL) {
125+
return BOOT_EBADARGS;
126+
} else if (hdr->ih_protect_tlv_size == 0) {
127+
return BOOT_EBADIMAGE;
128+
}
129+
130+
if (!IS_ENCRYPTED(hdr)) {
131+
/* Update is not encrypted so use size from header */
132+
*img_comp_size = hdr->ih_img_size;
133+
} else {
134+
struct image_tlv_iter it;
135+
uint32_t off;
136+
uint16_t len;
137+
int32_t rc;
138+
139+
rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_COMP_DEC_SIZE, true);
140+
141+
if (rc) {
142+
return rc;
143+
}
144+
145+
rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
146+
147+
if (rc != 0) {
148+
return -1;
149+
}
150+
151+
if (len != sizeof(*img_comp_size)) {
152+
BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len);
153+
return BOOT_EBADIMAGE;
154+
}
155+
156+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_comp_size, len);
157+
158+
if (rc) {
159+
BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d",
160+
off, len, fap->fa_id, rc);
161+
return BOOT_EFLASH;
162+
}
163+
}
164+
165+
return 0;
166+
}
167+
#endif
168+
114169
int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index,
115170
struct image_header *hdr, const struct flash_area *fap,
116171
uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result,
@@ -128,8 +183,28 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index
128183
bootutil_sha_context sha_ctx;
129184
uint8_t flash_erased_value;
130185

186+
#ifdef MCUBOOT_ENC_IMAGES
187+
uint32_t comp_size = 0;
188+
189+
rc = bootutil_get_img_decrypted_comp_size(hdr, fap, &comp_size);
190+
191+
if (rc) {
192+
BOOT_LOG_ERR("Invalid/missing image decrypted compressed size value");
193+
rc = BOOT_EBADIMAGE;
194+
goto finish_end;
195+
}
196+
#endif
197+
131198
bootutil_sha_init(&sha_ctx);
132199

200+
#ifdef MCUBOOT_ENC_IMAGES
201+
/* Encrypted images only exist in the secondary slot */
202+
if (MUST_DECRYPT(fap, image_index, hdr) &&
203+
!boot_enc_valid(enc_state, 1)) {
204+
return -1;
205+
}
206+
#endif
207+
133208
/* Setup decompression system */
134209
#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1
135210
if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) {
@@ -212,8 +287,13 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index
212287
/* Read in compressed data, decompress and add to hash calculation */
213288
read_pos = 0;
214289

290+
#ifdef MCUBOOT_ENC_IMAGES
291+
while (read_pos < comp_size) {
292+
uint32_t copy_size = comp_size - read_pos;
293+
#else
215294
while (read_pos < hdr->ih_img_size) {
216295
uint32_t copy_size = hdr->ih_img_size - read_pos;
296+
#endif
217297
uint32_t tmp_off = 0;
218298
uint8_t offset_zero_check = 0;
219299

@@ -230,6 +310,14 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index
230310
goto finish;
231311
}
232312

313+
#ifdef MCUBOOT_ENC_IMAGES
314+
if (MUST_DECRYPT(fap, image_index, hdr)) {
315+
boot_enc_decrypt(enc_state, 1, read_pos,
316+
copy_size, (read_pos & 0xf),
317+
tmp_buf);
318+
}
319+
#endif
320+
233321
/* Decompress data in chunks, writing it back with a larger write offset of the primary
234322
* slot than read size of the secondary slot
235323
*/
@@ -246,7 +334,11 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index
246334
chunk_size = (copy_size - tmp_off);
247335
}
248336

337+
#ifdef MCUBOOT_ENC_IMAGES
338+
if ((read_pos + tmp_off + chunk_size) >= comp_size) {
339+
#else
249340
if ((read_pos + tmp_off + chunk_size) >= hdr->ih_img_size) {
341+
#endif
250342
last_packet = true;
251343
}
252344

@@ -366,6 +458,9 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index
366458
finish_without_clean:
367459
bootutil_sha_drop(&sha_ctx);
368460

461+
#ifdef MCUBOOT_ENC_IMAGES
462+
finish_end:
463+
#endif
369464
return rc;
370465
}
371466

@@ -437,7 +532,7 @@ static int boot_copy_protected_tlvs(const struct image_header *hdr,
437532
}
438533

439534
if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA ||
440-
type == IMAGE_TLV_DECOMP_SIGNATURE) {
535+
type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) {
441536
/* Skip these TLVs as they are not needed */
442537
continue;
443538
} else {
@@ -546,7 +641,7 @@ static int boot_sha_protected_tlvs(const struct image_header *hdr,
546641
}
547642

548643
if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA ||
549-
type == IMAGE_TLV_DECOMP_SIGNATURE) {
644+
type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) {
550645
/* Skip these TLVs as they are not needed */
551646
continue;
552647
}
@@ -611,7 +706,7 @@ int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_
611706
}
612707

613708
if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA ||
614-
type == IMAGE_TLV_DECOMP_SIGNATURE) {
709+
type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) {
615710
/* Exclude these TLVs as they will be copied to the unprotected area */
616711
tlv_size -= len + sizeof(struct image_tlv);
617712
}
@@ -663,7 +758,7 @@ int boot_size_unprotected_tlvs(const struct image_header *hdr, const struct flas
663758
* original ones
664759
*/
665760
continue;
666-
} else if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV) {
761+
} else if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV || type == IMAGE_TLV_COMP_DEC_SIZE) {
667762
/* Exclude the original unprotected TLVs for signature and hash, the length of the
668763
* signature of the compressed data might not be the same size as the signaute of the
669764
* decompressed data, as is the case when using ECDSA-P256
@@ -885,8 +980,22 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
885980
bool excess_data_buffer_full = false;
886981
#endif
887982

983+
#ifdef MCUBOOT_ENC_IMAGES
984+
uint32_t comp_size = 0;
985+
#endif
986+
888987
hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT);
889988

989+
#ifdef MCUBOOT_ENC_IMAGES
990+
rc = bootutil_get_img_decrypted_comp_size(hdr, fap_src, &comp_size);
991+
992+
if (rc) {
993+
BOOT_LOG_ERR("Invalid/missing image decrypted compressed size value");
994+
rc = BOOT_EBADIMAGE;
995+
goto finish;
996+
}
997+
#endif
998+
890999
/* Setup decompression system */
8911000
#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1
8921001
if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) {
@@ -966,8 +1075,13 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
9661075
}
9671076

9681077
/* Read in, decompress and write out data */
1078+
#ifdef MCUBOOT_ENC_IMAGES
1079+
while (pos < comp_size) {
1080+
uint32_t copy_size = comp_size - pos;
1081+
#else
9691082
while (pos < hdr->ih_img_size) {
9701083
uint32_t copy_size = hdr->ih_img_size - pos;
1084+
#endif
9711085
uint32_t tmp_off = 0;
9721086

9731087
if (copy_size > buf_size) {
@@ -983,6 +1097,12 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
9831097
goto finish;
9841098
}
9851099

1100+
#ifdef MCUBOOT_ENC_IMAGES
1101+
if (IS_ENCRYPTED(hdr)) {
1102+
boot_enc_decrypt(BOOT_CURR_ENC(state), 1, pos, copy_size, (pos & 0xf), buf);
1103+
}
1104+
#endif
1105+
9861106
/* Decompress data in chunks, writing it back with a larger write offset of the primary
9871107
* slot than read size of the secondary slot
9881108
*/
@@ -1000,7 +1120,11 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
10001120
chunk_size = (copy_size - tmp_off);
10011121
}
10021122

1123+
#ifdef MCUBOOT_ENC_IMAGES
1124+
if ((pos + tmp_off + chunk_size) >= comp_size) {
1125+
#else
10031126
if ((pos + tmp_off + chunk_size) >= hdr->ih_img_size) {
1127+
#endif
10041128
last_packet = true;
10051129
}
10061130

0 commit comments

Comments
 (0)