1 /*
2  * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <string.h>
7 #include <sys/param.h>
8 #include <esp_cpu.h>
9 #include <bootloader_utility.h>
10 #include <bootloader_signature.h>
11 #include <esp_secure_boot.h>
12 #include <esp_fault.h>
13 #include <esp_log.h>
14 #include <esp_attr.h>
15 #include <spi_flash_mmap.h>
16 #include <bootloader_flash_priv.h>
17 #include <bootloader_random.h>
18 #include <bootloader_sha.h>
19 #include "bootloader_util.h"
20 #include "bootloader_common.h"
21 #include "esp_rom_sys.h"
22 #include "esp_efuse.h"
23 #include "esp_app_desc.h"
24 #include "bootloader_memory_utils.h"
25 #include "soc/soc_caps.h"
26 #if CONFIG_IDF_TARGET_ESP32
27 #include "esp32/rom/secure_boot.h"
28 #elif CONFIG_IDF_TARGET_ESP32S2
29 #include "esp32s2/rom/secure_boot.h"
30 #elif CONFIG_IDF_TARGET_ESP32S3
31 #include "esp32s3/rom/secure_boot.h"
32 #elif CONFIG_IDF_TARGET_ESP32C3
33 #include "esp32c3/rom/secure_boot.h"
34 #elif CONFIG_IDF_TARGET_ESP32C2
35 #include "esp32c2/rom/rtc.h"
36 #include "esp32c2/rom/secure_boot.h"
37 #elif CONFIG_IDF_TARGET_ESP32C6
38 #include "esp32c6/rom/rtc.h"
39 #include "esp32c6/rom/secure_boot.h"
40 #elif CONFIG_IDF_TARGET_ESP32H2
41 #include "esp32h2/rom/rtc.h"
42 #include "esp32h2/rom/secure_boot.h"
43 #endif
44 
45 #define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
46 
47 /* Checking signatures as part of verifying images is necessary:
48    - Always if secure boot is enabled
49    - Differently in bootloader and/or app, depending on kconfig
50 */
51 #ifdef BOOTLOADER_BUILD
52 #ifdef CONFIG_SECURE_SIGNED_ON_BOOT
53 #define SECURE_BOOT_CHECK_SIGNATURE 1
54 #else
55 #define SECURE_BOOT_CHECK_SIGNATURE 0
56 #endif
57 #else /* !BOOTLOADER_BUILD */
58 #ifdef CONFIG_SECURE_SIGNED_ON_UPDATE
59 #define SECURE_BOOT_CHECK_SIGNATURE 1
60 #else
61 #define SECURE_BOOT_CHECK_SIGNATURE 0
62 #endif
63 #endif
64 
65 static const char *TAG = "esp_image";
66 
67 #define HASH_LEN ESP_IMAGE_HASH_LEN
68 
69 #define SIXTEEN_MB 0x1000000
70 #define ESP_ROM_CHECKSUM_INITIAL 0xEF
71 
72 /* Headroom to ensure between stack SP (at time of checking) and data loaded from flash */
73 #define STACK_LOAD_HEADROOM 32768
74 
75 #ifdef BOOTLOADER_BUILD
76 /* 64 bits of random data to obfuscate loaded RAM with, until verification is complete
77    (Means loaded code isn't executable until after the secure boot check.)
78 */
79 static uint32_t ram_obfs_value[2];
80 
81 #endif
82 
83 /* Return true if load_addr is an address the bootloader should load into */
84 static bool should_load(uint32_t load_addr);
85 /* Return true if load_addr is an address the bootloader should map via flash cache */
86 static bool should_map(uint32_t load_addr);
87 
88 static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
89 /* Load or verify a segment */
90 static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata);
91 
92 /* split segment and verify if data_len is too long */
93 static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata);
94 
95 /* Verify the main image header */
96 static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent);
97 
98 /* Verify a segment header */
99 static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent);
100 
101 /* Log-and-fail macro for use in esp_image_load */
102 #define FAIL_LOAD(...) do {                         \
103         if (!silent) {                              \
104             ESP_LOGE(TAG, __VA_ARGS__);             \
105         }                                           \
106         goto err;                                   \
107     }                                               \
108     while(0)
109 
110 #define CHECK_ERR(func) do {                        \
111         if ((err = func) != ESP_OK) {               \
112             goto err;                               \
113         }                                           \
114     }                                               \
115     while(0)
116 
117 static esp_err_t process_image_header(esp_image_metadata_t *data, uint32_t part_offset, bootloader_sha256_handle_t *sha_handle, bool do_verify, bool silent);
118 static esp_err_t process_appended_hash_and_sig(esp_image_metadata_t *data, uint32_t part_offset, uint32_t part_len, bool do_verify, bool silent);
119 static esp_err_t process_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data, bool silent, bool skip_check_checksum);
120 
121 static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data, uint8_t *image_digest, uint8_t *verified_digest);
122 static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
123 
image_load(esp_image_load_mode_t mode,const esp_partition_pos_t * part,esp_image_metadata_t * data)124 static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
125 {
126 #ifdef BOOTLOADER_BUILD
127     bool do_load   = (mode == ESP_IMAGE_LOAD) || (mode == ESP_IMAGE_LOAD_NO_VALIDATE);
128     bool do_verify = (mode == ESP_IMAGE_LOAD) || (mode == ESP_IMAGE_VERIFY) || (mode == ESP_IMAGE_VERIFY_SILENT);
129 #else
130     bool do_load   = false; // Can't load the image in app mode
131     bool do_verify = true;  // In app mode is available only verify mode
132 #endif
133     bool silent    = (mode == ESP_IMAGE_VERIFY_SILENT);
134     esp_err_t err = ESP_OK;
135     // checksum the image a word at a time. This shaves 30-40ms per MB of image size
136     uint32_t checksum_word = ESP_ROM_CHECKSUM_INITIAL;
137     uint32_t *checksum = (do_verify) ? &checksum_word : NULL;
138     bootloader_sha256_handle_t sha_handle = NULL;
139     bool verify_sha;
140 #if (SECURE_BOOT_CHECK_SIGNATURE == 1)
141      /* used for anti-FI checks */
142     uint8_t image_digest[HASH_LEN] = { [ 0 ... 31] = 0xEE };
143     uint8_t verified_digest[HASH_LEN] = { [ 0 ... 31 ] = 0x01 };
144 #endif
145 
146     if (data == NULL || part == NULL) {
147         return ESP_ERR_INVALID_ARG;
148     }
149 
150 #if CONFIG_SECURE_BOOT_V2_ENABLED
151     // For Secure Boot V2, we do verify signature on bootloader which includes the SHA calculation.
152     verify_sha = do_verify;
153 #else // Secure boot not enabled
154     // For secure boot V1 on ESP32, we don't calculate SHA or verify signature on bootloaders.
155     // (For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because
156     // esptool.py may have rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.)
157     verify_sha = (part->offset != ESP_BOOTLOADER_OFFSET) && do_verify;
158 #endif
159 
160     if (part->size > SIXTEEN_MB) {
161         err = ESP_ERR_INVALID_ARG;
162         FAIL_LOAD("partition size 0x%"PRIx32" invalid, larger than 16MB", part->size);
163     }
164 
165     bootloader_sha256_handle_t *p_sha_handle = &sha_handle;
166     CHECK_ERR(process_image_header(data, part->offset, (verify_sha) ? p_sha_handle : NULL, do_verify, silent));
167     CHECK_ERR(process_segments(data, silent, do_load, sha_handle, checksum));
168     bool skip_check_checksum = !do_verify || esp_cpu_dbgr_is_attached();
169     CHECK_ERR(process_checksum(sha_handle, checksum_word, data, silent, skip_check_checksum));
170     CHECK_ERR(process_appended_hash_and_sig(data, part->offset, part->size, do_verify, silent));
171     if (verify_sha) {
172 #if (SECURE_BOOT_CHECK_SIGNATURE == 1)
173         // secure boot images have a signature appended
174 #if defined(BOOTLOADER_BUILD) && !defined(CONFIG_SECURE_BOOT)
175         // If secure boot is not enabled in hardware, then
176         // skip the signature check in bootloader when the debugger is attached.
177         // This is done to allow for breakpoints in Flash.
178         bool do_verify_sig = !esp_cpu_dbgr_is_attached();
179 #else // CONFIG_SECURE_BOOT
180         bool do_verify_sig = true;
181 #endif // end checking for JTAG
182         if (do_verify_sig) {
183             err = verify_secure_boot_signature(sha_handle, data, image_digest, verified_digest);
184             sha_handle = NULL; // verify_secure_boot_signature finishes sha_handle
185         }
186 #else // SECURE_BOOT_CHECK_SIGNATURE
187         // No secure boot, but SHA-256 can be appended for basic corruption detection
188         if (sha_handle != NULL && !esp_cpu_dbgr_is_attached()) {
189             err = verify_simple_hash(sha_handle, data);
190             sha_handle = NULL; // calling verify_simple_hash finishes sha_handle
191         }
192 #endif // SECURE_BOOT_CHECK_SIGNATURE
193     } // verify_sha
194 
195     // bootloader may still have a sha256 digest handle open
196     if (sha_handle != NULL) {
197         bootloader_sha256_finish(sha_handle, NULL);
198         sha_handle = NULL;
199     }
200 
201     if (err != ESP_OK) {
202         goto err;
203     }
204 
205 #ifdef BOOTLOADER_BUILD
206 
207 #if (SECURE_BOOT_CHECK_SIGNATURE == 1)
208     /* If signature was checked in bootloader build, verified_digest should equal image_digest
209 
210        This is to detect any fault injection that caused signature verification to not complete normally.
211 
212        Any attack which bypasses this check should be of limited use as the RAM contents are still obfuscated, therefore we do the check
213        immediately before we deobfuscate.
214 
215        Note: the conditions for making this check are the same as for setting verify_sha above, but on ESP32 SB V1 we move the test for
216        "only verify signature in bootloader" into the macro so it's tested multiple times.
217      */
218 #if CONFIG_SECURE_BOOT_V2_ENABLED
219     ESP_FAULT_ASSERT(!esp_secure_boot_enabled() || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
220 #else // Secure Boot V1 on ESP32, only verify signatures for apps not bootloaders
221     ESP_FAULT_ASSERT(data->start_addr == ESP_BOOTLOADER_OFFSET || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
222 #endif
223 
224 #endif // SECURE_BOOT_CHECK_SIGNATURE
225 
226     // Deobfuscate RAM
227     if (do_load && ram_obfs_value[0] != 0 && ram_obfs_value[1] != 0) {
228         for (int i = 0; i < data->image.segment_count; i++) {
229             uint32_t load_addr = data->segments[i].load_addr;
230             if (should_load(load_addr)) {
231                 uint32_t *loaded = (uint32_t *)load_addr;
232                 for (size_t j = 0; j < data->segments[i].data_len / sizeof(uint32_t); j++) {
233                     loaded[j] ^= (j & 1) ? ram_obfs_value[0] : ram_obfs_value[1];
234                 }
235             }
236         }
237     }
238 
239 #if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
240     /* For anti-rollback case, reconfirm security version of the application to prevent FI attacks */
241     bool sec_ver = false;
242     if (do_load) {
243         sec_ver = esp_efuse_check_secure_version(data->secure_version);
244         if (!sec_ver) {
245             err = ESP_FAIL;
246             goto err;
247         }
248     }
249     /* Ensure that the security version check passes for image loading scenario */
250     ESP_FAULT_ASSERT(!do_load || sec_ver == true);
251 #endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
252 
253 #endif // BOOTLOADER_BUILD
254 
255     // Success!
256     return ESP_OK;
257 
258 err:
259     if (err == ESP_OK) {
260         err = ESP_ERR_IMAGE_INVALID;
261     }
262     if (sha_handle != NULL) {
263         // Need to finish the hash process to free the handle
264         bootloader_sha256_finish(sha_handle, NULL);
265     }
266     // Prevent invalid/incomplete data leaking out
267     bzero(data, sizeof(esp_image_metadata_t));
268     return err;
269 }
270 
bootloader_load_image(const esp_partition_pos_t * part,esp_image_metadata_t * data)271 esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
272 {
273 #if !defined(BOOTLOADER_BUILD)
274     return ESP_FAIL;
275 #else
276     esp_image_load_mode_t mode = ESP_IMAGE_LOAD;
277 
278 #if !defined(CONFIG_SECURE_BOOT)
279     /* Skip validation under particular configurations */
280 #if CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS
281     mode = ESP_IMAGE_LOAD_NO_VALIDATE;
282 #elif CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON
283     if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON
284 #if SOC_EFUSE_HAS_EFUSE_RST_BUG
285         || esp_rom_get_reset_reason(0) == RESET_REASON_CORE_EFUSE_CRC
286 #endif
287         ) {
288         mode = ESP_IMAGE_LOAD_NO_VALIDATE;
289     }
290 #endif // CONFIG_BOOTLOADER_SKIP_...
291 #endif // CONFIG_SECURE_BOOT
292 
293  return image_load(mode, part, data);
294 #endif // BOOTLOADER_BUILD
295 }
296 
bootloader_load_image_no_verify(const esp_partition_pos_t * part,esp_image_metadata_t * data)297 esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data)
298 {
299 #ifdef BOOTLOADER_BUILD
300     return image_load(ESP_IMAGE_LOAD_NO_VALIDATE, part, data);
301 #else
302     return ESP_FAIL;
303 #endif
304 }
305 
esp_image_verify(esp_image_load_mode_t mode,const esp_partition_pos_t * part,esp_image_metadata_t * data)306 esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
307 {
308     return image_load(mode, part, data);
309 }
310 
esp_image_get_metadata(const esp_partition_pos_t * part,esp_image_metadata_t * metadata)311 esp_err_t esp_image_get_metadata(const esp_partition_pos_t *part, esp_image_metadata_t *metadata)
312 {
313     esp_err_t err;
314     if (metadata == NULL || part == NULL || part->size > SIXTEEN_MB) {
315         return ESP_ERR_INVALID_ARG;
316     }
317 
318     bool silent = true;
319     bool do_verify = false;
320     bool do_load = false;
321     CHECK_ERR(process_image_header(metadata, part->offset, NULL, do_verify, silent));
322     CHECK_ERR(process_segments(metadata, silent, do_load, NULL, NULL));
323     bool skip_check_checksum = true;
324     CHECK_ERR(process_checksum(NULL, 0, metadata, silent, skip_check_checksum));
325     CHECK_ERR(process_appended_hash_and_sig(metadata, part->offset, part->size, true, silent));
326     return ESP_OK;
327 err:
328     return err;
329 }
330 
verify_image_header(uint32_t src_addr,const esp_image_header_t * image,bool silent)331 static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
332 {
333     esp_err_t err = ESP_OK;
334 
335     ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08"PRIx32,
336                 image->magic,
337                 image->segment_count,
338                 image->spi_mode,
339                 image->spi_size,
340                 image->entry_addr);
341 
342     if (image->magic != ESP_IMAGE_HEADER_MAGIC) {
343         FAIL_LOAD("image at 0x%"PRIx32" has invalid magic byte (nothing flashed here?)", src_addr);
344     }
345 
346     // Checking the chip revision header *will* print a bunch of other info
347     // regardless of silent setting as this may be important, but don't bother checking it
348     // if it looks like the app partition is erased or otherwise garbage
349     CHECK_ERR(bootloader_common_check_chip_validity(image, ESP_IMAGE_APPLICATION));
350 
351     if (image->segment_count > ESP_IMAGE_MAX_SEGMENTS) {
352         FAIL_LOAD("image at 0x%"PRIx32" segment count %d exceeds max %d", src_addr, image->segment_count, ESP_IMAGE_MAX_SEGMENTS);
353     }
354     return err;
355 err:
356     if (err == ESP_OK) {
357         err = ESP_ERR_IMAGE_INVALID;
358     }
359     return err;
360 }
361 
362 #ifdef BOOTLOADER_BUILD
363 /* Check the region load_addr - load_end doesn't overlap any memory used by the bootloader, registers, or other invalid memory
364  */
verify_load_addresses(int segment_index,intptr_t load_addr,intptr_t load_end,bool print_error,bool no_recurse)365 static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_t load_end, bool print_error, bool no_recurse)
366 {
367     /* Addresses of static data and the "loader" section of bootloader IRAM, all defined in ld script */
368     const char *reason = NULL;
369     extern int _dram_start, _dram_end, _loader_text_start, _loader_text_end;
370     void *load_addr_p = (void *)load_addr;
371     void *load_inclusive_end_p = (void *)load_end - 0x1;
372     void *load_exclusive_end_p = (void *)load_end;
373 
374     if (load_end == load_addr) {
375         return true; // zero-length segments are fine
376     }
377     assert(load_end > load_addr); // data_len<16MB is checked in verify_segment_header() which is called before this, so this should always be true
378 
379     if (esp_ptr_in_dram(load_addr_p) && esp_ptr_in_dram(load_inclusive_end_p)) { /* Writing to DRAM */
380         /* Check if we're clobbering the stack */
381         intptr_t sp = (intptr_t)esp_cpu_get_sp();
382         if (bootloader_util_regions_overlap(sp - STACK_LOAD_HEADROOM, SOC_ROM_STACK_START,
383                                            load_addr, load_end)) {
384             reason = "overlaps bootloader stack";
385             goto invalid;
386         }
387 
388         /* Check if we're clobbering static data
389 
390            (_dram_start.._dram_end includes bss, data, rodata sections in DRAM)
391          */
392         if (bootloader_util_regions_overlap((intptr_t)&_dram_start, (intptr_t)&_dram_end, load_addr, load_end)) {
393             reason = "overlaps bootloader data";
394             goto invalid;
395         }
396 
397         /* LAST DRAM CHECK (recursive): for D/IRAM, check the equivalent IRAM addresses if needed
398 
399            Allow for the possibility that even though both pointers are IRAM, only part of the region is in a D/IRAM
400            section. In which case we recurse to check the part which falls in D/IRAM.
401 
402            Note: We start with SOC_DIRAM_DRAM_LOW/HIGH and convert that address to IRAM to account for any reversing of word order
403            (chip-specific).
404          */
405         if (!no_recurse && bootloader_util_regions_overlap(SOC_DIRAM_DRAM_LOW, SOC_DIRAM_DRAM_HIGH, load_addr, load_end)) {
406             intptr_t iram_load_addr, iram_load_end;
407 
408             if (esp_ptr_in_diram_dram(load_addr_p)) {
409                 iram_load_addr = (intptr_t)esp_ptr_diram_dram_to_iram(load_addr_p);
410             } else {
411                 iram_load_addr = (intptr_t)esp_ptr_diram_dram_to_iram((void *)SOC_DIRAM_DRAM_LOW);
412             }
413 
414             if (esp_ptr_in_diram_dram(load_inclusive_end_p)) {
415                 iram_load_end = (intptr_t)esp_ptr_diram_dram_to_iram(load_exclusive_end_p);
416             } else {
417                 iram_load_end = (intptr_t)esp_ptr_diram_dram_to_iram((void *)SOC_DIRAM_DRAM_HIGH);
418             }
419 
420             if (iram_load_end < iram_load_addr) {
421                 return verify_load_addresses(segment_index, iram_load_end, iram_load_addr, print_error, true);
422             } else {
423                 return verify_load_addresses(segment_index, iram_load_addr, iram_load_end, print_error, true);
424             }
425         }
426     }
427     else if (esp_ptr_in_iram(load_addr_p) && esp_ptr_in_iram(load_inclusive_end_p)) { /* Writing to IRAM */
428         /* Check for overlap of 'loader' section of IRAM */
429         if (bootloader_util_regions_overlap((intptr_t)&_loader_text_start, (intptr_t)&_loader_text_end,
430                                             load_addr, load_end)) {
431             reason = "overlaps loader IRAM";
432             goto invalid;
433         }
434 
435         /* LAST IRAM CHECK (recursive): for D/IRAM, check the equivalent DRAM address if needed
436 
437            Allow for the possibility that even though both pointers are IRAM, only part of the region is in a D/IRAM
438            section. In which case we recurse to check the part which falls in D/IRAM.
439            Note: We start with SOC_DIRAM_IRAM_LOW/HIGH and convert that address to DRAM to account for any reversing of word order
440            (chip-specific).
441          */
442         if (!no_recurse && bootloader_util_regions_overlap(SOC_DIRAM_IRAM_LOW, SOC_DIRAM_IRAM_HIGH, load_addr, load_end)) {
443             intptr_t dram_load_addr, dram_load_end;
444 
445             if (esp_ptr_in_diram_iram(load_addr_p)) {
446                 dram_load_addr = (intptr_t)esp_ptr_diram_iram_to_dram(load_addr_p);
447             } else {
448                 dram_load_addr = (intptr_t)esp_ptr_diram_iram_to_dram((void *)SOC_DIRAM_IRAM_LOW);
449             }
450 
451             if (esp_ptr_in_diram_iram(load_inclusive_end_p)) {
452                 dram_load_end = (intptr_t)esp_ptr_diram_iram_to_dram(load_exclusive_end_p);
453             } else {
454                 dram_load_end = (intptr_t)esp_ptr_diram_iram_to_dram((void *)SOC_DIRAM_IRAM_HIGH);
455             }
456 
457             if (dram_load_end < dram_load_addr) {
458                 return verify_load_addresses(segment_index, dram_load_end, dram_load_addr, print_error, true);
459             } else {
460                 return verify_load_addresses(segment_index, dram_load_addr, dram_load_end, print_error, true);
461             }
462         }
463     /* Sections entirely in RTC memory won't overlap with a vanilla bootloader but are valid load addresses, thus skipping them from the check */
464     }
465 #if SOC_RTC_FAST_MEM_SUPPORTED
466     else if (esp_ptr_in_rtc_iram_fast(load_addr_p) && esp_ptr_in_rtc_iram_fast(load_inclusive_end_p)){
467         return true;
468     } else if (esp_ptr_in_rtc_dram_fast(load_addr_p) && esp_ptr_in_rtc_dram_fast(load_inclusive_end_p)){
469         return true;
470     }
471 #endif
472 
473 #if SOC_RTC_SLOW_MEM_SUPPORTED
474     else if (esp_ptr_in_rtc_slow(load_addr_p) && esp_ptr_in_rtc_slow(load_inclusive_end_p)) {
475         return true;
476     }
477 #endif
478 
479     else { /* Not a DRAM or an IRAM or RTC Fast IRAM, RTC Fast DRAM or RTC Slow address */
480         reason = "bad load address range";
481         goto invalid;
482     }
483     return true;
484 
485  invalid:
486     if (print_error) {
487         ESP_LOGE(TAG, "Segment %d 0x%08x-0x%08x invalid: %s", segment_index, load_addr, load_end, reason);
488     }
489     return false;
490 }
491 #endif // BOOTLOADER_BUILD
492 
process_image_header(esp_image_metadata_t * data,uint32_t part_offset,bootloader_sha256_handle_t * sha_handle,bool do_verify,bool silent)493 static esp_err_t process_image_header(esp_image_metadata_t *data, uint32_t part_offset, bootloader_sha256_handle_t *sha_handle, bool do_verify, bool silent)
494 {
495     esp_err_t err;
496     bzero(data, sizeof(esp_image_metadata_t));
497     data->start_addr = part_offset;
498 
499     ESP_LOGD(TAG, "reading image header @ 0x%"PRIx32, data->start_addr);
500     CHECK_ERR(bootloader_flash_read(data->start_addr, &data->image, sizeof(esp_image_header_t), true));
501 
502     if (do_verify) {
503         // Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
504         if (SECURE_BOOT_CHECK_SIGNATURE || data->image.hash_appended) {
505             if (sha_handle != NULL) {
506                 *sha_handle = bootloader_sha256_start();
507                 if (*sha_handle == NULL) {
508                     return ESP_ERR_NO_MEM;
509                 }
510                 bootloader_sha256_data(*sha_handle, &data->image, sizeof(esp_image_header_t));
511             }
512         }
513         CHECK_ERR(verify_image_header(data->start_addr, &data->image, silent));
514     }
515     data->image_len = sizeof(esp_image_header_t);
516     return ESP_OK;
517 err:
518     return err;
519 }
520 
process_segments(esp_image_metadata_t * data,bool silent,bool do_load,bootloader_sha256_handle_t sha_handle,uint32_t * checksum)521 static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
522 {
523     esp_err_t err = ESP_OK;
524     uint32_t start_segments = data->start_addr + data->image_len;
525     uint32_t next_addr = start_segments;
526     for (int i = 0; i < data->image.segment_count; i++) {
527         esp_image_segment_header_t *header = &data->segments[i];
528         ESP_LOGV(TAG, "loading segment header %d at offset 0x%"PRIx32, i, next_addr);
529         CHECK_ERR(process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum, data));
530         next_addr += sizeof(esp_image_segment_header_t);
531         data->segment_data[i] = next_addr;
532         next_addr += header->data_len;
533     }
534     // Segments all loaded, verify length
535     uint32_t end_addr = next_addr;
536     if (end_addr < data->start_addr) {
537         FAIL_LOAD("image offset has wrapped");
538     }
539 
540     data->image_len += end_addr - start_segments;
541     ESP_LOGV(TAG, "image start 0x%08"PRIx32" end of last section 0x%08"PRIx32, data->start_addr, end_addr);
542     return err;
543 err:
544     if (err == ESP_OK) {
545         err = ESP_ERR_IMAGE_INVALID;
546     }
547     return err;
548 }
549 
process_segment(int index,uint32_t flash_addr,esp_image_segment_header_t * header,bool silent,bool do_load,bootloader_sha256_handle_t sha_handle,uint32_t * checksum,esp_image_metadata_t * metadata)550 static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata)
551 {
552     esp_err_t err;
553 
554     /* read segment header */
555     err = bootloader_flash_read(flash_addr, header, sizeof(esp_image_segment_header_t), true);
556     if (err != ESP_OK) {
557         ESP_LOGE(TAG, "bootloader_flash_read failed at 0x%08"PRIx32, flash_addr);
558         return err;
559     }
560     if (sha_handle != NULL) {
561         bootloader_sha256_data(sha_handle, header, sizeof(esp_image_segment_header_t));
562     }
563 
564     intptr_t load_addr = header->load_addr;
565     uint32_t data_len = header->data_len;
566     uint32_t data_addr = flash_addr + sizeof(esp_image_segment_header_t);
567 
568     ESP_LOGV(TAG, "segment data length 0x%"PRIx32" data starts 0x%"PRIx32, data_len, data_addr);
569 
570     CHECK_ERR(verify_segment_header(index, header, data_addr, silent));
571 
572     if (data_len % 4 != 0) {
573         FAIL_LOAD("unaligned segment length 0x%"PRIx32, data_len);
574     }
575 
576     bool is_mapping = should_map(load_addr);
577     do_load = do_load && should_load(load_addr);
578 
579     if (!silent) {
580         ESP_LOGI(TAG, "segment %d: paddr=%08"PRIx32" vaddr=%08x size=%05"PRIx32"h (%6"PRIu32") %s",
581                  index, data_addr, load_addr,
582                  data_len, data_len,
583                  (do_load) ? "load" : (is_mapping) ? "map" : "");
584     }
585 
586 
587 #ifdef BOOTLOADER_BUILD
588     /* Before loading segment, check it doesn't clobber bootloader RAM. */
589     if (do_load && data_len > 0) {
590         if (!verify_load_addresses(index, load_addr, load_addr + data_len, true, false)) {
591             return ESP_ERR_IMAGE_INVALID;
592         }
593     }
594 #endif // BOOTLOADER_BUILD
595 
596     uint32_t free_page_count = bootloader_mmap_get_free_pages();
597     ESP_LOGD(TAG, "free data page_count 0x%08"PRIx32, free_page_count);
598 
599     uint32_t data_len_remain = data_len;
600     while (data_len_remain > 0) {
601 #if (SECURE_BOOT_CHECK_SIGNATURE == 1) && defined(BOOTLOADER_BUILD)
602         /* Double check the address verification done above */
603         ESP_FAULT_ASSERT(!do_load || verify_load_addresses(0, load_addr, load_addr + data_len_remain, false, false));
604 #endif
605         uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
606         /* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
607         data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
608         CHECK_ERR(process_segment_data(index, load_addr, data_addr, data_len, do_load, sha_handle, checksum, metadata));
609         data_addr += data_len;
610         data_len_remain -= data_len;
611     }
612 
613     return ESP_OK;
614 
615 err:
616     if (err == ESP_OK) {
617         err = ESP_ERR_IMAGE_INVALID;
618     }
619 
620     return err;
621 }
622 
623 #if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
624 /* The __attribute__((optimize("O0"))) is used to disable optimizations for this function,
625  * preventing the compiler from potentially optimizing data_buffer and reading data directly from src.
626  * This is crucial as we want to read from Flash only once, ensuring the integrity of the data.
627  */
628 __attribute__((optimize("O0")))
process_esp_app_desc_data(const uint32_t * src,bootloader_sha256_handle_t sha_handle,uint32_t * checksum,esp_image_metadata_t * metadata)629 static size_t process_esp_app_desc_data(const uint32_t *src, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata)
630 {
631     /* Using data_buffer here helps to securely read secure_version
632      * (for anti-rollback) from esp_app_desc_t, preventing FI attack.
633      * We read data from Flash into this buffer, which is covered by sha256.
634      * Therefore, if the flash is under attackers control and contents are modified
635      * the sha256 comparison will fail.
636      *
637      * The esp_app_desc_t structure is located in DROM and is always in segment #0.
638      *
639      * esp_app_desc_t is always at #0 segment (index==0).
640      * secure_version field of esp_app_desc_t is located at #2 word (w_i==1).
641      */
642     uint32_t data_buffer[2];
643     memcpy(data_buffer, src, sizeof(data_buffer));
644     assert(data_buffer[0] == ESP_APP_DESC_MAGIC_WORD);
645     metadata->secure_version = data_buffer[1];
646     if (checksum != NULL) {
647         *checksum ^= data_buffer[0] ^ data_buffer[1];
648     }
649     if (sha_handle != NULL) {
650         bootloader_sha256_data(sha_handle, data_buffer, sizeof(data_buffer));
651     }
652     ESP_FAULT_ASSERT(memcmp(data_buffer, src, sizeof(data_buffer)) == 0);
653     ESP_FAULT_ASSERT(memcmp(&metadata->secure_version, &src[1], sizeof(uint32_t)) == 0);
654     return sizeof(data_buffer);
655 }
656 #endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
657 
process_segment_data(int segment,intptr_t load_addr,uint32_t data_addr,uint32_t data_len,bool do_load,bootloader_sha256_handle_t sha_handle,uint32_t * checksum,esp_image_metadata_t * metadata)658 static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata)
659 {
660     // If we are not loading, and the checksum is empty, skip processing this
661     // segment for data
662     if (!do_load && checksum == NULL) {
663         ESP_LOGD(TAG, "skipping checksum for segment");
664         return ESP_OK;
665     }
666 
667     const uint32_t *data = (const uint32_t *)bootloader_mmap(data_addr, data_len);
668     if (!data) {
669         ESP_LOGE(TAG, "bootloader_mmap(0x%"PRIx32", 0x%"PRIx32") failed",
670                  data_addr, data_len);
671         return ESP_FAIL;
672     }
673 
674     if (checksum == NULL && sha_handle == NULL) {
675         memcpy((void *)load_addr, data, data_len);
676         bootloader_munmap(data);
677         return ESP_OK;
678     }
679 
680 #ifdef BOOTLOADER_BUILD
681     // Set up the obfuscation value to use for loading
682     while (ram_obfs_value[0] == 0 || ram_obfs_value[1] == 0) {
683         bootloader_fill_random(ram_obfs_value, sizeof(ram_obfs_value));
684 #if CONFIG_IDF_ENV_FPGA
685         /* FPGA doesn't always emulate the RNG */
686         ram_obfs_value[0] ^= 0x33;
687         ram_obfs_value[1] ^= 0x66;
688 #endif
689     }
690     uint32_t *dest = (uint32_t *)load_addr;
691 #endif // BOOTLOADER_BUILD
692 
693     const uint32_t *src = data;
694 
695 #if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
696     // Case I: Bootloader verifying application
697     // Case II: Bootloader verifying bootloader
698     // Anti-rollback check should handle only Case I from above.
699     if (segment == 0 && metadata->start_addr != ESP_BOOTLOADER_OFFSET) {
700         ESP_LOGD(TAG, "additional anti-rollback check 0x%"PRIx32, data_addr);
701         // The esp_app_desc_t structure is located in DROM and is always in segment #0.
702         size_t len = process_esp_app_desc_data(src, sha_handle, checksum, metadata);
703         data_len -= len;
704         src += len / 4;
705         // In BOOTLOADER_BUILD, for DROM (segment #0) we do not load it into dest (only map it), do_load = false.
706     }
707 #endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
708 
709     for (size_t i = 0; i < data_len; i += 4) {
710         int w_i = i / 4; // Word index
711         uint32_t w = src[w_i];
712         if (checksum != NULL) {
713             *checksum ^= w;
714         }
715 #ifdef BOOTLOADER_BUILD
716         if (do_load) {
717             dest[w_i] = w ^ ((w_i & 1) ? ram_obfs_value[0] : ram_obfs_value[1]);
718         }
719 #endif
720         // SHA_CHUNK determined experimentally as the optimum size
721         // to call bootloader_sha256_data() with. This is a bit
722         // counter-intuitive, but it's ~3ms better than using the
723         // SHA256 block size.
724         const size_t SHA_CHUNK = 1024;
725         if (sha_handle != NULL && i % SHA_CHUNK == 0) {
726             bootloader_sha256_data(sha_handle, &src[w_i],
727                                    MIN(SHA_CHUNK, data_len - i));
728         }
729     }
730 
731     bootloader_munmap(data);
732 
733     return ESP_OK;
734 }
735 
verify_segment_header(int index,const esp_image_segment_header_t * segment,uint32_t segment_data_offs,bool silent)736 static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent)
737 {
738     if ((segment->data_len & 3) != 0
739             || segment->data_len >= SIXTEEN_MB) {
740         if (!silent) {
741             ESP_LOGE(TAG, "invalid segment length 0x%"PRIx32, segment->data_len);
742         }
743         return ESP_ERR_IMAGE_INVALID;
744     }
745 
746     uint32_t load_addr = segment->load_addr;
747     bool map_segment = should_map(load_addr);
748 
749     /* Check that flash cache mapped segment aligns correctly from flash to its mapped address,
750        relative to the 64KB page mapping size.
751     */
752     ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%"PRIx32" load_addr 0x%"PRIx32,
753              index, map_segment, segment_data_offs, load_addr);
754     if (map_segment
755             && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) {
756         if (!silent) {
757             ESP_LOGE(TAG, "Segment %d load address 0x%08"PRIx32", doesn't match data 0x%08"PRIx32,
758                      index, load_addr, segment_data_offs);
759         }
760         return ESP_ERR_IMAGE_INVALID;
761     }
762 
763     return ESP_OK;
764 }
765 
should_map(uint32_t load_addr)766 static bool should_map(uint32_t load_addr)
767 {
768     return (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH)
769            || (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH);
770 }
771 
should_load(uint32_t load_addr)772 static bool should_load(uint32_t load_addr)
773 {
774     /* Reload the RTC memory segments whenever a non-deepsleep reset
775        is occurring */
776     bool load_rtc_memory = esp_rom_get_reset_reason(0) != RESET_REASON_CORE_DEEP_SLEEP;
777 
778     if (should_map(load_addr)) {
779         return false;
780     }
781 
782     if (load_addr < 0x10000000) {
783         // Reserved for non-loaded addresses.
784         // Current reserved values are
785         // 0x0 (padding block)
786         // 0x4 (unused, but reserved for an MD5 block)
787         return false;
788     }
789 
790     if (!load_rtc_memory) {
791 #if SOC_RTC_FAST_MEM_SUPPORTED
792         if (load_addr >= SOC_RTC_IRAM_LOW && load_addr < SOC_RTC_IRAM_HIGH) {
793             ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08"PRIx32, load_addr);
794             return false;
795         }
796         if (load_addr >= SOC_RTC_DRAM_LOW && load_addr < SOC_RTC_DRAM_HIGH) {
797             ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08"PRIx32, load_addr);
798             return false;
799         }
800 #endif
801 
802 #if SOC_RTC_SLOW_MEM_SUPPORTED
803         if (load_addr >= SOC_RTC_DATA_LOW && load_addr < SOC_RTC_DATA_HIGH) {
804             ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08"PRIx32, load_addr);
805             return false;
806         }
807 #endif
808     }
809 
810     return true;
811 }
812 
esp_image_verify_bootloader(uint32_t * length)813 esp_err_t esp_image_verify_bootloader(uint32_t *length)
814 {
815     esp_image_metadata_t data;
816     esp_err_t err = esp_image_verify_bootloader_data(&data);
817     if (length != NULL) {
818         *length = (err == ESP_OK) ? data.image_len : 0;
819     }
820     return err;
821 }
822 
esp_image_verify_bootloader_data(esp_image_metadata_t * data)823 esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data)
824 {
825     if (data == NULL) {
826         return ESP_ERR_INVALID_ARG;
827     }
828     const esp_partition_pos_t bootloader_part = {
829         .offset = ESP_BOOTLOADER_OFFSET,
830         .size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
831     };
832     return esp_image_verify(ESP_IMAGE_VERIFY,
833                             &bootloader_part,
834                             data);
835 }
836 
process_appended_hash_and_sig(esp_image_metadata_t * data,uint32_t part_offset,uint32_t part_len,bool do_verify,bool silent)837 static esp_err_t process_appended_hash_and_sig(esp_image_metadata_t *data, uint32_t part_offset, uint32_t part_len, bool do_verify, bool silent)
838 {
839     esp_err_t err = ESP_OK;
840     if (data->image.hash_appended) {
841         // Account for the hash in the total image length
842         if (do_verify) {
843             CHECK_ERR(bootloader_flash_read(data->start_addr + data->image_len, &data->image_digest, HASH_LEN, true));
844         }
845         data->image_len += HASH_LEN;
846     }
847 
848     uint32_t sig_block_len = 0;
849     const uint32_t end = data->image_len;
850 #if CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
851 
852     // Case I: Bootloader part
853     if (part_offset == ESP_BOOTLOADER_OFFSET) {
854         // For bootloader with secure boot v1, signature stays in an independant flash
855         // sector (offset 0x0)  and does not get appended to the image.
856 #if CONFIG_SECURE_BOOT_V2_ENABLED
857         // Sanity check - secure boot v2 signature block starts on 4K boundary
858         sig_block_len = ALIGN_UP(end, FLASH_SECTOR_SIZE) - end;
859         sig_block_len += sizeof(ets_secure_boot_signature_t);
860 #endif
861     } else {
862     // Case II: Application part
863 #if CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
864         sig_block_len = sizeof(esp_secure_boot_sig_block_t);
865 #else
866         // Sanity check - secure boot v2 signature block starts on 4K boundary
867         sig_block_len = ALIGN_UP(end, FLASH_SECTOR_SIZE) - end;
868         sig_block_len += sizeof(ets_secure_boot_signature_t);
869 #endif
870     }
871 #endif // CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
872 
873     const uint32_t full_image_len = end + sig_block_len;
874     if (full_image_len > part_len) {
875         FAIL_LOAD("Image length %"PRIu32" doesn't fit in partition length %"PRIu32, full_image_len, part_len);
876     }
877     return err;
878 err:
879     if (err == ESP_OK) {
880         err = ESP_ERR_IMAGE_INVALID;
881     }
882 
883     return err;
884 }
885 
process_checksum(bootloader_sha256_handle_t sha_handle,uint32_t checksum_word,esp_image_metadata_t * data,bool silent,bool skip_check_checksum)886 static esp_err_t process_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data, bool silent, bool skip_check_checksum)
887 {
888     esp_err_t err = ESP_OK;
889     uint32_t unpadded_length = data->image_len;
890     uint32_t length = unpadded_length + 1; // Add a byte for the checksum
891     length = (length + 15) & ~15; // Pad to next full 16 byte block
892     length = length - unpadded_length;
893 
894     // Verify checksum
895     WORD_ALIGNED_ATTR uint8_t buf[16] = {0};
896     if (!skip_check_checksum || sha_handle != NULL) {
897         CHECK_ERR(bootloader_flash_read(data->start_addr + unpadded_length, buf, length, true));
898     }
899     uint8_t read_checksum = buf[length - 1];
900     uint8_t calc_checksum = (checksum_word >> 24) ^ (checksum_word >> 16) ^ (checksum_word >> 8) ^ (checksum_word >> 0);
901     if (!skip_check_checksum && calc_checksum != read_checksum) {
902         FAIL_LOAD("Checksum failed. Calculated 0x%x read 0x%x", calc_checksum, read_checksum);
903     }
904     if (sha_handle != NULL) {
905         bootloader_sha256_data(sha_handle, buf, length);
906     }
907     data->image_len += length;
908 
909     return err;
910 err:
911     if (err == ESP_OK) {
912         err = ESP_ERR_IMAGE_INVALID;
913     }
914 
915     return err;
916 }
917 
verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle,esp_image_metadata_t * data,uint8_t * image_digest,uint8_t * verified_digest)918 static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data, uint8_t *image_digest, uint8_t *verified_digest)
919 {
920 #if (SECURE_BOOT_CHECK_SIGNATURE == 1)
921     uint32_t end = data->start_addr + data->image_len;
922 
923     ESP_LOGI(TAG, "Verifying image signature...");
924 
925     // For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash
926     // appended to the image for corruption detection
927     if (data->image.hash_appended) {
928         const void *simple_hash = bootloader_mmap(end - HASH_LEN, HASH_LEN);
929         bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN);
930         bootloader_munmap(simple_hash);
931     }
932 
933 #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
934     // End of the image needs to be padded all the way to a 4KB boundary, after the simple hash
935     // (for apps they are usually already padded due to --secure-pad-v2, only a problem if this option was not used.)
936     uint32_t padded_end = ALIGN_UP(end, FLASH_SECTOR_SIZE);
937     if (padded_end > end) {
938         const void *padding = bootloader_mmap(end, padded_end - end);
939         bootloader_sha256_data(sha_handle, padding, padded_end - end);
940         bootloader_munmap(padding);
941         end = padded_end;
942     }
943 #endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
944 
945     bootloader_sha256_finish(sha_handle, image_digest);
946 
947     // Log the hash for debugging
948     bootloader_debug_buffer(image_digest, HASH_LEN, "Calculated secure boot hash");
949 
950     // Use hash to verify signature block
951     esp_err_t err = ESP_ERR_IMAGE_INVALID;
952 #if CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
953     const void *sig_block;
954     ESP_FAULT_ASSERT(memcmp(image_digest, verified_digest, HASH_LEN) != 0); /* sanity check that these values start differently */
955 #if defined(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)
956     sig_block = bootloader_mmap(data->start_addr + data->image_len, sizeof(esp_secure_boot_sig_block_t));
957     err = esp_secure_boot_verify_ecdsa_signature_block(sig_block, image_digest, verified_digest);
958 #else
959     sig_block = bootloader_mmap(end, sizeof(ets_secure_boot_signature_t));
960     err = esp_secure_boot_verify_sbv2_signature_block(sig_block, image_digest, verified_digest);
961 #endif
962     bootloader_munmap(sig_block);
963 #endif // CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
964     if (err != ESP_OK) {
965         ESP_LOGE(TAG, "Secure boot signature verification failed");
966 
967         // Go back and check if the simple hash matches or not (we're off the fast path so we can re-hash the whole image now)
968         ESP_LOGI(TAG, "Calculating simple hash to check for corruption...");
969         const void *whole_image = bootloader_mmap(data->start_addr, data->image_len - HASH_LEN);
970         if (whole_image != NULL) {
971             sha_handle = bootloader_sha256_start();
972             bootloader_sha256_data(sha_handle, whole_image, data->image_len - HASH_LEN);
973             bootloader_munmap(whole_image);
974             if (verify_simple_hash(sha_handle, data) != ESP_OK) {
975                 ESP_LOGW(TAG, "image corrupted on flash");
976             } else {
977                 ESP_LOGW(TAG, "image valid, signature bad");
978             }
979         }
980         return ESP_ERR_IMAGE_INVALID;
981     }
982 
983     // Adjust image length result to include the appended signature
984 #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
985     data->image_len = end - data->start_addr + sizeof(ets_secure_boot_signature_t);
986 #elif defined(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)
987     if (data->start_addr != ESP_BOOTLOADER_OFFSET) {
988         data->image_len = end - data->start_addr + sizeof(esp_secure_boot_sig_block_t);
989     }
990 #endif
991 
992 #endif // SECURE_BOOT_CHECK_SIGNATURE
993     return ESP_OK;
994 }
995 
verify_simple_hash(bootloader_sha256_handle_t sha_handle,esp_image_metadata_t * data)996 static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data)
997 {
998     uint8_t image_hash[HASH_LEN] = { 0 };
999     bootloader_sha256_finish(sha_handle, image_hash);
1000 
1001     // Log the hash for debugging
1002     bootloader_debug_buffer(image_hash, HASH_LEN, "Calculated hash");
1003 
1004     // Simple hash for verification only
1005     if (memcmp(data->image_digest, image_hash, HASH_LEN) != 0) {
1006         ESP_LOGE(TAG, "Image hash failed - image is corrupt");
1007         bootloader_debug_buffer(data->image_digest, HASH_LEN, "Expected hash");
1008 #ifdef CONFIG_IDF_ENV_FPGA
1009         ESP_LOGW(TAG, "Ignoring invalid SHA-256 as running on FPGA");
1010         return ESP_OK;
1011 #endif
1012         return ESP_ERR_IMAGE_INVALID;
1013     }
1014 
1015     return ESP_OK;
1016 }
1017 
esp_image_get_flash_size(esp_image_flash_size_t app_flash_size)1018 int esp_image_get_flash_size(esp_image_flash_size_t app_flash_size)
1019 {
1020     switch (app_flash_size) {
1021     case ESP_IMAGE_FLASH_SIZE_1MB:
1022         return 1 * 1024 * 1024;
1023     case ESP_IMAGE_FLASH_SIZE_2MB:
1024         return 2 * 1024 * 1024;
1025     case ESP_IMAGE_FLASH_SIZE_4MB:
1026         return 4 * 1024 * 1024;
1027     case ESP_IMAGE_FLASH_SIZE_8MB:
1028         return 8 * 1024 * 1024;
1029     case ESP_IMAGE_FLASH_SIZE_16MB:
1030         return 16 * 1024 * 1024;
1031     case ESP_IMAGE_FLASH_SIZE_32MB:
1032         return 32 * 1024 * 1024;
1033     case ESP_IMAGE_FLASH_SIZE_64MB:
1034         return 64 * 1024 * 1024;
1035     case ESP_IMAGE_FLASH_SIZE_128MB:
1036         return 128 * 1024 * 1024;
1037     default:
1038         return 0;
1039     }
1040 }
1041