@@ -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+
114169int 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
366458finish_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