1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Copyright (c) 2017-2019 Linaro LTD
5  * Copyright (c) 2016-2019 JUUL Labs
6  * Copyright (c) 2019-2021 Arm Limited
7  * Copyright (c) 2020-2023 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  * @file
31  * @brief Public MCUBoot interface API implementation
32  *
33  * This file contains API implementation which can be combined with
34  * the application in order to interact with the MCUBoot bootloader.
35  * This file contains shared code-base betwen MCUBoot and the application
36  * which controls DFU process.
37  */
38 
39 #include <string.h>
40 #include <inttypes.h>
41 #include <stddef.h>
42 
43 #include "sysflash/sysflash.h"
44 #include "flash_map_backend/flash_map_backend.h"
45 
46 #include "bootutil/image.h"
47 #include "bootutil/bootutil_public.h"
48 #include "bootutil/bootutil_log.h"
49 
50 #include "bootutil/boot_public_hooks.h"
51 #include "bootutil_priv.h"
52 #include "bootutil_misc.h"
53 
54 #ifdef CONFIG_MCUBOOT
55 BOOT_LOG_MODULE_DECLARE(mcuboot);
56 #else
57 BOOT_LOG_MODULE_REGISTER(mcuboot_util);
58 #endif
59 
60 #if BOOT_MAX_ALIGN == 8
61 const union boot_img_magic_t boot_img_magic = {
62     .val = {
63         0x77, 0xc2, 0x95, 0xf3,
64         0x60, 0xd2, 0xef, 0x7f,
65         0x35, 0x52, 0x50, 0x0f,
66         0x2c, 0xb6, 0x79, 0x80
67     }
68 };
69 #else
70 const union boot_img_magic_t boot_img_magic = {
71     .align = BOOT_MAX_ALIGN,
72     .magic = {
73         0x2d, 0xe1,
74         0x5d, 0x29, 0x41, 0x0b,
75         0x8d, 0x77, 0x67, 0x9c,
76         0x11, 0x0f, 0x1f, 0x8a
77     }
78 };
79 #endif
80 
81 struct boot_swap_table {
82     uint8_t magic_primary_slot;
83     uint8_t magic_secondary_slot;
84     uint8_t image_ok_primary_slot;
85     uint8_t image_ok_secondary_slot;
86     uint8_t copy_done_primary_slot;
87 
88     uint8_t swap_type;
89 };
90 
91 /**
92  * This set of tables maps image trailer contents to swap operation type.
93  * When searching for a match, these tables must be iterated sequentially.
94  *
95  * NOTE: the table order is very important. The settings in the secondary
96  * slot always are priority to the primary slot and should be located
97  * earlier in the table.
98  *
99  * The table lists only states where there is action needs to be taken by
100  * the bootloader, as in starting/finishing a swap operation.
101  */
102 static const struct boot_swap_table boot_swap_tables[] = {
103     {
104         .magic_primary_slot =       BOOT_MAGIC_ANY,
105         .magic_secondary_slot =     BOOT_MAGIC_GOOD,
106         .image_ok_primary_slot =    BOOT_FLAG_ANY,
107         .image_ok_secondary_slot =  BOOT_FLAG_UNSET,
108         .copy_done_primary_slot =   BOOT_FLAG_ANY,
109         .swap_type =                BOOT_SWAP_TYPE_TEST,
110     },
111     {
112         .magic_primary_slot =       BOOT_MAGIC_ANY,
113         .magic_secondary_slot =     BOOT_MAGIC_GOOD,
114         .image_ok_primary_slot =    BOOT_FLAG_ANY,
115         .image_ok_secondary_slot =  BOOT_FLAG_SET,
116         .copy_done_primary_slot =   BOOT_FLAG_ANY,
117         .swap_type =                BOOT_SWAP_TYPE_PERM,
118     },
119     {
120         .magic_primary_slot =       BOOT_MAGIC_GOOD,
121         .magic_secondary_slot =     BOOT_MAGIC_UNSET,
122         .image_ok_primary_slot =    BOOT_FLAG_UNSET,
123         .image_ok_secondary_slot =  BOOT_FLAG_ANY,
124         .copy_done_primary_slot =   BOOT_FLAG_SET,
125         .swap_type =                BOOT_SWAP_TYPE_REVERT,
126     },
127 };
128 
129 #define BOOT_SWAP_TABLES_COUNT \
130     (sizeof boot_swap_tables / sizeof boot_swap_tables[0])
131 
132 static int
boot_flag_decode(uint8_t flag)133 boot_flag_decode(uint8_t flag)
134 {
135     if (flag != BOOT_FLAG_SET) {
136         return BOOT_FLAG_BAD;
137     }
138     return BOOT_FLAG_SET;
139 }
140 
141 uint32_t
boot_swap_info_off(const struct flash_area * fap)142 boot_swap_info_off(const struct flash_area *fap)
143 {
144     return boot_copy_done_off(fap) - BOOT_MAX_ALIGN;
145 }
146 
147 /**
148  * Determines if a status source table is satisfied by the specified magic
149  * code.
150  *
151  * @param tbl_val               A magic field from a status source table.
152  * @param val                   The magic value in a trailer, encoded as a
153  *                                  BOOT_MAGIC_[...].
154  *
155  * @return                      1 if the two values are compatible;
156  *                              0 otherwise.
157  */
158 int
boot_magic_compatible_check(uint8_t tbl_val,uint8_t val)159 boot_magic_compatible_check(uint8_t tbl_val, uint8_t val)
160 {
161     switch (tbl_val) {
162     case BOOT_MAGIC_ANY:
163         return 1;
164 
165     case BOOT_MAGIC_NOTGOOD:
166         return val != BOOT_MAGIC_GOOD;
167 
168     default:
169         return tbl_val == val;
170     }
171 }
172 
bootutil_buffer_is_erased(const struct flash_area * area,const void * buffer,size_t len)173 bool bootutil_buffer_is_erased(const struct flash_area *area,
174                                const void *buffer, size_t len)
175 {
176     size_t i;
177     uint8_t *u8b;
178     uint8_t erased_val;
179 
180     if (buffer == NULL || len == 0) {
181         return false;
182     }
183 
184     erased_val = flash_area_erased_val(area);
185     for (i = 0, u8b = (uint8_t *)buffer; i < len; i++) {
186         if (u8b[i] != erased_val) {
187             return false;
188         }
189     }
190 
191     return true;
192 }
193 
194 static int
boot_read_flag(const struct flash_area * fap,uint8_t * flag,uint32_t off)195 boot_read_flag(const struct flash_area *fap, uint8_t *flag, uint32_t off)
196 {
197     int rc;
198 
199     rc = flash_area_read(fap, off, flag, sizeof *flag);
200     if (rc < 0) {
201         return BOOT_EFLASH;
202     }
203     if (bootutil_buffer_is_erased(fap, flag, sizeof *flag)) {
204         *flag = BOOT_FLAG_UNSET;
205     } else {
206         *flag = boot_flag_decode(*flag);
207     }
208 
209     return 0;
210 }
211 
212 static inline int
boot_read_copy_done(const struct flash_area * fap,uint8_t * copy_done)213 boot_read_copy_done(const struct flash_area *fap, uint8_t *copy_done)
214 {
215     return boot_read_flag(fap, copy_done, boot_copy_done_off(fap));
216 }
217 
218 
219 int
boot_read_swap_state(const struct flash_area * fap,struct boot_swap_state * state)220 boot_read_swap_state(const struct flash_area *fap,
221                      struct boot_swap_state *state)
222 {
223     uint8_t magic[BOOT_MAGIC_SZ];
224     uint32_t off;
225     uint8_t swap_info;
226     int rc;
227 
228     off = boot_magic_off(fap);
229     rc = flash_area_read(fap, off, magic, BOOT_MAGIC_SZ);
230     if (rc < 0) {
231         return BOOT_EFLASH;
232     }
233     if (bootutil_buffer_is_erased(fap, magic, BOOT_MAGIC_SZ)) {
234         state->magic = BOOT_MAGIC_UNSET;
235     } else {
236         state->magic = boot_magic_decode(magic);
237     }
238 
239     off = boot_swap_info_off(fap);
240     rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
241     if (rc < 0) {
242         return BOOT_EFLASH;
243     }
244 
245     /* Extract the swap type and image number */
246     state->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
247     state->image_num = BOOT_GET_IMAGE_NUM(swap_info);
248 
249     if (bootutil_buffer_is_erased(fap, &swap_info, sizeof swap_info) ||
250             state->swap_type > BOOT_SWAP_TYPE_REVERT) {
251         state->swap_type = BOOT_SWAP_TYPE_NONE;
252         state->image_num = 0;
253     }
254 
255     rc = boot_read_copy_done(fap, &state->copy_done);
256     if (rc) {
257         return BOOT_EFLASH;
258     }
259 
260     return boot_read_image_ok(fap, &state->image_ok);
261 }
262 
263 int
boot_read_swap_state_by_id(int flash_area_id,struct boot_swap_state * state)264 boot_read_swap_state_by_id(int flash_area_id, struct boot_swap_state *state)
265 {
266     const struct flash_area *fap;
267     int rc;
268 
269     rc = flash_area_open(flash_area_id, &fap);
270     if (rc != 0) {
271         return BOOT_EFLASH;
272     }
273 
274     rc = boot_read_swap_state(fap, state);
275     flash_area_close(fap);
276     return rc;
277 }
278 
279 int
boot_write_magic(const struct flash_area * fap)280 boot_write_magic(const struct flash_area *fap)
281 {
282     uint32_t off;
283     uint32_t pad_off;
284     int rc;
285     uint8_t magic[BOOT_MAGIC_ALIGN_SIZE];
286     uint8_t erased_val;
287 
288     off = boot_magic_off(fap);
289 
290     /* image_trailer structure was modified with additional padding such that
291      * the pad+magic ends up in a flash minimum write region. The address
292      * returned by boot_magic_off() is the start of magic which is not the
293      * start of the flash write boundary and thus writes to the magic will fail.
294      * To account for this change, write to magic is first padded with 0xFF
295      * before writing to the trailer.
296      */
297     pad_off = ALIGN_DOWN(off, BOOT_MAX_ALIGN);
298 
299     erased_val = flash_area_erased_val(fap);
300 
301     memset(&magic[0], erased_val, sizeof(magic));
302     memcpy(&magic[BOOT_MAGIC_ALIGN_SIZE - BOOT_MAGIC_SZ], BOOT_IMG_MAGIC, BOOT_MAGIC_SZ);
303 
304     BOOT_LOG_DBG("writing magic; fa_id=%d off=0x%lx (0x%lx)",
305                  flash_area_get_id(fap), (unsigned long)off,
306                  (unsigned long)(flash_area_get_off(fap) + off));
307     rc = flash_area_write(fap, pad_off, &magic[0], BOOT_MAGIC_ALIGN_SIZE);
308 
309     if (rc != 0) {
310         return BOOT_EFLASH;
311     }
312 
313     return 0;
314 }
315 
316 /**
317  * Write trailer data; status bytes, swap_size, etc
318  *
319  * @returns 0 on success, != 0 on error.
320  */
321 int
boot_write_trailer(const struct flash_area * fap,uint32_t off,const uint8_t * inbuf,uint8_t inlen)322 boot_write_trailer(const struct flash_area *fap, uint32_t off,
323         const uint8_t *inbuf, uint8_t inlen)
324 {
325     uint8_t buf[BOOT_MAX_ALIGN];
326     uint8_t erased_val;
327     uint32_t align;
328     int rc;
329 
330     align = flash_area_align(fap);
331     align = ALIGN_UP(inlen, align);
332     if (align > BOOT_MAX_ALIGN) {
333         return -1;
334     }
335     erased_val = flash_area_erased_val(fap);
336 
337     memcpy(buf, inbuf, inlen);
338     memset(&buf[inlen], erased_val, align - inlen);
339 
340     rc = flash_area_write(fap, off, buf, align);
341     if (rc != 0) {
342         return BOOT_EFLASH;
343     }
344 
345     return 0;
346 }
347 
348 int
boot_write_trailer_flag(const struct flash_area * fap,uint32_t off,uint8_t flag_val)349 boot_write_trailer_flag(const struct flash_area *fap, uint32_t off,
350         uint8_t flag_val)
351 {
352     const uint8_t buf[1] = { flag_val };
353     return boot_write_trailer(fap, off, buf, 1);
354 }
355 
356 int
boot_write_image_ok(const struct flash_area * fap)357 boot_write_image_ok(const struct flash_area *fap)
358 {
359     uint32_t off;
360 
361     off = boot_image_ok_off(fap);
362     BOOT_LOG_DBG("writing image_ok; fa_id=%d off=0x%lx (0x%lx)",
363                  flash_area_get_id(fap), (unsigned long)off,
364                  (unsigned long)(flash_area_get_off(fap) + off));
365     return boot_write_trailer_flag(fap, off, BOOT_FLAG_SET);
366 }
367 
368 int
boot_read_image_ok(const struct flash_area * fap,uint8_t * image_ok)369 boot_read_image_ok(const struct flash_area *fap, uint8_t *image_ok)
370 {
371     return boot_read_flag(fap, image_ok, boot_image_ok_off(fap));
372 }
373 
374 /**
375  * Writes the specified value to the `swap-type` field of an image trailer.
376  * This value is persisted so that the boot loader knows what swap operation to
377  * resume in case of an unexpected reset.
378  */
379 int
boot_write_swap_info(const struct flash_area * fap,uint8_t swap_type,uint8_t image_num)380 boot_write_swap_info(const struct flash_area *fap, uint8_t swap_type,
381                      uint8_t image_num)
382 {
383     uint32_t off;
384     uint8_t swap_info;
385 
386     BOOT_SET_SWAP_INFO(swap_info, image_num, swap_type);
387     off = boot_swap_info_off(fap);
388     BOOT_LOG_DBG("writing swap_info; fa_id=%d off=0x%lx (0x%lx), swap_type=0x%x"
389                  " image_num=0x%x",
390                  flash_area_get_id(fap), (unsigned long)off,
391                  (unsigned long)(flash_area_get_off(fap) + off),
392                  swap_type, image_num);
393     return boot_write_trailer(fap, off, (const uint8_t *) &swap_info, 1);
394 }
395 
396 int
boot_swap_type_multi(int image_index)397 boot_swap_type_multi(int image_index)
398 {
399     const struct boot_swap_table *table;
400     struct boot_swap_state primary_slot;
401     struct boot_swap_state secondary_slot;
402     int rc;
403     size_t i;
404 
405     rc = BOOT_HOOK_CALL(boot_read_swap_state_primary_slot_hook,
406                         BOOT_HOOK_REGULAR, image_index, &primary_slot);
407     if (rc == BOOT_HOOK_REGULAR)
408     {
409         rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_PRIMARY(image_index),
410                                         &primary_slot);
411     }
412     if (rc) {
413         return BOOT_SWAP_TYPE_PANIC;
414     }
415 
416     rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SECONDARY(image_index),
417                                     &secondary_slot);
418     if (rc == BOOT_EFLASH) {
419         BOOT_LOG_INF("Secondary image of image pair (%d.) "
420                      "is unreachable. Treat it as empty", image_index);
421         secondary_slot.magic = BOOT_MAGIC_UNSET;
422         secondary_slot.swap_type = BOOT_SWAP_TYPE_NONE;
423         secondary_slot.copy_done = BOOT_FLAG_UNSET;
424         secondary_slot.image_ok = BOOT_FLAG_UNSET;
425         secondary_slot.image_num = 0;
426     } else if (rc) {
427         return BOOT_SWAP_TYPE_PANIC;
428     }
429 
430     for (i = 0; i < BOOT_SWAP_TABLES_COUNT; i++) {
431         table = boot_swap_tables + i;
432 
433         if (boot_magic_compatible_check(table->magic_primary_slot,
434                                         primary_slot.magic) &&
435             boot_magic_compatible_check(table->magic_secondary_slot,
436                                         secondary_slot.magic) &&
437             (table->image_ok_primary_slot == BOOT_FLAG_ANY   ||
438                 table->image_ok_primary_slot == primary_slot.image_ok) &&
439             (table->image_ok_secondary_slot == BOOT_FLAG_ANY ||
440                 table->image_ok_secondary_slot == secondary_slot.image_ok) &&
441             (table->copy_done_primary_slot == BOOT_FLAG_ANY  ||
442                 table->copy_done_primary_slot == primary_slot.copy_done)) {
443             BOOT_LOG_INF("Swap type: %s",
444                          table->swap_type == BOOT_SWAP_TYPE_TEST   ? "test"   :
445                          table->swap_type == BOOT_SWAP_TYPE_PERM   ? "perm"   :
446                          table->swap_type == BOOT_SWAP_TYPE_REVERT ? "revert" :
447                          "BUG; can't happen");
448             if (table->swap_type != BOOT_SWAP_TYPE_TEST &&
449                     table->swap_type != BOOT_SWAP_TYPE_PERM &&
450                     table->swap_type != BOOT_SWAP_TYPE_REVERT) {
451                 return BOOT_SWAP_TYPE_PANIC;
452             }
453             return table->swap_type;
454         }
455     }
456 
457     BOOT_LOG_INF("Swap type: none");
458     return BOOT_SWAP_TYPE_NONE;
459 }
460 
461 int
boot_set_next(const struct flash_area * fa,bool active,bool confirm)462 boot_set_next(const struct flash_area *fa, bool active, bool confirm)
463 {
464     struct boot_swap_state slot_state;
465     int rc;
466 
467     if (active) {
468         confirm = true;
469     }
470 
471     rc = boot_read_swap_state(fa, &slot_state);
472     if (rc != 0) {
473         return rc;
474     }
475 
476     switch (slot_state.magic) {
477     case BOOT_MAGIC_GOOD:
478         /* If non-active then swap already scheduled, else confirm needed.*/
479 
480         if (active && slot_state.image_ok == BOOT_FLAG_UNSET) {
481             /* Intentionally do not check copy_done flag to be able to
482              * confirm a padded image which has been programmed using
483              * a programming interface.
484              */
485             rc = boot_write_image_ok(fa);
486         }
487 
488         break;
489 
490     case BOOT_MAGIC_UNSET:
491         if (!active) {
492             rc = boot_write_magic(fa);
493 
494             if (rc == 0 && confirm) {
495                 rc = boot_write_image_ok(fa);
496             }
497 
498             if (rc == 0) {
499                 uint8_t swap_type;
500 
501                 if (confirm) {
502                     swap_type = BOOT_SWAP_TYPE_PERM;
503                 } else {
504                     swap_type = BOOT_SWAP_TYPE_TEST;
505                 }
506                 rc = boot_write_swap_info(fa, swap_type, 0);
507             }
508         }
509         break;
510 
511     case BOOT_MAGIC_BAD:
512         if (active) {
513             rc = BOOT_EBADVECT;
514         } else {
515             /* The image slot is corrupt.  There is no way to recover, so erase the
516              * slot to allow future upgrades.
517              */
518             flash_area_erase(fa, 0, flash_area_get_size(fa));
519             rc = BOOT_EBADIMAGE;
520         }
521         break;
522 
523     default:
524         /* Something is not OK, this should never happen */
525         assert(0);
526         rc = BOOT_EBADIMAGE;
527     }
528 
529     return rc;
530 }
531 
532 /*
533  * This function is not used by the bootloader itself, but its required API
534  * by external tooling like mcumgr.
535  */
536 int
boot_swap_type(void)537 boot_swap_type(void)
538 {
539     return boot_swap_type_multi(0);
540 }
541 
542 /**
543  * Marks the image with the given index in the secondary slot as pending. On the
544  * next reboot, the system will perform a one-time boot of the the secondary
545  * slot image.
546  *
547  * @param image_index       Image pair index.
548  *
549  * @param permanent         Whether the image should be used permanently or
550  *                          only tested once:
551  *                               0=run image once, then confirm or revert.
552  *                               1=run image forever.
553  *
554  * @return                  0 on success; nonzero on failure.
555  */
556 int
boot_set_pending_multi(int image_index,int permanent)557 boot_set_pending_multi(int image_index, int permanent)
558 {
559     const struct flash_area *fap;
560     int rc;
561 
562     rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap);
563     if (rc != 0) {
564         return BOOT_EFLASH;
565     }
566 
567     rc = boot_set_next(fap, false, !(permanent == 0));
568 
569     flash_area_close(fap);
570     return rc;
571 }
572 
573 /**
574  * Marks the image with index 0 in the secondary slot as pending. On the next
575  * reboot, the system will perform a one-time boot of the the secondary slot
576  * image. Note that this API is kept for compatibility. The
577  * boot_set_pending_multi() API is recommended.
578  *
579  * @param permanent         Whether the image should be used permanently or
580  *                          only tested once:
581  *                               0=run image once, then confirm or revert.
582  *                               1=run image forever.
583  *
584  * @return                  0 on success; nonzero on failure.
585  */
586 int
boot_set_pending(int permanent)587 boot_set_pending(int permanent)
588 {
589     return boot_set_pending_multi(0, permanent);
590 }
591 
592 /**
593  * Marks the image with the given index in the primary slot as confirmed.  The
594  * system will continue booting into the image in the primary slot until told to
595  * boot from a different slot.
596  *
597  * @param image_index       Image pair index.
598  *
599  * @return                  0 on success; nonzero on failure.
600  */
601 int
boot_set_confirmed_multi(int image_index)602 boot_set_confirmed_multi(int image_index)
603 {
604     const struct flash_area *fap = NULL;
605     int rc;
606 
607     rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap);
608     if (rc != 0) {
609         return BOOT_EFLASH;
610     }
611 
612     rc = boot_set_next(fap, true, true);
613 
614     flash_area_close(fap);
615     return rc;
616 }
617 
618 /**
619  * Marks the image with index 0 in the primary slot as confirmed.  The system
620  * will continue booting into the image in the primary slot until told to boot
621  * from a different slot.  Note that this API is kept for compatibility. The
622  * boot_set_confirmed_multi() API is recommended.
623  *
624  * @return                  0 on success; nonzero on failure.
625  */
626 int
boot_set_confirmed(void)627 boot_set_confirmed(void)
628 {
629     return boot_set_confirmed_multi(0);
630 }
631