1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #pragma once
7 
8 #include <stdbool.h>
9 #include <esp_err.h>
10 #include "esp_flash_partitions.h"
11 #include "esp_app_format.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 #define ESP_ERR_IMAGE_BASE       0x2000
18 #define ESP_ERR_IMAGE_FLASH_FAIL (ESP_ERR_IMAGE_BASE + 1)
19 #define ESP_ERR_IMAGE_INVALID    (ESP_ERR_IMAGE_BASE + 2)
20 
21 /* Support for app/bootloader image parsing
22    Can be compiled as part of app or bootloader code.
23 */
24 
25 #define ESP_IMAGE_HASH_LEN 32 /* Length of the appended SHA-256 digest */
26 
27 /* Structure to hold on-flash image metadata */
28 typedef struct {
29   uint32_t start_addr;   /* Start address of image */
30   esp_image_header_t image; /* Header for entire image */
31   esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS]; /* Per-segment header data */
32   uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */
33   uint32_t image_len; /* Length of image on flash, in bytes */
34   uint8_t image_digest[32]; /* appended SHA-256 digest */
35 } esp_image_metadata_t;
36 
37 typedef enum {
38     ESP_IMAGE_VERIFY,            /* Verify image contents, not load to memory, load metadata. Print errors. */
39     ESP_IMAGE_VERIFY_SILENT,     /* Verify image contents, not load to memory, load metadata. Don't print errors. */
40 #ifdef BOOTLOADER_BUILD
41     ESP_IMAGE_LOAD,              /* Verify image contents, load to memory, load metadata. Print errors. */
42     ESP_IMAGE_LOAD_NO_VALIDATE,  /* Not verify image contents, load to memory, load metadata. Print errors. */
43 #endif
44 } esp_image_load_mode_t;
45 
46 typedef struct {
47     esp_partition_pos_t partition;  /*!< Partition of application which worked before goes to the deep sleep. */
48     uint16_t reboot_counter;        /*!< Reboot counter. Reset only when power is off. */
49     uint16_t reserve;               /*!< Reserve */
50 #ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
51     uint8_t custom[CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE]; /*!< Reserve for custom propose */
52 #endif
53     uint32_t crc;                   /*!< Check sum crc32 */
54 } rtc_retain_mem_t;
55 
56 #ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
57 _Static_assert(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
58 #endif
59 
60 #if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
61 _Static_assert(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
62 #endif
63 
64 #ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
65 #define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
66 #elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
67 #define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
68 #endif
69 
70 #if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
71 _Static_assert(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved RTC area must exceed size of rtc_retain_mem_t");
72 #endif
73 
74 /**
75  * @brief Verify an app image.
76  *
77  * If encryption is enabled, data will be transparently decrypted.
78  *
79  * @param mode Mode of operation (verify, silent verify, or load).
80  * @param part Partition to load the app from.
81  * @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
82  *                    'start_addr' member should be set (to the start address of the image.)
83  *                    Other fields will all be initialised by this function.
84  *
85  * Image validation checks:
86  * - Magic byte.
87  * - Partition smaller than 16MB.
88  * - All segments & image fit in partition.
89  * - 8 bit image checksum is valid.
90  * - SHA-256 of image is valid (if image has this appended).
91  * - (Signature) if signature verification is enabled.
92  *
93  * @return
94  * - ESP_OK if verify or load was successful
95  * - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
96  * - ESP_ERR_IMAGE_INVALID if the image appears invalid.
97  * - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
98  */
99 esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
100 
101 /**
102  * @brief Get metadata of app
103  *
104  * If encryption is enabled, data will be transparently decrypted.
105  *
106  * @param part Partition to load the app from.
107  * @param[out] metadata Pointer to the image metadata structure which is be filled in by this function.
108  *                      Fields will all be initialised by this function.
109  *
110  * @return
111  * - ESP_OK if filling of metadata was successful
112  */
113 esp_err_t esp_image_get_metadata(const esp_partition_pos_t *part, esp_image_metadata_t *metadata);
114 
115 /**
116  * @brief Verify and load an app image (available only in space of bootloader).
117  *
118  * If encryption is enabled, data will be transparently decrypted.
119  *
120  * @param part Partition to load the app from.
121  * @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
122  *                    'start_addr' member should be set (to the start address of the image.)
123  *                    Other fields will all be initialised by this function.
124  *
125  * Image validation checks:
126  * - Magic byte.
127  * - Partition smaller than 16MB.
128  * - All segments & image fit in partition.
129  * - 8 bit image checksum is valid.
130  * - SHA-256 of image is valid (if image has this appended).
131  * - (Signature) if signature verification is enabled.
132  *
133  * @return
134  * - ESP_OK if verify or load was successful
135  * - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
136  * - ESP_ERR_IMAGE_INVALID if the image appears invalid.
137  * - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
138  */
139 esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data);
140 
141 /**
142  * @brief Load an app image without verification (available only in space of bootloader).
143  *
144  * If encryption is enabled, data will be transparently decrypted.
145  *
146  * @param part Partition to load the app from.
147  * @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
148  *                    'start_addr' member should be set (to the start address of the image.)
149  *                    Other fields will all be initialised by this function.
150  *
151  * @return
152  * - ESP_OK if verify or load was successful
153  * - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
154  * - ESP_ERR_IMAGE_INVALID if the image appears invalid.
155  * - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
156  */
157 esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data);
158 
159 /**
160  * @brief Verify the bootloader image.
161  *
162  * @param[out] If result is ESP_OK and this pointer is non-NULL, it
163  * will be set to the length of the bootloader image.
164  *
165  * @return As per esp_image_load_metadata().
166  */
167 esp_err_t esp_image_verify_bootloader(uint32_t *length);
168 
169 /**
170  * @brief Verify the bootloader image.
171  *
172  * @param[out] Metadata for the image. Only valid if result is ESP_OK.
173  *
174  * @return As per esp_image_load_metadata().
175  */
176 esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data);
177 
178 /**
179  * @brief Get the flash size of the image
180  *
181  * @param app_flash_size The value configured in the image header
182  * @return Actual size, in bytes.
183  */
184 int esp_image_get_flash_size(esp_image_flash_size_t app_flash_size);
185 
186 
187 typedef struct {
188     uint32_t drom_addr;
189     uint32_t drom_load_addr;
190     uint32_t drom_size;
191     uint32_t irom_addr;
192     uint32_t irom_load_addr;
193     uint32_t irom_size;
194 } esp_image_flash_mapping_t;
195 
196 #ifdef __cplusplus
197 }
198 #endif
199