blob: 17a10f1216e2f916908a70c4e450fdb02a2650f2 [file] [log] [blame]
David Brownde7729e2017-01-09 10:41:35 -07001/* Run the boot image. */
2
Fabio Utzig9b0ee902017-11-23 19:49:00 -02003#include <assert.h>
David Brownde7729e2017-01-09 10:41:35 -07004#include <setjmp.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <bootutil/bootutil.h>
9#include <bootutil/image.h>
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020010
11#include <flash_map_backend/flash_map_backend.h>
David Brownde7729e2017-01-09 10:41:35 -070012
David Brownd2b18532017-07-12 09:51:31 -060013#include "../../../boot/bootutil/src/bootutil_priv.h"
Fabio Utzig57c40f72017-12-12 21:48:30 -020014#include "bootsim.h"
David Brownde7729e2017-01-09 10:41:35 -070015
Fabio Utzig92be3fb2017-12-05 08:52:53 -020016#ifdef MCUBOOT_SIGN_EC256
17#include "../../../ext/tinycrypt/lib/include/tinycrypt/ecc_dsa.h"
18#endif
19
David Brown54b77792017-05-05 09:40:01 -060020#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
David Brown75fd5dc2017-05-04 09:04:47 -060021#include <bootutil/bootutil_log.h>
22
David Brownbdb6db72017-07-06 10:14:37 -060023extern int sim_flash_erase(uint32_t offset, uint32_t size);
24extern int sim_flash_read(uint32_t offset, uint8_t *dest, uint32_t size);
25extern int sim_flash_write(uint32_t offset, const uint8_t *src, uint32_t size);
David Brownde7729e2017-01-09 10:41:35 -070026
David Brownde7729e2017-01-09 10:41:35 -070027static jmp_buf boot_jmpbuf;
28int flash_counter;
29
30int jumped = 0;
Fabio Utzig9b0ee902017-11-23 19:49:00 -020031uint8_t c_asserts = 0;
32uint8_t c_catch_asserts = 0;
David Brownde7729e2017-01-09 10:41:35 -070033
Fabio Utzig92be3fb2017-12-05 08:52:53 -020034int ecdsa256_sign_(const uint8_t *privkey, const uint8_t *hash,
35 unsigned hash_len, uint8_t *signature)
36{
37#ifdef MCUBOOT_SIGN_EC256
38 return uECC_sign(privkey, hash, hash_len, signature, uECC_secp256r1());
39#else
40 (void)privkey;
41 (void)hash;
42 (void)hash_len;
43 (void)signature;
44 return 0;
45#endif
46}
47
David Brown5acda262017-01-23 15:42:19 -070048uint8_t sim_flash_align = 1;
49uint8_t flash_area_align(const struct flash_area *area)
50{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020051 (void)area;
David Brown7ad80882017-06-20 15:30:36 -060052 return sim_flash_align;
David Brown5acda262017-01-23 15:42:19 -070053}
54
Fabio Utzigea0290b2018-08-09 14:23:01 -030055uint8_t sim_flash_erased_val = 0xff;
56uint8_t flash_area_erased_val(const struct flash_area *area)
57{
58 (void)area;
59 return sim_flash_erased_val;
60}
61
David Brownde7729e2017-01-09 10:41:35 -070062struct area {
David Brown7ad80882017-06-20 15:30:36 -060063 struct flash_area whole;
64 struct flash_area *areas;
65 uint32_t num_areas;
66 uint8_t id;
David Brownde7729e2017-01-09 10:41:35 -070067};
68
69struct area_desc {
David Brown7ad80882017-06-20 15:30:36 -060070 struct area slots[16];
71 uint32_t num_slots;
David Brownde7729e2017-01-09 10:41:35 -070072};
73
74static struct area_desc *flash_areas;
75
Fabio Utzigb04afa92018-09-12 15:27:04 -030076#ifdef MCUBOOT_SIGN_RSA
77int mbedtls_platform_set_calloc_free(void * (*calloc_func)(size_t, size_t),
78 void (*free_func)(void *));
79#endif
David Brown7e701d82017-07-11 13:24:25 -060080
David Brownbdb6db72017-07-06 10:14:37 -060081int invoke_boot_go(struct area_desc *adesc)
David Brownde7729e2017-01-09 10:41:35 -070082{
David Brown7ad80882017-06-20 15:30:36 -060083 int res;
84 struct boot_rsp rsp;
David Brownde7729e2017-01-09 10:41:35 -070085
Fabio Utzigb04afa92018-09-12 15:27:04 -030086#ifdef MCUBOOT_SIGN_RSA
87 mbedtls_platform_set_calloc_free(calloc, free);
88#endif
David Brown7e701d82017-07-11 13:24:25 -060089
David Brown7ad80882017-06-20 15:30:36 -060090 flash_areas = adesc;
91 if (setjmp(boot_jmpbuf) == 0) {
92 res = boot_go(&rsp);
David Brownbdb6db72017-07-06 10:14:37 -060093 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060094 /* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
95 return res;
96 } else {
David Brownbdb6db72017-07-06 10:14:37 -060097 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060098 return -0x13579;
99 }
David Brownde7729e2017-01-09 10:41:35 -0700100}
101
102int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600103 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -0700104{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200105 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600106 // printf("hal_flash_read: %d, 0x%08x (0x%x)\n",
107 // flash_id, address, num_bytes);
David Brownbdb6db72017-07-06 10:14:37 -0600108 return sim_flash_read(address, dst, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700109}
110
111int hal_flash_write(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -0600112 const void *src, int32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -0700113{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200114 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600115 // printf("hal_flash_write: 0x%08x (0x%x)\n", address, num_bytes);
116 // fflush(stdout);
117 if (--flash_counter == 0) {
118 jumped++;
119 longjmp(boot_jmpbuf, 1);
120 }
David Brownbdb6db72017-07-06 10:14:37 -0600121 return sim_flash_write(address, src, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700122}
123
124int hal_flash_erase(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -0600125 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -0700126{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200127 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600128 // printf("hal_flash_erase: 0x%08x, (0x%x)\n", address, num_bytes);
129 // fflush(stdout);
130 if (--flash_counter == 0) {
131 jumped++;
132 longjmp(boot_jmpbuf, 1);
133 }
David Brownbdb6db72017-07-06 10:14:37 -0600134 return sim_flash_erase(address, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700135}
136
David Brownde7729e2017-01-09 10:41:35 -0700137void *os_malloc(size_t size)
138{
David Brown7ad80882017-06-20 15:30:36 -0600139 // printf("os_malloc 0x%x bytes\n", size);
140 return malloc(size);
David Brownde7729e2017-01-09 10:41:35 -0700141}
142
143int flash_area_id_from_image_slot(int slot)
144{
David Brown7ad80882017-06-20 15:30:36 -0600145 return slot + 1;
David Brownde7729e2017-01-09 10:41:35 -0700146}
147
148int flash_area_open(uint8_t id, const struct flash_area **area)
149{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200150 uint32_t i;
David Brownde7729e2017-01-09 10:41:35 -0700151
David Brown7ad80882017-06-20 15:30:36 -0600152 for (i = 0; i < flash_areas->num_slots; i++) {
153 if (flash_areas->slots[i].id == id)
154 break;
155 }
156 if (i == flash_areas->num_slots) {
157 printf("Unsupported area\n");
158 abort();
159 }
David Brownde7729e2017-01-09 10:41:35 -0700160
David Brown7ad80882017-06-20 15:30:36 -0600161 /* Unsure if this is right, just returning the first area. */
162 *area = &flash_areas->slots[i].whole;
163 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700164}
165
166void flash_area_close(const struct flash_area *area)
167{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200168 (void)area;
David Brownde7729e2017-01-09 10:41:35 -0700169}
170
171/*
172 * Read/write/erase. Offset is relative from beginning of flash area.
173 */
174int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600175 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700176{
David Brown7ad80882017-06-20 15:30:36 -0600177 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
178 __func__, area->fa_id, off, len);
179 return hal_flash_read(area->fa_id,
180 area->fa_off + off,
181 dst, len);
David Brownde7729e2017-01-09 10:41:35 -0700182}
183
184int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
David Brown7ad80882017-06-20 15:30:36 -0600185 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700186{
David Brown7ad80882017-06-20 15:30:36 -0600187 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
188 area->fa_id, off, len);
189 return hal_flash_write(area->fa_id,
190 area->fa_off + off,
191 src, len);
David Brownde7729e2017-01-09 10:41:35 -0700192}
193
194int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
195{
David Brown7ad80882017-06-20 15:30:36 -0600196 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
197 area->fa_id, off, len);
198 return hal_flash_erase(area->fa_id,
199 area->fa_off + off,
200 len);
David Brownde7729e2017-01-09 10:41:35 -0700201}
202
Fabio Utzig35d31b42018-09-19 08:09:37 -0300203int flash_area_read_is_empty(const struct flash_area *area, uint32_t off,
204 void *dst, uint32_t len)
205{
206 uint8_t i;
207 uint8_t *u8dst;
208 int rc;
209
210 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__, area->fa_id, off, len);
211
212 rc = hal_flash_read(area->fa_device_id, area->fa_off + off, dst, len);
213 if (rc) {
214 return -1;
215 }
216
217 for (i = 0, u8dst = (uint8_t *)dst; i < len; i++) {
218 if (u8dst[i] != sim_flash_erased_val) {
219 return 0;
220 }
221 }
222
223 return 1;
224}
225
David Brownde7729e2017-01-09 10:41:35 -0700226int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
227{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200228 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600229 struct area *slot;
David Brownde7729e2017-01-09 10:41:35 -0700230
David Brown7ad80882017-06-20 15:30:36 -0600231 for (i = 0; i < flash_areas->num_slots; i++) {
232 if (flash_areas->slots[i].id == idx)
233 break;
234 }
235 if (i == flash_areas->num_slots) {
236 printf("Unsupported area\n");
237 abort();
238 }
David Brownde7729e2017-01-09 10:41:35 -0700239
David Brown7ad80882017-06-20 15:30:36 -0600240 slot = &flash_areas->slots[i];
David Brownde7729e2017-01-09 10:41:35 -0700241
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200242 if (slot->num_areas > (uint32_t)*cnt) {
David Brown7ad80882017-06-20 15:30:36 -0600243 printf("Too many areas in slot\n");
244 abort();
245 }
David Brownde7729e2017-01-09 10:41:35 -0700246
David Brown7ad80882017-06-20 15:30:36 -0600247 *cnt = slot->num_areas;
248 memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
David Brownde7729e2017-01-09 10:41:35 -0700249
David Brown7ad80882017-06-20 15:30:36 -0600250 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700251}
252
David Brown60399f62017-05-11 10:20:34 -0600253int flash_area_get_sectors(int fa_id, uint32_t *count,
254 struct flash_sector *sectors)
255{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200256 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600257 struct area *slot;
David Brown60399f62017-05-11 10:20:34 -0600258
David Brown7ad80882017-06-20 15:30:36 -0600259 for (i = 0; i < flash_areas->num_slots; i++) {
260 if (flash_areas->slots[i].id == fa_id)
261 break;
262 }
263 if (i == flash_areas->num_slots) {
264 printf("Unsupported area\n");
265 abort();
266 }
David Brown60399f62017-05-11 10:20:34 -0600267
David Brown7ad80882017-06-20 15:30:36 -0600268 slot = &flash_areas->slots[i];
David Brown60399f62017-05-11 10:20:34 -0600269
David Brown7ad80882017-06-20 15:30:36 -0600270 if (slot->num_areas > *count) {
271 printf("Too many areas in slot\n");
272 abort();
273 }
David Brown60399f62017-05-11 10:20:34 -0600274
David Brown7ad80882017-06-20 15:30:36 -0600275 for (i = 0; i < slot->num_areas; i++) {
276 sectors[i].fs_off = slot->areas[i].fa_off -
277 slot->whole.fa_off;
278 sectors[i].fs_size = slot->areas[i].fa_size;
279 }
280 *count = slot->num_areas;
David Brown60399f62017-05-11 10:20:34 -0600281
David Brown7ad80882017-06-20 15:30:36 -0600282 return 0;
David Brown60399f62017-05-11 10:20:34 -0600283}
Fabio Utzig9b0ee902017-11-23 19:49:00 -0200284
285void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
286{
287 if (!(x)) {
288 if (c_catch_asserts) {
289 c_asserts++;
290 } else {
291 BOOT_LOG_ERR("%s:%d: %s: Assertion `%s' failed.", file, line, function, assertion);
292
293 /* NOTE: if the assert below is triggered, the place where it was originally
294 * asserted is printed by the message above...
295 */
296 assert(x);
297 }
298 }
299}