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