blob: a5e9d1f7681392f6f4b7d9dcaca1ac3411f705b1 [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"
13#include "bootutil/fault_injection_hardening_delay_rng.h"
Dominik Ermel8101c0c2020-05-19 13:01:16 +000014
15#include "mcuboot_config/mcuboot_config.h"
16
17MCUBOOT_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#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
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 *
Tamas Banee6615d2020-09-30 07:58:48 +010030 * @return FIH_SUCCESS on success, error code otherwise
Dominik Ermel8101c0c2020-05-19 13:01:16 +000031 */
Tamas Banee6615d2020-09-30 07:58:48 +010032inline static fih_int
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];
Tamas Banee6615d2020-09-30 07:58:48 +010037 fih_int fih_rc = FIH_FAILURE;
Dominik Ermel8101c0c2020-05-19 13:01:16 +000038
39 /* NOTE: The enc-state pointer may be NULL only because when there is
40 * only one image (BOOT_IMAGE_NUMBER == 1), the code that uses the
41 * pointer, within bootutil_img_validate and down the call path,
42 * is excluded from compilation.
43 */
44 /* Validate hash */
Tamas Banee6615d2020-09-30 07:58:48 +010045 FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, hdr, fa_p, tmpbuf,
46 BOOT_TMPBUF_SZ, NULL, 0, NULL);
Dominik Ermel8101c0c2020-05-19 13:01:16 +000047
Tamas Banee6615d2020-09-30 07:58:48 +010048 FIH_RET(fih_rc);
Dominik Ermel8101c0c2020-05-19 13:01:16 +000049}
50#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
51
52
53/**
54 * Attempts to load image header from flash; verifies flash header fields.
55 *
56 * @param[in] fa_p flash area pointer
57 * @param[out] hdr buffer for image header
58 *
59 * @return 0 on success, error code otherwise
60 */
61static int
62boot_image_load_header(const struct flash_area *fa_p,
63 struct image_header *hdr)
64{
65 uint32_t size;
66 int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr);
67
68 if (rc != 0) {
69 rc = BOOT_EFLASH;
70 BOOT_LOG_ERR("Failed reading image header");
71 return BOOT_EFLASH;
72 }
73
74 if (hdr->ih_magic != IMAGE_MAGIC) {
75 BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic);
76
77 return BOOT_EBADIMAGE;
78 }
79
80 if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) {
81 BOOT_LOG_ERR("Image not bootable");
82
83 return BOOT_EBADIMAGE;
84 }
85
86 if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) ||
87 size >= fa_p->fa_size) {
88 return BOOT_EBADIMAGE;
89 }
90
91 return 0;
92}
93
94
95/**
96 * Gather information on image and prepare for booting.
97 *
98 * @parami[out] rsp Parameters for booting image, on success
99 *
Tamas Banee6615d2020-09-30 07:58:48 +0100100 * @return FIH_SUCCESS on success; nonzero on failure.
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000101 */
Tamas Banee6615d2020-09-30 07:58:48 +0100102fih_int
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000103boot_go(struct boot_rsp *rsp)
104{
105 int rc = -1;
Tamas Banee6615d2020-09-30 07:58:48 +0100106 fih_int fih_rc = FIH_FAILURE;
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000107
108 rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &_fa_p);
109 assert(rc == 0);
110
111 rc = boot_image_load_header(_fa_p, &_hdr);
112 if (rc != 0)
113 goto out;
114
115#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
Tamas Banee6615d2020-09-30 07:58:48 +0100116 FIH_CALL(boot_image_validate, fih_rc, _fa_p, &_hdr);
117 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000118 goto out;
119 }
Tamas Banee6615d2020-09-30 07:58:48 +0100120#else
121 fih_rc = FIH_SUCCESS;
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000122#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
123
124 rsp->br_flash_dev_id = _fa_p->fa_device_id;
125 rsp->br_image_off = _fa_p->fa_off;
126 rsp->br_hdr = &_hdr;
127
128out:
129 flash_area_close(_fa_p);
Tamas Banee6615d2020-09-30 07:58:48 +0100130
131 FIH_RET(fih_rc);
Dominik Ermel8101c0c2020-05-19 13:01:16 +0000132}