blob: 258d38bef0001f5ab0a37c95d4997b6c5138f549 [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
5 */
6
7#include <assert.h>
8#include "bootutil/image.h"
9#include "bootutil_priv.h"
10#include "bootutil/bootutil_log.h"
11
12#include "mcuboot_config/mcuboot_config.h"
13
14MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
15
16/* Variables passed outside of unit via poiters. */
17static const struct flash_area *_fa_p;
18static struct image_header _hdr = { 0 };
19
20#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
21/**
22 * Validate hash of a primary boot image.
23 *
24 * @param[in] fa_p flash area pointer
25 * @param[in] hdr boot image header pointer
26 *
27 * @return 0 on success, error code otherwise
28 */
29inline static int
30boot_image_validate(const struct flash_area *fa_p,
31 struct image_header *hdr)
32{
33 static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
34
35 /* NOTE: The enc-state pointer may be NULL only because when there is
36 * only one image (BOOT_IMAGE_NUMBER == 1), the code that uses the
37 * pointer, within bootutil_img_validate and down the call path,
38 * is excluded from compilation.
39 */
40 /* Validate hash */
41 if (bootutil_img_validate(NULL, 0, hdr, fa_p, tmpbuf,
42 BOOT_TMPBUF_SZ, NULL, 0, NULL)) {
43 return BOOT_EBADIMAGE;
44 }
45
46 return 0;
47}
48#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
49
50
51/**
52 * Attempts to load image header from flash; verifies flash header fields.
53 *
54 * @param[in] fa_p flash area pointer
55 * @param[out] hdr buffer for image header
56 *
57 * @return 0 on success, error code otherwise
58 */
59static int
60boot_image_load_header(const struct flash_area *fa_p,
61 struct image_header *hdr)
62{
63 uint32_t size;
64 int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr);
65
66 if (rc != 0) {
67 rc = BOOT_EFLASH;
68 BOOT_LOG_ERR("Failed reading image header");
69 return BOOT_EFLASH;
70 }
71
72 if (hdr->ih_magic != IMAGE_MAGIC) {
73 BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic);
74
75 return BOOT_EBADIMAGE;
76 }
77
78 if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) {
79 BOOT_LOG_ERR("Image not bootable");
80
81 return BOOT_EBADIMAGE;
82 }
83
84 if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) ||
85 size >= fa_p->fa_size) {
86 return BOOT_EBADIMAGE;
87 }
88
89 return 0;
90}
91
92
93/**
94 * Gather information on image and prepare for booting.
95 *
96 * @parami[out] rsp Parameters for booting image, on success
97 *
98 * @return 0 on success, error code otherwise.
99 */
100int
101boot_go(struct boot_rsp *rsp)
102{
103 int rc = -1;
104
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
113 rc = boot_image_validate(_fa_p, &_hdr);
114 if (rc != 0) {
115 goto out;
116 }
117#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
118
119 rsp->br_flash_dev_id = _fa_p->fa_device_id;
120 rsp->br_image_off = _fa_p->fa_off;
121 rsp->br_hdr = &_hdr;
122
123out:
124 flash_area_close(_fa_p);
125 return rc;
126}