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