blob: 564d7489e6634e30c1a9f19f8379b3bfc458abd9 [file] [log] [blame]
Jerzy Kasenberged6460b2024-04-09 10:49:14 +02001/*
2 * SPDX-License-Identifier: Apache-2.0
3 *
4 * Copyright (c) 2020 Nordic Semiconductor ASA
5 * Copyright (c) 2020 Arm Limited
6 */
7
8#include <assert.h>
9#include "bootutil/image.h"
10#include "../../../bootutil/src/bootutil_priv.h"
11#include "bootutil/bootutil_log.h"
12#include "bootutil/bootutil_public.h"
13#include "bootutil/fault_injection_hardening.h"
14
15#include "mcuboot_config/mcuboot_config.h"
16
17BOOT_LOG_MODULE_DECLARE(mcuboot);
18
19/* Variables passed outside of unit via poiters. */
20static const struct flash_area *_fa_p;
21static struct image_header _hdr = { 0 };
22
23#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT) || defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
24/**
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 *
30 * @return FIH_SUCCESS on success, error code otherwise
31 */
32fih_ret
33boot_image_validate(const struct flash_area *fa_p,
34 struct image_header *hdr)
35{
36 static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
37 FIH_DECLARE(fih_rc, FIH_FAILURE);
38
39 /* 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.
43 */
44 /* Validate hash */
45 if (IS_ENCRYPTED(hdr))
46 {
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 */
52 hdr->ih_flags &= ~(ENCRYPTIONFLAGS);
53 }
54 FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, hdr, fa_p, tmpbuf,
55 BOOT_TMPBUF_SZ, NULL, 0, NULL);
56
57 FIH_RET(fih_rc);
58}
59#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT || MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE*/
60
61#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
62inline static fih_ret
63boot_image_validate_once(const struct flash_area *fa_p,
64 struct image_header *hdr)
65{
66 static struct boot_swap_state state;
67 int rc;
68 FIH_DECLARE(fih_rc, FIH_FAILURE);
69
70 memset(&state, 0, sizeof(struct boot_swap_state));
71 rc = boot_read_swap_state(fa_p, &state);
72 if (rc != 0)
73 FIH_RET(FIH_FAILURE);
74 if (state.magic != BOOT_MAGIC_GOOD
75 || state.image_ok != BOOT_FLAG_SET) {
76 /* At least validate the image once */
77 FIH_CALL(boot_image_validate, fih_rc, fa_p, hdr);
78 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
79 FIH_RET(FIH_FAILURE);
80 }
81 if (state.magic != BOOT_MAGIC_GOOD) {
82 rc = boot_write_magic(fa_p);
83 if (rc != 0)
84 FIH_RET(FIH_FAILURE);
85 }
86 rc = boot_write_image_ok(fa_p);
87 if (rc != 0)
88 FIH_RET(FIH_FAILURE);
89 }
90 FIH_RET(FIH_SUCCESS);
91}
92#endif
93
94/**
95 * Gather information on image and prepare for booting.
96 *
97 * @parami[out] rsp Parameters for booting image, on success
98 *
99 * @return FIH_SUCCESS on success; nonzero on failure.
100 */
101fih_ret
102boot_go(struct boot_rsp *rsp)
103{
104 int rc = -1;
105 FIH_DECLARE(fih_rc, FIH_FAILURE);
106
107 rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &_fa_p);
108 assert(rc == 0);
109
110 rc = boot_image_load_header(_fa_p, &_hdr);
111 if (rc != 0)
112 goto out;
113
114#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
115 FIH_CALL(boot_image_validate, fih_rc, _fa_p, &_hdr);
116 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
117 goto out;
118 }
119#elif defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
120 FIH_CALL(boot_image_validate_once, fih_rc, _fa_p, &_hdr);
121 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
122 goto out;
123 }
124#else
125 fih_rc = FIH_SUCCESS;
126#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
127
128 rsp->br_flash_dev_id = flash_area_get_device_id(_fa_p);
129 rsp->br_image_off = flash_area_get_off(_fa_p);
130 rsp->br_hdr = &_hdr;
131
132out:
133 flash_area_close(_fa_p);
134
135 FIH_RET(fih_rc);
136}