1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Copyright (c) 2016-2020 Linaro LTD
5  * Copyright (c) 2016-2019 JUUL Labs
6  * Copyright (c) 2019-2021 Arm Limited
7  *
8  * Original license:
9  *
10  * Licensed to the Apache Software Foundation (ASF) under one
11  * or more contributor license agreements.  See the NOTICE file
12  * distributed with this work for additional information
13  * regarding copyright ownership.  The ASF licenses this file
14  * to you under the Apache License, Version 2.0 (the
15  * "License"); you may not use this file except in compliance
16  * with the License.  You may obtain a copy of the License at
17  *
18  *  http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing,
21  * software distributed under the License is distributed on an
22  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23  * KIND, either express or implied.  See the License for the
24  * specific language governing permissions and limitations
25  * under the License.
26  */
27 
28 /**
29  * This file provides an interface to the boot loader.  Functions defined in
30  * this file should only be called while the boot loader is running.
31  */
32 
33 #include <stddef.h>
34 #include <stdbool.h>
35 #include <inttypes.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include "bootutil/bootutil.h"
39 #include "bootutil/bootutil_public.h"
40 #include "bootutil/image.h"
41 #include "bootutil_priv.h"
42 #include "swap_priv.h"
43 #include "bootutil/bootutil_log.h"
44 #include "bootutil/security_cnt.h"
45 #include "bootutil/boot_record.h"
46 #include "bootutil/fault_injection_hardening.h"
47 #include "bootutil/ramload.h"
48 #include "bootutil/boot_hooks.h"
49 #include "bootutil/mcuboot_status.h"
50 
51 #ifdef MCUBOOT_ENC_IMAGES
52 #include "bootutil/enc_key.h"
53 #endif
54 
55 #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
56 #include <os/os_malloc.h>
57 #endif
58 
59 #include "mcuboot_config/mcuboot_config.h"
60 
61 BOOT_LOG_MODULE_DECLARE(mcuboot);
62 
63 static struct boot_loader_state boot_data;
64 
65 #if (BOOT_IMAGE_NUMBER > 1)
66 #define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x))
67 #else
68 #define IMAGES_ITER(x)
69 #endif
70 
71 /*
72  * This macro allows some control on the allocation of local variables.
73  * When running natively on a target, we don't want to allocated huge
74  * variables on the stack, so make them global instead. For the simulator
75  * we want to run as many threads as there are tests, and it's safer
76  * to just make those variables stack allocated.
77  */
78 #if !defined(__BOOTSIM__)
79 #define TARGET_STATIC static
80 #else
81 #define TARGET_STATIC
82 #endif
83 
84 #if BOOT_MAX_ALIGN > 1024
85 #define BUF_SZ BOOT_MAX_ALIGN
86 #else
87 #define BUF_SZ 1024
88 #endif
89 
90 static int
boot_read_image_headers(struct boot_loader_state * state,bool require_all,struct boot_status * bs)91 boot_read_image_headers(struct boot_loader_state *state, bool require_all,
92         struct boot_status *bs)
93 {
94     int rc;
95     int i;
96 
97     for (i = 0; i < BOOT_NUM_SLOTS; i++) {
98         rc = BOOT_HOOK_CALL(boot_read_image_header_hook, BOOT_HOOK_REGULAR,
99                             BOOT_CURR_IMG(state), i, boot_img_hdr(state, i));
100         if (rc == BOOT_HOOK_REGULAR)
101         {
102             rc = boot_read_image_header(state, i, boot_img_hdr(state, i), bs);
103         }
104         if (rc != 0) {
105             /* If `require_all` is set, fail on any single fail, otherwise
106              * if at least the first slot's header was read successfully,
107              * then the boot loader can attempt a boot.
108              *
109              * Failure to read any headers is a fatal error.
110              */
111             if (i > 0 && !require_all) {
112                 return 0;
113             } else {
114                 return rc;
115             }
116         }
117     }
118 
119     return 0;
120 }
121 
122 /**
123  * Saves boot status and shared data for current image.
124  *
125  * @param  state        Boot loader status information.
126  * @param  active_slot  Index of the slot will be loaded for current image.
127  *
128  * @return              0 on success; nonzero on failure.
129  */
130 static int
boot_add_shared_data(struct boot_loader_state * state,uint32_t active_slot)131 boot_add_shared_data(struct boot_loader_state *state,
132                      uint32_t active_slot)
133 {
134 #if defined(MCUBOOT_MEASURED_BOOT) || defined(MCUBOOT_DATA_SHARING)
135     int rc;
136 
137 #ifdef MCUBOOT_MEASURED_BOOT
138     rc = boot_save_boot_status(BOOT_CURR_IMG(state),
139                                 boot_img_hdr(state, active_slot),
140                                 BOOT_IMG_AREA(state, active_slot));
141     if (rc != 0) {
142         BOOT_LOG_ERR("Failed to add image data to shared area");
143         return rc;
144     }
145 #endif /* MCUBOOT_MEASURED_BOOT */
146 
147 #ifdef MCUBOOT_DATA_SHARING
148     rc = boot_save_shared_data(boot_img_hdr(state, active_slot),
149                                 BOOT_IMG_AREA(state, active_slot));
150     if (rc != 0) {
151         BOOT_LOG_ERR("Failed to add data to shared memory area.");
152         return rc;
153     }
154 #endif /* MCUBOOT_DATA_SHARING */
155 
156     return 0;
157 
158 #else /* MCUBOOT_MEASURED_BOOT || MCUBOOT_DATA_SHARING */
159     (void) (state);
160     (void) (active_slot);
161 
162     return 0;
163 #endif
164 }
165 
166 /**
167  * Fills rsp to indicate how booting should occur.
168  *
169  * @param  state        Boot loader status information.
170  * @param  rsp          boot_rsp struct to fill.
171  */
172 static void
fill_rsp(struct boot_loader_state * state,struct boot_rsp * rsp)173 fill_rsp(struct boot_loader_state *state, struct boot_rsp *rsp)
174 {
175     uint32_t active_slot;
176 
177 #if (BOOT_IMAGE_NUMBER > 1)
178     /* Always boot from the first enabled image. */
179     BOOT_CURR_IMG(state) = 0;
180     IMAGES_ITER(BOOT_CURR_IMG(state)) {
181         if (!state->img_mask[BOOT_CURR_IMG(state)]) {
182             break;
183         }
184     }
185     /* At least one image must be active, otherwise skip the execution */
186     if (BOOT_CURR_IMG(state) >= BOOT_IMAGE_NUMBER) {
187         return;
188     }
189 #endif
190 
191 #if defined(MCUBOOT_DIRECT_XIP) || defined(MCUBOOT_RAM_LOAD)
192     active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
193 #else
194     active_slot = BOOT_PRIMARY_SLOT;
195 #endif
196 
197     rsp->br_flash_dev_id = flash_area_get_device_id(BOOT_IMG_AREA(state, active_slot));
198     rsp->br_image_off = boot_img_slot_off(state, active_slot);
199     rsp->br_hdr = boot_img_hdr(state, active_slot);
200 }
201 
202 /**
203  * Closes all flash areas.
204  *
205  * @param  state    Boot loader status information.
206  */
207 static void
close_all_flash_areas(struct boot_loader_state * state)208 close_all_flash_areas(struct boot_loader_state *state)
209 {
210     uint32_t slot;
211 
212     IMAGES_ITER(BOOT_CURR_IMG(state)) {
213 #if BOOT_IMAGE_NUMBER > 1
214         if (state->img_mask[BOOT_CURR_IMG(state)]) {
215             continue;
216         }
217 #endif
218 #if MCUBOOT_SWAP_USING_SCRATCH
219         flash_area_close(BOOT_SCRATCH_AREA(state));
220 #endif
221         for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
222             flash_area_close(BOOT_IMG_AREA(state, BOOT_NUM_SLOTS - 1 - slot));
223         }
224     }
225 }
226 
227 #if !defined(MCUBOOT_DIRECT_XIP)
228 /*
229  * Compute the total size of the given image.  Includes the size of
230  * the TLVs.
231  */
232 #if !defined(MCUBOOT_OVERWRITE_ONLY) ||  defined(MCUBOOT_OVERWRITE_ONLY_FAST)
233 static int
boot_read_image_size(struct boot_loader_state * state,int slot,uint32_t * size)234 boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size)
235 {
236     const struct flash_area *fap;
237     struct image_tlv_info info;
238     uint32_t off;
239     uint32_t protect_tlv_size;
240     int area_id;
241     int rc;
242 
243 #if (BOOT_IMAGE_NUMBER == 1)
244     (void)state;
245 #endif
246 
247     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
248     rc = flash_area_open(area_id, &fap);
249     if (rc != 0) {
250         rc = BOOT_EFLASH;
251         goto done;
252     }
253 
254     off = BOOT_TLV_OFF(boot_img_hdr(state, slot));
255 
256     if (flash_area_read(fap, off, &info, sizeof(info))) {
257         rc = BOOT_EFLASH;
258         goto done;
259     }
260 
261     protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size;
262     if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) {
263         if (protect_tlv_size != info.it_tlv_tot) {
264             rc = BOOT_EBADIMAGE;
265             goto done;
266         }
267 
268         if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) {
269             rc = BOOT_EFLASH;
270             goto done;
271         }
272     } else if (protect_tlv_size != 0) {
273         rc = BOOT_EBADIMAGE;
274         goto done;
275     }
276 
277     if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
278         rc = BOOT_EBADIMAGE;
279         goto done;
280     }
281 
282     *size = off + protect_tlv_size + info.it_tlv_tot;
283     rc = 0;
284 
285 done:
286     flash_area_close(fap);
287     return rc;
288 }
289 #endif /* !MCUBOOT_OVERWRITE_ONLY */
290 
291 #if !defined(MCUBOOT_RAM_LOAD)
292 static uint32_t
boot_write_sz(struct boot_loader_state * state)293 boot_write_sz(struct boot_loader_state *state)
294 {
295     uint32_t elem_sz;
296 #if MCUBOOT_SWAP_USING_SCRATCH
297     uint32_t align;
298 #endif
299 
300     /* Figure out what size to write update status update as.  The size depends
301      * on what the minimum write size is for scratch area, active image slot.
302      * We need to use the bigger of those 2 values.
303      */
304     elem_sz = flash_area_align(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
305 #if MCUBOOT_SWAP_USING_SCRATCH
306     align = flash_area_align(BOOT_SCRATCH_AREA(state));
307     if (align > elem_sz) {
308         elem_sz = align;
309     }
310 #endif
311 
312     return elem_sz;
313 }
314 
315 static int
boot_initialize_area(struct boot_loader_state * state,int flash_area)316 boot_initialize_area(struct boot_loader_state *state, int flash_area)
317 {
318     uint32_t num_sectors = BOOT_MAX_IMG_SECTORS;
319     boot_sector_t *out_sectors;
320     uint32_t *out_num_sectors;
321     int rc;
322 
323     num_sectors = BOOT_MAX_IMG_SECTORS;
324 
325     if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) {
326         out_sectors = BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors;
327         out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors;
328     } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
329         out_sectors = BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors;
330         out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors;
331 #if MCUBOOT_SWAP_USING_SCRATCH
332     } else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
333         out_sectors = state->scratch.sectors;
334         out_num_sectors = &state->scratch.num_sectors;
335 #endif
336     } else {
337         return BOOT_EFLASH;
338     }
339 
340 #ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
341     rc = flash_area_get_sectors(flash_area, &num_sectors, out_sectors);
342 #else
343     _Static_assert(sizeof(int) <= sizeof(uint32_t), "Fix needed");
344     rc = flash_area_to_sectors(flash_area, (int *)&num_sectors, out_sectors);
345 #endif /* defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
346     if (rc != 0) {
347         return rc;
348     }
349     *out_num_sectors = num_sectors;
350     return 0;
351 }
352 
353 /**
354  * Determines the sector layout of both image slots and the scratch area.
355  * This information is necessary for calculating the number of bytes to erase
356  * and copy during an image swap.  The information collected during this
357  * function is used to populate the state.
358  */
359 static int
boot_read_sectors(struct boot_loader_state * state)360 boot_read_sectors(struct boot_loader_state *state)
361 {
362     uint8_t image_index;
363     int rc;
364 
365     image_index = BOOT_CURR_IMG(state);
366 
367     rc = boot_initialize_area(state, FLASH_AREA_IMAGE_PRIMARY(image_index));
368     if (rc != 0) {
369         return BOOT_EFLASH;
370     }
371 
372     rc = boot_initialize_area(state, FLASH_AREA_IMAGE_SECONDARY(image_index));
373     if (rc != 0) {
374         /* We need to differentiate from the primary image issue */
375         return BOOT_EFLASH_SEC;
376     }
377 
378 #if MCUBOOT_SWAP_USING_SCRATCH
379     rc = boot_initialize_area(state, FLASH_AREA_IMAGE_SCRATCH);
380     if (rc != 0) {
381         return BOOT_EFLASH;
382     }
383 #endif
384 
385     BOOT_WRITE_SZ(state) = boot_write_sz(state);
386 
387     return 0;
388 }
389 
390 void
boot_status_reset(struct boot_status * bs)391 boot_status_reset(struct boot_status *bs)
392 {
393 #ifdef MCUBOOT_ENC_IMAGES
394     memset(&bs->enckey, 0xff, BOOT_NUM_SLOTS * BOOT_ENC_KEY_ALIGN_SIZE);
395 #if MCUBOOT_SWAP_SAVE_ENCTLV
396     memset(&bs->enctlv, 0xff, BOOT_NUM_SLOTS * BOOT_ENC_TLV_ALIGN_SIZE);
397 #endif
398 #endif /* MCUBOOT_ENC_IMAGES */
399 
400     bs->use_scratch = 0;
401     bs->swap_size = 0;
402     bs->source = 0;
403 
404     bs->op = BOOT_STATUS_OP_MOVE;
405     bs->idx = BOOT_STATUS_IDX_0;
406     bs->state = BOOT_STATUS_STATE_0;
407     bs->swap_type = BOOT_SWAP_TYPE_NONE;
408 }
409 
410 bool
boot_status_is_reset(const struct boot_status * bs)411 boot_status_is_reset(const struct boot_status *bs)
412 {
413     return (bs->op == BOOT_STATUS_OP_MOVE &&
414             bs->idx == BOOT_STATUS_IDX_0 &&
415             bs->state == BOOT_STATUS_STATE_0);
416 }
417 
418 /**
419  * Writes the supplied boot status to the flash file system.  The boot status
420  * contains the current state of an in-progress image copy operation.
421  *
422  * @param bs                    The boot status to write.
423  *
424  * @return                      0 on success; nonzero on failure.
425  */
426 int
boot_write_status(const struct boot_loader_state * state,struct boot_status * bs)427 boot_write_status(const struct boot_loader_state *state, struct boot_status *bs)
428 {
429     const struct flash_area *fap;
430     uint32_t off;
431     int area_id;
432     int rc = 0;
433     uint8_t buf[BOOT_MAX_ALIGN];
434     uint32_t align;
435     uint8_t erased_val;
436 
437     /* NOTE: The first sector copied (that is the last sector on slot) contains
438      *       the trailer. Since in the last step the primary slot is erased, the
439      *       first two status writes go to the scratch which will be copied to
440      *       the primary slot!
441      */
442 
443 #if MCUBOOT_SWAP_USING_SCRATCH
444     if (bs->use_scratch) {
445         /* Write to scratch. */
446         area_id = FLASH_AREA_IMAGE_SCRATCH;
447     } else {
448 #endif
449         /* Write to the primary slot. */
450         area_id = FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state));
451 #if MCUBOOT_SWAP_USING_SCRATCH
452     }
453 #endif
454 
455     rc = flash_area_open(area_id, &fap);
456     if (rc != 0) {
457         return BOOT_EFLASH;
458     }
459 
460     off = boot_status_off(fap) +
461           boot_status_internal_off(bs, BOOT_WRITE_SZ(state));
462     align = flash_area_align(fap);
463     erased_val = flash_area_erased_val(fap);
464     memset(buf, erased_val, BOOT_MAX_ALIGN);
465     buf[0] = bs->state;
466 
467     rc = flash_area_write(fap, off, buf, align);
468     if (rc != 0) {
469         rc = BOOT_EFLASH;
470     }
471 
472     flash_area_close(fap);
473 
474     return rc;
475 }
476 #endif /* !MCUBOOT_RAM_LOAD */
477 #endif /* !MCUBOOT_DIRECT_XIP */
478 
479 /*
480  * Validate image hash/signature and optionally the security counter in a slot.
481  */
482 static fih_ret
boot_image_check(struct boot_loader_state * state,struct image_header * hdr,const struct flash_area * fap,struct boot_status * bs)483 boot_image_check(struct boot_loader_state *state, struct image_header *hdr,
484                  const struct flash_area *fap, struct boot_status *bs)
485 {
486     TARGET_STATIC uint8_t tmpbuf[BOOT_TMPBUF_SZ];
487     uint8_t image_index;
488     int rc;
489     FIH_DECLARE(fih_rc, FIH_FAILURE);
490 
491 #if (BOOT_IMAGE_NUMBER == 1)
492     (void)state;
493 #endif
494 
495     (void)bs;
496     (void)rc;
497 
498     image_index = BOOT_CURR_IMG(state);
499 
500 /* In the case of ram loading the image has already been decrypted as it is
501  * decrypted when copied in ram */
502 #if defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_RAM_LOAD)
503     if (MUST_DECRYPT(fap, image_index, hdr)) {
504         rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs);
505         if (rc < 0) {
506             FIH_RET(fih_rc);
507         }
508         if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs)) {
509             FIH_RET(fih_rc);
510         }
511     }
512 #endif
513 
514     FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index,
515              hdr, fap, tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, NULL);
516 
517     FIH_RET(fih_rc);
518 }
519 
520 #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
521 static fih_ret
split_image_check(struct image_header * app_hdr,const struct flash_area * app_fap,struct image_header * loader_hdr,const struct flash_area * loader_fap)522 split_image_check(struct image_header *app_hdr,
523                   const struct flash_area *app_fap,
524                   struct image_header *loader_hdr,
525                   const struct flash_area *loader_fap)
526 {
527     static void *tmpbuf;
528     uint8_t loader_hash[32];
529     FIH_DECLARE(fih_rc, FIH_FAILURE);
530 
531     if (!tmpbuf) {
532         tmpbuf = malloc(BOOT_TMPBUF_SZ);
533         if (!tmpbuf) {
534             goto out;
535         }
536     }
537 
538     FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, loader_hdr, loader_fap,
539              tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, loader_hash);
540     if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
541         FIH_RET(fih_rc);
542     }
543 
544     FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, app_hdr, app_fap,
545              tmpbuf, BOOT_TMPBUF_SZ, loader_hash, 32, NULL);
546 
547 out:
548     FIH_RET(fih_rc);
549 }
550 #endif /* !MCUBOOT_DIRECT_XIP && !MCUBOOT_RAM_LOAD */
551 
552 /*
553  * Check that this is a valid header.  Valid means that the magic is
554  * correct, and that the sizes/offsets are "sane".  Sane means that
555  * there is no overflow on the arithmetic, and that the result fits
556  * within the flash area we are in.
557  */
558 static bool
boot_is_header_valid(const struct image_header * hdr,const struct flash_area * fap)559 boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fap)
560 {
561     uint32_t size;
562 
563     if (hdr->ih_magic != IMAGE_MAGIC) {
564         return false;
565     }
566 
567     if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size)) {
568         return false;
569     }
570 
571     if (size >= flash_area_get_size(fap)) {
572         return false;
573     }
574 
575     return true;
576 }
577 
578 /*
579  * Check that a memory area consists of a given value.
580  */
581 static inline bool
boot_data_is_set_to(uint8_t val,void * data,size_t len)582 boot_data_is_set_to(uint8_t val, void *data, size_t len)
583 {
584     uint8_t i;
585     uint8_t *p = (uint8_t *)data;
586     for (i = 0; i < len; i++) {
587         if (val != p[i]) {
588             return false;
589         }
590     }
591     return true;
592 }
593 
594 static int
boot_check_header_erased(struct boot_loader_state * state,int slot)595 boot_check_header_erased(struct boot_loader_state *state, int slot)
596 {
597     const struct flash_area *fap;
598     struct image_header *hdr;
599     uint8_t erased_val;
600     int area_id;
601     int rc;
602 
603     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
604     rc = flash_area_open(area_id, &fap);
605     if (rc != 0) {
606         return -1;
607     }
608 
609     erased_val = flash_area_erased_val(fap);
610     flash_area_close(fap);
611 
612     hdr = boot_img_hdr(state, slot);
613     if (!boot_data_is_set_to(erased_val, &hdr->ih_magic, sizeof(hdr->ih_magic))) {
614         return -1;
615     }
616 
617     return 0;
618 }
619 
620 #if (BOOT_IMAGE_NUMBER > 1) || \
621     defined(MCUBOOT_DIRECT_XIP) || \
622     defined(MCUBOOT_RAM_LOAD) || \
623     defined(MCUBOOT_DOWNGRADE_PREVENTION)
624 /**
625  * Compare image version numbers
626  *
627  * By default, the comparison does not take build number into account.
628  * Enable MCUBOOT_VERSION_CMP_USE_BUILD_NUMBER to take the build number into account.
629  *
630  * @param ver1           Pointer to the first image version to compare.
631  * @param ver2           Pointer to the second image version to compare.
632  *
633  * @retval -1           If ver1 is less than ver2.
634  * @retval 0            If the image version numbers are equal.
635  * @retval 1            If ver1 is greater than ver2.
636  */
637 static int
boot_version_cmp(const struct image_version * ver1,const struct image_version * ver2)638 boot_version_cmp(const struct image_version *ver1,
639                  const struct image_version *ver2)
640 {
641     if (ver1->iv_major > ver2->iv_major) {
642         return 1;
643     }
644     if (ver1->iv_major < ver2->iv_major) {
645         return -1;
646     }
647     /* The major version numbers are equal, continue comparison. */
648     if (ver1->iv_minor > ver2->iv_minor) {
649         return 1;
650     }
651     if (ver1->iv_minor < ver2->iv_minor) {
652         return -1;
653     }
654     /* The minor version numbers are equal, continue comparison. */
655     if (ver1->iv_revision > ver2->iv_revision) {
656         return 1;
657     }
658     if (ver1->iv_revision < ver2->iv_revision) {
659         return -1;
660     }
661 
662 #if defined(MCUBOOT_VERSION_CMP_USE_BUILD_NUMBER)
663     /* The revisions are equal, continue comparison. */
664     if (ver1->iv_build_num > ver2->iv_build_num) {
665         return 1;
666     }
667     if (ver1->iv_build_num < ver2->iv_build_num) {
668         return -1;
669     }
670 #endif
671 
672     return 0;
673 }
674 #endif
675 
676 #if defined(MCUBOOT_DIRECT_XIP)
677 /**
678  * Check if image in slot has been set with specific ROM address to run from
679  * and whether the slot starts at that address.
680  *
681  * @returns 0 if IMAGE_F_ROM_FIXED flag is not set;
682  *          0 if IMAGE_F_ROM_FIXED flag is set and ROM address specified in
683  *            header matches the slot address;
684  *          1 if IMF_F_ROM_FIXED flag is set but ROM address specified in header
685  *          does not match the slot address.
686  */
687 static bool
boot_rom_address_check(struct boot_loader_state * state)688 boot_rom_address_check(struct boot_loader_state *state)
689 {
690     uint32_t active_slot;
691     const struct image_header *hdr;
692     uint32_t f_off;
693 
694     active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
695     hdr = boot_img_hdr(state, active_slot);
696     f_off = boot_img_slot_off(state, active_slot);
697 
698     if (hdr->ih_flags & IMAGE_F_ROM_FIXED && hdr->ih_load_addr != f_off) {
699         BOOT_LOG_WRN("Image in %s slot at 0x%x has been built for offset 0x%x"\
700                      ", skipping",
701                      active_slot == 0 ? "primary" : "secondary", f_off,
702                      hdr->ih_load_addr);
703 
704         /* If there is address mismatch, the image is not bootable from this
705          * slot.
706          */
707         return 1;
708     }
709     return 0;
710 }
711 #endif
712 
713 /*
714  * Check that there is a valid image in a slot
715  *
716  * @returns
717  *         FIH_SUCCESS                      if image was successfully validated
718  *         FIH_NO_BOOTABLE_IMAGE            if no bootloable image was found
719  *         FIH_FAILURE                      on any errors
720  */
721 static fih_ret
boot_validate_slot(struct boot_loader_state * state,int slot,struct boot_status * bs)722 boot_validate_slot(struct boot_loader_state *state, int slot,
723                    struct boot_status *bs)
724 {
725     const struct flash_area *fap;
726     struct image_header *hdr;
727     int area_id;
728     FIH_DECLARE(fih_rc, FIH_FAILURE);
729     int rc;
730 
731     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
732     rc = flash_area_open(area_id, &fap);
733     if (rc != 0) {
734         FIH_RET(fih_rc);
735     }
736 
737     hdr = boot_img_hdr(state, slot);
738     if (boot_check_header_erased(state, slot) == 0 ||
739         (hdr->ih_flags & IMAGE_F_NON_BOOTABLE)) {
740 
741 #if defined(MCUBOOT_SWAP_USING_SCRATCH) || defined(MCUBOOT_SWAP_USING_MOVE)
742         /*
743          * This fixes an issue where an image might be erased, but a trailer
744          * be left behind. It can happen if the image is in the secondary slot
745          * and did not pass validation, in which case the whole slot is erased.
746          * If during the erase operation, a reset occurs, parts of the slot
747          * might have been erased while some did not. The concerning part is
748          * the trailer because it might disable a new image from being loaded
749          * through mcumgr; so we just get rid of the trailer here, if the header
750          * is erased.
751          */
752         if (slot != BOOT_PRIMARY_SLOT) {
753             swap_erase_trailer_sectors(state, fap);
754         }
755 #endif
756 
757         /* No bootable image in slot; continue booting from the primary slot. */
758         fih_rc = FIH_NO_BOOTABLE_IMAGE;
759         goto out;
760     }
761 
762 #if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION)
763     if (slot != BOOT_PRIMARY_SLOT) {
764         /* Check if version of secondary slot is sufficient */
765         rc = boot_version_cmp(
766                 &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver,
767                 &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver);
768         if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) {
769             BOOT_LOG_ERR("insufficient version in secondary slot");
770             flash_area_erase(fap, 0, flash_area_get_size(fap));
771             /* Image in the secondary slot does not satisfy version requirement.
772              * Erase the image and continue booting from the primary slot.
773              */
774             fih_rc = FIH_NO_BOOTABLE_IMAGE;
775             goto out;
776         }
777     }
778 #endif
779     BOOT_HOOK_CALL_FIH(boot_image_check_hook, FIH_BOOT_HOOK_REGULAR,
780                        fih_rc, BOOT_CURR_IMG(state), slot);
781     if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
782     {
783         FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs);
784     }
785     if (!boot_is_header_valid(hdr, fap) || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
786         if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) {
787             flash_area_erase(fap, 0, flash_area_get_size(fap));
788             /* Image is invalid, erase it to prevent further unnecessary
789              * attempts to validate and boot it.
790              */
791         }
792 #if !defined(__BOOTSIM__)
793         BOOT_LOG_ERR("Image in the %s slot is not valid!",
794                      (slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary");
795 #endif
796         fih_rc = FIH_NO_BOOTABLE_IMAGE;
797         goto out;
798     }
799 
800 #if MCUBOOT_IMAGE_NUMBER > 1 && !defined(MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_VERIFY_IMG_ADDRESS)
801     /* Verify that the image in the secondary slot has a reset address
802      * located in the primary slot. This is done to avoid users incorrectly
803      * overwriting an application written to the incorrect slot.
804      * This feature is only supported by ARM platforms.
805      */
806     if (area_id == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
807         const struct flash_area *pri_fa = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT);
808         struct image_header *secondary_hdr = boot_img_hdr(state, slot);
809         uint32_t reset_value = 0;
810         uint32_t reset_addr = secondary_hdr->ih_hdr_size + sizeof(reset_value);
811 
812         rc = flash_area_read(fap, reset_addr, &reset_value, sizeof(reset_value));
813         if (rc != 0) {
814             fih_rc = FIH_NO_BOOTABLE_IMAGE;
815             goto out;
816         }
817 
818         if (reset_value < pri_fa->fa_off || reset_value> (pri_fa->fa_off + pri_fa->fa_size)) {
819             BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot");
820             BOOT_LOG_ERR("Erasing image from secondary slot");
821 
822             /* The vector table in the image located in the secondary
823              * slot does not target the primary slot. This might
824              * indicate that the image was loaded to the wrong slot.
825              *
826              * Erase the image and continue booting from the primary slot.
827              */
828             flash_area_erase(fap, 0, fap->fa_size);
829             fih_rc = FIH_NO_BOOTABLE_IMAGE;
830             goto out;
831         }
832     }
833 #endif
834 
835 out:
836     flash_area_close(fap);
837 
838     FIH_RET(fih_rc);
839 }
840 
841 #ifdef MCUBOOT_HW_ROLLBACK_PROT
842 /**
843  * Updates the stored security counter value with the image's security counter
844  * value which resides in the given slot, only if it's greater than the stored
845  * value.
846  *
847  * @param image_index   Index of the image to determine which security
848  *                      counter to update.
849  * @param slot          Slot number of the image.
850  * @param hdr           Pointer to the image header structure of the image
851  *                      that is currently stored in the given slot.
852  *
853  * @return              0 on success; nonzero on failure.
854  */
855 static int
boot_update_security_counter(uint8_t image_index,int slot,struct image_header * hdr)856 boot_update_security_counter(uint8_t image_index, int slot,
857                              struct image_header *hdr)
858 {
859     const struct flash_area *fap = NULL;
860     uint32_t img_security_cnt;
861     int rc;
862 
863     rc = flash_area_open(flash_area_id_from_multi_image_slot(image_index, slot),
864                          &fap);
865     if (rc != 0) {
866         rc = BOOT_EFLASH;
867         goto done;
868     }
869 
870     rc = bootutil_get_img_security_cnt(hdr, fap, &img_security_cnt);
871     if (rc != 0) {
872         goto done;
873     }
874 
875     rc = boot_nv_security_counter_update(image_index, img_security_cnt);
876     if (rc != 0) {
877         goto done;
878     }
879 
880 done:
881     flash_area_close(fap);
882     return rc;
883 }
884 #endif /* MCUBOOT_HW_ROLLBACK_PROT */
885 
886 #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
887 /**
888  * Determines which swap operation to perform, if any.  If it is determined
889  * that a swap operation is required, the image in the secondary slot is checked
890  * for validity.  If the image in the secondary slot is invalid, it is erased,
891  * and a swap type of "none" is indicated.
892  *
893  * @return                      The type of swap to perform (BOOT_SWAP_TYPE...)
894  */
895 static int
boot_validated_swap_type(struct boot_loader_state * state,struct boot_status * bs)896 boot_validated_swap_type(struct boot_loader_state *state,
897                          struct boot_status *bs)
898 {
899     int swap_type;
900     FIH_DECLARE(fih_rc, FIH_FAILURE);
901 
902     swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state));
903     if (BOOT_IS_UPGRADE(swap_type)) {
904         /* Boot loader wants to switch to the secondary slot.
905          * Ensure image is valid.
906          */
907         FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_SECONDARY_SLOT, bs);
908         if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
909             if (FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) {
910                 swap_type = BOOT_SWAP_TYPE_NONE;
911             } else {
912                 swap_type = BOOT_SWAP_TYPE_FAIL;
913             }
914         }
915     }
916 
917     return swap_type;
918 }
919 #endif
920 
921 /**
922  * Erases a region of flash.
923  *
924  * @param flash_area           The flash_area containing the region to erase.
925  * @param off                   The offset within the flash area to start the
926  *                                  erase.
927  * @param sz                    The number of bytes to erase.
928  *
929  * @return                      0 on success; nonzero on failure.
930  */
931 int
boot_erase_region(const struct flash_area * fap,uint32_t off,uint32_t sz)932 boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz)
933 {
934     return flash_area_erase(fap, off, sz);
935 }
936 
937 #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
938 
939 #if defined(MCUBOOT_ENC_IMAGES) || defined(MCUBOOT_SWAP_SAVE_ENCTLV)
940 /* Replacement for memset(p, 0, sizeof(*p) that does not get
941  * optimized out.
942  */
like_mbedtls_zeroize(void * p,size_t n)943 static void like_mbedtls_zeroize(void *p, size_t n)
944 {
945     volatile unsigned char *v = (unsigned char *)p;
946 
947     for (size_t i = 0; i < n; i++) {
948         v[i] = 0;
949     }
950 }
951 #endif
952 
953 /**
954  * Copies the contents of one flash region to another.  You must erase the
955  * destination region prior to calling this function.
956  *
957  * @param flash_area_id_src     The ID of the source flash area.
958  * @param flash_area_id_dst     The ID of the destination flash area.
959  * @param off_src               The offset within the source flash area to
960  *                                  copy from.
961  * @param off_dst               The offset within the destination flash area to
962  *                                  copy to.
963  * @param sz                    The number of bytes to copy.
964  *
965  * @return                      0 on success; nonzero on failure.
966  */
967 int
boot_copy_region(struct boot_loader_state * state,const struct flash_area * fap_src,const struct flash_area * fap_dst,uint32_t off_src,uint32_t off_dst,uint32_t sz)968 boot_copy_region(struct boot_loader_state *state,
969                  const struct flash_area *fap_src,
970                  const struct flash_area *fap_dst,
971                  uint32_t off_src, uint32_t off_dst, uint32_t sz)
972 {
973     uint32_t bytes_copied;
974     int chunk_sz;
975     int rc;
976 #ifdef MCUBOOT_ENC_IMAGES
977     uint32_t off;
978     uint32_t tlv_off;
979     size_t blk_off;
980     struct image_header *hdr;
981     uint16_t idx;
982     uint32_t blk_sz;
983     uint8_t image_index;
984 #endif
985 
986     TARGET_STATIC uint8_t buf[BUF_SZ] __attribute__((aligned(4)));
987 
988 #if !defined(MCUBOOT_ENC_IMAGES)
989     (void)state;
990 #endif
991 
992     bytes_copied = 0;
993     while (bytes_copied < sz) {
994         if (sz - bytes_copied > sizeof buf) {
995             chunk_sz = sizeof buf;
996         } else {
997             chunk_sz = sz - bytes_copied;
998         }
999 
1000         rc = flash_area_read(fap_src, off_src + bytes_copied, buf, chunk_sz);
1001         if (rc != 0) {
1002             return BOOT_EFLASH;
1003         }
1004 
1005 #ifdef MCUBOOT_ENC_IMAGES
1006         image_index = BOOT_CURR_IMG(state);
1007         if ((flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_SECONDARY(image_index) ||
1008              flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) &&
1009             !(flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_SECONDARY(image_index) &&
1010               flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index))) {
1011             /* assume the secondary slot as src, needs decryption */
1012             hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT);
1013 #if !defined(MCUBOOT_SWAP_USING_MOVE)
1014             off = off_src;
1015             if (flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) {
1016                 /* might need encryption (metadata from the primary slot) */
1017                 hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT);
1018                 off = off_dst;
1019             }
1020 #else
1021             off = off_dst;
1022             if (flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_SECONDARY(image_index)) {
1023                 hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT);
1024             }
1025 #endif
1026             if (IS_ENCRYPTED(hdr)) {
1027                 uint32_t abs_off = off + bytes_copied;
1028                 if (abs_off < hdr->ih_hdr_size) {
1029                     /* do not decrypt header */
1030                     if (abs_off + chunk_sz > hdr->ih_hdr_size) {
1031                         /* The lower part of the chunk contains header data */
1032                         blk_off = 0;
1033                         blk_sz = chunk_sz - (hdr->ih_hdr_size - abs_off);
1034                         idx = hdr->ih_hdr_size  - abs_off;
1035                     } else {
1036                         /* The chunk contains exclusively header data */
1037                         blk_sz = 0; /* nothing to decrypt */
1038                     }
1039                 } else {
1040                     idx = 0;
1041                     blk_sz = chunk_sz;
1042                     blk_off = (abs_off - hdr->ih_hdr_size) & 0xf;
1043                 }
1044 
1045                 if (blk_sz > 0)
1046                 {
1047                     tlv_off = BOOT_TLV_OFF(hdr);
1048                     if (abs_off + chunk_sz > tlv_off) {
1049                         /* do not decrypt TLVs */
1050                         if (abs_off >= tlv_off) {
1051                             blk_sz = 0;
1052                         } else {
1053                             blk_sz = tlv_off - abs_off;
1054                         }
1055                     }
1056                     boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
1057                             (abs_off + idx) - hdr->ih_hdr_size, blk_sz,
1058                             blk_off, &buf[idx]);
1059                 }
1060             }
1061         }
1062 #endif
1063 
1064         rc = flash_area_write(fap_dst, off_dst + bytes_copied, buf, chunk_sz);
1065         if (rc != 0) {
1066             return BOOT_EFLASH;
1067         }
1068 
1069         bytes_copied += chunk_sz;
1070 
1071         MCUBOOT_WATCHDOG_FEED();
1072     }
1073 
1074     return 0;
1075 }
1076 
1077 /**
1078  * Overwrite primary slot with the image contained in the secondary slot.
1079  * If a prior copy operation was interrupted by a system reset, this function
1080  * redos the copy.
1081  *
1082  * @param bs                    The current boot status.  This function reads
1083  *                                  this struct to determine if it is resuming
1084  *                                  an interrupted swap operation.  This
1085  *                                  function writes the updated status to this
1086  *                                  function on return.
1087  *
1088  * @return                      0 on success; nonzero on failure.
1089  */
1090 #if defined(MCUBOOT_OVERWRITE_ONLY) || defined(MCUBOOT_BOOTSTRAP)
1091 static int
boot_copy_image(struct boot_loader_state * state,struct boot_status * bs)1092 boot_copy_image(struct boot_loader_state *state, struct boot_status *bs)
1093 {
1094     size_t sect_count;
1095     size_t sect;
1096     int rc;
1097     size_t size;
1098     size_t this_size;
1099     size_t last_sector;
1100     const struct flash_area *fap_primary_slot;
1101     const struct flash_area *fap_secondary_slot;
1102     uint8_t image_index;
1103 
1104 #if defined(MCUBOOT_OVERWRITE_ONLY_FAST)
1105     uint32_t sector;
1106     uint32_t trailer_sz;
1107     uint32_t off;
1108     uint32_t sz;
1109 #endif
1110 
1111     (void)bs;
1112 
1113 #if defined(MCUBOOT_OVERWRITE_ONLY_FAST)
1114     uint32_t src_size = 0;
1115     rc = boot_read_image_size(state, BOOT_SECONDARY_SLOT, &src_size);
1116     assert(rc == 0);
1117 #endif
1118 
1119     BOOT_LOG_INF("Image upgrade secondary slot -> primary slot");
1120     BOOT_LOG_INF("Erasing the primary slot");
1121 
1122     image_index = BOOT_CURR_IMG(state);
1123 
1124     rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index),
1125             &fap_primary_slot);
1126     assert (rc == 0);
1127 
1128     rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index),
1129             &fap_secondary_slot);
1130     assert (rc == 0);
1131 
1132     sect_count = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT);
1133     for (sect = 0, size = 0; sect < sect_count; sect++) {
1134         this_size = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, sect);
1135         rc = boot_erase_region(fap_primary_slot, size, this_size);
1136         assert(rc == 0);
1137 
1138 #if defined(MCUBOOT_OVERWRITE_ONLY_FAST)
1139         if ((size + this_size) >= src_size) {
1140             size += src_size - size;
1141             size += BOOT_WRITE_SZ(state) - (size % BOOT_WRITE_SZ(state));
1142             break;
1143         }
1144 #endif
1145 
1146         size += this_size;
1147     }
1148 
1149 #if defined(MCUBOOT_OVERWRITE_ONLY_FAST)
1150     trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
1151     sector = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - 1;
1152     sz = 0;
1153     do {
1154         sz += boot_img_sector_size(state, BOOT_PRIMARY_SLOT, sector);
1155         off = boot_img_sector_off(state, BOOT_PRIMARY_SLOT, sector);
1156         sector--;
1157     } while (sz < trailer_sz);
1158 
1159     rc = boot_erase_region(fap_primary_slot, off, sz);
1160     assert(rc == 0);
1161 #endif
1162 
1163 #ifdef MCUBOOT_ENC_IMAGES
1164     if (IS_ENCRYPTED(boot_img_hdr(state, BOOT_SECONDARY_SLOT))) {
1165         rc = boot_enc_load(BOOT_CURR_ENC(state), image_index,
1166                 boot_img_hdr(state, BOOT_SECONDARY_SLOT),
1167                 fap_secondary_slot, bs);
1168 
1169         if (rc < 0) {
1170             return BOOT_EBADIMAGE;
1171         }
1172         if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs)) {
1173             return BOOT_EBADIMAGE;
1174         }
1175     }
1176 #endif
1177 
1178     BOOT_LOG_INF("Copying the secondary slot to the primary slot: 0x%zx bytes",
1179                  size);
1180     rc = boot_copy_region(state, fap_secondary_slot, fap_primary_slot, 0, 0, size);
1181     if (rc != 0) {
1182         return rc;
1183     }
1184 
1185 #if defined(MCUBOOT_OVERWRITE_ONLY_FAST)
1186     rc = boot_write_magic(fap_primary_slot);
1187     if (rc != 0) {
1188         return rc;
1189     }
1190 #endif
1191 
1192     rc = BOOT_HOOK_CALL(boot_copy_region_post_hook, 0, BOOT_CURR_IMG(state),
1193                         BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT), size);
1194     if (rc != 0) {
1195         return rc;
1196     }
1197 
1198 #ifdef MCUBOOT_HW_ROLLBACK_PROT
1199     /* Update the stored security counter with the new image's security counter
1200      * value. Both slots hold the new image at this point, but the secondary
1201      * slot's image header must be passed since the image headers in the
1202      * boot_data structure have not been updated yet.
1203      */
1204     rc = boot_update_security_counter(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT,
1205                                 boot_img_hdr(state, BOOT_SECONDARY_SLOT));
1206     if (rc != 0) {
1207         BOOT_LOG_ERR("Security counter update failed after image upgrade.");
1208         return rc;
1209     }
1210 #endif /* MCUBOOT_HW_ROLLBACK_PROT */
1211 
1212     /*
1213      * Erases header and trailer. The trailer is erased because when a new
1214      * image is written without a trailer as is the case when using newt, the
1215      * trailer that was left might trigger a new upgrade.
1216      */
1217     BOOT_LOG_DBG("erasing secondary header");
1218     rc = boot_erase_region(fap_secondary_slot,
1219                            boot_img_sector_off(state, BOOT_SECONDARY_SLOT, 0),
1220                            boot_img_sector_size(state, BOOT_SECONDARY_SLOT, 0));
1221     assert(rc == 0);
1222     last_sector = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) - 1;
1223     BOOT_LOG_DBG("erasing secondary trailer");
1224     rc = boot_erase_region(fap_secondary_slot,
1225                            boot_img_sector_off(state, BOOT_SECONDARY_SLOT,
1226                                last_sector),
1227                            boot_img_sector_size(state, BOOT_SECONDARY_SLOT,
1228                                last_sector));
1229     assert(rc == 0);
1230 
1231     flash_area_close(fap_primary_slot);
1232     flash_area_close(fap_secondary_slot);
1233 
1234     /* TODO: Perhaps verify the primary slot's signature again? */
1235 
1236     return 0;
1237 }
1238 #endif
1239 
1240 #if !defined(MCUBOOT_OVERWRITE_ONLY)
1241 /**
1242  * Swaps the two images in flash.  If a prior copy operation was interrupted
1243  * by a system reset, this function completes that operation.
1244  *
1245  * @param bs                    The current boot status.  This function reads
1246  *                                  this struct to determine if it is resuming
1247  *                                  an interrupted swap operation.  This
1248  *                                  function writes the updated status to this
1249  *                                  function on return.
1250  *
1251  * @return                      0 on success; nonzero on failure.
1252  */
1253 static int
boot_swap_image(struct boot_loader_state * state,struct boot_status * bs)1254 boot_swap_image(struct boot_loader_state *state, struct boot_status *bs)
1255 {
1256     struct image_header *hdr;
1257     const struct flash_area *fap;
1258 #ifdef MCUBOOT_ENC_IMAGES
1259     uint8_t slot;
1260     uint8_t i;
1261 #endif
1262     uint32_t size;
1263     uint32_t copy_size;
1264     uint8_t image_index;
1265     int rc;
1266 
1267     /* FIXME: just do this if asked by user? */
1268 
1269     size = copy_size = 0;
1270     image_index = BOOT_CURR_IMG(state);
1271 
1272     if (boot_status_is_reset(bs)) {
1273         /*
1274          * No swap ever happened, so need to find the largest image which
1275          * will be used to determine the amount of sectors to swap.
1276          */
1277         hdr = boot_img_hdr(state, BOOT_PRIMARY_SLOT);
1278         if (hdr->ih_magic == IMAGE_MAGIC) {
1279             rc = boot_read_image_size(state, BOOT_PRIMARY_SLOT, &copy_size);
1280             assert(rc == 0);
1281         }
1282 
1283 #ifdef MCUBOOT_ENC_IMAGES
1284         if (IS_ENCRYPTED(hdr)) {
1285             fap = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT);
1286             rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs);
1287             assert(rc >= 0);
1288 
1289             if (rc == 0) {
1290                 rc = boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs);
1291                 assert(rc == 0);
1292             } else {
1293                 rc = 0;
1294             }
1295         } else {
1296             memset(bs->enckey[0], 0xff, BOOT_ENC_KEY_ALIGN_SIZE);
1297         }
1298 #endif
1299 
1300         hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT);
1301         if (hdr->ih_magic == IMAGE_MAGIC) {
1302             rc = boot_read_image_size(state, BOOT_SECONDARY_SLOT, &size);
1303             assert(rc == 0);
1304         }
1305 
1306 #ifdef MCUBOOT_ENC_IMAGES
1307         hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT);
1308         if (IS_ENCRYPTED(hdr)) {
1309             fap = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT);
1310             rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap, bs);
1311             assert(rc >= 0);
1312 
1313             if (rc == 0) {
1314                 rc = boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs);
1315                 assert(rc == 0);
1316             } else {
1317                 rc = 0;
1318             }
1319         } else {
1320             memset(bs->enckey[1], 0xff, BOOT_ENC_KEY_ALIGN_SIZE);
1321         }
1322 #endif
1323 
1324         if (size > copy_size) {
1325             copy_size = size;
1326         }
1327 
1328         bs->swap_size = copy_size;
1329     } else {
1330         /*
1331          * If a swap was under way, the swap_size should already be present
1332          * in the trailer...
1333          */
1334 
1335         rc = boot_find_status(image_index, &fap);
1336         assert(fap != NULL);
1337         rc = boot_read_swap_size(fap, &bs->swap_size);
1338         assert(rc == 0);
1339 
1340         copy_size = bs->swap_size;
1341 
1342 #ifdef MCUBOOT_ENC_IMAGES
1343         for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
1344             rc = boot_read_enc_key(fap, slot, bs);
1345             assert(rc == 0);
1346 
1347             for (i = 0; i < BOOT_ENC_KEY_SIZE; i++) {
1348                 if (bs->enckey[slot][i] != 0xff) {
1349                     break;
1350                 }
1351             }
1352 
1353             if (i != BOOT_ENC_KEY_SIZE) {
1354                 boot_enc_set_key(BOOT_CURR_ENC(state), slot, bs);
1355             }
1356         }
1357 #endif
1358         flash_area_close(fap);
1359     }
1360 
1361     swap_run(state, bs, copy_size);
1362 
1363 #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
1364     extern int boot_status_fails;
1365     if (boot_status_fails > 0) {
1366         BOOT_LOG_WRN("%d status write fails performing the swap",
1367                      boot_status_fails);
1368     }
1369 #endif
1370     rc = BOOT_HOOK_CALL(boot_copy_region_post_hook, 0, BOOT_CURR_IMG(state),
1371                         BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT), size);
1372 
1373     return 0;
1374 }
1375 #endif
1376 
1377 #if (BOOT_IMAGE_NUMBER > 1)
1378 /**
1379  * Check the image dependency whether it is satisfied and modify
1380  * the swap type if necessary.
1381  *
1382  * @param dep               Image dependency which has to be verified.
1383  *
1384  * @return                  0 on success; nonzero on failure.
1385  */
1386 static int
boot_verify_slot_dependency(struct boot_loader_state * state,struct image_dependency * dep)1387 boot_verify_slot_dependency(struct boot_loader_state *state,
1388                             struct image_dependency *dep)
1389 {
1390     struct image_version *dep_version;
1391     size_t dep_slot;
1392     int rc;
1393     uint8_t swap_type;
1394 
1395     /* Determine the source of the image which is the subject of
1396      * the dependency and get it's version. */
1397     swap_type = state->swap_type[dep->image_id];
1398     dep_slot = BOOT_IS_UPGRADE(swap_type) ? BOOT_SECONDARY_SLOT
1399                                           : BOOT_PRIMARY_SLOT;
1400     dep_version = &state->imgs[dep->image_id][dep_slot].hdr.ih_ver;
1401 
1402     rc = boot_version_cmp(dep_version, &dep->image_min_version);
1403     if (rc < 0) {
1404         /* Dependency not satisfied.
1405          * Modify the swap type to decrease the version number of the image
1406          * (which will be located in the primary slot after the boot process),
1407          * consequently the number of unsatisfied dependencies will be
1408          * decreased or remain the same.
1409          */
1410         switch (BOOT_SWAP_TYPE(state)) {
1411         case BOOT_SWAP_TYPE_TEST:
1412         case BOOT_SWAP_TYPE_PERM:
1413             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
1414             break;
1415         case BOOT_SWAP_TYPE_NONE:
1416             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_REVERT;
1417             break;
1418         default:
1419             break;
1420         }
1421     } else {
1422         /* Dependency satisfied. */
1423         rc = 0;
1424     }
1425 
1426     return rc;
1427 }
1428 
1429 /**
1430  * Read all dependency TLVs of an image from the flash and verify
1431  * one after another to see if they are all satisfied.
1432  *
1433  * @param slot              Image slot number.
1434  *
1435  * @return                  0 on success; nonzero on failure.
1436  */
1437 static int
boot_verify_slot_dependencies(struct boot_loader_state * state,uint32_t slot)1438 boot_verify_slot_dependencies(struct boot_loader_state *state, uint32_t slot)
1439 {
1440     const struct flash_area *fap;
1441     struct image_tlv_iter it;
1442     struct image_dependency dep;
1443     uint32_t off;
1444     uint16_t len;
1445     int area_id;
1446     int rc;
1447 
1448     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
1449     rc = flash_area_open(area_id, &fap);
1450     if (rc != 0) {
1451         rc = BOOT_EFLASH;
1452         goto done;
1453     }
1454 
1455     rc = bootutil_tlv_iter_begin(&it, boot_img_hdr(state, slot), fap,
1456             IMAGE_TLV_DEPENDENCY, true);
1457     if (rc != 0) {
1458         goto done;
1459     }
1460 
1461     while (true) {
1462         rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
1463         if (rc < 0) {
1464             return -1;
1465         } else if (rc > 0) {
1466             rc = 0;
1467             break;
1468         }
1469 
1470         if (len != sizeof(dep)) {
1471             rc = BOOT_EBADIMAGE;
1472             goto done;
1473         }
1474 
1475         rc = flash_area_read(fap, off, &dep, len);
1476         if (rc != 0) {
1477             rc = BOOT_EFLASH;
1478             goto done;
1479         }
1480 
1481         if (dep.image_id >= BOOT_IMAGE_NUMBER) {
1482             rc = BOOT_EBADARGS;
1483             goto done;
1484         }
1485 
1486         /* Verify dependency and modify the swap type if not satisfied. */
1487         rc = boot_verify_slot_dependency(state, &dep);
1488         if (rc != 0) {
1489             /* Dependency not satisfied. */
1490             goto done;
1491         }
1492     }
1493 
1494 done:
1495     flash_area_close(fap);
1496     return rc;
1497 }
1498 
1499 /**
1500  * Iterate over all the images and verify whether the image dependencies in the
1501  * TLV area are all satisfied and update the related swap type if necessary.
1502  */
1503 static int
boot_verify_dependencies(struct boot_loader_state * state)1504 boot_verify_dependencies(struct boot_loader_state *state)
1505 {
1506     int rc = -1;
1507     uint8_t slot;
1508 
1509     BOOT_CURR_IMG(state) = 0;
1510     while (BOOT_CURR_IMG(state) < BOOT_IMAGE_NUMBER) {
1511         if (state->img_mask[BOOT_CURR_IMG(state)]) {
1512             BOOT_CURR_IMG(state)++;
1513             continue;
1514         }
1515         if (BOOT_SWAP_TYPE(state) != BOOT_SWAP_TYPE_NONE &&
1516             BOOT_SWAP_TYPE(state) != BOOT_SWAP_TYPE_FAIL) {
1517             slot = BOOT_SECONDARY_SLOT;
1518         } else {
1519             slot = BOOT_PRIMARY_SLOT;
1520         }
1521 
1522         rc = boot_verify_slot_dependencies(state, slot);
1523         if (rc == 0) {
1524             /* All dependencies've been satisfied, continue with next image. */
1525             BOOT_CURR_IMG(state)++;
1526         } else {
1527             /* Cannot upgrade due to non-met dependencies, so disable all
1528              * image upgrades.
1529              */
1530             for (int idx = 0; idx < BOOT_IMAGE_NUMBER; idx++) {
1531                 BOOT_CURR_IMG(state) = idx;
1532                 BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
1533             }
1534             break;
1535         }
1536     }
1537     return rc;
1538 }
1539 #endif /* (BOOT_IMAGE_NUMBER > 1) */
1540 
1541 /**
1542  * Performs a clean (not aborted) image update.
1543  *
1544  * @param bs                    The current boot status.
1545  *
1546  * @return                      0 on success; nonzero on failure.
1547  */
1548 static int
boot_perform_update(struct boot_loader_state * state,struct boot_status * bs)1549 boot_perform_update(struct boot_loader_state *state, struct boot_status *bs)
1550 {
1551     int rc;
1552 #ifndef MCUBOOT_OVERWRITE_ONLY
1553     uint8_t swap_type;
1554 #endif
1555 
1556     /* At this point there are no aborted swaps. */
1557 #if defined(MCUBOOT_OVERWRITE_ONLY)
1558     rc = boot_copy_image(state, bs);
1559 #elif defined(MCUBOOT_BOOTSTRAP)
1560     /* Check if the image update was triggered by a bad image in the
1561      * primary slot (the validity of the image in the secondary slot had
1562      * already been checked).
1563      */
1564     FIH_DECLARE(fih_rc, FIH_FAILURE);
1565     rc = boot_check_header_erased(state, BOOT_PRIMARY_SLOT);
1566     FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, bs);
1567     if (rc == 0 || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
1568         rc = boot_copy_image(state, bs);
1569     } else {
1570         rc = boot_swap_image(state, bs);
1571     }
1572 #else
1573         rc = boot_swap_image(state, bs);
1574 #endif
1575     assert(rc == 0);
1576 
1577 #ifndef MCUBOOT_OVERWRITE_ONLY
1578     /* The following state needs image_ok be explicitly set after the
1579      * swap was finished to avoid a new revert.
1580      */
1581     swap_type = BOOT_SWAP_TYPE(state);
1582     if (swap_type == BOOT_SWAP_TYPE_REVERT ||
1583             swap_type == BOOT_SWAP_TYPE_PERM) {
1584         rc = swap_set_image_ok(BOOT_CURR_IMG(state));
1585         if (rc != 0) {
1586             BOOT_SWAP_TYPE(state) = swap_type = BOOT_SWAP_TYPE_PANIC;
1587         }
1588     }
1589 
1590 #ifdef MCUBOOT_HW_ROLLBACK_PROT
1591     if (swap_type == BOOT_SWAP_TYPE_PERM) {
1592         /* Update the stored security counter with the new image's security
1593          * counter value. The primary slot holds the new image at this point,
1594          * but the secondary slot's image header must be passed since image
1595          * headers in the boot_data structure have not been updated yet.
1596          *
1597          * In case of a permanent image swap mcuboot will never attempt to
1598          * revert the images on the next reboot. Therefore, the security
1599          * counter must be increased right after the image upgrade.
1600          */
1601         rc = boot_update_security_counter(
1602                                     BOOT_CURR_IMG(state),
1603                                     BOOT_PRIMARY_SLOT,
1604                                     boot_img_hdr(state, BOOT_SECONDARY_SLOT));
1605         if (rc != 0) {
1606             BOOT_LOG_ERR("Security counter update failed after "
1607                          "image upgrade.");
1608             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_PANIC;
1609         }
1610     }
1611 #endif /* MCUBOOT_HW_ROLLBACK_PROT */
1612 
1613     if (BOOT_IS_UPGRADE(swap_type)) {
1614         rc = swap_set_copy_done(BOOT_CURR_IMG(state));
1615         if (rc != 0) {
1616             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_PANIC;
1617         }
1618     }
1619 #endif /* !MCUBOOT_OVERWRITE_ONLY */
1620 
1621     return rc;
1622 }
1623 
1624 /**
1625  * Completes a previously aborted image swap.
1626  *
1627  * @param bs                    The current boot status.
1628  *
1629  * @return                      0 on success; nonzero on failure.
1630  */
1631 #if !defined(MCUBOOT_OVERWRITE_ONLY)
1632 static int
boot_complete_partial_swap(struct boot_loader_state * state,struct boot_status * bs)1633 boot_complete_partial_swap(struct boot_loader_state *state,
1634         struct boot_status *bs)
1635 {
1636     int rc;
1637 
1638     /* Determine the type of swap operation being resumed from the
1639      * `swap-type` trailer field.
1640      */
1641     rc = boot_swap_image(state, bs);
1642     assert(rc == 0);
1643 
1644     BOOT_SWAP_TYPE(state) = bs->swap_type;
1645 
1646     /* The following states need image_ok be explicitly set after the
1647      * swap was finished to avoid a new revert.
1648      */
1649     if (bs->swap_type == BOOT_SWAP_TYPE_REVERT ||
1650         bs->swap_type == BOOT_SWAP_TYPE_PERM) {
1651         rc = swap_set_image_ok(BOOT_CURR_IMG(state));
1652         if (rc != 0) {
1653             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_PANIC;
1654         }
1655     }
1656 
1657     if (BOOT_IS_UPGRADE(bs->swap_type)) {
1658         rc = swap_set_copy_done(BOOT_CURR_IMG(state));
1659         if (rc != 0) {
1660             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_PANIC;
1661         }
1662     }
1663 
1664     if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_PANIC) {
1665         BOOT_LOG_ERR("panic!");
1666         assert(0);
1667 
1668         /* Loop forever... */
1669         while (1) {}
1670     }
1671 
1672     return rc;
1673 }
1674 #endif /* !MCUBOOT_OVERWRITE_ONLY */
1675 
1676 #if (BOOT_IMAGE_NUMBER > 1)
1677 /**
1678  * Review the validity of previously determined swap types of other images.
1679  *
1680  * @param aborted_swap          The current image upgrade is a
1681  *                              partial/aborted swap.
1682  */
1683 static void
boot_review_image_swap_types(struct boot_loader_state * state,bool aborted_swap)1684 boot_review_image_swap_types(struct boot_loader_state *state,
1685                              bool aborted_swap)
1686 {
1687     /* In that case if we rebooted in the middle of an image upgrade process, we
1688      * must review the validity of swap types, that were previously determined
1689      * for other images. The image_ok flag had not been set before the reboot
1690      * for any of the updated images (only the copy_done flag) and thus falsely
1691      * the REVERT swap type has been determined for the previous images that had
1692      * been updated before the reboot.
1693      *
1694      * There are two separate scenarios that we have to deal with:
1695      *
1696      * 1. The reboot has happened during swapping an image:
1697      *      The current image upgrade has been determined as a
1698      *      partial/aborted swap.
1699      * 2. The reboot has happened between two separate image upgrades:
1700      *      In this scenario we must check the swap type of the current image.
1701      *      In those cases if it is NONE or REVERT we cannot certainly determine
1702      *      the fact of a reboot. In a consistent state images must move in the
1703      *      same direction or stay in place, e.g. in practice REVERT and TEST
1704      *      swap types cannot be present at the same time. If the swap type of
1705      *      the current image is either TEST, PERM or FAIL we must review the
1706      *      already determined swap types of other images and set each false
1707      *      REVERT swap types to NONE (these images had been successfully
1708      *      updated before the system rebooted between two separate image
1709      *      upgrades).
1710      */
1711 
1712     if (BOOT_CURR_IMG(state) == 0) {
1713         /* Nothing to do */
1714         return;
1715     }
1716 
1717     if (!aborted_swap) {
1718         if ((BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) ||
1719             (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_REVERT)) {
1720             /* Nothing to do */
1721             return;
1722         }
1723     }
1724 
1725     for (uint8_t i = 0; i < BOOT_CURR_IMG(state); i++) {
1726         if (state->swap_type[i] == BOOT_SWAP_TYPE_REVERT) {
1727             state->swap_type[i] = BOOT_SWAP_TYPE_NONE;
1728         }
1729     }
1730 }
1731 #endif
1732 
1733 /**
1734  * Prepare image to be updated if required.
1735  *
1736  * Prepare image to be updated if required with completing an image swap
1737  * operation if one was aborted and/or determining the type of the
1738  * swap operation. In case of any error set the swap type to NONE.
1739  *
1740  * @param state                 TODO
1741  * @param bs                    Pointer where the read and possibly updated
1742  *                              boot status can be written to.
1743  */
1744 static void
boot_prepare_image_for_update(struct boot_loader_state * state,struct boot_status * bs)1745 boot_prepare_image_for_update(struct boot_loader_state *state,
1746                               struct boot_status *bs)
1747 {
1748     int rc;
1749     FIH_DECLARE(fih_rc, FIH_FAILURE);
1750 
1751     /* Determine the sector layout of the image slots and scratch area. */
1752     rc = boot_read_sectors(state);
1753     if (rc != 0) {
1754         BOOT_LOG_WRN("Failed reading sectors; BOOT_MAX_IMG_SECTORS=%d"
1755                      " - too small?", BOOT_MAX_IMG_SECTORS);
1756         /* Unable to determine sector layout, continue with next image
1757          * if there is one.
1758          */
1759         BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
1760         if (rc == BOOT_EFLASH)
1761         {
1762             /* Only return on error from the primary image flash */
1763             return;
1764         }
1765     }
1766 
1767     /* Attempt to read an image header from each slot. */
1768     rc = boot_read_image_headers(state, false, NULL);
1769     if (rc != 0) {
1770         /* Continue with next image if there is one. */
1771         BOOT_LOG_WRN("Failed reading image headers; Image=%u",
1772                 BOOT_CURR_IMG(state));
1773         BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
1774         return;
1775     }
1776 
1777     /* If the current image's slots aren't compatible, no swap is possible.
1778      * Just boot into primary slot.
1779      */
1780     if (boot_slots_compatible(state)) {
1781         boot_status_reset(bs);
1782 
1783 #ifndef MCUBOOT_OVERWRITE_ONLY
1784         rc = swap_read_status(state, bs);
1785         if (rc != 0) {
1786             BOOT_LOG_WRN("Failed reading boot status; Image=%u",
1787                     BOOT_CURR_IMG(state));
1788             /* Continue with next image if there is one. */
1789             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
1790             return;
1791         }
1792 #endif
1793 
1794 #ifdef MCUBOOT_SWAP_USING_MOVE
1795         /*
1796          * Must re-read image headers because the boot status might
1797          * have been updated in the previous function call.
1798          */
1799         rc = boot_read_image_headers(state, !boot_status_is_reset(bs), bs);
1800 #ifdef MCUBOOT_BOOTSTRAP
1801         /* When bootstrapping it's OK to not have image magic in the primary slot */
1802         if (rc != 0 && (BOOT_CURR_IMG(state) != BOOT_PRIMARY_SLOT ||
1803                 boot_check_header_erased(state, BOOT_PRIMARY_SLOT) != 0)) {
1804 #else
1805         if (rc != 0) {
1806 #endif
1807 
1808             /* Continue with next image if there is one. */
1809             BOOT_LOG_WRN("Failed reading image headers; Image=%u",
1810                     BOOT_CURR_IMG(state));
1811             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
1812             return;
1813         }
1814 #endif
1815 
1816         /* Determine if we rebooted in the middle of an image swap
1817          * operation. If a partial swap was detected, complete it.
1818          */
1819         if (!boot_status_is_reset(bs)) {
1820 
1821 #if (BOOT_IMAGE_NUMBER > 1)
1822             boot_review_image_swap_types(state, true);
1823 #endif
1824 
1825 #ifdef MCUBOOT_OVERWRITE_ONLY
1826             /* Should never arrive here, overwrite-only mode has
1827              * no swap state.
1828              */
1829             assert(0);
1830 #else
1831             /* Determine the type of swap operation being resumed from the
1832              * `swap-type` trailer field.
1833              */
1834             rc = boot_complete_partial_swap(state, bs);
1835             assert(rc == 0);
1836 #endif
1837             /* Attempt to read an image header from each slot. Ensure that
1838              * image headers in slots are aligned with headers in boot_data.
1839              */
1840             rc = boot_read_image_headers(state, false, bs);
1841             assert(rc == 0);
1842 
1843             /* Swap has finished set to NONE */
1844             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
1845         } else {
1846             /* There was no partial swap, determine swap type. */
1847             if (bs->swap_type == BOOT_SWAP_TYPE_NONE) {
1848                 BOOT_SWAP_TYPE(state) = boot_validated_swap_type(state, bs);
1849             } else {
1850                 FIH_CALL(boot_validate_slot, fih_rc,
1851                          state, BOOT_SECONDARY_SLOT, bs);
1852                 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
1853                     BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_FAIL;
1854                 } else {
1855                     BOOT_SWAP_TYPE(state) = bs->swap_type;
1856                 }
1857             }
1858 
1859 #if (BOOT_IMAGE_NUMBER > 1)
1860             boot_review_image_swap_types(state, false);
1861 #endif
1862 
1863 #ifdef MCUBOOT_BOOTSTRAP
1864             if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) {
1865                 /* Header checks are done first because they are
1866                  * inexpensive. Since overwrite-only copies starting from
1867                  * offset 0, if interrupted, it might leave a valid header
1868                  * magic, so also run validation on the primary slot to be
1869                  * sure it's not OK.
1870                  */
1871                 rc = boot_check_header_erased(state, BOOT_PRIMARY_SLOT);
1872                 FIH_CALL(boot_validate_slot, fih_rc,
1873                          state, BOOT_PRIMARY_SLOT, bs);
1874 
1875                 if (rc == 0 || FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
1876 
1877                     rc = (boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_magic == IMAGE_MAGIC) ? 1: 0;
1878                     FIH_CALL(boot_validate_slot, fih_rc,
1879                              state, BOOT_SECONDARY_SLOT, bs);
1880 
1881                     if (rc == 1 && FIH_EQ(fih_rc, FIH_SUCCESS)) {
1882                         /* Set swap type to REVERT to overwrite the primary
1883                          * slot with the image contained in secondary slot
1884                          * and to trigger the explicit setting of the
1885                          * image_ok flag.
1886                          */
1887                         BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_REVERT;
1888                     }
1889                 }
1890             }
1891 #endif
1892         }
1893     } else {
1894         /* In that case if slots are not compatible. */
1895         BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
1896     }
1897 }
1898 
1899 /**
1900  * Updates the security counter for the current image.
1901  *
1902  * @param  state        Boot loader status information.
1903  *
1904  * @return              0 on success; nonzero on failure.
1905  */
1906 static int
1907 boot_update_hw_rollback_protection(struct boot_loader_state *state)
1908 {
1909 #ifdef MCUBOOT_HW_ROLLBACK_PROT
1910     int rc;
1911 
1912     /* Update the stored security counter with the active image's security
1913     * counter value. It will only be updated if the new security counter is
1914     * greater than the stored value.
1915     *
1916     * In case of a successful image swapping when the swap type is TEST the
1917     * security counter can be increased only after a reset, when the swap
1918     * type is NONE and the image has marked itself "OK" (the image_ok flag
1919     * has been set). This way a "revert" can be performed when it's
1920     * necessary.
1921     */
1922     if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) {
1923         rc = boot_update_security_counter(
1924                                 BOOT_CURR_IMG(state),
1925                                 BOOT_PRIMARY_SLOT,
1926                                 boot_img_hdr(state, BOOT_PRIMARY_SLOT));
1927         if (rc != 0) {
1928             BOOT_LOG_ERR("Security counter update failed after image "
1929                             "validation.");
1930             return rc;
1931         }
1932     }
1933 
1934     return 0;
1935 
1936 #else /* MCUBOOT_HW_ROLLBACK_PROT */
1937     (void) (state);
1938 
1939     return 0;
1940 #endif
1941 }
1942 
1943 /**
1944  * Checks test swap downgrade prevention conditions.
1945  *
1946  * Function called only for swap upgrades test run.  It may prevent
1947  * swap if slot 1 image has <= version number or < security counter
1948  *
1949  * @param  state        Boot loader status information.
1950  *
1951  * @return              0 - image can be swapped, -1 downgrade prevention
1952  */
1953 static int
1954 check_downgrade_prevention(struct boot_loader_state *state)
1955 {
1956 #if defined(MCUBOOT_DOWNGRADE_PREVENTION) && \
1957     (defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_SCRATCH))
1958     uint32_t security_counter[2];
1959     int rc;
1960 
1961     if (MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER) {
1962         /* If there was security no counter in slot 0, allow swap */
1963         rc = bootutil_get_img_security_cnt(&(BOOT_IMG(state, 0).hdr),
1964                                            BOOT_IMG(state, 0).area,
1965                                            &security_counter[0]);
1966         if (rc != 0) {
1967             return 0;
1968         }
1969         /* If there is no security counter in slot 1, or it's lower than
1970          * that of slot 0, prevent downgrade */
1971         rc = bootutil_get_img_security_cnt(&(BOOT_IMG(state, 1).hdr),
1972                                            BOOT_IMG(state, 1).area,
1973                                            &security_counter[1]);
1974         if (rc != 0 || security_counter[0] > security_counter[1]) {
1975             rc = -1;
1976         }
1977     }
1978     else {
1979         rc = boot_version_cmp(&boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver,
1980                               &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver);
1981     }
1982     if (rc < 0) {
1983         /* Image in slot 0 prevents downgrade, delete image in slot 1 */
1984         BOOT_LOG_INF("Image in slot 1 erased due to downgrade prevention");
1985         flash_area_erase(BOOT_IMG(state, 1).area, 0,
1986                          flash_area_get_size(BOOT_IMG(state, 1).area));
1987     } else {
1988         rc = 0;
1989     }
1990     return rc;
1991 #else
1992     (void)state;
1993     return 0;
1994 #endif
1995 }
1996 
1997 fih_ret
1998 context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
1999 {
2000     size_t slot;
2001     struct boot_status bs;
2002     int rc = -1;
2003     FIH_DECLARE(fih_rc, FIH_FAILURE);
2004     int fa_id;
2005     int image_index;
2006     bool has_upgrade;
2007     volatile int fih_cnt;
2008 
2009     /* The array of slot sectors are defined here (as opposed to file scope) so
2010      * that they don't get allocated for non-boot-loader apps.  This is
2011      * necessary because the gcc option "-fdata-sections" doesn't seem to have
2012      * any effect in older gcc versions (e.g., 4.8.4).
2013      */
2014     TARGET_STATIC boot_sector_t primary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
2015     TARGET_STATIC boot_sector_t secondary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
2016 #if MCUBOOT_SWAP_USING_SCRATCH
2017     TARGET_STATIC boot_sector_t scratch_sectors[BOOT_MAX_IMG_SECTORS];
2018 #endif
2019 
2020     has_upgrade = false;
2021 
2022 #if (BOOT_IMAGE_NUMBER == 1)
2023     (void)has_upgrade;
2024 #endif
2025 
2026     /* Iterate over all the images. By the end of the loop the swap type has
2027      * to be determined for each image and all aborted swaps have to be
2028      * completed.
2029      */
2030     IMAGES_ITER(BOOT_CURR_IMG(state)) {
2031 #if BOOT_IMAGE_NUMBER > 1
2032         if (state->img_mask[BOOT_CURR_IMG(state)]) {
2033             continue;
2034         }
2035 #endif
2036 #if defined(MCUBOOT_ENC_IMAGES) && (BOOT_IMAGE_NUMBER > 1)
2037         /* The keys used for encryption may no longer be valid (could belong to
2038          * another images). Therefore, mark them as invalid to force their reload
2039          * by boot_enc_load().
2040          */
2041         boot_enc_zeroize(BOOT_CURR_ENC(state));
2042 #endif
2043 
2044         image_index = BOOT_CURR_IMG(state);
2045 
2046         BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors =
2047             primary_slot_sectors[image_index];
2048         BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors =
2049             secondary_slot_sectors[image_index];
2050 #if MCUBOOT_SWAP_USING_SCRATCH
2051         state->scratch.sectors = scratch_sectors;
2052 #endif
2053 
2054         /* Open primary and secondary image areas for the duration
2055          * of this call.
2056          */
2057         for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
2058             fa_id = flash_area_id_from_multi_image_slot(image_index, slot);
2059             rc = flash_area_open(fa_id, &BOOT_IMG_AREA(state, slot));
2060             assert(rc == 0);
2061         }
2062 #if MCUBOOT_SWAP_USING_SCRATCH
2063         rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH,
2064                              &BOOT_SCRATCH_AREA(state));
2065         assert(rc == 0);
2066 #endif
2067 
2068         /* Determine swap type and complete swap if it has been aborted. */
2069         boot_prepare_image_for_update(state, &bs);
2070 
2071         if (BOOT_IS_UPGRADE(BOOT_SWAP_TYPE(state))) {
2072             has_upgrade = true;
2073         }
2074     }
2075 
2076 #if (BOOT_IMAGE_NUMBER > 1)
2077     if (has_upgrade) {
2078         /* Iterate over all the images and verify whether the image dependencies
2079          * are all satisfied and update swap type if necessary.
2080          */
2081         rc = boot_verify_dependencies(state);
2082         if (rc != 0) {
2083             /*
2084              * It was impossible to upgrade because the expected dependency version
2085              * was not available. Here we already changed the swap_type so that
2086              * instead of asserting the bootloader, we continue and no upgrade is
2087              * performed.
2088              */
2089             rc = 0;
2090         }
2091     }
2092 #endif
2093 
2094     /* Trigger status change callback with upgrading status */
2095     mcuboot_status_change(MCUBOOT_STATUS_UPGRADING);
2096 
2097     /* Iterate over all the images. At this point there are no aborted swaps
2098      * and the swap types are determined for each image. By the end of the loop
2099      * all required update operations will have been finished.
2100      */
2101     IMAGES_ITER(BOOT_CURR_IMG(state)) {
2102 #if (BOOT_IMAGE_NUMBER > 1)
2103         if (state->img_mask[BOOT_CURR_IMG(state)]) {
2104             continue;
2105         }
2106 
2107 #ifdef MCUBOOT_ENC_IMAGES
2108         /* The keys used for encryption may no longer be valid (could belong to
2109          * another images). Therefore, mark them as invalid to force their reload
2110          * by boot_enc_load().
2111          */
2112         boot_enc_zeroize(BOOT_CURR_ENC(state));
2113 #endif /* MCUBOOT_ENC_IMAGES */
2114 
2115         /* Indicate that swap is not aborted */
2116         boot_status_reset(&bs);
2117 #endif /* (BOOT_IMAGE_NUMBER > 1) */
2118 
2119         /* Set the previously determined swap type */
2120         bs.swap_type = BOOT_SWAP_TYPE(state);
2121 
2122         switch (BOOT_SWAP_TYPE(state)) {
2123         case BOOT_SWAP_TYPE_NONE:
2124             break;
2125 
2126         case BOOT_SWAP_TYPE_TEST:
2127             if (check_downgrade_prevention(state) != 0) {
2128                 /* Downgrade prevented */
2129                 BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
2130                 break;
2131             }
2132             /* fallthrough */
2133         case BOOT_SWAP_TYPE_PERM:          /* fallthrough */
2134         case BOOT_SWAP_TYPE_REVERT:
2135             rc = BOOT_HOOK_CALL(boot_perform_update_hook, BOOT_HOOK_REGULAR,
2136                                 BOOT_CURR_IMG(state), &(BOOT_IMG(state, 1).hdr),
2137                                 BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT));
2138             if (rc == BOOT_HOOK_REGULAR)
2139             {
2140                 rc = boot_perform_update(state, &bs);
2141             }
2142             assert(rc == 0);
2143             break;
2144 
2145         case BOOT_SWAP_TYPE_FAIL:
2146             /* The image in secondary slot was invalid and is now erased. Ensure
2147              * we don't try to boot into it again on the next reboot. Do this by
2148              * pretending we just reverted back to primary slot.
2149              */
2150 #ifndef MCUBOOT_OVERWRITE_ONLY
2151             /* image_ok needs to be explicitly set to avoid a new revert. */
2152             rc = swap_set_image_ok(BOOT_CURR_IMG(state));
2153             if (rc != 0) {
2154                 BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_PANIC;
2155             }
2156 #endif /* !MCUBOOT_OVERWRITE_ONLY */
2157             break;
2158 
2159         default:
2160             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_PANIC;
2161         }
2162 
2163         if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_PANIC) {
2164             BOOT_LOG_ERR("panic!");
2165             assert(0);
2166 
2167             /* Loop forever... */
2168             FIH_PANIC;
2169         }
2170     }
2171 
2172     /* Iterate over all the images. At this point all required update operations
2173      * have finished. By the end of the loop each image in the primary slot will
2174      * have been re-validated.
2175      */
2176     FIH_SET(fih_cnt, 0);
2177     IMAGES_ITER(BOOT_CURR_IMG(state)) {
2178 #if BOOT_IMAGE_NUMBER > 1
2179         /* Hardenned to prevent from skipping check of a given image,
2180          * tmp_img_mask is declared volatile
2181          */
2182         volatile bool tmp_img_mask;
2183         FIH_SET(tmp_img_mask, state->img_mask[BOOT_CURR_IMG(state)]);
2184         if (FIH_EQ(tmp_img_mask, true)) {
2185             ++fih_cnt;
2186             continue;
2187         }
2188 #endif
2189         if (BOOT_SWAP_TYPE(state) != BOOT_SWAP_TYPE_NONE) {
2190             /* Attempt to read an image header from each slot. Ensure that image
2191              * headers in slots are aligned with headers in boot_data.
2192              */
2193             rc = boot_read_image_headers(state, false, &bs);
2194             if (rc != 0) {
2195                 FIH_SET(fih_rc, FIH_FAILURE);
2196                 goto out;
2197             }
2198             /* Since headers were reloaded, it can be assumed we just performed
2199              * a swap or overwrite. Now the header info that should be used to
2200              * provide the data for the bootstrap, which previously was at
2201              * secondary slot, was updated to primary slot.
2202              */
2203         }
2204 
2205 #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
2206         FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL);
2207         /* Check for all possible values is redundant in normal operation it
2208          * is meant to prevent FI attack.
2209          */
2210         if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) ||
2211             FIH_EQ(fih_rc, FIH_FAILURE) ||
2212             FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) {
2213             FIH_SET(fih_rc, FIH_FAILURE);
2214             goto out;
2215         }
2216 #else
2217         /* Even if we're not re-validating the primary slot, we could be booting
2218          * onto an empty flash chip. At least do a basic sanity check that
2219          * the magic number on the image is OK.
2220          */
2221         if (BOOT_IMG(state, BOOT_PRIMARY_SLOT).hdr.ih_magic != IMAGE_MAGIC) {
2222             BOOT_LOG_ERR("bad image magic 0x%lx; Image=%u", (unsigned long)
2223                          BOOT_IMG(state, BOOT_PRIMARY_SLOT).hdr.ih_magic,
2224                          BOOT_CURR_IMG(state));
2225             rc = BOOT_EBADIMAGE;
2226             FIH_SET(fih_rc, FIH_FAILURE);
2227             goto out;
2228         }
2229 #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
2230 
2231         rc = boot_update_hw_rollback_protection(state);
2232         if (rc != 0) {
2233             FIH_SET(fih_rc, FIH_FAILURE);
2234             goto out;
2235         }
2236 
2237         rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT);
2238         if (rc != 0) {
2239             FIH_SET(fih_rc, FIH_FAILURE);
2240             goto out;
2241         }
2242         ++fih_cnt;
2243     }
2244     /*
2245      * fih_cnt should be equal to BOOT_IMAGE_NUMBER now.
2246      * If this is not the case, at least one iteration of the loop
2247      * has been skipped.
2248      */
2249     if(FIH_NOT_EQ(fih_cnt, BOOT_IMAGE_NUMBER)) {
2250         FIH_PANIC;
2251     }
2252 
2253     fill_rsp(state, rsp);
2254 
2255     fih_rc = FIH_SUCCESS;
2256 out:
2257     /*
2258      * Since the boot_status struct stores plaintext encryption keys, reset
2259      * them here to avoid the possibility of jumping into an image that could
2260      * easily recover them.
2261      */
2262 #if defined(MCUBOOT_ENC_IMAGES) || defined(MCUBOOT_SWAP_SAVE_ENCTLV)
2263     like_mbedtls_zeroize(&bs, sizeof(bs));
2264 #else
2265     memset(&bs, 0, sizeof(struct boot_status));
2266 #endif
2267 
2268     close_all_flash_areas(state);
2269     FIH_RET(fih_rc);
2270 }
2271 
2272 fih_ret
2273 split_go(int loader_slot, int split_slot, void **entry)
2274 {
2275     boot_sector_t *sectors;
2276     uintptr_t entry_val;
2277     int loader_flash_id;
2278     int split_flash_id;
2279     int rc;
2280     FIH_DECLARE(fih_rc, FIH_FAILURE);
2281 
2282     sectors = malloc(BOOT_MAX_IMG_SECTORS * 2 * sizeof *sectors);
2283     if (sectors == NULL) {
2284         FIH_RET(FIH_FAILURE);
2285     }
2286     BOOT_IMG(&boot_data, loader_slot).sectors = sectors + 0;
2287     BOOT_IMG(&boot_data, split_slot).sectors = sectors + BOOT_MAX_IMG_SECTORS;
2288 
2289     loader_flash_id = flash_area_id_from_image_slot(loader_slot);
2290     rc = flash_area_open(loader_flash_id,
2291                          &BOOT_IMG_AREA(&boot_data, loader_slot));
2292     assert(rc == 0);
2293     split_flash_id = flash_area_id_from_image_slot(split_slot);
2294     rc = flash_area_open(split_flash_id,
2295                          &BOOT_IMG_AREA(&boot_data, split_slot));
2296     assert(rc == 0);
2297 
2298     /* Determine the sector layout of the image slots and scratch area. */
2299     rc = boot_read_sectors(&boot_data);
2300     if (rc != 0) {
2301         rc = SPLIT_GO_ERR;
2302         goto done;
2303     }
2304 
2305     rc = boot_read_image_headers(&boot_data, true, NULL);
2306     if (rc != 0) {
2307         goto done;
2308     }
2309 
2310     /* Don't check the bootable image flag because we could really call a
2311      * bootable or non-bootable image.  Just validate that the image check
2312      * passes which is distinct from the normal check.
2313      */
2314     FIH_CALL(split_image_check, fih_rc,
2315              boot_img_hdr(&boot_data, split_slot),
2316              BOOT_IMG_AREA(&boot_data, split_slot),
2317              boot_img_hdr(&boot_data, loader_slot),
2318              BOOT_IMG_AREA(&boot_data, loader_slot));
2319     if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
2320         goto done;
2321     }
2322 
2323     entry_val = boot_img_slot_off(&boot_data, split_slot) +
2324                 boot_img_hdr(&boot_data, split_slot)->ih_hdr_size;
2325     *entry = (void *) entry_val;
2326     rc = SPLIT_GO_OK;
2327 
2328 done:
2329     flash_area_close(BOOT_IMG_AREA(&boot_data, split_slot));
2330     flash_area_close(BOOT_IMG_AREA(&boot_data, loader_slot));
2331     free(sectors);
2332 
2333     if (rc) {
2334         FIH_SET(fih_rc, FIH_FAILURE);
2335     }
2336 
2337     FIH_RET(fih_rc);
2338 }
2339 
2340 #else /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
2341 
2342 #define NO_ACTIVE_SLOT UINT32_MAX
2343 
2344 /**
2345  * Opens all flash areas and checks which contain an image with a valid header.
2346  *
2347  * @param  state        Boot loader status information.
2348  *
2349  * @return              0 on success; nonzero on failure.
2350  */
2351 static int
2352 boot_get_slot_usage(struct boot_loader_state *state)
2353 {
2354     uint32_t slot;
2355     int fa_id;
2356     int rc;
2357     struct image_header *hdr = NULL;
2358 
2359     IMAGES_ITER(BOOT_CURR_IMG(state)) {
2360 #if BOOT_IMAGE_NUMBER > 1
2361         if (state->img_mask[BOOT_CURR_IMG(state)]) {
2362             continue;
2363         }
2364 #endif
2365         /* Open all the slots */
2366         for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
2367             fa_id = flash_area_id_from_multi_image_slot(
2368                                                 BOOT_CURR_IMG(state), slot);
2369             rc = flash_area_open(fa_id, &BOOT_IMG_AREA(state, slot));
2370             assert(rc == 0);
2371         }
2372 
2373         /* Attempt to read an image header from each slot. */
2374         rc = boot_read_image_headers(state, false, NULL);
2375         if (rc != 0) {
2376             BOOT_LOG_WRN("Failed reading image headers.");
2377             return rc;
2378         }
2379 
2380         /* Check headers in all slots */
2381         for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
2382             hdr = boot_img_hdr(state, slot);
2383 
2384             if (boot_is_header_valid(hdr, BOOT_IMG_AREA(state, slot))) {
2385                 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = true;
2386                 BOOT_LOG_IMAGE_INFO(slot, hdr);
2387             } else {
2388                 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = false;
2389                 BOOT_LOG_INF("Image %d %s slot: Image not found",
2390                              BOOT_CURR_IMG(state),
2391                              (slot == BOOT_PRIMARY_SLOT)
2392                              ? "Primary" : "Secondary");
2393             }
2394         }
2395 
2396         state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
2397     }
2398 
2399     return 0;
2400 }
2401 
2402 /**
2403  * Finds the slot containing the image with the highest version number for the
2404  * current image.
2405  *
2406  * @param  state        Boot loader status information.
2407  *
2408  * @return              NO_ACTIVE_SLOT if no available slot found, number of
2409  *                      the found slot otherwise.
2410  */
2411 static uint32_t
2412 find_slot_with_highest_version(struct boot_loader_state *state)
2413 {
2414     uint32_t slot;
2415     uint32_t candidate_slot = NO_ACTIVE_SLOT;
2416     int rc;
2417 
2418     for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
2419         if (state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot]) {
2420             if (candidate_slot == NO_ACTIVE_SLOT) {
2421                 candidate_slot = slot;
2422             } else {
2423                 rc = boot_version_cmp(
2424                             &boot_img_hdr(state, slot)->ih_ver,
2425                             &boot_img_hdr(state, candidate_slot)->ih_ver);
2426                 if (rc == 1) {
2427                     /* The version of the image being examined is greater than
2428                      * the version of the current candidate.
2429                      */
2430                     candidate_slot = slot;
2431                 }
2432             }
2433         }
2434     }
2435 
2436     return candidate_slot;
2437 }
2438 
2439 #ifdef MCUBOOT_HAVE_LOGGING
2440 /**
2441  * Prints the state of the loaded images.
2442  *
2443  * @param  state        Boot loader status information.
2444  */
2445 static void
2446 print_loaded_images(struct boot_loader_state *state)
2447 {
2448     uint32_t active_slot;
2449 
2450     (void)state;
2451 
2452     IMAGES_ITER(BOOT_CURR_IMG(state)) {
2453 #if BOOT_IMAGE_NUMBER > 1
2454         if (state->img_mask[BOOT_CURR_IMG(state)]) {
2455             continue;
2456         }
2457 #endif
2458         active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
2459 
2460         BOOT_LOG_INF("Image %d loaded from the %s slot",
2461                      BOOT_CURR_IMG(state),
2462                      (active_slot == BOOT_PRIMARY_SLOT) ?
2463                      "primary" : "secondary");
2464     }
2465 }
2466 #endif
2467 
2468 #if defined(MCUBOOT_DIRECT_XIP) && defined(MCUBOOT_DIRECT_XIP_REVERT)
2469 /**
2470  * Checks whether the active slot of the current image was previously selected
2471  * to run. Erases the image if it was selected but its execution failed,
2472  * otherwise marks it as selected if it has not been before.
2473  *
2474  * @param  state        Boot loader status information.
2475  *
2476  * @return              0 on success; nonzero on failure.
2477  */
2478 static int
2479 boot_select_or_erase(struct boot_loader_state *state)
2480 {
2481     const struct flash_area *fap;
2482     int fa_id;
2483     int rc;
2484     uint32_t active_slot;
2485     struct boot_swap_state* active_swap_state;
2486 
2487     active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
2488 
2489     fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), active_slot);
2490     rc = flash_area_open(fa_id, &fap);
2491     assert(rc == 0);
2492 
2493     active_swap_state = &(state->slot_usage[BOOT_CURR_IMG(state)].swap_state);
2494 
2495     memset(active_swap_state, 0, sizeof(struct boot_swap_state));
2496     rc = boot_read_swap_state(fap, active_swap_state);
2497     assert(rc == 0);
2498 
2499     if (active_swap_state->magic != BOOT_MAGIC_GOOD ||
2500         (active_swap_state->copy_done == BOOT_FLAG_SET &&
2501          active_swap_state->image_ok  != BOOT_FLAG_SET)) {
2502         /*
2503          * A reboot happened without the image being confirmed at
2504          * runtime or its trailer is corrupted/invalid. Erase the image
2505          * to prevent it from being selected again on the next reboot.
2506          */
2507         BOOT_LOG_DBG("Erasing faulty image in the %s slot.",
2508                      (active_slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary");
2509         rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
2510         assert(rc == 0);
2511 
2512         flash_area_close(fap);
2513         rc = -1;
2514     } else {
2515         if (active_swap_state->copy_done != BOOT_FLAG_SET) {
2516             if (active_swap_state->copy_done == BOOT_FLAG_BAD) {
2517                 BOOT_LOG_DBG("The copy_done flag had an unexpected value. Its "
2518                              "value was neither 'set' nor 'unset', but 'bad'.");
2519             }
2520             /*
2521              * Set the copy_done flag, indicating that the image has been
2522              * selected to boot. It can be set in advance, before even
2523              * validating the image, because in case the validation fails, the
2524              * entire image slot will be erased (including the trailer).
2525              */
2526             rc = boot_write_copy_done(fap);
2527             if (rc != 0) {
2528                 BOOT_LOG_WRN("Failed to set copy_done flag of the image in "
2529                              "the %s slot.", (active_slot == BOOT_PRIMARY_SLOT) ?
2530                              "primary" : "secondary");
2531                 rc = 0;
2532             }
2533         }
2534         flash_area_close(fap);
2535     }
2536 
2537     return rc;
2538 }
2539 #endif /* MCUBOOT_DIRECT_XIP && MCUBOOT_DIRECT_XIP_REVERT */
2540 
2541 #ifdef MCUBOOT_RAM_LOAD
2542 
2543 #ifndef MULTIPLE_EXECUTABLE_RAM_REGIONS
2544 #if !defined(IMAGE_EXECUTABLE_RAM_START) || !defined(IMAGE_EXECUTABLE_RAM_SIZE)
2545 #error "Platform MUST define executable RAM bounds in case of RAM_LOAD"
2546 #endif
2547 #endif
2548 
2549 /**
2550  * Verifies that the active slot of the current image can be loaded within the
2551  * predefined bounds that are allowed to be used by executable images.
2552  *
2553  * @param  state        Boot loader status information.
2554  *
2555  * @return              0 on success; nonzero on failure.
2556  */
2557 static int
2558 boot_verify_ram_load_address(struct boot_loader_state *state)
2559 {
2560     uint32_t img_dst;
2561     uint32_t img_sz;
2562     uint32_t img_end_addr;
2563     uint32_t exec_ram_start;
2564     uint32_t exec_ram_size;
2565 
2566     (void)state;
2567 
2568 #ifdef MULTIPLE_EXECUTABLE_RAM_REGIONS
2569     int      rc;
2570 
2571     rc = boot_get_image_exec_ram_info(BOOT_CURR_IMG(state), &exec_ram_start,
2572                                       &exec_ram_size);
2573     if (rc != 0) {
2574         return BOOT_EBADSTATUS;
2575     }
2576 #else
2577     exec_ram_start = IMAGE_EXECUTABLE_RAM_START;
2578     exec_ram_size = IMAGE_EXECUTABLE_RAM_SIZE;
2579 #endif
2580 
2581     img_dst = state->slot_usage[BOOT_CURR_IMG(state)].img_dst;
2582     img_sz = state->slot_usage[BOOT_CURR_IMG(state)].img_sz;
2583 
2584     if (img_dst < exec_ram_start) {
2585         return BOOT_EBADIMAGE;
2586     }
2587 
2588     if (!boot_u32_safe_add(&img_end_addr, img_dst, img_sz)) {
2589         return BOOT_EBADIMAGE;
2590     }
2591 
2592     if (img_end_addr > (exec_ram_start + exec_ram_size)) {
2593         return BOOT_EBADIMAGE;
2594     }
2595 
2596     return 0;
2597 }
2598 
2599 #ifdef MCUBOOT_ENC_IMAGES
2600 
2601 /**
2602  * Copies and decrypts an image from a slot in the flash to an SRAM address.
2603  *
2604  * @param  state    Boot loader status information.
2605  * @param  slot     The flash slot of the image to be copied to SRAM.
2606  * @param  hdr      The image header.
2607  * @param  src_sz   Size of the image.
2608  * @param  img_dst  Pointer to the address at which the image needs to be
2609  *                  copied to SRAM.
2610  *
2611  * @return          0 on success; nonzero on failure.
2612  */
2613 static int
2614 boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state,
2615                                     uint32_t slot, struct image_header *hdr,
2616                                     uint32_t src_sz, uint32_t img_dst)
2617 {
2618     /* The flow for the decryption and copy of the image is as follows :
2619      * 1. The whole image is copied to the RAM (header + payload + TLV).
2620      * 2. The encryption key is loaded from the TLV in flash.
2621      * 3. The image is then decrypted chunk by chunk in RAM (1 chunk
2622      * is 1024 bytes). Only the payload section is decrypted.
2623      * 4. The image is authenticated in RAM.
2624      */
2625     const struct flash_area *fap_src = NULL;
2626     struct boot_status bs;
2627     uint32_t blk_off;
2628     uint32_t tlv_off;
2629     uint32_t blk_sz;
2630     uint32_t bytes_copied = hdr->ih_hdr_size;
2631     uint32_t chunk_sz;
2632     uint32_t max_sz = 1024;
2633     uint16_t idx;
2634     uint8_t image_index;
2635     uint8_t * cur_dst;
2636     int area_id;
2637     int rc;
2638     uint8_t * ram_dst = (void *)(IMAGE_RAM_BASE + img_dst);
2639 
2640     image_index = BOOT_CURR_IMG(state);
2641     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
2642     rc = flash_area_open(area_id, &fap_src);
2643     if (rc != 0){
2644         return BOOT_EFLASH;
2645     }
2646 
2647     tlv_off = BOOT_TLV_OFF(hdr);
2648 
2649     /* Copying the whole image in RAM */
2650     rc = flash_area_read(fap_src, 0, ram_dst, src_sz);
2651     if (rc != 0) {
2652         goto done;
2653     }
2654 
2655     rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fap_src, &bs);
2656     if (rc < 0) {
2657         goto done;
2658     }
2659 
2660     /* if rc > 0 then the key has already been loaded */
2661     if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), slot, &bs)) {
2662         goto done;
2663     }
2664 
2665     /* Starting at the end of the header as the header section is not encrypted */
2666     while (bytes_copied < tlv_off) { /* TLV section copied previously */
2667         if (src_sz - bytes_copied > max_sz) {
2668             chunk_sz = max_sz;
2669         } else {
2670             chunk_sz = src_sz - bytes_copied;
2671         }
2672 
2673         cur_dst = ram_dst + bytes_copied;
2674         blk_sz = chunk_sz;
2675         idx = 0;
2676         if (bytes_copied + chunk_sz > tlv_off) {
2677             /* Going over TLV section
2678              * Part of the chunk is encrypted payload */
2679             blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf;
2680             blk_sz = tlv_off - (bytes_copied);
2681             boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
2682                 (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
2683                 blk_off, cur_dst);
2684         } else {
2685             /* Image encrypted payload section */
2686             blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf;
2687             boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
2688                     (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
2689                     blk_off, cur_dst);
2690         }
2691 
2692         bytes_copied += chunk_sz;
2693     }
2694     rc = 0;
2695 
2696 done:
2697     flash_area_close(fap_src);
2698 
2699     return rc;
2700 }
2701 
2702 #endif /* MCUBOOT_ENC_IMAGES */
2703 /**
2704  * Copies a slot of the current image into SRAM.
2705  *
2706  * @param  state    Boot loader status information.
2707  * @param  slot     The flash slot of the image to be copied to SRAM.
2708  * @param  img_dst  The address at which the image needs to be copied to
2709  *                  SRAM.
2710  * @param  img_sz   The size of the image that needs to be copied to SRAM.
2711  *
2712  * @return          0 on success; nonzero on failure.
2713  */
2714 static int
2715 boot_copy_image_to_sram(struct boot_loader_state *state, int slot,
2716                         uint32_t img_dst, uint32_t img_sz)
2717 {
2718     int rc;
2719     const struct flash_area *fap_src = NULL;
2720     int area_id;
2721 
2722 #if (BOOT_IMAGE_NUMBER == 1)
2723     (void)state;
2724 #endif
2725 
2726     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
2727 
2728     rc = flash_area_open(area_id, &fap_src);
2729     if (rc != 0) {
2730         return BOOT_EFLASH;
2731     }
2732 
2733     /* Direct copy from flash to its new location in SRAM. */
2734     rc = flash_area_read(fap_src, 0, (void *)(IMAGE_RAM_BASE + img_dst), img_sz);
2735     if (rc != 0) {
2736         BOOT_LOG_INF("Error whilst copying image from Flash to SRAM: %d", rc);
2737     }
2738 
2739     flash_area_close(fap_src);
2740 
2741     return rc;
2742 }
2743 
2744 #if (BOOT_IMAGE_NUMBER > 1)
2745 /**
2746  * Checks if two memory regions (A and B) are overlap or not.
2747  *
2748  * @param  start_a  Start of the A region.
2749  * @param  end_a    End of the A region.
2750  * @param  start_b  Start of the B region.
2751  * @param  end_b    End of the B region.
2752  *
2753  * @return          true if there is overlap; false otherwise.
2754  */
2755 static bool
2756 do_regions_overlap(uint32_t start_a, uint32_t end_a,
2757                    uint32_t start_b, uint32_t end_b)
2758 {
2759     if (start_b > end_a) {
2760         return false;
2761     } else if (start_b >= start_a) {
2762         return true;
2763     } else if (end_b > start_a) {
2764         return true;
2765     }
2766 
2767     return false;
2768 }
2769 
2770 /**
2771  * Checks if the image we want to load to memory overlap with an already
2772  * ramloaded image.
2773  *
2774  * @param  state    Boot loader status information.
2775  *
2776  * @return                    0 if there is no overlap; nonzero otherwise.
2777  */
2778 static int
2779 boot_check_ram_load_overlapping(struct boot_loader_state *state)
2780 {
2781     uint32_t i;
2782 
2783     uint32_t start_a;
2784     uint32_t end_a;
2785     uint32_t start_b;
2786     uint32_t end_b;
2787     uint32_t image_id_to_check = BOOT_CURR_IMG(state);
2788 
2789     start_a = state->slot_usage[image_id_to_check].img_dst;
2790     /* Safe to add here, values are already verified in
2791      * boot_verify_ram_load_address() */
2792     end_a = start_a + state->slot_usage[image_id_to_check].img_sz;
2793 
2794     for (i = 0; i < BOOT_IMAGE_NUMBER; i++) {
2795         if (state->slot_usage[i].active_slot == NO_ACTIVE_SLOT
2796             || i == image_id_to_check) {
2797             continue;
2798         }
2799 
2800         start_b = state->slot_usage[i].img_dst;
2801         /* Safe to add here, values are already verified in
2802          * boot_verify_ram_load_address() */
2803         end_b = start_b + state->slot_usage[i].img_sz;
2804 
2805         if (do_regions_overlap(start_a, end_a, start_b, end_b)) {
2806             return -1;
2807         }
2808     }
2809 
2810     return 0;
2811 }
2812 #endif
2813 
2814 /**
2815  * Loads the active slot of the current image into SRAM. The load address and
2816  * image size is extracted from the image header.
2817  *
2818  * @param  state        Boot loader status information.
2819  *
2820  * @return              0 on success; nonzero on failure.
2821  */
2822 static int
2823 boot_load_image_to_sram(struct boot_loader_state *state)
2824 {
2825     uint32_t active_slot;
2826     struct image_header *hdr = NULL;
2827     uint32_t img_dst;
2828     uint32_t img_sz;
2829     int rc;
2830 
2831     active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
2832     hdr = boot_img_hdr(state, active_slot);
2833 
2834     if (hdr->ih_flags & IMAGE_F_RAM_LOAD) {
2835 
2836         img_dst = hdr->ih_load_addr;
2837 
2838         rc = boot_read_image_size(state, active_slot, &img_sz);
2839         if (rc != 0) {
2840             return rc;
2841         }
2842 
2843         state->slot_usage[BOOT_CURR_IMG(state)].img_dst = img_dst;
2844         state->slot_usage[BOOT_CURR_IMG(state)].img_sz = img_sz;
2845 
2846         rc = boot_verify_ram_load_address(state);
2847         if (rc != 0) {
2848             BOOT_LOG_INF("Image RAM load address 0x%x is invalid.", img_dst);
2849             return rc;
2850         }
2851 
2852 #if (BOOT_IMAGE_NUMBER > 1)
2853         rc = boot_check_ram_load_overlapping(state);
2854         if (rc != 0) {
2855             BOOT_LOG_INF("Image RAM loading to address 0x%x would overlap with\
2856                          another image.", img_dst);
2857             return rc;
2858         }
2859 #endif
2860 #ifdef MCUBOOT_ENC_IMAGES
2861         /* decrypt image if encrypted and copy it to RAM */
2862         if (IS_ENCRYPTED(hdr)) {
2863             rc = boot_decrypt_and_copy_image_to_sram(state, active_slot, hdr, img_sz, img_dst);
2864         } else {
2865             rc = boot_copy_image_to_sram(state, active_slot, img_dst, img_sz);
2866         }
2867 #else
2868         /* Copy image to the load address from where it currently resides in
2869          * flash.
2870          */
2871         rc = boot_copy_image_to_sram(state, active_slot, img_dst, img_sz);
2872 #endif
2873         if (rc != 0) {
2874             BOOT_LOG_INF("RAM loading to 0x%x is failed.", img_dst);
2875         } else {
2876             BOOT_LOG_INF("RAM loading to 0x%x is succeeded.", img_dst);
2877         }
2878     } else {
2879         /* Only images that support IMAGE_F_RAM_LOAD are allowed if
2880          * MCUBOOT_RAM_LOAD is set.
2881          */
2882         rc = BOOT_EBADIMAGE;
2883     }
2884 
2885     if (rc != 0) {
2886         state->slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
2887         state->slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
2888     }
2889 
2890     return rc;
2891 }
2892 
2893 /**
2894  * Removes an image from SRAM, by overwriting it with zeros.
2895  *
2896  * @param  state        Boot loader status information.
2897  *
2898  * @return              0 on success; nonzero on failure.
2899  */
2900 static inline int
2901 boot_remove_image_from_sram(struct boot_loader_state *state)
2902 {
2903     (void)state;
2904 
2905     BOOT_LOG_INF("Removing image from SRAM at address 0x%x",
2906                  state->slot_usage[BOOT_CURR_IMG(state)].img_dst);
2907 
2908     memset((void*)(IMAGE_RAM_BASE + state->slot_usage[BOOT_CURR_IMG(state)].img_dst),
2909            0, state->slot_usage[BOOT_CURR_IMG(state)].img_sz);
2910 
2911     state->slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
2912     state->slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
2913 
2914     return 0;
2915 }
2916 
2917 /**
2918  * Removes an image from flash by erasing the corresponding flash area
2919  *
2920  * @param  state    Boot loader status information.
2921  * @param  slot     The flash slot of the image to be erased.
2922  *
2923  * @return          0 on success; nonzero on failure.
2924  */
2925 static inline int
2926 boot_remove_image_from_flash(struct boot_loader_state *state, uint32_t slot)
2927 {
2928     int area_id;
2929     int rc;
2930     const struct flash_area *fap;
2931 
2932     (void)state;
2933 
2934     BOOT_LOG_INF("Removing image %d slot %d from flash", BOOT_CURR_IMG(state),
2935                                                          slot);
2936     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
2937     rc = flash_area_open(area_id, &fap);
2938     if (rc == 0) {
2939         flash_area_erase(fap, 0, flash_area_get_size(fap));
2940         flash_area_close(fap);
2941     }
2942 
2943     return rc;
2944 }
2945 #endif /* MCUBOOT_RAM_LOAD */
2946 
2947 #if (BOOT_IMAGE_NUMBER > 1)
2948 /**
2949  * Checks the image dependency whether it is satisfied.
2950  *
2951  * @param  state        Boot loader status information.
2952  * @param  dep          Image dependency which has to be verified.
2953  *
2954  * @return              0 if dependencies are met; nonzero otherwise.
2955  */
2956 static int
2957 boot_verify_slot_dependency(struct boot_loader_state *state,
2958                             struct image_dependency *dep)
2959 {
2960     struct image_version *dep_version;
2961     uint32_t dep_slot;
2962     int rc;
2963 
2964     /* Determine the source of the image which is the subject of
2965      * the dependency and get it's version.
2966      */
2967     dep_slot = state->slot_usage[dep->image_id].active_slot;
2968     dep_version = &state->imgs[dep->image_id][dep_slot].hdr.ih_ver;
2969 
2970     rc = boot_version_cmp(dep_version, &dep->image_min_version);
2971     if (rc >= 0) {
2972         /* Dependency satisfied. */
2973         rc = 0;
2974     }
2975 
2976     return rc;
2977 }
2978 
2979 /**
2980  * Reads all dependency TLVs of an image and verifies one after another to see
2981  * if they are all satisfied.
2982  *
2983  * @param  state        Boot loader status information.
2984  *
2985  * @return              0 if dependencies are met; nonzero otherwise.
2986  */
2987 static int
2988 boot_verify_slot_dependencies(struct boot_loader_state *state)
2989 {
2990     uint32_t active_slot;
2991     const struct flash_area *fap;
2992     struct image_tlv_iter it;
2993     struct image_dependency dep;
2994     uint32_t off;
2995     uint16_t len;
2996     int area_id;
2997     int rc;
2998 
2999     active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
3000 
3001     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state),
3002                                                                 active_slot);
3003     rc = flash_area_open(area_id, &fap);
3004     if (rc != 0) {
3005         rc = BOOT_EFLASH;
3006         goto done;
3007     }
3008 
3009     rc = bootutil_tlv_iter_begin(&it, boot_img_hdr(state, active_slot), fap,
3010             IMAGE_TLV_DEPENDENCY, true);
3011     if (rc != 0) {
3012         goto done;
3013     }
3014 
3015     while (true) {
3016         rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
3017         if (rc < 0) {
3018             return -1;
3019         } else if (rc > 0) {
3020             rc = 0;
3021             break;
3022         }
3023 
3024         if (len != sizeof(dep)) {
3025             rc = BOOT_EBADIMAGE;
3026             goto done;
3027         }
3028 
3029         rc = LOAD_IMAGE_DATA(boot_img_hdr(state, active_slot),
3030                              fap, off, &dep, len);
3031         if (rc != 0) {
3032             rc = BOOT_EFLASH;
3033             goto done;
3034         }
3035 
3036         if (dep.image_id >= BOOT_IMAGE_NUMBER) {
3037             rc = BOOT_EBADARGS;
3038             goto done;
3039         }
3040 
3041         rc = boot_verify_slot_dependency(state, &dep);
3042         if (rc != 0) {
3043             /* Dependency not satisfied. */
3044             goto done;
3045         }
3046     }
3047 
3048 done:
3049     flash_area_close(fap);
3050     return rc;
3051 }
3052 
3053 /**
3054  * Checks the dependency of all the active slots. If an image found with
3055  * invalid or not satisfied dependencies the image is removed from SRAM (in
3056  * case of MCUBOOT_RAM_LOAD strategy) and its slot is set to unavailable.
3057  *
3058  * @param  state        Boot loader status information.
3059  *
3060  * @return              0 if dependencies are met; nonzero otherwise.
3061  */
3062 static int
3063 boot_verify_dependencies(struct boot_loader_state *state)
3064 {
3065     int rc = -1;
3066     uint32_t active_slot;
3067 
3068     IMAGES_ITER(BOOT_CURR_IMG(state)) {
3069         if (state->img_mask[BOOT_CURR_IMG(state)]) {
3070             continue;
3071         }
3072         rc = boot_verify_slot_dependencies(state);
3073         if (rc != 0) {
3074             /* Dependencies not met or invalid dependencies. */
3075 
3076 #ifdef MCUBOOT_RAM_LOAD
3077             boot_remove_image_from_sram(state);
3078 #endif /* MCUBOOT_RAM_LOAD */
3079 
3080             active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
3081             state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
3082             state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
3083 
3084             return rc;
3085         }
3086     }
3087 
3088     return rc;
3089 }
3090 #endif /* (BOOT_IMAGE_NUMBER > 1) */
3091 
3092 /**
3093  * Tries to load a slot for all the images with validation.
3094  *
3095  * @param  state        Boot loader status information.
3096  *
3097  * @return              0 on success; nonzero on failure.
3098  */
3099 fih_ret
3100 boot_load_and_validate_images(struct boot_loader_state *state)
3101 {
3102     uint32_t active_slot;
3103     int rc;
3104     fih_ret fih_rc;
3105 
3106     /* Go over all the images and try to load one */
3107     IMAGES_ITER(BOOT_CURR_IMG(state)) {
3108         /* All slots tried until a valid image found. Breaking from this loop
3109          * means that a valid image found or already loaded. If no slot is
3110          * found the function returns with error code. */
3111         while (true) {
3112             /* Go over all the slots and try to load one */
3113             active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
3114             if (active_slot != NO_ACTIVE_SLOT){
3115                 /* A slot is already active, go to next image. */
3116                 break;
3117             }
3118 
3119             active_slot = find_slot_with_highest_version(state);
3120             if (active_slot == NO_ACTIVE_SLOT) {
3121                 BOOT_LOG_INF("No slot to load for image %d",
3122                              BOOT_CURR_IMG(state));
3123                 FIH_RET(FIH_FAILURE);
3124             }
3125 
3126             /* Save the number of the active slot. */
3127             state->slot_usage[BOOT_CURR_IMG(state)].active_slot = active_slot;
3128 
3129 #if BOOT_IMAGE_NUMBER > 1
3130         if (state->img_mask[BOOT_CURR_IMG(state)]) {
3131             continue;
3132         }
3133 #endif
3134 
3135 #ifdef MCUBOOT_DIRECT_XIP
3136             rc = boot_rom_address_check(state);
3137             if (rc != 0) {
3138                 /* The image is placed in an unsuitable slot. */
3139                 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
3140                 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
3141                 continue;
3142             }
3143 
3144 #ifdef MCUBOOT_DIRECT_XIP_REVERT
3145             rc = boot_select_or_erase(state);
3146             if (rc != 0) {
3147                 /* The selected image slot has been erased. */
3148                 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
3149                 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
3150                 continue;
3151             }
3152 #endif /* MCUBOOT_DIRECT_XIP_REVERT */
3153 #endif /* MCUBOOT_DIRECT_XIP */
3154 
3155 #ifdef MCUBOOT_RAM_LOAD
3156             /* Image is first loaded to RAM and authenticated there in order to
3157              * prevent TOCTOU attack during image copy. This could be applied
3158              * when loading images from external (untrusted) flash to internal
3159              * (trusted) RAM and image is authenticated before copying.
3160              */
3161             rc = boot_load_image_to_sram(state);
3162             if (rc != 0 ) {
3163                 /* Image cannot be ramloaded. */
3164                 boot_remove_image_from_flash(state, active_slot);
3165                 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
3166                 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
3167                 continue;
3168             }
3169 #endif /* MCUBOOT_RAM_LOAD */
3170 
3171             FIH_CALL(boot_validate_slot, fih_rc, state, active_slot, NULL);
3172             if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
3173                 /* Image is invalid. */
3174 #ifdef MCUBOOT_RAM_LOAD
3175                 boot_remove_image_from_sram(state);
3176 #endif /* MCUBOOT_RAM_LOAD */
3177                 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
3178                 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
3179                 continue;
3180             }
3181 
3182             /* Valid image loaded from a slot, go to next image. */
3183             break;
3184         }
3185     }
3186 
3187     FIH_RET(FIH_SUCCESS);
3188 }
3189 
3190 /**
3191  * Updates the security counter for the current image.
3192  *
3193  * @param  state        Boot loader status information.
3194  *
3195  * @return              0 on success; nonzero on failure.
3196  */
3197 static int
3198 boot_update_hw_rollback_protection(struct boot_loader_state *state)
3199 {
3200 #ifdef MCUBOOT_HW_ROLLBACK_PROT
3201     int rc;
3202 
3203     /* Update the stored security counter with the newer (active) image's
3204      * security counter value.
3205      */
3206 #if defined(MCUBOOT_DIRECT_XIP) && defined(MCUBOOT_DIRECT_XIP_REVERT)
3207     /* When the 'revert' mechanism is enabled in direct-xip mode, the
3208      * security counter can be increased only after reboot, if the image
3209      * has been confirmed at runtime (the image_ok flag has been set).
3210      * This way a 'revert' can be performed when it's necessary.
3211      */
3212     if (state->slot_usage[BOOT_CURR_IMG(state)].swap_state.image_ok == BOOT_FLAG_SET) {
3213 #endif
3214         rc = boot_update_security_counter(BOOT_CURR_IMG(state),
3215                                           state->slot_usage[BOOT_CURR_IMG(state)].active_slot,
3216                                           boot_img_hdr(state, state->slot_usage[BOOT_CURR_IMG(state)].active_slot));
3217         if (rc != 0) {
3218             BOOT_LOG_ERR("Security counter update failed after image "
3219                             "validation.");
3220             return rc;
3221         }
3222 #if defined(MCUBOOT_DIRECT_XIP) && defined(MCUBOOT_DIRECT_XIP_REVERT)
3223     }
3224 #endif
3225 
3226     return 0;
3227 
3228 #else /* MCUBOOT_HW_ROLLBACK_PROT */
3229     (void) (state);
3230     return 0;
3231 #endif
3232 }
3233 
3234 fih_ret
3235 context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
3236 {
3237     int rc;
3238     FIH_DECLARE(fih_rc, FIH_FAILURE);
3239 
3240     rc = boot_get_slot_usage(state);
3241     if (rc != 0) {
3242         goto out;
3243     }
3244 
3245 #if (BOOT_IMAGE_NUMBER > 1)
3246     while (true) {
3247 #endif
3248         FIH_CALL(boot_load_and_validate_images, fih_rc, state);
3249         if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
3250             FIH_SET(fih_rc, FIH_FAILURE);
3251             goto out;
3252         }
3253 
3254 #if (BOOT_IMAGE_NUMBER > 1)
3255         rc = boot_verify_dependencies(state);
3256         if (rc != 0) {
3257             /* Dependency check failed for an image, it has been removed from
3258              * SRAM in case of MCUBOOT_RAM_LOAD strategy, and set to
3259              * unavailable. Try to load an image from another slot.
3260              */
3261             continue;
3262         }
3263         /* Dependency check was successful. */
3264         break;
3265     }
3266 #endif
3267 
3268     IMAGES_ITER(BOOT_CURR_IMG(state)) {
3269 #if BOOT_IMAGE_NUMBER > 1
3270         if (state->img_mask[BOOT_CURR_IMG(state)]) {
3271             continue;
3272         }
3273 #endif
3274         rc = boot_update_hw_rollback_protection(state);
3275         if (rc != 0) {
3276             FIH_SET(fih_rc, FIH_FAILURE);
3277             goto out;
3278         }
3279 
3280         rc = boot_add_shared_data(state, state->slot_usage[BOOT_CURR_IMG(state)].active_slot);
3281         if (rc != 0) {
3282             FIH_SET(fih_rc, FIH_FAILURE);
3283             goto out;
3284         }
3285     }
3286 
3287     /* All image loaded successfully. */
3288 #ifdef MCUBOOT_HAVE_LOGGING
3289     print_loaded_images(state);
3290 #endif
3291 
3292     fill_rsp(state, rsp);
3293 
3294 out:
3295     close_all_flash_areas(state);
3296 
3297     if (rc != 0) {
3298         FIH_SET(fih_rc, FIH_FAILURE);
3299     }
3300 
3301     FIH_RET(fih_rc);
3302 }
3303 #endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
3304 
3305 /**
3306  * Prepares the booting process. This function moves images around in flash as
3307  * appropriate, and tells you what address to boot from.
3308  *
3309  * @param rsp                   On success, indicates how booting should occur.
3310  *
3311  * @return                      FIH_SUCCESS on success; nonzero on failure.
3312  */
3313 fih_ret
3314 boot_go(struct boot_rsp *rsp)
3315 {
3316     FIH_DECLARE(fih_rc, FIH_FAILURE);
3317 
3318     boot_state_clear(NULL);
3319 
3320     FIH_CALL(context_boot_go, fih_rc, &boot_data, rsp);
3321     FIH_RET(fih_rc);
3322 }
3323 
3324 /**
3325  * Prepares the booting process, considering only a single image. This function
3326  * moves images around in flash as appropriate, and tells you what address to
3327  * boot from.
3328  *
3329  * @param rsp                   On success, indicates how booting should occur.
3330  *
3331  * @param image_id              The image ID to prepare the boot process for.
3332  *
3333  * @return                      FIH_SUCCESS on success; nonzero on failure.
3334  */
3335 fih_ret
3336 boot_go_for_image_id(struct boot_rsp *rsp, uint32_t image_id)
3337 {
3338     FIH_DECLARE(fih_rc, FIH_FAILURE);
3339 
3340     if (image_id >= BOOT_IMAGE_NUMBER) {
3341         FIH_RET(FIH_FAILURE);
3342     }
3343 
3344 #if BOOT_IMAGE_NUMBER > 1
3345     memset(&boot_data.img_mask, 1, BOOT_IMAGE_NUMBER);
3346     boot_data.img_mask[image_id] = 0;
3347 #endif
3348 
3349     FIH_CALL(context_boot_go, fih_rc, &boot_data, rsp);
3350     FIH_RET(fih_rc);
3351 }
3352 
3353 /**
3354  * Clears the boot state, so that previous operations have no effect on new
3355  * ones.
3356  *
3357  * @param state                 The state that should be cleared. If the value
3358  *                              is NULL, the default bootloader state will be
3359  *                              cleared.
3360  */
3361 void boot_state_clear(struct boot_loader_state *state)
3362 {
3363     if (state != NULL) {
3364         memset(state, 0, sizeof(struct boot_loader_state));
3365     } else {
3366         memset(&boot_data, 0, sizeof(struct boot_loader_state));
3367     }
3368 }
3369