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