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