blob: c16a0b790d9fccfc0e4edaa736521a0b451b6153 [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"
Tamas Banee6615d2020-09-30 07:58:48 +010012#include "bootutil/fault_injection_hardening.h"
Dominik Ermel8101c0c2020-05-19 13:01:16 +000013
14#include "mcuboot_config/mcuboot_config.h"
15
16MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
17
18/* Variables passed outside of unit via poiters. */
19static const struct flash_area *_fa_p;
20static struct image_header _hdr = { 0 };
21
22#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
23/**
24 * Validate hash of a primary boot image.
25 *
26 * @param[in] fa_p flash area pointer
27 * @param[in] hdr boot image header pointer
28 *
Tamas Banee6615d2020-09-30 07:58:48 +010029 * @return FIH_SUCCESS on success, error code otherwise
Dominik Ermel8101c0c2020-05-19 13:01:16 +000030 */
Tamas Banee6615d2020-09-30 07:58:48 +010031inline static fih_int
Dominik Ermel8101c0c2020-05-19 13:01:16 +000032boot_image_validate(const struct flash_area *fa_p,
33 struct image_header *hdr)
34{
35 static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
Tamas Banee6615d2020-09-30 07:58:48 +010036 fih_int fih_rc = FIH_FAILURE;
Dominik Ermel8101c0c2020-05-19 13:01:16 +000037
Dominik Ermeld8db0252020-10-07 11:22:45 +000038 /* NOTE: The first argument to boot_image_validate, for enc_state pointer,
39 * is allowed to be NULL only because the single image loader compiles
40 * with BOOT_IMAGE_NUMBER == 1, which excludes the code that uses
41 * the pointer from compilation.
Dominik Ermel8101c0c2020-05-19 13:01:16 +000042 */
43 /* Validate hash */
Tamas Banee6615d2020-09-30 07:58:48 +010044 FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, hdr, fa_p, tmpbuf,
45 BOOT_TMPBUF_SZ, NULL, 0, NULL);
Dominik Ermel8101c0c2020-05-19 13:01:16 +000046
Tamas Banee6615d2020-09-30 07:58:48 +010047 FIH_RET(fih_rc);
Dominik Ermel8101c0c2020-05-19 13:01:16 +000048}
49#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
50
51
52/**
53 * Attempts to load image header from flash; verifies flash header fields.
54 *
55 * @param[in] fa_p flash area pointer
56 * @param[out] hdr buffer for image header
57 *
58 * @return 0 on success, error code otherwise
59 */
60static int
61boot_image_load_header(const struct flash_area *fa_p,
62 struct image_header *hdr)
63{
64 uint32_t size;
65 int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr);
66
67 if (rc != 0) {
68 rc = BOOT_EFLASH;
69 BOOT_LOG_ERR("Failed reading image header");
70 return BOOT_EFLASH;
71 }
72
73 if (hdr->ih_magic != IMAGE_MAGIC) {
74 BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic);
75
76 return BOOT_EBADIMAGE;
77 }
78
79 if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) {
80 BOOT_LOG_ERR("Image not bootable");
81
82 return BOOT_EBADIMAGE;
83 }
84
85 if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) ||
86 size >= fa_p->fa_size) {
87 return BOOT_EBADIMAGE;
88 }
89
90 return 0;
91}
92
93
94/**
95 * Gather information on image and prepare for booting.
96 *
97 * @parami[out] rsp Parameters for booting image, on success
98 *
Tamas Banee6615d2020-09-30 07:58:48 +010099 * @return FIH_SUCCESS on success; nonzero on failure.
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000100 */
Tamas Banee6615d2020-09-30 07:58:48 +0100101fih_int
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000102boot_go(struct boot_rsp *rsp)
103{
104 int rc = -1;
Tamas Banee6615d2020-09-30 07:58:48 +0100105 fih_int fih_rc = FIH_FAILURE;
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000106
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
Tamas Banee6615d2020-09-30 07:58:48 +0100115 FIH_CALL(boot_image_validate, fih_rc, _fa_p, &_hdr);
116 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000117 goto out;
118 }
Tamas Banee6615d2020-09-30 07:58:48 +0100119#else
120 fih_rc = FIH_SUCCESS;
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000121#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
122
123 rsp->br_flash_dev_id = _fa_p->fa_device_id;
124 rsp->br_image_off = _fa_p->fa_off;
125 rsp->br_hdr = &_hdr;
126
127out:
128 flash_area_close(_fa_p);
Tamas Banee6615d2020-09-30 07:58:48 +0100129
130 FIH_RET(fih_rc);
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000131}