1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Copyright (c) 2016-2020 Linaro LTD
5  * Copyright (c) 2016-2019 JUUL Labs
6  * Copyright (c) 2019-2023 Arm Limited
7  * Copyright (c) 2024 Nordic Semiconductor ASA
8  *
9  * Original license:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one
12  * or more contributor license agreements.  See the NOTICE file
13  * distributed with this work for additional information
14  * regarding copyright ownership.  The ASF licenses this file
15  * to you under the Apache License, Version 2.0 (the
16  * "License"); you may not use this file except in compliance
17  * with the License.  You may obtain a copy of the License at
18  *
19  *  http://www.apache.org/licenses/LICENSE-2.0
20  *
21  * Unless required by applicable law or agreed to in writing,
22  * software distributed under the License is distributed on an
23  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
24  * KIND, either express or implied.  See the License for the
25  * specific language governing permissions and limitations
26  * under the License.
27  */
28 
29 #include "bootutil/bootutil.h"
30 #include "bootutil/bootutil_log.h"
31 #include "bootutil/bootutil_public.h"
32 #include "bootutil/image.h"
33 #include "bootutil_priv.h"
34 #include "bootutil/fault_injection_hardening.h"
35 #include "bootutil/ramload.h"
36 #include "bootutil/mcuboot_status.h"
37 
38 #ifdef MCUBOOT_ENC_IMAGES
39 #include "bootutil/enc_key.h"
40 #endif
41 
42 #include "mcuboot_config/mcuboot_config.h"
43 
44 BOOT_LOG_MODULE_DECLARE(mcuboot);
45 
46 #ifndef MULTIPLE_EXECUTABLE_RAM_REGIONS
47 #if !defined(IMAGE_EXECUTABLE_RAM_START) || !defined(IMAGE_EXECUTABLE_RAM_SIZE)
48 #error "Platform MUST define executable RAM bounds in case of RAM_LOAD"
49 #endif
50 #endif
51 
52 /**
53  * Verifies that the active slot of the current image can be loaded within the
54  * predefined bounds that are allowed to be used by executable images.
55  *
56  * @param  state        Boot loader status information.
57  *
58  * @return              0 on success; nonzero on failure.
59  */
60 static int
boot_verify_ram_load_address(struct boot_loader_state * state)61 boot_verify_ram_load_address(struct boot_loader_state *state)
62 {
63     uint32_t img_dst;
64     uint32_t img_sz;
65     uint32_t img_end_addr;
66     uint32_t exec_ram_start;
67     uint32_t exec_ram_size;
68 
69     (void)state;
70 
71 #ifdef MULTIPLE_EXECUTABLE_RAM_REGIONS
72     int      rc;
73 
74     rc = boot_get_image_exec_ram_info(BOOT_CURR_IMG(state), &exec_ram_start,
75                                       &exec_ram_size);
76     if (rc != 0) {
77         return BOOT_EBADSTATUS;
78     }
79 #else
80     exec_ram_start = IMAGE_EXECUTABLE_RAM_START;
81     exec_ram_size = IMAGE_EXECUTABLE_RAM_SIZE;
82 #endif
83 
84     img_dst = state->slot_usage[BOOT_CURR_IMG(state)].img_dst;
85     img_sz = state->slot_usage[BOOT_CURR_IMG(state)].img_sz;
86 
87     if (img_dst < exec_ram_start) {
88         return BOOT_EBADIMAGE;
89     }
90 
91     if (!boot_u32_safe_add(&img_end_addr, img_dst, img_sz)) {
92         return BOOT_EBADIMAGE;
93     }
94 
95     if (img_end_addr > (exec_ram_start + exec_ram_size)) {
96         return BOOT_EBADIMAGE;
97     }
98 
99     return 0;
100 }
101 
102 #ifdef MCUBOOT_ENC_IMAGES
103 
104 /**
105  * Copies and decrypts an image from a slot in the flash to an SRAM address.
106  *
107  * @param  state    Boot loader status information.
108  * @param  slot     The flash slot of the image to be copied to SRAM.
109  * @param  hdr      The image header.
110  * @param  src_sz   Size of the image.
111  * @param  img_dst  Pointer to the address at which the image needs to be
112  *                  copied to SRAM.
113  *
114  * @return          0 on success; nonzero on failure.
115  */
116 static int
boot_decrypt_and_copy_image_to_sram(struct boot_loader_state * state,uint32_t slot,struct image_header * hdr,uint32_t src_sz,uint32_t img_dst)117 boot_decrypt_and_copy_image_to_sram(struct boot_loader_state *state,
118                                     uint32_t slot, struct image_header *hdr,
119                                     uint32_t src_sz, uint32_t img_dst)
120 {
121     /* The flow for the decryption and copy of the image is as follows :
122      * 1. The whole image is copied to the RAM (header + payload + TLV).
123      * 2. The encryption key is loaded from the TLV in flash.
124      * 3. The image is then decrypted chunk by chunk in RAM (1 chunk
125      * is 1024 bytes). Only the payload section is decrypted.
126      * 4. The image is authenticated in RAM.
127      */
128     const struct flash_area *fap_src = NULL;
129     struct boot_status bs;
130     uint32_t blk_off;
131     uint32_t tlv_off;
132     uint32_t blk_sz;
133     uint32_t bytes_copied = hdr->ih_hdr_size;
134     uint32_t chunk_sz;
135     uint32_t max_sz = 1024;
136     uint16_t idx;
137     uint8_t * cur_dst;
138     int area_id;
139     int rc;
140     uint8_t * ram_dst = (void *)(IMAGE_RAM_BASE + img_dst);
141 
142     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
143     rc = flash_area_open(area_id, &fap_src);
144     if (rc != 0){
145         return BOOT_EFLASH;
146     }
147 
148     tlv_off = BOOT_TLV_OFF(hdr);
149 
150     /* Copying the whole image in RAM */
151     rc = flash_area_read(fap_src, 0, ram_dst, src_sz);
152     if (rc != 0) {
153         goto done;
154     }
155 
156     rc = boot_enc_load(state, slot, hdr, fap_src, &bs);
157     if (rc < 0) {
158         goto done;
159     }
160 
161     /* if rc > 0 then the key has already been loaded */
162     if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), slot, &bs)) {
163         goto done;
164     }
165 
166     /* Starting at the end of the header as the header section is not encrypted */
167     while (bytes_copied < tlv_off) { /* TLV section copied previously */
168         if (src_sz - bytes_copied > max_sz) {
169             chunk_sz = max_sz;
170         } else {
171             chunk_sz = src_sz - bytes_copied;
172         }
173 
174         cur_dst = ram_dst + bytes_copied;
175         blk_sz = chunk_sz;
176         idx = 0;
177         blk_off = ((bytes_copied) - hdr->ih_hdr_size) & 0xf;
178         if (bytes_copied + chunk_sz > tlv_off) {
179             /* Going over TLV section
180              * Part of the chunk is encrypted payload */
181             blk_sz = tlv_off - (bytes_copied);
182         }
183         boot_enc_decrypt(BOOT_CURR_ENC(state), slot,
184                 (bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
185                 blk_off, cur_dst);
186         bytes_copied += chunk_sz;
187     }
188     rc = 0;
189 
190 done:
191     flash_area_close(fap_src);
192 
193     return rc;
194 }
195 
196 #endif /* MCUBOOT_ENC_IMAGES */
197 /**
198  * Copies a slot of the current image into SRAM.
199  *
200  * @param  state    Boot loader status information.
201  * @param  slot     The flash slot of the image to be copied to SRAM.
202  * @param  img_dst  The address at which the image needs to be copied to
203  *                  SRAM.
204  * @param  img_sz   The size of the image that needs to be copied to SRAM.
205  *
206  * @return          0 on success; nonzero on failure.
207  */
208 static int
boot_copy_image_to_sram(struct boot_loader_state * state,int slot,uint32_t img_dst,uint32_t img_sz)209 boot_copy_image_to_sram(struct boot_loader_state *state, int slot,
210                         uint32_t img_dst, uint32_t img_sz)
211 {
212     int rc;
213     const struct flash_area *fap_src = NULL;
214     int area_id;
215 
216 #if (BOOT_IMAGE_NUMBER == 1)
217     (void)state;
218 #endif
219 
220     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
221 
222     rc = flash_area_open(area_id, &fap_src);
223     if (rc != 0) {
224         return BOOT_EFLASH;
225     }
226 
227     /* Direct copy from flash to its new location in SRAM. */
228     rc = flash_area_read(fap_src, 0, (void *)(IMAGE_RAM_BASE + img_dst), img_sz);
229     if (rc != 0) {
230         BOOT_LOG_INF("Error whilst copying image %d from Flash to SRAM: %d",
231                      BOOT_CURR_IMG(state), rc);
232     }
233 
234     flash_area_close(fap_src);
235 
236     return rc;
237 }
238 
239 #if (BOOT_IMAGE_NUMBER > 1)
240 /**
241  * Checks if two memory regions (A and B) are overlap or not.
242  *
243  * @param  start_a  Start of the A region.
244  * @param  end_a    End of the A region.
245  * @param  start_b  Start of the B region.
246  * @param  end_b    End of the B region.
247  *
248  * @return          true if there is overlap; false otherwise.
249  */
250 static bool
do_regions_overlap(uint32_t start_a,uint32_t end_a,uint32_t start_b,uint32_t end_b)251 do_regions_overlap(uint32_t start_a, uint32_t end_a,
252                    uint32_t start_b, uint32_t end_b)
253 {
254     if (start_b > end_a) {
255         return false;
256     } else if (start_b >= start_a) {
257         return true;
258     } else if (end_b > start_a) {
259         return true;
260     }
261 
262     return false;
263 }
264 
265 /**
266  * Checks if the image we want to load to memory overlap with an already
267  * ramloaded image.
268  *
269  * @param  state    Boot loader status information.
270  *
271  * @return                    0 if there is no overlap; nonzero otherwise.
272  */
273 static int
boot_check_ram_load_overlapping(struct boot_loader_state * state)274 boot_check_ram_load_overlapping(struct boot_loader_state *state)
275 {
276     uint32_t i;
277 
278     uint32_t start_a;
279     uint32_t end_a;
280     uint32_t start_b;
281     uint32_t end_b;
282     uint32_t image_id_to_check = BOOT_CURR_IMG(state);
283 
284     start_a = state->slot_usage[image_id_to_check].img_dst;
285     /* Safe to add here, values are already verified in
286      * boot_verify_ram_load_address() */
287     end_a = start_a + state->slot_usage[image_id_to_check].img_sz;
288 
289     for (i = 0; i < BOOT_IMAGE_NUMBER; i++) {
290         if (state->slot_usage[i].active_slot == NO_ACTIVE_SLOT
291             || i == image_id_to_check) {
292             continue;
293         }
294 
295         start_b = state->slot_usage[i].img_dst;
296         /* Safe to add here, values are already verified in
297          * boot_verify_ram_load_address() */
298         end_b = start_b + state->slot_usage[i].img_sz;
299 
300         if (do_regions_overlap(start_a, end_a, start_b, end_b)) {
301             return -1;
302         }
303     }
304 
305     return 0;
306 }
307 #endif
308 
309 /**
310  * Loads the active slot of the current image into SRAM. The load address and
311  * image size is extracted from the image header.
312  *
313  * @param  state        Boot loader status information.
314  *
315  * @return              0 on success; nonzero on failure.
316  */
317 int
boot_load_image_to_sram(struct boot_loader_state * state)318 boot_load_image_to_sram(struct boot_loader_state *state)
319 {
320     uint32_t active_slot;
321     struct image_header *hdr = NULL;
322     uint32_t img_dst;
323     uint32_t img_sz;
324     int rc;
325 
326     active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
327     hdr = boot_img_hdr(state, active_slot);
328 
329     if (hdr->ih_flags & IMAGE_F_RAM_LOAD) {
330 
331         img_dst = hdr->ih_load_addr;
332 
333         rc = boot_read_image_size(state, active_slot, &img_sz);
334         if (rc != 0) {
335             return rc;
336         }
337 
338         state->slot_usage[BOOT_CURR_IMG(state)].img_dst = img_dst;
339         state->slot_usage[BOOT_CURR_IMG(state)].img_sz = img_sz;
340 
341         rc = boot_verify_ram_load_address(state);
342         if (rc != 0) {
343             BOOT_LOG_INF("Image %d RAM load address 0x%x is invalid.", BOOT_CURR_IMG(state), img_dst);
344             return rc;
345         }
346 
347 #if (BOOT_IMAGE_NUMBER > 1)
348         rc = boot_check_ram_load_overlapping(state);
349         if (rc != 0) {
350             BOOT_LOG_INF("Image %d RAM loading to address 0x%x would overlap with\
351                          another image.", BOOT_CURR_IMG(state), img_dst);
352             return rc;
353         }
354 #endif
355 #ifdef MCUBOOT_ENC_IMAGES
356         /* decrypt image if encrypted and copy it to RAM */
357         if (IS_ENCRYPTED(hdr)) {
358             rc = boot_decrypt_and_copy_image_to_sram(state, active_slot, hdr, img_sz, img_dst);
359         } else {
360             rc = boot_copy_image_to_sram(state, active_slot, img_dst, img_sz);
361         }
362 #else
363         /* Copy image to the load address from where it currently resides in
364          * flash.
365          */
366         rc = boot_copy_image_to_sram(state, active_slot, img_dst, img_sz);
367 #endif
368         if (rc != 0) {
369             BOOT_LOG_INF("Image %d RAM loading to 0x%x is failed.", BOOT_CURR_IMG(state), img_dst);
370         } else {
371             BOOT_LOG_INF("Image %d RAM loading to 0x%x is succeeded.", BOOT_CURR_IMG(state), img_dst);
372         }
373     } else {
374         /* Only images that support IMAGE_F_RAM_LOAD are allowed if
375          * MCUBOOT_RAM_LOAD is set.
376          */
377         rc = BOOT_EBADIMAGE;
378     }
379 
380     if (rc != 0) {
381         state->slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
382         state->slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
383     }
384 
385     return rc;
386 }
387 
388 /**
389  * Removes an image from SRAM, by overwriting it with zeros.
390  *
391  * @param  state        Boot loader status information.
392  *
393  * @return              0 on success; nonzero on failure.
394  */
395 int
boot_remove_image_from_sram(struct boot_loader_state * state)396 boot_remove_image_from_sram(struct boot_loader_state *state)
397 {
398     (void)state;
399 
400     BOOT_LOG_INF("Removing image %d from SRAM at address 0x%x",
401                  BOOT_CURR_IMG(state),
402                  state->slot_usage[BOOT_CURR_IMG(state)].img_dst);
403 
404     memset((void*)(IMAGE_RAM_BASE + state->slot_usage[BOOT_CURR_IMG(state)].img_dst),
405            0, state->slot_usage[BOOT_CURR_IMG(state)].img_sz);
406 
407     state->slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
408     state->slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
409 
410     return 0;
411 }
412 
413 /**
414  * Removes an image from flash by erasing the corresponding flash area
415  *
416  * @param  state    Boot loader status information.
417  * @param  slot     The flash slot of the image to be erased.
418  *
419  * @return          0 on success; nonzero on failure.
420  */
421 int
boot_remove_image_from_flash(struct boot_loader_state * state,uint32_t slot)422 boot_remove_image_from_flash(struct boot_loader_state *state, uint32_t slot)
423 {
424     int area_id;
425     int rc;
426     const struct flash_area *fap;
427 
428     (void)state;
429 
430     BOOT_LOG_INF("Removing image %d slot %d from flash", BOOT_CURR_IMG(state),
431                                                          slot);
432     area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot);
433     rc = flash_area_open(area_id, &fap);
434     if (rc == 0) {
435         flash_area_erase(fap, 0, flash_area_get_size(fap));
436         flash_area_close(fap);
437     }
438 
439     return rc;
440 }
441 
boot_load_image_from_flash_to_sram(struct boot_loader_state * state,struct image_header * hdr)442 int boot_load_image_from_flash_to_sram(struct boot_loader_state *state,
443                                        struct image_header *hdr)
444 {
445     int active_slot;
446 
447     /* boot_load_image_to_sram will load the image from state active_slot,
448      * so force it before loading the image.
449      */
450     active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
451     BOOT_IMG(state, active_slot).hdr = *hdr;
452 
453     return boot_load_image_to_sram(state);
454 }
455