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