blob: eb5b155315970e314a10628da2414b37554eab57 [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 Utzig1e48b912018-09-18 09:04:18 -030016#ifdef MCUBOOT_ENCRYPT_RSA
17#include "mbedtls/rsa.h"
18#include "mbedtls/asn1.h"
19#endif
20
21#ifdef MCUBOOT_ENCRYPT_KW
22#include "mbedtls/nist_kw.h"
23#endif
24
David Brown54b77792017-05-05 09:40:01 -060025#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
David Brown75fd5dc2017-05-04 09:04:47 -060026#include <bootutil/bootutil_log.h>
27
Fabio Utzig99dfc782018-10-15 15:10:55 -070028extern int sim_flash_erase(uint8_t flash_id, uint32_t offset, uint32_t size);
29extern int sim_flash_read(uint8_t flash_id, uint32_t offset, uint8_t *dest,
30 uint32_t size);
31extern int sim_flash_write(uint8_t flash_id, uint32_t offset, const uint8_t *src,
32 uint32_t size);
Fabio Utzig73ffc442018-10-24 21:49:09 -030033extern uint8_t sim_flash_align(uint8_t flash_id);
34extern uint8_t sim_flash_erased_val(uint8_t flash_id);
David Brownde7729e2017-01-09 10:41:35 -070035
David Brownde7729e2017-01-09 10:41:35 -070036static jmp_buf boot_jmpbuf;
37int flash_counter;
38
39int jumped = 0;
Fabio Utzig9b0ee902017-11-23 19:49:00 -020040uint8_t c_asserts = 0;
41uint8_t c_catch_asserts = 0;
David Brownde7729e2017-01-09 10:41:35 -070042
Fabio Utzig1e48b912018-09-18 09:04:18 -030043#ifdef MCUBOOT_ENCRYPT_RSA
44static int
45parse_pubkey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
46{
47 int rc;
48 size_t len;
49
50 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
51 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
52 return -1;
53 }
54
55 if (*p + len != end) {
56 return -2;
57 }
58
59 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
60 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
61 return -3;
62 }
63
64 *p += len;
65
66 if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
67 return -4;
68 }
69
70 if (**p != MBEDTLS_ASN1_PRIMITIVE) {
71 return -5;
72 }
73
74 *p += 1;
75
76 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
77 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
78 return -6;
79 }
80
81 if (mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0) {
82 return -7;
83 }
84
85 if (mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0) {
86 return -8;
87 }
88
89 ctx->len = mbedtls_mpi_size(&ctx->N);
90
91 if (*p != end) {
92 return -9;
93 }
94
95 if (mbedtls_rsa_check_pubkey(ctx) != 0) {
96 return -10;
97 }
98
99 return 0;
100}
101
102static int
103fake_rng(void *p_rng, unsigned char *output, size_t len)
104{
105 size_t i;
106
107 (void)p_rng;
108 for (i = 0; i < len; i++) {
109 output[i] = (char)i;
110 }
111
112 return 0;
113}
114#endif
115
116int mbedtls_platform_set_calloc_free(void * (*calloc_func)(size_t, size_t),
117 void (*free_func)(void *));
118
119int rsa_oaep_encrypt_(const uint8_t *pubkey, unsigned pubkey_len,
120 const uint8_t *seckey, unsigned seckey_len,
121 uint8_t *encbuf)
122{
123#ifdef MCUBOOT_ENCRYPT_RSA
124 mbedtls_rsa_context ctx;
125 uint8_t *cp;
126 uint8_t *cpend;
127 int rc;
128
129 mbedtls_platform_set_calloc_free(calloc, free);
130
131 mbedtls_rsa_init(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
132
133 cp = (uint8_t *)pubkey;
134 cpend = cp + pubkey_len;
135
136 rc = parse_pubkey(&ctx, &cp, cpend);
137 if (rc) {
138 goto done;
139 }
140
141 rc = mbedtls_rsa_rsaes_oaep_encrypt(&ctx, fake_rng, NULL, MBEDTLS_RSA_PUBLIC,
142 NULL, 0, seckey_len, seckey, encbuf);
143 if (rc) {
144 goto done;
145 }
146
147done:
148 mbedtls_rsa_free(&ctx);
149 return rc;
150
151#else
152 (void)pubkey;
153 (void)pubkey_len;
154 (void)seckey;
155 (void)seckey_len;
156 (void)encbuf;
157 return 0;
158#endif
159}
160
161int kw_encrypt_(const uint8_t *kek, const uint8_t *seckey, uint8_t *encbuf)
162{
163#ifdef MCUBOOT_ENCRYPT_KW
164 mbedtls_nist_kw_context kw;
165 size_t olen;
166 int rc;
167
168 mbedtls_platform_set_calloc_free(calloc, free);
169
170 mbedtls_nist_kw_init(&kw);
171
172 rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES, kek, 128, 1);
173 if (rc) {
174 goto done;
175 }
176
177 rc = mbedtls_nist_kw_wrap(&kw, MBEDTLS_KW_MODE_KW, seckey, 16, encbuf,
178 &olen, 24);
179
180done:
181 mbedtls_nist_kw_free(&kw);
182 return rc;
183
184#else
185 (void)kek;
186 (void)seckey;
187 (void)encbuf;
188 return 0;
189#endif
190}
191
David Brown5acda262017-01-23 15:42:19 -0700192uint8_t flash_area_align(const struct flash_area *area)
193{
Fabio Utzig73ffc442018-10-24 21:49:09 -0300194 return sim_flash_align(area->fa_device_id);
David Brown5acda262017-01-23 15:42:19 -0700195}
196
Fabio Utzigea0290b2018-08-09 14:23:01 -0300197uint8_t flash_area_erased_val(const struct flash_area *area)
198{
Fabio Utzig73ffc442018-10-24 21:49:09 -0300199 return sim_flash_erased_val(area->fa_device_id);
Fabio Utzigea0290b2018-08-09 14:23:01 -0300200}
201
David Brownde7729e2017-01-09 10:41:35 -0700202struct area {
David Brown7ad80882017-06-20 15:30:36 -0600203 struct flash_area whole;
204 struct flash_area *areas;
205 uint32_t num_areas;
206 uint8_t id;
David Brownde7729e2017-01-09 10:41:35 -0700207};
208
209struct area_desc {
David Brown7ad80882017-06-20 15:30:36 -0600210 struct area slots[16];
211 uint32_t num_slots;
David Brownde7729e2017-01-09 10:41:35 -0700212};
213
214static struct area_desc *flash_areas;
215
David Brownbdb6db72017-07-06 10:14:37 -0600216int invoke_boot_go(struct area_desc *adesc)
David Brownde7729e2017-01-09 10:41:35 -0700217{
David Brown7ad80882017-06-20 15:30:36 -0600218 int res;
219 struct boot_rsp rsp;
David Brownde7729e2017-01-09 10:41:35 -0700220
Fabio Utzig1e48b912018-09-18 09:04:18 -0300221#if defined(MCUBOOT_SIGN_RSA)
Fabio Utzigb04afa92018-09-12 15:27:04 -0300222 mbedtls_platform_set_calloc_free(calloc, free);
223#endif
David Brown7e701d82017-07-11 13:24:25 -0600224
David Brown7ad80882017-06-20 15:30:36 -0600225 flash_areas = adesc;
226 if (setjmp(boot_jmpbuf) == 0) {
227 res = boot_go(&rsp);
David Brownbdb6db72017-07-06 10:14:37 -0600228 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -0600229 /* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
230 return res;
231 } else {
David Brownbdb6db72017-07-06 10:14:37 -0600232 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -0600233 return -0x13579;
234 }
David Brownde7729e2017-01-09 10:41:35 -0700235}
236
David Brownde7729e2017-01-09 10:41:35 -0700237void *os_malloc(size_t size)
238{
David Brown7ad80882017-06-20 15:30:36 -0600239 // printf("os_malloc 0x%x bytes\n", size);
240 return malloc(size);
David Brownde7729e2017-01-09 10:41:35 -0700241}
242
243int flash_area_id_from_image_slot(int slot)
244{
David Brown7ad80882017-06-20 15:30:36 -0600245 return slot + 1;
David Brownde7729e2017-01-09 10:41:35 -0700246}
247
248int flash_area_open(uint8_t id, const struct flash_area **area)
249{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200250 uint32_t i;
David Brownde7729e2017-01-09 10:41:35 -0700251
David Brown7ad80882017-06-20 15:30:36 -0600252 for (i = 0; i < flash_areas->num_slots; i++) {
253 if (flash_areas->slots[i].id == id)
254 break;
255 }
256 if (i == flash_areas->num_slots) {
257 printf("Unsupported area\n");
258 abort();
259 }
David Brownde7729e2017-01-09 10:41:35 -0700260
David Brown7ad80882017-06-20 15:30:36 -0600261 /* Unsure if this is right, just returning the first area. */
262 *area = &flash_areas->slots[i].whole;
263 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700264}
265
266void flash_area_close(const struct flash_area *area)
267{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200268 (void)area;
David Brownde7729e2017-01-09 10:41:35 -0700269}
270
271/*
272 * Read/write/erase. Offset is relative from beginning of flash area.
273 */
274int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600275 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700276{
David Brown7ad80882017-06-20 15:30:36 -0600277 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
278 __func__, area->fa_id, off, len);
Fabio Utzig99dfc782018-10-15 15:10:55 -0700279 return sim_flash_read(area->fa_device_id, area->fa_off + off, dst, len);
David Brownde7729e2017-01-09 10:41:35 -0700280}
281
282int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
David Brown7ad80882017-06-20 15:30:36 -0600283 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700284{
David Brown7ad80882017-06-20 15:30:36 -0600285 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
286 area->fa_id, off, len);
Fabio Utzig99dfc782018-10-15 15:10:55 -0700287 if (--flash_counter == 0) {
288 jumped++;
289 longjmp(boot_jmpbuf, 1);
290 }
291 return sim_flash_write(area->fa_device_id, area->fa_off + off, src, len);
David Brownde7729e2017-01-09 10:41:35 -0700292}
293
294int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
295{
David Brown7ad80882017-06-20 15:30:36 -0600296 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
297 area->fa_id, off, len);
Fabio Utzig99dfc782018-10-15 15:10:55 -0700298 if (--flash_counter == 0) {
299 jumped++;
300 longjmp(boot_jmpbuf, 1);
301 }
302 return sim_flash_erase(area->fa_device_id, area->fa_off + off, len);
David Brownde7729e2017-01-09 10:41:35 -0700303}
304
Fabio Utzig35d31b42018-09-19 08:09:37 -0300305int flash_area_read_is_empty(const struct flash_area *area, uint32_t off,
306 void *dst, uint32_t len)
307{
308 uint8_t i;
309 uint8_t *u8dst;
310 int rc;
311
312 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__, area->fa_id, off, len);
313
Fabio Utzig99dfc782018-10-15 15:10:55 -0700314 rc = sim_flash_read(area->fa_device_id, area->fa_off + off, dst, len);
Fabio Utzig35d31b42018-09-19 08:09:37 -0300315 if (rc) {
316 return -1;
317 }
318
319 for (i = 0, u8dst = (uint8_t *)dst; i < len; i++) {
Fabio Utzig73ffc442018-10-24 21:49:09 -0300320 if (u8dst[i] != sim_flash_erased_val(area->fa_device_id)) {
Fabio Utzig35d31b42018-09-19 08:09:37 -0300321 return 0;
322 }
323 }
324
325 return 1;
326}
327
David Brownde7729e2017-01-09 10:41:35 -0700328int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
329{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200330 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600331 struct area *slot;
David Brownde7729e2017-01-09 10:41:35 -0700332
David Brown7ad80882017-06-20 15:30:36 -0600333 for (i = 0; i < flash_areas->num_slots; i++) {
334 if (flash_areas->slots[i].id == idx)
335 break;
336 }
337 if (i == flash_areas->num_slots) {
338 printf("Unsupported area\n");
339 abort();
340 }
David Brownde7729e2017-01-09 10:41:35 -0700341
David Brown7ad80882017-06-20 15:30:36 -0600342 slot = &flash_areas->slots[i];
David Brownde7729e2017-01-09 10:41:35 -0700343
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200344 if (slot->num_areas > (uint32_t)*cnt) {
David Brown7ad80882017-06-20 15:30:36 -0600345 printf("Too many areas in slot\n");
346 abort();
347 }
David Brownde7729e2017-01-09 10:41:35 -0700348
David Brown7ad80882017-06-20 15:30:36 -0600349 *cnt = slot->num_areas;
350 memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
David Brownde7729e2017-01-09 10:41:35 -0700351
David Brown7ad80882017-06-20 15:30:36 -0600352 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700353}
354
David Brown60399f62017-05-11 10:20:34 -0600355int flash_area_get_sectors(int fa_id, uint32_t *count,
356 struct flash_sector *sectors)
357{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200358 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600359 struct area *slot;
David Brown60399f62017-05-11 10:20:34 -0600360
David Brown7ad80882017-06-20 15:30:36 -0600361 for (i = 0; i < flash_areas->num_slots; i++) {
362 if (flash_areas->slots[i].id == fa_id)
363 break;
364 }
365 if (i == flash_areas->num_slots) {
366 printf("Unsupported area\n");
367 abort();
368 }
David Brown60399f62017-05-11 10:20:34 -0600369
David Brown7ad80882017-06-20 15:30:36 -0600370 slot = &flash_areas->slots[i];
David Brown60399f62017-05-11 10:20:34 -0600371
David Brown7ad80882017-06-20 15:30:36 -0600372 if (slot->num_areas > *count) {
373 printf("Too many areas in slot\n");
374 abort();
375 }
David Brown60399f62017-05-11 10:20:34 -0600376
David Brown7ad80882017-06-20 15:30:36 -0600377 for (i = 0; i < slot->num_areas; i++) {
378 sectors[i].fs_off = slot->areas[i].fa_off -
379 slot->whole.fa_off;
380 sectors[i].fs_size = slot->areas[i].fa_size;
381 }
382 *count = slot->num_areas;
David Brown60399f62017-05-11 10:20:34 -0600383
David Brown7ad80882017-06-20 15:30:36 -0600384 return 0;
David Brown60399f62017-05-11 10:20:34 -0600385}
Fabio Utzig9b0ee902017-11-23 19:49:00 -0200386
387void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
388{
389 if (!(x)) {
390 if (c_catch_asserts) {
391 c_asserts++;
392 } else {
393 BOOT_LOG_ERR("%s:%d: %s: Assertion `%s' failed.", file, line, function, assertion);
394
395 /* NOTE: if the assert below is triggered, the place where it was originally
396 * asserted is printed by the message above...
397 */
398 assert(x);
399 }
400 }
401}