1 /* Run the boot image. */
2
3 #include <assert.h>
4 #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>
10 #include <errno.h>
11
12 #include <flash_map_backend/flash_map_backend.h>
13
14 #include "../../../boot/bootutil/src/bootutil_priv.h"
15 #include "bootsim.h"
16
17 #ifdef MCUBOOT_ENCRYPT_RSA
18 #include "mbedtls/rsa.h"
19 #include "mbedtls/asn1.h"
20 #endif
21
22 #ifdef MCUBOOT_ENCRYPT_KW
23 #include "mbedtls/nist_kw.h"
24 #endif
25
26 #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
27 #include <bootutil/bootutil_log.h>
28 #include "bootutil/crypto/common.h"
29
30 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
31
32 struct area_desc;
33 extern struct area_desc *sim_get_flash_areas(void);
34 extern void sim_set_flash_areas(struct area_desc *areas);
35 extern void sim_reset_flash_areas(void);
36
37 struct sim_context;
38 extern struct sim_context *sim_get_context(void);
39 extern void sim_set_context(struct sim_context *ctx);
40 extern void sim_reset_context(void);
41
42 extern int sim_flash_erase(uint8_t flash_id, uint32_t offset, uint32_t size);
43 extern int sim_flash_read(uint8_t flash_id, uint32_t offset, uint8_t *dest,
44 uint32_t size);
45 extern int sim_flash_write(uint8_t flash_id, uint32_t offset, const uint8_t *src,
46 uint32_t size);
47 extern uint32_t sim_flash_align(uint8_t flash_id);
48 extern uint8_t sim_flash_erased_val(uint8_t flash_id);
49
50 struct sim_context {
51 int flash_counter;
52 int jumped;
53 uint8_t c_asserts;
54 uint8_t c_catch_asserts;
55 jmp_buf boot_jmpbuf;
56 };
57
58 #ifdef MCUBOOT_ENCRYPT_RSA
59 static int
parse_pubkey(mbedtls_rsa_context * ctx,uint8_t ** p,uint8_t * end)60 parse_pubkey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
61 {
62 int rc;
63 size_t len;
64
65 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
66 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
67 return -1;
68 }
69
70 if (*p + len != end) {
71 return -2;
72 }
73
74 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
75 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
76 return -3;
77 }
78
79 *p += len;
80
81 if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
82 return -4;
83 }
84
85 if (**p != MBEDTLS_ASN1_PRIMITIVE) {
86 return -5;
87 }
88
89 *p += 1;
90
91 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
92 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
93 return -6;
94 }
95
96 if (mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(N)) != 0) {
97 return -7;
98 }
99
100 if (mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(E)) != 0) {
101 return -8;
102 }
103
104 ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
105
106 if (*p != end) {
107 return -9;
108 }
109
110 if (mbedtls_rsa_check_pubkey(ctx) != 0) {
111 return -10;
112 }
113
114 return 0;
115 }
116
117 static int
fake_rng(void * p_rng,unsigned char * output,size_t len)118 fake_rng(void *p_rng, unsigned char *output, size_t len)
119 {
120 size_t i;
121
122 (void)p_rng;
123 for (i = 0; i < len; i++) {
124 output[i] = (char)i;
125 }
126
127 return 0;
128 }
129 #endif
130
131 int mbedtls_platform_set_calloc_free(void * (*calloc_func)(size_t, size_t),
132 void (*free_func)(void *));
133
rsa_oaep_encrypt_(const uint8_t * pubkey,unsigned pubkey_len,const uint8_t * seckey,unsigned seckey_len,uint8_t * encbuf)134 int rsa_oaep_encrypt_(const uint8_t *pubkey, unsigned pubkey_len,
135 const uint8_t *seckey, unsigned seckey_len,
136 uint8_t *encbuf)
137 {
138 #ifdef MCUBOOT_ENCRYPT_RSA
139 mbedtls_rsa_context ctx;
140 uint8_t *cp;
141 uint8_t *cpend;
142 int rc;
143
144 mbedtls_platform_set_calloc_free(calloc, free);
145
146 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
147 mbedtls_rsa_init(&ctx);
148 mbedtls_rsa_set_padding(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
149 #else
150 mbedtls_rsa_init(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
151 #endif
152
153 cp = (uint8_t *)pubkey;
154 cpend = cp + pubkey_len;
155
156 rc = parse_pubkey(&ctx, &cp, cpend);
157 if (rc) {
158 goto done;
159 }
160
161 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
162 rc = mbedtls_rsa_rsaes_oaep_encrypt(&ctx, fake_rng, NULL,
163 NULL, 0, seckey_len, seckey, encbuf);
164 #else
165 rc = mbedtls_rsa_rsaes_oaep_encrypt(&ctx, fake_rng, NULL, MBEDTLS_RSA_PUBLIC,
166 NULL, 0, seckey_len, seckey, encbuf);
167 #endif
168 if (rc) {
169 goto done;
170 }
171
172 done:
173 mbedtls_rsa_free(&ctx);
174 return rc;
175
176 #else
177 (void)pubkey;
178 (void)pubkey_len;
179 (void)seckey;
180 (void)seckey_len;
181 (void)encbuf;
182 return 0;
183 #endif
184 }
185
kw_encrypt_(const uint8_t * kek,const uint8_t * seckey,uint8_t * encbuf)186 int kw_encrypt_(const uint8_t *kek, const uint8_t *seckey, uint8_t *encbuf)
187 {
188 #ifdef MCUBOOT_ENCRYPT_KW
189 #ifdef MCUBOOT_AES_256
190 int key_len = 256;
191 int out_size = 40;
192 int in_len = 32;
193 #else
194 int key_len = 128;
195 int out_size = 24;
196 int in_len = 16;
197 #endif
198 mbedtls_nist_kw_context kw;
199 size_t olen;
200 int rc;
201
202 mbedtls_platform_set_calloc_free(calloc, free);
203
204 mbedtls_nist_kw_init(&kw);
205
206 rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES, kek, key_len, 1);
207 if (rc) {
208 goto done;
209 }
210
211 rc = mbedtls_nist_kw_wrap(&kw, MBEDTLS_KW_MODE_KW, seckey, in_len, encbuf,
212 &olen, out_size);
213
214 done:
215 mbedtls_nist_kw_free(&kw);
216 return rc;
217
218 #else
219 (void)kek;
220 (void)seckey;
221 (void)encbuf;
222 return 0;
223 #endif
224 }
225
flash_area_align(const struct flash_area * area)226 uint32_t flash_area_align(const struct flash_area *area)
227 {
228 return sim_flash_align(area->fa_device_id);
229 }
230
flash_area_erased_val(const struct flash_area * area)231 uint8_t flash_area_erased_val(const struct flash_area *area)
232 {
233 return sim_flash_erased_val(area->fa_device_id);
234 }
235
236 struct area {
237 struct flash_area whole;
238 struct flash_area *areas;
239 uint32_t num_areas;
240 uint8_t id;
241 };
242
243 struct area_desc {
244 struct area slots[16];
245 uint32_t num_slots;
246 };
247
invoke_boot_go(struct sim_context * ctx,struct area_desc * adesc,struct boot_rsp * rsp,int image_id)248 int invoke_boot_go(struct sim_context *ctx, struct area_desc *adesc,
249 struct boot_rsp *rsp, int image_id)
250 {
251 int res;
252 struct boot_loader_state *state;
253
254 #if defined(MCUBOOT_SIGN_RSA) || \
255 (defined(MCUBOOT_SIGN_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ||\
256 (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ||\
257 (defined(MCUBOOT_ENCRYPT_X25519) && defined(MCUBOOT_USE_MBED_TLS))
258 mbedtls_platform_set_calloc_free(calloc, free);
259 #endif
260
261 state = malloc(sizeof(struct boot_loader_state));
262
263 sim_set_flash_areas(adesc);
264 sim_set_context(ctx);
265
266 if (setjmp(ctx->boot_jmpbuf) == 0) {
267 boot_state_clear(state);
268
269 #if BOOT_IMAGE_NUMBER > 1
270 if (image_id >= 0) {
271 memset(state->img_mask, 1, sizeof(state->img_mask));
272 state->img_mask[image_id] = 0;
273 }
274 #else
275 (void) image_id;
276 #endif /* BOOT_IMAGE_NUMBER > 1 */
277
278 res = context_boot_go(state, rsp);
279 sim_reset_flash_areas();
280 sim_reset_context();
281 free(state);
282 /* printf("boot_go off: %d (0x%08x)\n", res, rsp->br_image_off); */
283 return res;
284 } else {
285 sim_reset_flash_areas();
286 sim_reset_context();
287 free(state);
288 return -0x13579;
289 }
290 }
291
os_malloc(size_t size)292 void *os_malloc(size_t size)
293 {
294 // printf("os_malloc 0x%x bytes\n", size);
295 return malloc(size);
296 }
297
flash_area_id_from_multi_image_slot(int image_index,int slot)298 int flash_area_id_from_multi_image_slot(int image_index, int slot)
299 {
300 switch (slot) {
301 case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index);
302 case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index);
303 case 2: return FLASH_AREA_IMAGE_SCRATCH;
304 }
305
306 printf("Image flash area ID not found\n");
307 return -1; /* flash_area_open will fail on that */
308 }
309
flash_area_open(uint8_t id,const struct flash_area ** area)310 int flash_area_open(uint8_t id, const struct flash_area **area)
311 {
312 uint32_t i;
313 struct area_desc *flash_areas;
314
315 flash_areas = sim_get_flash_areas();
316 for (i = 0; i < flash_areas->num_slots; i++) {
317 if (flash_areas->slots[i].id == id)
318 break;
319 }
320 if (i == flash_areas->num_slots) {
321 printf("Unsupported area\n");
322 abort();
323 }
324
325 /* Unsure if this is right, just returning the first area. */
326 *area = &flash_areas->slots[i].whole;
327 return 0;
328 }
329
flash_area_close(const struct flash_area * area)330 void flash_area_close(const struct flash_area *area)
331 {
332 (void)area;
333 }
334
335 /*
336 * Read/write/erase. Offset is relative from beginning of flash area.
337 */
flash_area_read(const struct flash_area * area,uint32_t off,void * dst,uint32_t len)338 int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
339 uint32_t len)
340 {
341 BOOT_LOG_SIM("%s: area=%d, off=%x, len=%x",
342 __func__, area->fa_id, off, len);
343 return sim_flash_read(area->fa_device_id, area->fa_off + off, dst, len);
344 }
345
flash_area_write(const struct flash_area * area,uint32_t off,const void * src,uint32_t len)346 int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
347 uint32_t len)
348 {
349 BOOT_LOG_SIM("%s: area=%d, off=%x, len=%x", __func__,
350 area->fa_id, off, len);
351 struct sim_context *ctx = sim_get_context();
352 if (--(ctx->flash_counter) == 0) {
353 ctx->jumped++;
354 longjmp(ctx->boot_jmpbuf, 1);
355 }
356 return sim_flash_write(area->fa_device_id, area->fa_off + off, src, len);
357 }
358
flash_area_erase(const struct flash_area * area,uint32_t off,uint32_t len)359 int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
360 {
361 BOOT_LOG_SIM("%s: area=%d, off=%x, len=%x", __func__,
362 area->fa_id, off, len);
363 struct sim_context *ctx = sim_get_context();
364 if (--(ctx->flash_counter) == 0) {
365 ctx->jumped++;
366 longjmp(ctx->boot_jmpbuf, 1);
367 }
368 return sim_flash_erase(area->fa_device_id, area->fa_off + off, len);
369 }
370
flash_area_to_sectors(int idx,int * cnt,struct flash_area * ret)371 int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
372 {
373 int rc = 0;
374 uint32_t i;
375 struct area *slot;
376 struct area_desc *flash_areas;
377
378 flash_areas = sim_get_flash_areas();
379 for (i = 0; i < flash_areas->num_slots; i++) {
380 if (flash_areas->slots[i].id == idx)
381 break;
382 }
383 if (i == flash_areas->num_slots) {
384 printf("Unsupported area\n");
385 abort();
386 }
387
388 slot = &flash_areas->slots[i];
389
390 if ((uint32_t)*cnt > slot->num_areas) {
391 *cnt = slot->num_areas;
392 } else if (slot->num_areas > (uint32_t)*cnt) {
393 rc = -ENOMEM;
394 }
395
396 memcpy(ret, slot->areas, *cnt * sizeof(struct flash_area));
397
398 return rc;
399 }
400
flash_area_get_sectors(int fa_id,uint32_t * count,struct flash_sector * sectors)401 int flash_area_get_sectors(int fa_id, uint32_t *count,
402 struct flash_sector *sectors)
403 {
404 int rc = 0;
405 uint32_t i;
406 struct area *slot;
407 struct area_desc *flash_areas;
408
409 flash_areas = sim_get_flash_areas();
410 for (i = 0; i < flash_areas->num_slots; i++) {
411 if (flash_areas->slots[i].id == fa_id)
412 break;
413 }
414 if (i == flash_areas->num_slots) {
415 printf("Unsupported area\n");
416 abort();
417 }
418
419 slot = &flash_areas->slots[i];
420
421 if (*count > slot->num_areas) {
422 *count = slot->num_areas;
423 } else if (slot->num_areas > *count) {
424 rc = -ENOMEM;
425 }
426
427 for (i = 0; i < *count; i++) {
428 sectors[i].fs_off = slot->areas[i].fa_off -
429 slot->whole.fa_off;
430 sectors[i].fs_size = slot->areas[i].fa_size;
431 }
432
433 return rc;
434 }
435
flash_area_id_to_multi_image_slot(int image_index,int area_id)436 int flash_area_id_to_multi_image_slot(int image_index, int area_id)
437 {
438 if (area_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) {
439 return 0;
440 }
441 if (area_id == FLASH_AREA_IMAGE_SECONDARY(image_index)) {
442 return 1;
443 }
444
445 printf("Unsupported image area ID\n");
446 abort();
447 }
448
flash_area_id_from_image_slot(int slot)449 int flash_area_id_from_image_slot(int slot) {
450 /* For single image cases, just use the first image. */
451 return flash_area_id_from_multi_image_slot(0, slot);
452 }
453
flash_area_sector_from_off(uint32_t off,struct flash_sector * sector)454 int flash_area_sector_from_off(uint32_t off, struct flash_sector *sector)
455 {
456 uint32_t i, sec_off, sec_size;
457 struct area *slot;
458 struct area_desc *flash_areas;
459
460 flash_areas = sim_get_flash_areas();
461 for (i = 0; i < flash_areas->num_slots; i++) {
462 if (flash_areas->slots[i].id == FLASH_AREA_ID(image_0))
463 break;
464 }
465
466 if (i == flash_areas->num_slots) {
467 printf("Unsupported area\n");
468 abort();
469 }
470
471 slot = &flash_areas->slots[i];
472
473 for (i = 0; i < slot->num_areas; i++) {
474 sec_off = slot->areas[i].fa_off - slot->whole.fa_off;
475 sec_size = slot->areas[i].fa_size;
476
477 if (off >= sec_off && off < (sec_off + sec_size)) {
478 sector->fs_off = sec_off;
479 sector->fs_size = sec_size;
480 break;
481 }
482 }
483
484 return (i < slot->num_areas) ? 0 : -1;
485 }
486
flash_area_get_sector(const struct flash_area * fa,uint32_t off,struct flash_sector * sector)487 int flash_area_get_sector(const struct flash_area *fa, uint32_t off,
488 struct flash_sector *sector)
489 {
490 uint32_t i, sec_off, sec_size;
491 struct area *slot;
492 struct area_desc *flash_areas;
493
494 flash_areas = sim_get_flash_areas();
495 for (i = 0; i < flash_areas->num_slots; i++) {
496 if (&flash_areas->slots[i].whole == fa)
497 break;
498 }
499
500 if (i == flash_areas->num_slots) {
501 printf("Unsupported area\n");
502 abort();
503 }
504
505 slot = &flash_areas->slots[i];
506
507 for (i = 0; i < slot->num_areas; i++) {
508 sec_off = slot->areas[i].fa_off - slot->whole.fa_off;
509 sec_size = slot->areas[i].fa_size;
510
511 if (off >= sec_off && off < (sec_off + sec_size)) {
512 sector->fs_off = sec_off;
513 sector->fs_size = sec_size;
514 break;
515 }
516 }
517
518 return (i < slot->num_areas) ? 0 : -1;
519 }
520
sim_assert(int x,const char * assertion,const char * file,unsigned int line,const char * function)521 void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
522 {
523 if (!(x)) {
524 struct sim_context *ctx = sim_get_context();
525 if (ctx->c_catch_asserts) {
526 ctx->c_asserts++;
527 } else {
528 BOOT_LOG_ERR("%s:%d: %s: Assertion `%s' failed.", file, line, function, assertion);
529
530 /* NOTE: if the assert below is triggered, the place where it was originally
531 * asserted is printed by the message above...
532 */
533 assert(x);
534 }
535 }
536 }
537
boot_max_align(void)538 uint32_t boot_max_align(void)
539 {
540 return BOOT_MAX_ALIGN;
541 }
542
boot_magic_sz(void)543 uint32_t boot_magic_sz(void)
544 {
545 return BOOT_MAGIC_ALIGN_SIZE;
546 }
547