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