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