Import bootloader from esp-idf v3
[apeos.git] / components / bootloader_support / src / esp_image_format.c
blobc65020595bd7c9ffc88184cffd3a56edae6d8bd4
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include <string.h>
15 #include <sys/param.h>
17 #include <rom/rtc.h>
18 #include <soc/cpu.h>
19 #include <esp_image_format.h>
20 #include <esp_secure_boot.h>
21 #include <esp_log.h>
22 #include <esp_spi_flash.h>
23 #include <bootloader_flash.h>
24 #include <bootloader_random.h>
25 #include <bootloader_sha.h>
27 static const char *TAG = "esp_image";
29 #define HASH_LEN 32 /* SHA-256 digest length */
31 #define SIXTEEN_MB 0x1000000
32 #define ESP_ROM_CHECKSUM_INITIAL 0xEF
34 /* Headroom to ensure between stack SP (at time of checking) and data loaded from flash */
35 #define STACK_LOAD_HEADROOM 32768
37 /* Mmap source address mask */
38 #define MMAP_ALIGNED_MASK 0x0000FFFF
40 #ifdef BOOTLOADER_BUILD
41 /* 64 bits of random data to obfuscate loaded RAM with, until verification is complete
42 (Means loaded code isn't executable until after the secure boot check.)
44 static uint32_t ram_obfs_value[2];
45 #endif
47 /* Return true if load_addr is an address the bootloader should load into */
48 static bool should_load(uint32_t load_addr);
49 /* Return true if load_addr is an address the bootloader should map via flash cache */
50 static bool should_map(uint32_t load_addr);
52 /* Load or verify a segment */
53 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);
55 /* split segment and verify if data_len is too long */
56 static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
58 /* Verify the main image header */
59 static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent);
61 /* Verify a segment header */
62 static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent);
64 /* Log-and-fail macro for use in esp_image_load */
65 #define FAIL_LOAD(...) do { \
66 if (!silent) { \
67 ESP_LOGE(TAG, __VA_ARGS__); \
68 } \
69 goto err; \
70 } \
71 while(0)
73 static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data);
75 static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
76 static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
78 esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
80 #ifdef BOOTLOADER_BUILD
81 bool do_load = (mode == ESP_IMAGE_LOAD);
82 #else
83 bool do_load = false; // Can't load the image in app mode
84 #endif
85 bool silent = (mode == ESP_IMAGE_VERIFY_SILENT);
86 esp_err_t err = ESP_OK;
87 // checksum the image a word at a time. This shaves 30-40ms per MB of image size
88 uint32_t checksum_word = ESP_ROM_CHECKSUM_INITIAL;
89 bootloader_sha256_handle_t sha_handle = NULL;
91 if (data == NULL || part == NULL) {
92 return ESP_ERR_INVALID_ARG;
95 if (part->size > SIXTEEN_MB) {
96 err = ESP_ERR_INVALID_ARG;
97 FAIL_LOAD("partition size 0x%x invalid, larger than 16MB", part->size);
100 bzero(data, sizeof(esp_image_metadata_t));
101 data->start_addr = part->offset;
103 ESP_LOGD(TAG, "reading image header @ 0x%x", data->start_addr);
104 err = bootloader_flash_read(data->start_addr, &data->image, sizeof(esp_image_header_t), true);
105 if (err != ESP_OK) {
106 goto err;
109 // Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
110 #ifdef CONFIG_SECURE_BOOT_ENABLED
111 if (1) {
112 #else
113 if (data->image.hash_appended) {
114 #endif
115 sha_handle = bootloader_sha256_start();
116 if (sha_handle == NULL) {
117 return ESP_ERR_NO_MEM;
119 bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t));
122 ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x",
123 data->image.magic,
124 data->image.segment_count,
125 data->image.spi_mode,
126 data->image.spi_size,
127 data->image.entry_addr);
129 err = verify_image_header(data->start_addr, &data->image, silent);
130 if (err != ESP_OK) {
131 goto err;
134 if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
135 FAIL_LOAD("image at 0x%x segment count %d exceeds max %d",
136 data->start_addr, data->image.segment_count, ESP_IMAGE_MAX_SEGMENTS);
139 uint32_t next_addr = data->start_addr + sizeof(esp_image_header_t);
140 for(int i = 0; i < data->image.segment_count; i++) {
141 esp_image_segment_header_t *header = &data->segments[i];
142 ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
143 err = process_segment(i, next_addr, header, silent, do_load, sha_handle, &checksum_word);
144 if (err != ESP_OK) {
145 goto err;
147 next_addr += sizeof(esp_image_segment_header_t);
148 data->segment_data[i] = next_addr;
149 next_addr += header->data_len;
152 // Segments all loaded, verify length
153 uint32_t end_addr = next_addr;
154 if (end_addr < data->start_addr) {
155 FAIL_LOAD("image offset has wrapped");
158 data->image_len = end_addr - data->start_addr;
159 ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
160 err = verify_checksum(sha_handle, checksum_word, data);
161 if (err != ESP_OK) {
162 goto err;
165 if (data->image_len > part->size) {
166 FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
169 bool is_bootloader = (data->start_addr == ESP_BOOTLOADER_OFFSET);
170 /* For secure boot, we don't verify signature on bootloaders.
172 For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because esptool.py may have
173 rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.
175 if (!is_bootloader) {
176 #ifdef CONFIG_SECURE_BOOT_ENABLED
177 // secure boot images have a signature appended
178 err = verify_secure_boot_signature(sha_handle, data);
179 #else
180 // No secure boot, but SHA-256 can be appended for basic corruption detection
181 if (sha_handle != NULL) {
182 err = verify_simple_hash(sha_handle, data);
184 #endif // CONFIG_SECURE_BOOT_ENABLED
185 } else { // is_bootloader
186 // bootloader may still have a sha256 digest handle open
187 if (sha_handle != NULL) {
188 bootloader_sha256_finish(sha_handle, NULL);
191 sha_handle = NULL;
192 if (err != ESP_OK) {
193 goto err;
196 #ifdef BOOTLOADER_BUILD
197 if (do_load) { // Need to deobfuscate RAM
198 for (int i = 0; i < data->image.segment_count; i++) {
199 uint32_t load_addr = data->segments[i].load_addr;
200 if (should_load(load_addr)) {
201 uint32_t *loaded = (uint32_t *)load_addr;
202 for (int j = 0; j < data->segments[i].data_len/sizeof(uint32_t); j++) {
203 loaded[j] ^= (j & 1) ? ram_obfs_value[0] : ram_obfs_value[1];
208 #endif
210 // Success!
211 return ESP_OK;
213 err:
214 if (err == ESP_OK) {
215 err = ESP_ERR_IMAGE_INVALID;
217 if (sha_handle != NULL) {
218 // Need to finish the hash process to free the handle
219 bootloader_sha256_finish(sha_handle, NULL);
221 // Prevent invalid/incomplete data leaking out
222 bzero(data, sizeof(esp_image_metadata_t));
223 return err;
226 static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
228 esp_err_t err = ESP_OK;
230 if (image->magic != ESP_IMAGE_HEADER_MAGIC) {
231 if (!silent) {
232 ESP_LOGE(TAG, "image at 0x%x has invalid magic byte", src_addr);
234 err = ESP_ERR_IMAGE_INVALID;
236 if (!silent) {
237 if (image->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
238 ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image->spi_mode);
240 if (image->spi_speed > ESP_IMAGE_SPI_SPEED_80M) {
241 ESP_LOGW(TAG, "image at 0x%x has invalid SPI speed %d", src_addr, image->spi_speed);
243 if (image->spi_size > ESP_IMAGE_FLASH_SIZE_MAX) {
244 ESP_LOGW(TAG, "image at 0x%x has invalid SPI size %d", src_addr, image->spi_size);
247 return err;
250 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)
252 esp_err_t err;
254 /* read segment header */
255 err = bootloader_flash_read(flash_addr, header, sizeof(esp_image_segment_header_t), true);
256 if (err != ESP_OK) {
257 ESP_LOGE(TAG, "bootloader_flash_read failed at 0x%08x", flash_addr);
258 return err;
260 if (sha_handle != NULL) {
261 bootloader_sha256_data(sha_handle, header, sizeof(esp_image_segment_header_t));
264 intptr_t load_addr = header->load_addr;
265 uint32_t data_len = header->data_len;
266 uint32_t data_addr = flash_addr + sizeof(esp_image_segment_header_t);
268 ESP_LOGV(TAG, "segment data length 0x%x data starts 0x%x", data_len, data_addr);
270 err = verify_segment_header(index, header, data_addr, silent);
271 if (err != ESP_OK) {
272 return err;
275 if (data_len % 4 != 0) {
276 FAIL_LOAD("unaligned segment length 0x%x", data_len);
279 bool is_mapping = should_map(load_addr);
280 do_load = do_load && should_load(load_addr);
282 if (!silent) {
283 ESP_LOGI(TAG, "segment %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s",
284 index, data_addr, load_addr,
285 data_len, data_len,
286 (do_load)?"load":(is_mapping)?"map":"");
289 if (do_load) {
290 /* Before loading segment, check it doesn't clobber bootloader RAM... */
291 uint32_t end_addr = load_addr + data_len;
292 if (end_addr < 0x40000000) {
293 intptr_t sp = (intptr_t)get_sp();
294 if (end_addr > sp - STACK_LOAD_HEADROOM) {
295 ESP_LOGE(TAG, "Segment %d end address 0x%08x too high (bootloader stack 0x%08x liimit 0x%08x)",
296 index, end_addr, sp, sp - STACK_LOAD_HEADROOM);
297 return ESP_ERR_IMAGE_INVALID;
301 #ifndef BOOTLOADER_BUILD
302 uint32_t free_page_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
303 ESP_LOGD(TAG, "free data page_count 0x%08x",free_page_count);
304 uint32_t offset_page = 0;
305 while (data_len >= free_page_count * SPI_FLASH_MMU_PAGE_SIZE) {
306 offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0)?1:0;
307 err = process_segment_data(load_addr, data_addr, (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE, do_load, sha_handle, checksum);
308 if (err != ESP_OK) {
309 return err;
311 data_addr += (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
312 data_len -= (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
314 #endif
315 err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
316 if (err != ESP_OK) {
317 return err;
319 return ESP_OK;
321 err:
322 if (err == ESP_OK) {
323 err = ESP_ERR_IMAGE_INVALID;
326 return err;
329 static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
331 const uint32_t *data = (const uint32_t *)bootloader_mmap(data_addr, data_len);
332 if(!data) {
333 ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed",
334 data_addr, data_len);
335 return ESP_FAIL;
338 #ifdef BOOTLOADER_BUILD
339 // Set up the obfuscation value to use for loading
340 while (ram_obfs_value[0] == 0 || ram_obfs_value[1] == 0) {
341 bootloader_fill_random(ram_obfs_value, sizeof(ram_obfs_value));
343 uint32_t *dest = (uint32_t *)load_addr;
344 #endif
346 const uint32_t *src = data;
348 for (int i = 0; i < data_len; i += 4) {
349 int w_i = i/4; // Word index
350 uint32_t w = src[w_i];
351 *checksum ^= w;
352 #ifdef BOOTLOADER_BUILD
353 if (do_load) {
354 dest[w_i] = w ^ ((w_i & 1) ? ram_obfs_value[0] : ram_obfs_value[1]);
356 #endif
357 // SHA_CHUNK determined experimentally as the optimum size
358 // to call bootloader_sha256_data() with. This is a bit
359 // counter-intuitive, but it's ~3ms better than using the
360 // SHA256 block size.
361 const size_t SHA_CHUNK = 1024;
362 if (sha_handle != NULL && i % SHA_CHUNK == 0) {
363 bootloader_sha256_data(sha_handle, &src[w_i],
364 MIN(SHA_CHUNK, data_len - i));
368 bootloader_munmap(data);
370 return ESP_OK;
373 static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent)
375 if ((segment->data_len & 3) != 0
376 || segment->data_len >= SIXTEEN_MB) {
377 if (!silent) {
378 ESP_LOGE(TAG, "invalid segment length 0x%x", segment->data_len);
380 return ESP_ERR_IMAGE_INVALID;
383 uint32_t load_addr = segment->load_addr;
384 bool map_segment = should_map(load_addr);
386 /* Check that flash cache mapped segment aligns correctly from flash to its mapped address,
387 relative to the 64KB page mapping size.
389 ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%x load_addr 0x%x",
390 index, map_segment, segment_data_offs, load_addr);
391 if (map_segment
392 && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) {
393 if (!silent) {
394 ESP_LOGE(TAG, "Segment %d load address 0x%08x, doesn't match data 0x%08x",
395 index, load_addr, segment_data_offs);
397 return ESP_ERR_IMAGE_INVALID;
400 return ESP_OK;
403 static bool should_map(uint32_t load_addr)
405 return (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH)
406 || (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH);
409 static bool should_load(uint32_t load_addr)
411 /* Reload the RTC memory segments whenever a non-deepsleep reset
412 is occurring */
413 bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET;
415 if (should_map(load_addr)) {
416 return false;
419 if (load_addr < 0x10000000) {
420 // Reserved for non-loaded addresses.
421 // Current reserved values are
422 // 0x0 (padding block)
423 // 0x4 (unused, but reserved for an MD5 block)
424 return false;
427 if (!load_rtc_memory) {
428 if (load_addr >= SOC_RTC_IRAM_LOW && load_addr < SOC_RTC_IRAM_HIGH) {
429 ESP_LOGD(TAG, "Skipping RTC code segment at 0x%08x\n", load_addr);
430 return false;
432 if (load_addr >= SOC_RTC_DATA_LOW && load_addr < SOC_RTC_DATA_HIGH) {
433 ESP_LOGD(TAG, "Skipping RTC data segment at 0x%08x\n", load_addr);
434 return false;
438 return true;
441 esp_err_t esp_image_verify_bootloader(uint32_t *length)
443 esp_image_metadata_t data;
444 const esp_partition_pos_t bootloader_part = {
445 .offset = ESP_BOOTLOADER_OFFSET,
446 .size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
448 esp_err_t err = esp_image_load(ESP_IMAGE_VERIFY,
449 &bootloader_part,
450 &data);
451 if (length != NULL) {
452 *length = (err == ESP_OK) ? data.image_len : 0;
454 return err;
457 static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data)
459 uint32_t unpadded_length = data->image_len;
460 uint32_t length = unpadded_length + 1; // Add a byte for the checksum
461 length = (length + 15) & ~15; // Pad to next full 16 byte block
463 // Verify checksum
464 uint8_t buf[16];
465 esp_err_t err = bootloader_flash_read(data->start_addr + unpadded_length, buf, length - unpadded_length, true);
466 uint8_t calc = buf[length - unpadded_length - 1];
467 uint8_t checksum = (checksum_word >> 24)
468 ^ (checksum_word >> 16)
469 ^ (checksum_word >> 8)
470 ^ (checksum_word >> 0);
471 if (err != ESP_OK || checksum != calc) {
472 ESP_LOGE(TAG, "Checksum failed. Calculated 0x%x read 0x%x", checksum, calc);
473 return ESP_ERR_IMAGE_INVALID;
475 if (sha_handle != NULL) {
476 bootloader_sha256_data(sha_handle, buf, length - unpadded_length);
479 if (data->image.hash_appended) {
480 // Account for the hash in the total image length
481 length += HASH_LEN;
483 data->image_len = length;
485 return ESP_OK;
488 static void debug_log_hash(const uint8_t *image_hash, const char *caption);
490 static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data)
492 uint8_t image_hash[HASH_LEN] = { 0 };
494 // For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash
495 // appended to the image for corruption detection
496 if (data->image.hash_appended) {
497 const void *simple_hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
498 bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN);
499 bootloader_munmap(simple_hash);
502 bootloader_sha256_finish(sha_handle, image_hash);
504 // Log the hash for debugging
505 debug_log_hash(image_hash, "Calculated secure boot hash");
507 // Use hash to verify signature block
508 const esp_secure_boot_sig_block_t *sig_block = bootloader_mmap(data->start_addr + data->image_len, sizeof(esp_secure_boot_sig_block_t));
509 esp_err_t err = esp_secure_boot_verify_signature_block(sig_block, image_hash);
510 bootloader_munmap(sig_block);
511 if (err != ESP_OK) {
512 ESP_LOGE(TAG, "Secure boot signature verification failed");
514 // 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)
515 ESP_LOGI(TAG, "Calculating simple hash to check for corruption...");
516 const void *whole_image = bootloader_mmap(data->start_addr, data->image_len - HASH_LEN);
517 if (whole_image != NULL) {
518 sha_handle = bootloader_sha256_start();
519 bootloader_sha256_data(sha_handle, whole_image, data->image_len - HASH_LEN);
520 bootloader_munmap(whole_image);
521 if (verify_simple_hash(sha_handle, data) != ESP_OK) {
522 ESP_LOGW(TAG, "image corrupted on flash");
523 } else {
524 ESP_LOGW(TAG, "image valid, signature bad");
527 return ESP_ERR_IMAGE_INVALID;
530 return ESP_OK;
533 static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data)
535 uint8_t image_hash[HASH_LEN] = { 0 };
536 bootloader_sha256_finish(sha_handle, image_hash);
538 // Log the hash for debugging
539 debug_log_hash(image_hash, "Calculated hash");
541 // Simple hash for verification only
542 const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
543 if (memcmp(hash, image_hash, HASH_LEN) != 0) {
544 ESP_LOGE(TAG, "Image hash failed - image is corrupt");
545 debug_log_hash(hash, "Expected hash");
546 bootloader_munmap(hash);
547 return ESP_ERR_IMAGE_INVALID;
550 bootloader_munmap(hash);
551 return ESP_OK;
554 // Log a hash as a hex string
555 static void debug_log_hash(const uint8_t *image_hash, const char *label)
557 #if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
558 char hash_print[sizeof(image_hash)*2 + 1];
559 hash_print[sizeof(image_hash)*2] = 0;
560 for (int i = 0; i < sizeof(image_hash); i++) {
561 for (int shift = 0; shift < 2; shift++) {
562 uint8_t nibble = (image_hash[i] >> (shift ? 0 : 4)) & 0x0F;
563 if (nibble < 10) {
564 hash_print[i*2+shift] = '0' + nibble;
565 } else {
566 hash_print[i*2+shift] = 'a' + nibble - 10;
570 ESP_LOGD(TAG, "%s: %s", label, hash_print);
571 #endif