blob: 5d1e76fcf070edb3325d76ed6d3dc0f8728ea675 [file] [log] [blame]
Dominik Ermel8101c0c2020-05-19 13:01:16 +00001/*
2 * SPDX-License-Identifier: Apache-2.0
3 *
4 * Copyright (c) 2020 Nordic Semiconductor ASA
Tamas Banee6615d2020-09-30 07:58:48 +01005 * Copyright (c) 2020 Arm Limited
Dominik Ermel8101c0c2020-05-19 13:01:16 +00006 */
7
8#include <assert.h>
9#include "bootutil/image.h"
10#include "bootutil_priv.h"
11#include "bootutil/bootutil_log.h"
Jamie McCraec9fa6082023-07-21 10:23:17 +010012#include "bootutil/bootutil_public.h"
Tamas Banee6615d2020-09-30 07:58:48 +010013#include "bootutil/fault_injection_hardening.h"
Dominik Ermel8101c0c2020-05-19 13:01:16 +000014
15#include "mcuboot_config/mcuboot_config.h"
16
Carlos Falgueras GarcĂ­aa4b4b0f2021-06-22 10:00:22 +020017BOOT_LOG_MODULE_DECLARE(mcuboot);
Dominik Ermel8101c0c2020-05-19 13:01:16 +000018
19/* Variables passed outside of unit via poiters. */
20static const struct flash_area *_fa_p;
21static struct image_header _hdr = { 0 };
22
Wouter Cappelle953a7612021-05-03 16:53:05 +020023#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT) || defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
Dominik Ermel8101c0c2020-05-19 13:01:16 +000024/**
25 * Validate hash of a primary boot image.
26 *
27 * @param[in] fa_p flash area pointer
28 * @param[in] hdr boot image header pointer
29 *
Tamas Banee6615d2020-09-30 07:58:48 +010030 * @return FIH_SUCCESS on success, error code otherwise
Dominik Ermel8101c0c2020-05-19 13:01:16 +000031 */
Michael Grand5047f032022-11-24 16:49:56 +010032fih_ret
Dominik Ermel8101c0c2020-05-19 13:01:16 +000033boot_image_validate(const struct flash_area *fa_p,
34 struct image_header *hdr)
35{
36 static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
Michael Grand5047f032022-11-24 16:49:56 +010037 FIH_DECLARE(fih_rc, FIH_FAILURE);
Dominik Ermel8101c0c2020-05-19 13:01:16 +000038
Dominik Ermeld8db0252020-10-07 11:22:45 +000039 /* NOTE: The first argument to boot_image_validate, for enc_state pointer,
40 * is allowed to be NULL only because the single image loader compiles
41 * with BOOT_IMAGE_NUMBER == 1, which excludes the code that uses
42 * the pointer from compilation.
Dominik Ermel8101c0c2020-05-19 13:01:16 +000043 */
44 /* Validate hash */
Wouter Cappelle76792152022-01-19 17:28:55 +010045 if (IS_ENCRYPTED(hdr))
Wouter Cappelle953a7612021-05-03 16:53:05 +020046 {
47 /* Clear the encrypted flag we didn't supply a key
48 * This flag could be set if there was a decryption in place
49 * was performed. We will try to validate the image, and if still
50 * encrypted the validation will fail, and go in panic mode
51 */
Wouter Cappelle76792152022-01-19 17:28:55 +010052 hdr->ih_flags &= ~(ENCRYPTIONFLAGS);
Wouter Cappelle953a7612021-05-03 16:53:05 +020053 }
Tamas Banee6615d2020-09-30 07:58:48 +010054 FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, hdr, fa_p, tmpbuf,
55 BOOT_TMPBUF_SZ, NULL, 0, NULL);
Dominik Ermel8101c0c2020-05-19 13:01:16 +000056
Tamas Banee6615d2020-09-30 07:58:48 +010057 FIH_RET(fih_rc);
Dominik Ermel8101c0c2020-05-19 13:01:16 +000058}
Wouter Cappelle953a7612021-05-03 16:53:05 +020059#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT || MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE*/
Dominik Ermel8101c0c2020-05-19 13:01:16 +000060
Michael Grand5047f032022-11-24 16:49:56 +010061inline static fih_ret
Wouter Cappellebb7a39d2021-05-03 16:44:44 +020062boot_image_validate_once(const struct flash_area *fa_p,
63 struct image_header *hdr)
64{
65 static struct boot_swap_state state;
66 int rc;
Michael Grand5047f032022-11-24 16:49:56 +010067 FIH_DECLARE(fih_rc, FIH_FAILURE);
Wouter Cappellebb7a39d2021-05-03 16:44:44 +020068
69 memset(&state, 0, sizeof(struct boot_swap_state));
70 rc = boot_read_swap_state(fa_p, &state);
71 if (rc != 0)
72 FIH_RET(FIH_FAILURE);
73 if (state.magic != BOOT_MAGIC_GOOD
74 || state.image_ok != BOOT_FLAG_SET) {
75 /* At least validate the image once */
76 FIH_CALL(boot_image_validate, fih_rc, fa_p, hdr);
Michael Grand5047f032022-11-24 16:49:56 +010077 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
Wouter Cappellebb7a39d2021-05-03 16:44:44 +020078 FIH_RET(FIH_FAILURE);
79 }
80 if (state.magic != BOOT_MAGIC_GOOD) {
81 rc = boot_write_magic(fa_p);
82 if (rc != 0)
83 FIH_RET(FIH_FAILURE);
84 }
85 rc = boot_write_image_ok(fa_p);
86 if (rc != 0)
87 FIH_RET(FIH_FAILURE);
88 }
89 FIH_RET(FIH_SUCCESS);
90}
91
Dominik Ermel8101c0c2020-05-19 13:01:16 +000092/**
Dominik Ermel8101c0c2020-05-19 13:01:16 +000093 * Gather information on image and prepare for booting.
94 *
95 * @parami[out] rsp Parameters for booting image, on success
96 *
Tamas Banee6615d2020-09-30 07:58:48 +010097 * @return FIH_SUCCESS on success; nonzero on failure.
Dominik Ermel8101c0c2020-05-19 13:01:16 +000098 */
Michael Grand5047f032022-11-24 16:49:56 +010099fih_ret
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000100boot_go(struct boot_rsp *rsp)
101{
102 int rc = -1;
Michael Grand5047f032022-11-24 16:49:56 +0100103 FIH_DECLARE(fih_rc, FIH_FAILURE);
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000104
105 rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &_fa_p);
106 assert(rc == 0);
107
108 rc = boot_image_load_header(_fa_p, &_hdr);
109 if (rc != 0)
110 goto out;
111
112#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
Tamas Banee6615d2020-09-30 07:58:48 +0100113 FIH_CALL(boot_image_validate, fih_rc, _fa_p, &_hdr);
Michael Grand5047f032022-11-24 16:49:56 +0100114 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000115 goto out;
116 }
Wouter Cappellebb7a39d2021-05-03 16:44:44 +0200117#elif defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
118 FIH_CALL(boot_image_validate_once, fih_rc, _fa_p, &_hdr);
Michael Grand5047f032022-11-24 16:49:56 +0100119 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
Wouter Cappellebb7a39d2021-05-03 16:44:44 +0200120 goto out;
121 }
Tamas Banee6615d2020-09-30 07:58:48 +0100122#else
123 fih_rc = FIH_SUCCESS;
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000124#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
125
Dominik Ermel036d5212021-07-01 11:07:41 +0000126 rsp->br_flash_dev_id = flash_area_get_device_id(_fa_p);
127 rsp->br_image_off = flash_area_get_off(_fa_p);
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000128 rsp->br_hdr = &_hdr;
129
130out:
131 flash_area_close(_fa_p);
Tamas Banee6615d2020-09-30 07:58:48 +0100132
133 FIH_RET(fih_rc);
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000134}