chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:04:25 +08:00
commit 548b49ebc0
20937 changed files with 5455372 additions and 0 deletions
@@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Configure clocks for early boot
*
* Called by bootloader, or by the app if the bootloader version is old (pre v2.1).
*/
void bootloader_clock_configure(void);
/** @brief Return the rated maximum frequency of this chip
*/
int bootloader_clock_get_rated_freq_mhz(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,297 @@
/*
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_flash_partitions.h"
#include "esp_image_format.h"
#ifdef __cplusplus
extern "C" {
#endif
// Type of hold a GPIO in low state
typedef enum {
GPIO_LONG_HOLD = 1, /*!< The long hold GPIO */
GPIO_SHORT_HOLD = -1, /*!< The short hold GPIO */
GPIO_NOT_HOLD = 0 /*!< If the GPIO input is not low */
} esp_comm_gpio_hold_t;
typedef enum {
ESP_IMAGE_BOOTLOADER,
ESP_IMAGE_APPLICATION
} esp_image_type;
/**
* @brief Check if the chip revision meets the image requirements.
*
* This function verifies whether the actual chip revision satisfies the minimum
* and optionally the maximum chip revision requirements specified in the image.
*
* @param image_header Pointer to the image header containing revision details.
* @param check_max_revision If true, also checks the maximum chip revision requirements.
*
* @return true if the chip revision meets the requirements, false otherwise.
*/
bool bootloader_common_check_chip_revision_validity(const esp_image_header_t *image_header, bool check_max_revision);
/**
* @brief Read ota_info partition and fill array from two otadata structures.
*
* @param[in] ota_info It is a pointer to the OTA data partition.
* The "otadata" partition (Type = "data" and SubType = "ota")
* is defined in the CSV partition table.
* @param[out] two_otadata Pointer to array of OTA selection structure.
* @return - ESP_OK: On success
* - ESP_ERR_NOT_FOUND: Partition table does not have otadata partition
* - ESP_FAIL: On failure
*/
esp_err_t bootloader_common_read_otadata(const esp_partition_pos_t *ota_info, esp_ota_select_entry_t *two_otadata);
/**
* @brief Calculate crc for the OTA data select.
*
* @param[in] s The OTA data select.
* @return Returns crc value.
*/
uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s);
/**
* @brief Verifies the validity of the OTA data select
*
* @param[in] s The OTA data select.
* @return Returns true on valid, false otherwise.
*/
bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s);
/**
* @brief Returns true if OTADATA is not marked as bootable partition.
*
* @param[in] s The OTA data select.
* @return Returns true if OTADATA invalid, false otherwise.
*/
bool bootloader_common_ota_select_invalid(const esp_ota_select_entry_t *s);
/**
* @brief Check if a GPIO input is held low for a long period, short period, or not
* at all.
*
* This function will configure the specified GPIO as an input with internal pull-up enabled.
*
* If the GPIO input is held low continuously for delay_sec period then it is a long hold.
* If the GPIO input is held low for less period then it is a short hold.
*
* @param[in] num_pin Number of the GPIO input.
* @param[in] delay_sec Input must be driven low for at least this long, continuously.
* @return esp_comm_gpio_hold_t Type of low level hold detected, if any.
*/
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec);
/**
* @brief Check if a GPIO input is held low or high for a long period, short period, or not
* at all.
*
* This function will configure the specified GPIO as an input with internal pull-up enabled.
*
* If the GPIO input is held at 'level' continuously for delay_sec period then it is a long hold.
* If the GPIO input is held at 'level' for less period then it is a short hold.
*
* @param[in] num_pin Number of the GPIO input.
* @param[in] delay_sec Input must be driven to 'level' for at least this long, continuously.
* @param[in] level Input pin level to trigger on hold
* @return esp_comm_gpio_hold_t Type of hold detected, if any.
*/
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio_level(uint32_t num_pin, uint32_t delay_sec, bool level);
/**
* @brief Erase the partition data that is specified in the transferred list.
*
* @note This function can't be called in app.
*
* @param[in] list_erase String containing a list of cleared partitions. Like this "nvs, phy". The string must be null-terminal.
* @param[in] ota_data_erase If true then the OTA data partition will be cleared (if there is it in partition table).
* @return Returns true on success, false otherwise.
*/
bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_data_erase);
/**
* @brief Determines if the list contains the label
*
* @param[in] list A string of names delimited by commas or spaces. Like this "nvs, phy, data". The string must be null-terminated.
* @param[in] label The substring that will be searched in the list.
* @return Returns true if the list contains the label, false otherwise.
*/
bool bootloader_common_label_search(const char *list, char *label);
/**
* @brief Configure default SPI pin modes and drive strengths
*
* @param drv GPIO drive level (determined by clock frequency)
*/
void bootloader_configure_spi_pins(int drv);
/**
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
*
* This function can be used to return the SHA-256 digest of application, bootloader and data partitions.
* For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content.
* The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID.
* For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image.
* For other partition types, the result is the SHA-256 of the entire partition.
*
* @param[in] address Address of partition.
* @param[in] size Size of partition.
* @param[in] type Type of partition. For applications the type is 0, otherwise type is data.
* @param[out] out_sha_256 Returned SHA-256 digest for a given partition.
*
* @return
* - ESP_OK: In case of successful operation.
* - ESP_ERR_INVALID_ARG: The size was 0 or the sha_256 was NULL.
* - ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation.
* - ESP_ERR_IMAGE_INVALID: App partition doesn't contain a valid app image.
* - ESP_FAIL: An allocation error occurred.
*/
esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256);
/**
* @brief Returns the number of active otadata.
*
* @param[in] two_otadata Pointer on array from two otadata structures.
*
* @return The number of active otadata (0 or 1).
* - -1: If it does not have active otadata.
*/
int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata);
/**
* @brief Returns the number of active otadata.
*
* @param[in] two_otadata Pointer on array from two otadata structures.
* @param[in] valid_two_otadata Pointer on array from two bools. True means select.
* @param[in] max True - will select the maximum ota_seq number, otherwise the minimum.
*
* @return The number of active otadata (0 or 1).
* - -1: If it does not have active otadata.
*/
int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max);
/**
* @brief Get chip package
*
* @return Chip package number
*/
uint32_t bootloader_common_get_chip_ver_pkg(void);
/**
* @brief Check if the image (bootloader and application) has valid chip ID and revision
*
* @param[in] img_hdr: image header
* @param[in] type: image type, bootloader or application
* @return
* - ESP_OK: image and chip are matched well
* - ESP_FAIL: image doesn't match to the chip
*/
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type);
#if !CONFIG_IDF_TARGET_ESP32
/**
* @brief Check the eFuse block revision
*
* @param[in] min_rev_full The required minimum revision of the eFuse block
* @param[in] max_rev_full The required maximum revision of the eFuse block
* @return
* - ESP_OK: The eFuse block revision is in the required range.
* - ESP_OK: DISABLE_BLK_VERSION_MAJOR has been set in the eFuse of the SoC. No requirements shall be checked at this time.
* - ESP_FAIL: The eFuse block revision of this chip does not match the requirement of the current image.
*/
esp_err_t bootloader_common_check_efuse_blk_validity(uint32_t min_rev_full, uint32_t max_rev_full);
#endif // !CONFIG_IDF_TARGET_ESP32
/**
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
*/
void bootloader_common_vddsdio_configure(void);
#if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
/**
* @brief Returns partition from rtc_retain_mem
*
* Uses to get the partition of application which was worked before to go to the deep sleep.
* This partition was stored in rtc_retain_mem.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return partition: If rtc_retain_mem is valid.
* - NULL: If it is not valid.
*/
esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void);
/**
* @brief Update the partition and reboot_counter in rtc_retain_mem.
*
* This function saves the partition of application for fast booting from the deep sleep.
* An algorithm uses this partition to avoid reading the otadata and does not validate an image.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @param[in] partition App partition description. Can be NULL, in this case rtc_retain_mem.partition is not updated.
* @param[in] reboot_counter If true then update reboot_counter.
*
*/
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter);
/**
* @brief Reset entire rtc_retain_mem.
*
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*/
void bootloader_common_reset_rtc_retain_mem(void);
/**
* @brief Returns reboot_counter from rtc_retain_mem
*
* The reboot_counter counts the number of reboots. Reset only when power is off.
* The very first launch of the application will be from 1.
* Overflow is not possible, it will stop at the value UINT16_MAX.
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return reboot_counter: 1..65535
* - 0: If rtc_retain_mem is not valid.
*/
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void);
/**
* @brief Returns True if Factory reset has happened
*
* Reset the status after reading it.
*
* @return True: Factory reset has happened
* False: No Factory reset
*/
bool bootloader_common_get_rtc_retain_mem_factory_reset_state(void);
/**
* @brief Sets Factory reset status
*/
void bootloader_common_set_rtc_retain_mem_factory_reset_state(void);
/**
* @brief Returns rtc_retain_mem
*
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
* Make sure that this function is used only PRO_CPU.
*
* @return rtc_retain_mem
*/
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void);
#endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void bootloader_init_mem(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,256 @@
/*
* SPDX-FileCopyrightText: 2010-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc.h"
#include "soc/ext_mem_defs.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
/** The content of this file is to be kept in sync with the common section of esp_memory_utils.h **/
/**
* @brief Check if the IRAM and DRAM are separate or using the same memory space
*
* @return true if the DRAM and IRAM are sharing the same memory space, false otherwise
*/
__attribute__((always_inline))
inline static bool esp_dram_match_iram(void) {
return ((SOC_DRAM_LOW == SOC_IRAM_LOW) && (SOC_DRAM_HIGH == SOC_IRAM_HIGH));
}
/**
* @brief Check if the RTC IRAM and RTC DRAM are separate or using the same memory space
*
* @return true if the RTC DRAM and RTC IRAM are sharing the same memory space, false otherwise
*/
__attribute__((always_inline))
inline static bool esp_rtc_dram_match_rtc_iram(void) {
#if SOC_RTC_FAST_MEM_SUPPORTED
return ((SOC_RTC_IRAM_LOW == SOC_RTC_DRAM_LOW) && (SOC_RTC_IRAM_HIGH == SOC_RTC_DRAM_HIGH));
#else
return false;
#endif
}
/**
* @brief Check if the pointer is in iram
*
* @param p pointer
*
* @return true: is in iram; false: not in iram
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_iram(const void *p) {
#if CONFIG_IDF_TARGET_ESP32 && CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH);
#else
return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
#endif
}
/**
* @brief Check if the pointer is in dram
*
* @param p pointer
*
* @return true: is in dram; false: not in dram
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_dram(const void *p) {
return ((intptr_t)p >= SOC_DRAM_LOW && (intptr_t)p < SOC_DRAM_HIGH);
}
/**
* @brief Check if the pointer is in diram_dram
*
* @param p pointer
*
* @return true: is in diram_dram; false: not in diram_dram
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_diram_dram(const void *p) {
return ((intptr_t)p >= SOC_DIRAM_DRAM_LOW && (intptr_t)p < SOC_DIRAM_DRAM_HIGH);
}
/**
* @brief Check if the pointer is in diram_iram
*
* @param p pointer
*
* @return true: is in diram_iram; false: not in diram_iram
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_diram_iram(const void *p) {
// TODO: IDF-5980 esp32c6 D/I RAM share the same address
#if SOC_DIRAM_IRAM_LOW == SOC_DIRAM_DRAM_LOW
(void)p;
return false;
#else
return ((intptr_t)p >= SOC_DIRAM_IRAM_LOW && (intptr_t)p < SOC_DIRAM_IRAM_HIGH);
#endif
}
/**
* @brief Check if the pointer is in rtc_iram_fast
*
* @param p pointer
*
* @return true: is in rtc_iram_fast; false: not in rtc_iram_fast
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
#if SOC_RTC_FAST_MEM_SUPPORTED
return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
#else
(void)p;
return false;
#endif
}
/**
* @brief Check if the pointer is in rtc_dram_fast
*
* @param p pointer
*
* @return true: is in rtc_dram_fast; false: not in rtc_dram_fast
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_rtc_dram_fast(const void *p) {
#if SOC_RTC_FAST_MEM_SUPPORTED
return ((intptr_t)p >= SOC_RTC_DRAM_LOW && (intptr_t)p < SOC_RTC_DRAM_HIGH);
#else
(void)p;
return false;
#endif
}
/**
* @brief Check if the pointer is in rtc_slow
*
* @param p pointer
*
* @return true: is in rtc_slow; false: not in rtc_slow
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_rtc_slow(const void *p) {
#if SOC_RTC_SLOW_MEM_SUPPORTED
return ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH);
#else
return false;
#endif
}
/* Convert a D/IRAM DRAM pointer to equivalent word address in IRAM
- Address must be word aligned
- Address must pass esp_ptr_in_diram_dram() test, or result will be invalid pointer
*/
__attribute__((always_inline))
inline static void * esp_ptr_diram_dram_to_iram(const void *p) {
#if SOC_DIRAM_INVERTED
return (void *) ( SOC_DIRAM_IRAM_LOW + (SOC_DIRAM_DRAM_HIGH - (intptr_t)p) - 4);
#else
return (void *) ( SOC_DIRAM_IRAM_LOW + ((intptr_t)p - SOC_DIRAM_DRAM_LOW) );
#endif
}
/* Convert a RTC DRAM pointer to equivalent word address in RTC IRAM
- Address must be word aligned
- Address must pass esp_ptr_in_rtc_dram_fast() test, or result will be invalid pointer
*/
__attribute__((always_inline))
inline static void * esp_ptr_rtc_dram_to_iram(const void *p) {
intptr_t ptr = (intptr_t)p;
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
return (void *) ( SOC_RTC_IRAM_LOW + (ptr - SOC_RTC_DRAM_LOW) );
#else
return (void *) ptr;
#endif
}
/* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
- Address must be word aligned
- Address must pass esp_ptr_in_diram_iram() test, or result will be invalid pointer
*/
__attribute__((always_inline))
inline static void * esp_ptr_diram_iram_to_dram(const void *p) {
#if SOC_DIRAM_INVERTED
return (void *) ( SOC_DIRAM_DRAM_LOW + (SOC_DIRAM_IRAM_HIGH - (intptr_t)p) - 4);
#else
return (void *) ( SOC_DIRAM_DRAM_LOW + ((intptr_t)p - SOC_DIRAM_IRAM_LOW) );
#endif
}
#if SOC_MEM_SPM_SUPPORTED
/**
* @brief Check if the pointer is in TCM (SPM)
*
* @param p pointer
*
* @return true: is in TCM (SPM); false: not in TCM (SPM)
*/
__attribute__((always_inline, deprecated("esp_ptr_in_tcm is deprecated, please use esp_ptr_in_spm instead")))
inline static bool esp_ptr_in_tcm(const void *p) {
return ((intptr_t)p >= SOC_SPM_LOW && (intptr_t)p < SOC_SPM_HIGH);
}
/**
* @brief Check if the pointer is in SPM
*
* @param p pointer
*
* @return true: is in SPM; false: not in SPM
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_spm(const void *p) {
return ((intptr_t)p >= SOC_SPM_LOW && (intptr_t)p < SOC_SPM_HIGH);
}
#endif //#if SOC_MEM_SPM_SUPPORTED
/** End of the common section that has to be in sync with esp_memory_utils.h **/
/**
* @brief Check if the pointer is in PSRAM vaddr space
*
* @note This function is only used when in bootloader, where the PSRAM isn't initialised.
* This function simply check if the pointer is the in the PSRAM vaddr space.
* The PSRAM vaddr space is not always the same as the actual PSRAM vaddr range used in APP
*
* @param p pointer
*
* @return true: is in PSRAM; false: not in PSRAM
*/
__attribute__((always_inline))
inline static bool esp_ptr_in_extram(const void *p) {
bool valid = false;
#if SOC_IRAM_PSRAM_ADDRESS_LOW
valid |= ((intptr_t)p >= SOC_IRAM_PSRAM_ADDRESS_LOW && (intptr_t)p < SOC_IRAM_PSRAM_ADDRESS_HIGH);
#endif
#if SOC_DRAM_PSRAM_ADDRESS_LOW
valid |= ((intptr_t)p >= SOC_DRAM_PSRAM_ADDRESS_LOW && (intptr_t)p < SOC_DRAM_PSRAM_ADDRESS_HIGH);
#endif
return valid;
}
/** Don't add new functions below **/
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Enable an entropy source for RNG if RF subsystem is disabled
*
* @warning If use ADC as entropy source, this function is not safe
* if any other subsystem is accessing the RF subsystem or the ADC at the same time!
*
* The exact internal entropy source mechanism depends on the chip in use but
* all SoCs use the SAR ADC to continuously mix random bits (an internal
* noise reading) into the HWRNG. Consult the SoC Technical Reference
* Manual for more information.
*
* Can also be called from app code, if true random numbers are required without initialized RF subsystem.
* This might be the case in early startup code of the application when the RF subsystem has not
* started yet or if the RF subsystem should not be enabled for power saving.
*
* Consult ESP-IDF Programming Guide "Random Number Generation" section for
* details.
*/
void bootloader_random_enable(void);
/**
* @brief Disable entropy source for RNG
*
* Disables internal entropy source. Must be called after
* bootloader_random_enable() and before RF subsystem features, ADC, or
* I2S (ESP32 only) are initialized.
*
* Consult the ESP-IDF Programming Guide "Random Number Generation"
* section for details.
*/
void bootloader_random_disable(void);
/**
* @brief Fill buffer with 'length' random bytes
*
* @note If this function is being called from app code only, and never
* from the bootloader, then it's better to call esp_fill_random().
*
* @param buffer Pointer to buffer
* @param length This many bytes of random data will be copied to buffer
*/
void bootloader_fill_random(void *buffer, size_t length);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Check if half-open intervals overlap
*
* @param start1 interval 1 start
* @param end1 interval 1 end
* @param start2 interval 2 start
* @param end2 interval 2 end
* @return true iff [start1; end1) overlaps [start2; end2)
*/
static inline bool bootloader_util_regions_overlap(
const intptr_t start1, const intptr_t end1,
const intptr_t start2, const intptr_t end2)
{
assert(end1 > start1);
assert(end2 > start2);
return (end1 > start2 && end2 > start1);
}
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_flash_partitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Fetch the currently running TEE partition
*
* @param[in] tee_ota_info TEE OTA data partition
*
* @return Subtype of the running TEE partition, or -1 if an error occurred
*/
int bootloader_utility_tee_get_boot_partition(const esp_partition_pos_t *tee_ota_info);
/**
* @brief Set a new TEE boot partition in the TEE OTA data
*
* @param[in] tee_ota_info TEE OTA data partition
* @param[in] tee_try_part Partition table entry for the new boot partition
*
* @return ESP_OK on success, or an error code otherwise
*/
esp_err_t bootloader_utility_tee_set_boot_partition(const esp_partition_pos_t *tee_ota_info, const esp_partition_info_t *tee_try_part);
/**
* @brief Fetch the next TEE partition for update
*
* @param[in] tee_ota_info TEE OTA data partition
*
* @return Subtype of the next TEE partition for update, or -1 if an error occurred
*/
int bootloader_utility_tee_get_next_update_partition(const esp_partition_pos_t *tee_ota_info);
/**
* @brief Mark the current TEE app as valid and cancel update rollback
*
* @param[in] tee_ota_info TEE OTA data partition
*
* @return ESP_OK on success, or an error code otherwise
*/
esp_err_t bootloader_utility_tee_mark_app_valid_and_cancel_rollback(const esp_partition_pos_t *tee_ota_info);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,127 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <inttypes.h>
#include "esp_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief ESP chip ID
*
*/
typedef enum {
ESP_CHIP_ID_ESP32 = 0x0000, /*!< chip ID: ESP32 */
ESP_CHIP_ID_ESP32S2 = 0x0002, /*!< chip ID: ESP32-S2 */
ESP_CHIP_ID_ESP32C3 = 0x0005, /*!< chip ID: ESP32-C3 */
ESP_CHIP_ID_ESP32S3 = 0x0009, /*!< chip ID: ESP32-S3 */
ESP_CHIP_ID_ESP32C2 = 0x000C, /*!< chip ID: ESP32-C2 */
ESP_CHIP_ID_ESP32C6 = 0x000D, /*!< chip ID: ESP32-C6 */
ESP_CHIP_ID_ESP32H2 = 0x0010, /*!< chip ID: ESP32-H2 */
ESP_CHIP_ID_ESP32P4 = 0x0012, /*!< chip ID: ESP32-P4 */
ESP_CHIP_ID_ESP32C5 = 0x0017, /*!< chip ID: ESP32-C5 */
ESP_CHIP_ID_ESP32C61= 0x0014, /*!< chip ID: ESP32-C61 */
ESP_CHIP_ID_ESP32H21= 0x0019, /*!< chip ID: ESP32-H21 */
ESP_CHIP_ID_ESP32H4 = 0x001C, /*!< chip ID: ESP32-H4 */
ESP_CHIP_ID_ESP32S31 = 0x0020, /*!< chip ID: ESP32-S31 */
ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */
} __attribute__((packed)) esp_chip_id_t;
/** @cond */
ESP_STATIC_ASSERT(sizeof(esp_chip_id_t) == 2, "esp_chip_id_t should be 16 bit");
/** @endcond */
/**
* @brief SPI flash mode, used in esp_image_header_t
*/
typedef enum {
ESP_IMAGE_SPI_MODE_QIO, /*!< SPI mode QIO */
ESP_IMAGE_SPI_MODE_QOUT, /*!< SPI mode QOUT */
ESP_IMAGE_SPI_MODE_DIO, /*!< SPI mode DIO */
ESP_IMAGE_SPI_MODE_DOUT, /*!< SPI mode DOUT */
ESP_IMAGE_SPI_MODE_FAST_READ, /*!< SPI mode FAST_READ */
ESP_IMAGE_SPI_MODE_SLOW_READ /*!< SPI mode SLOW_READ */
} esp_image_spi_mode_t;
/**
* @brief SPI flash clock division factor.
*/
typedef enum {
ESP_IMAGE_SPI_SPEED_DIV_2, /*!< The SPI flash clock frequency is divided by 2 of the clock source */
ESP_IMAGE_SPI_SPEED_DIV_3, /*!< The SPI flash clock frequency is divided by 3 of the clock source */
ESP_IMAGE_SPI_SPEED_DIV_4, /*!< The SPI flash clock frequency is divided by 4 of the clock source */
ESP_IMAGE_SPI_SPEED_DIV_1 = 0xF /*!< The SPI flash clock frequency equals to the clock source */
} esp_image_spi_freq_t;
/**
* @brief Supported SPI flash sizes
*/
typedef enum {
ESP_IMAGE_FLASH_SIZE_1MB = 0, /*!< SPI flash size 1 MB */
ESP_IMAGE_FLASH_SIZE_2MB, /*!< SPI flash size 2 MB */
ESP_IMAGE_FLASH_SIZE_4MB, /*!< SPI flash size 4 MB */
ESP_IMAGE_FLASH_SIZE_8MB, /*!< SPI flash size 8 MB */
ESP_IMAGE_FLASH_SIZE_16MB, /*!< SPI flash size 16 MB */
ESP_IMAGE_FLASH_SIZE_32MB, /*!< SPI flash size 32 MB */
ESP_IMAGE_FLASH_SIZE_64MB, /*!< SPI flash size 64 MB */
ESP_IMAGE_FLASH_SIZE_128MB, /*!< SPI flash size 128 MB */
ESP_IMAGE_FLASH_SIZE_MAX /*!< SPI flash size MAX */
} esp_image_flash_size_t;
#define ESP_IMAGE_HEADER_MAGIC 0xE9 /*!< The magic word for the esp_image_header_t structure. */
/**
* @brief Main header of binary image
*/
typedef struct {
uint8_t magic; /*!< Magic word ESP_IMAGE_HEADER_MAGIC */
uint8_t segment_count; /*!< Count of memory segments */
uint8_t spi_mode; /*!< flash read mode (esp_image_spi_mode_t as uint8_t) */
uint8_t spi_speed: 4; /*!< flash frequency (esp_image_spi_freq_t as uint8_t) */
uint8_t spi_size: 4; /*!< flash chip size (esp_image_flash_size_t as uint8_t) */
uint32_t entry_addr; /*!< Entry address */
uint8_t wp_pin; /*!< WP pin when SPI pins set via efuse (read by ROM bootloader,
* the IDF bootloader uses software to configure the WP
* pin and sets this field to 0xEE=disabled) */
uint8_t spi_pin_drv[3]; /*!< Drive settings for the SPI flash pins (read by ROM bootloader) */
esp_chip_id_t chip_id; /*!< Chip identification number */
uint8_t min_chip_rev; /*!< Minimal chip revision supported by image
* After the Major and Minor revision eFuses were introduced into the chips, this field is no longer used.
* But for compatibility reasons, we keep this field and the data in it.
* Use min_chip_rev_full instead.
* The software interprets this as a Major version for most of the chips and as a Minor version for the ESP32-C3.
*/
uint16_t min_chip_rev_full; /*!< Minimal chip revision supported by image, in format: major * 100 + minor */
uint16_t max_chip_rev_full; /*!< Maximal chip revision supported by image, in format: major * 100 + minor */
uint8_t reserved[4]; /*!< Reserved bytes in additional header space, currently unused */
uint8_t hash_appended; /*!< If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum.
* Included in image length. This digest
* is separate to secure boot and only used for detecting corruption.
* For secure boot signed images, the signature
* is appended after this (and the simple hash is included in the signed data). */
} __attribute__((packed)) esp_image_header_t;
/** @cond */
ESP_STATIC_ASSERT(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes");
/** @endcond */
/**
* @brief Header of binary image segment
*/
typedef struct {
uint32_t load_addr; /*!< Address of segment */
uint32_t data_len; /*!< Length of data */
} esp_image_segment_header_t;
#define ESP_IMAGE_MAX_SEGMENTS 16 /*!< Max count of segments in the image. */
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#warning esp_flash_data_types.h has been merged into esp_flash_partitions.h, please include esp_flash_partitions.h instead
#include "esp_flash_partitions.h"
@@ -0,0 +1,229 @@
/*
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "esp_err.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
/* @brief Flash encryption mode based on efuse values
*/
typedef enum {
ESP_FLASH_ENC_MODE_DISABLED, // flash encryption is not enabled (flash crypt cnt=0)
ESP_FLASH_ENC_MODE_DEVELOPMENT, // flash encryption is enabled but for Development (reflash over UART allowed)
ESP_FLASH_ENC_MODE_RELEASE // flash encryption is enabled for Release (reflash over UART disabled)
} esp_flash_enc_mode_t;
/**
* @file esp_partition.h
* @brief Support functions for flash encryption features
*
* Can be compiled as part of app or bootloader code.
*/
/** @brief Is flash encryption currently enabled in hardware?
*
* Flash encryption is enabled if the FLASH_CRYPT_CNT efuse has an odd number of bits set.
*
* @deprecated This function is deprecated. Use esp_efuse_is_flash_encryption_enabled() instead.
*
* @return true if flash encryption is enabled.
*/
__attribute__((deprecated("Use esp_efuse_is_flash_encryption_enabled() instead")))
bool esp_flash_encryption_enabled(void);
/* @brief Update on-device flash encryption
*
* Intended to be called as part of the bootloader process if flash
* encryption is enabled in device menuconfig.
*
* If FLASH_CRYPT_CNT efuse parity is 1 (ie odd number of bits set),
* then return ESP_OK immediately (indicating flash encryption is enabled
* and functional).
*
* If FLASH_CRYPT_CNT efuse parity is 0 (ie even number of bits set),
* assume the flash has just been written with plaintext that needs encrypting.
*
* The following regions of flash are encrypted in place:
*
* - The bootloader image, if a valid plaintext image is found.[*]
* - The partition table, if a valid plaintext table is found.
* - Any app partition that contains a valid plaintext app image.
* - Any other partitions with the "encrypt" flag set. [**]
*
* After the re-encryption process completes, a '1' bit is added to the
* FLASH_CRYPT_CNT value (setting the parity to 1) and the EFUSE is re-burned.
*
* [*] If reflashing bootloader with secure boot enabled, pre-encrypt
* the bootloader before writing it to flash or secure boot will fail.
*
* [**] For this reason, if serial re-flashing a previous flashed
* device with secure boot enabled and using FLASH_CRYPT_CNT to
* trigger re-encryption, you must simultaneously re-flash plaintext
* content to all partitions with the "encrypt" flag set or this
* data will be corrupted (encrypted twice).
*
* @note The post-condition of this function is that all
* partitions that should be encrypted are encrypted.
*
* @note Take care not to power off the device while this function
* is running, or the partition currently being encrypted will be lost.
*
* @note RTC_WDT will reset while encryption operations will be performed (if RTC_WDT is configured).
*
* @return ESP_OK if all operations succeeded, ESP_ERR_INVALID_STATE
* if a fatal error occurred during encryption of all partitions.
*/
esp_err_t esp_flash_encrypt_check_and_update(void);
/** @brief Returns the Flash Encryption state and prints it
*
* @return True - Flash Encryption is enabled
* False - Flash Encryption is not enabled
*/
bool esp_flash_encrypt_state(void);
/** @brief Checks if the first initialization was done
*
* If the first initialization was done then FLASH_CRYPT_CNT != 0
*
* @return true - the first initialization was done
* false - the first initialization was NOT done
*/
bool esp_flash_encrypt_initialized_once(void);
/** @brief The first initialization of Flash Encryption key and related eFuses
*
* @return ESP_OK if all operations succeeded
*/
esp_err_t esp_flash_encrypt_init(void);
/** @brief Encrypts flash content
*
* @return ESP_OK if all operations succeeded
*/
esp_err_t esp_flash_encrypt_contents(void);
/** @brief Activates Flash encryption on the chip
*
* It burns FLASH_CRYPT_CNT eFuse based on the CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE option.
*
* @return ESP_OK if all operations succeeded
*/
esp_err_t esp_flash_encrypt_enable(void);
/** @brief Returns True if the write protection of FLASH_CRYPT_CNT is set
*
* @param print_error Print error if it is write protected
*
* @return true - if FLASH_CRYPT_CNT is write protected
*/
bool esp_flash_encrypt_is_write_protected(bool print_error);
/** @brief Encrypt-in-place a block of flash sectors
*
* @note This function resets RTC_WDT between operations with sectors.
* @param src_addr Source offset in flash. Should be multiple of 4096 bytes.
* @param data_length Length of data to encrypt in bytes. Will be rounded up to next multiple of 4096 bytes.
*
* @return ESP_OK if all operations succeeded, ESP_ERR_FLASH_OP_FAIL
* if SPI flash fails, ESP_ERR_FLASH_OP_TIMEOUT if flash times out.
*/
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
/** @brief Write protect FLASH_CRYPT_CNT
*
* Intended to be called as a part of boot process if flash encryption
* is enabled but secure boot is not used. This should protect against
* serial re-flashing of an unauthorised code in absence of secure boot.
*
* @note On ESP32 V3 only, write protecting FLASH_CRYPT_CNT will also prevent
* disabling UART Download Mode. If both are wanted, call
* esp_efuse_disable_rom_download_mode() before calling this function.
*
*/
void esp_flash_write_protect_crypt_cnt(void);
/** @brief Return the flash encryption mode
*
* The API is called during boot process but can also be called by
* application to check the current flash encryption mode of ESP32
*
* @return
*/
esp_flash_enc_mode_t esp_get_flash_encryption_mode(void);
/** @brief Check the flash encryption mode during startup
*
* @note This function is called automatically during app startup,
* it doesn't need to be called from the app.
*
* Verifies the flash encryption config during startup:
*
* - Correct any insecure flash encryption settings if hardware
* Secure Boot is enabled.
* - Log warnings if the efuse config doesn't match the project
* config in any way
*/
void esp_flash_encryption_init_checks(void);
#if BOOTLOADER_BUILD && CONFIG_SECURE_FLASH_ENC_ENABLED
/** @brief Set all secure eFuse features related to flash encryption
*
* @return
* - ESP_OK - On success
*/
esp_err_t esp_flash_encryption_enable_secure_features(void);
#if SOC_KEY_MANAGER_FE_KEY_DEPLOY
/** @brief Enable the key manager for flash encryption
*
* @return
* - ESP_OK - On success
*/
esp_err_t esp_flash_encryption_use_efuse_key(void);
#endif // SOC_KEY_MANAGER_FE_KEY_DEPLOY
#endif /* BOOTLOADER_BUILD && CONFIG_SECURE_FLASH_ENC_ENABLED */
/** @brief Returns the verification status for all physical security features of flash encryption in release mode
*
* If the device has flash encryption feature configured in the release mode,
* then it is highly recommended to call this API in the application startup code.
* This API verifies the sanity of the eFuse configuration against
* the release (production) mode of the flash encryption feature.
*
* @return
* - True - all eFuses are configured correctly
* - False - not all eFuses are configured correctly.
*/
bool esp_flash_encryption_cfg_verify_release_mode(void);
/** @brief Switches Flash Encryption from "Development" to "Release"
*
* If already in "Release" mode, the function will do nothing.
* If flash encryption efuse is not enabled yet then abort.
* It burns:
* - "disable encrypt in dl mode"
* - set FLASH_CRYPT_CNT efuse to max
*
* In case of the targets that support the XTS-AES peripheral's pseudo rounds function,
* this API would configure the pseudo rounds level efuse bit to level low if the efuse bit
* is not set already.
*/
void esp_flash_encryption_set_release_mode(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,135 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_err.h"
#include "esp_types.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_PARTITION_MAGIC 0x50AA
#define ESP_PARTITION_MAGIC_MD5 0xEBEB
#define PART_TYPE_APP 0x00
#define PART_SUBTYPE_FACTORY 0x00
#define PART_SUBTYPE_OTA_FLAG 0x10
#define PART_SUBTYPE_OTA_MASK 0x0f
#define PART_SUBTYPE_TEST 0x20
#define PART_SUBTYPE_TEE_0 0x30
#define PART_SUBTYPE_TEE_1 0x31
#define PART_TYPE_DATA 0x01
#define PART_SUBTYPE_DATA_OTA 0x00
#define PART_SUBTYPE_DATA_RF 0x01
#define PART_SUBTYPE_DATA_WIFI 0x02
#define PART_SUBTYPE_DATA_NVS_KEYS 0x04
#define PART_SUBTYPE_DATA_EFUSE_EM 0x05
#define PART_TYPE_BOOTLOADER 0x02
#define PART_SUBTYPE_BOOTLOADER_PRIMARY 0x00
#define PART_SUBTYPE_BOOTLOADER_OTA 0x01
#define PART_SUBTYPE_BOOTLOADER_RECOVERY 0x02
#define PART_TYPE_PARTITION_TABLE 0x03
#define PART_SUBTYPE_PARTITION_TABLE_PRIMARY 0x00
#define PART_SUBTYPE_PARTITION_TABLE_OTA 0x01
#define PART_SUBTYPE_DATA_TEE_OTA 0x90
#define PART_TYPE_END 0xff
#define PART_SUBTYPE_END 0xff
#define PART_FLAG_ENCRYPTED (1<<0)
#define PART_FLAG_READONLY (1<<1)
/* The md5sum value is found this many bytes after the ESP_PARTITION_MAGIC_MD5 offset */
#define ESP_PARTITION_MD5_OFFSET 16
/* Pre-partition table fixed flash offsets */
#define ESP_BOOTLOADER_DIGEST_OFFSET 0x0
#define ESP_BOOTLOADER_OFFSET CONFIG_BOOTLOADER_OFFSET_IN_FLASH /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */
#define ESP_PRIMARY_BOOTLOADER_OFFSET CONFIG_BOOTLOADER_OFFSET_IN_FLASH /* Offset of Primary bootloader image. */
#define ESP_PARTITION_TABLE_OFFSET CONFIG_PARTITION_TABLE_OFFSET /* Offset of partition table. Backwards-compatible name.*/
#define ESP_PRIMARY_PARTITION_TABLE_OFFSET CONFIG_PARTITION_TABLE_OFFSET /* Offset of partition table. */
#define ESP_PARTITION_TABLE_SIZE (0x1000) /* The partition table occupies 1 sector of flash (SPI_FLASH_SEC_SIZE) */
#define ESP_BOOTLOADER_SIZE (ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET)
#define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */
#define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */
/// OTA_DATA states for checking operability of the app.
typedef enum {
ESP_OTA_IMG_NEW = 0x0U, /*!< Monitor the first boot. In bootloader this state is changed to ESP_OTA_IMG_PENDING_VERIFY. */
ESP_OTA_IMG_PENDING_VERIFY = 0x1U, /*!< First boot for this app was. If while the second boot this state is then it will be changed to ABORTED. */
ESP_OTA_IMG_VALID = 0x2U, /*!< App was confirmed as workable. App can boot and work without limits. */
ESP_OTA_IMG_INVALID = 0x3U, /*!< App was confirmed as non-workable. This app will not selected to boot at all. */
ESP_OTA_IMG_ABORTED = 0x4U, /*!< App could not confirm the workable or non-workable. In bootloader IMG_PENDING_VERIFY state will be changed to IMG_ABORTED. This app will not selected to boot at all. */
ESP_OTA_IMG_UNDEFINED = 0xFFFFFFFFU, /*!< Undefined. App can boot and work without limits. */
} esp_ota_img_states_t;
/* OTA selection structure (two copies in the OTA data partition.)
Size of 32 bytes is friendly to flash encryption */
typedef struct {
uint32_t ota_seq;
uint8_t seq_label[20];
uint32_t ota_state;
uint32_t crc; /* CRC32 of ota_seq field only */
} esp_ota_select_entry_t;
typedef struct {
uint32_t offset;
uint32_t size;
} esp_partition_pos_t;
/* Structure which describes the layout of partition table entry.
* See docs/partition_tables.rst for more information about individual fields.
*/
typedef struct {
uint16_t magic;
uint8_t type;
uint8_t subtype;
esp_partition_pos_t pos;
uint8_t label[16];
uint32_t flags;
} esp_partition_info_t;
/* @brief Verify the partition table
*
* @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.)
* @param log_errors Log errors if the partition table is invalid.
* @param num_partitions If result is ESP_OK, num_partitions is updated with total number of partitions (not including terminating entry).
*
* @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid.
*/
esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
/**
* Check whether the region on the main flash is not read-only.
*
* @param addr Start address of the region
* @param size Size of the region
*
* @return true if the region is safe to write, otherwise false.
*/
bool esp_partition_is_flash_region_writable(size_t addr, size_t size);
/**
* Check whether the region on the main flash is safe to write.
*
* @param addr Start address of the region
* @param size Size of the region
*
* @return true if the region is safe to write, otherwise false.
*/
bool esp_partition_main_flash_region_safe(size_t addr, size_t size);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,232 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <esp_err.h>
#include "esp_flash_partitions.h"
#include "esp_app_format.h"
#include "esp_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_ERR_IMAGE_BASE 0x2000
#define ESP_ERR_IMAGE_FLASH_FAIL (ESP_ERR_IMAGE_BASE + 1)
#define ESP_ERR_IMAGE_INVALID (ESP_ERR_IMAGE_BASE + 2)
/* Support for app/bootloader image parsing
Can be compiled as part of app or bootloader code.
*/
#define ESP_IMAGE_HASH_LEN 32 /* Length of the appended SHA-256 digest */
/* Structure to hold on-flash image metadata */
typedef struct {
uint32_t start_addr; /* Start address of image */
esp_image_header_t image; /* Header for entire image */
esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS]; /* Per-segment header data */
uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */
uint32_t image_len; /* Length of image on flash, in bytes */
uint8_t image_digest[32]; /* appended SHA-256 digest */
uint32_t secure_version; /* secure version for anti-rollback, it is covered by sha256 (set if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y) */
uint32_t mmu_page_size; /* Flash MMU page size per binary header */
} esp_image_metadata_t;
typedef enum {
ESP_IMAGE_VERIFY, /* Verify image contents, not load to memory, load metadata. Print errors. */
ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, not load to memory, load metadata. Don't print errors. */
#ifdef BOOTLOADER_BUILD
ESP_IMAGE_LOAD, /* Verify image contents, load to memory, load metadata. Print errors. */
ESP_IMAGE_LOAD_NO_VALIDATE, /* Not verify image contents, load to memory, load metadata. Print errors. */
#endif
} esp_image_load_mode_t;
typedef struct {
esp_partition_pos_t partition; /*!< Partition of application which worked before goes to the deep sleep. */
uint16_t reboot_counter; /*!< Reboot counter. Reset only when power is off. */
union {
struct {
uint8_t factory_reset_state : 1; /* True when Factory reset has occurred */
uint8_t reserve : 7; /* Reserve */
};
uint8_t val;
} flags;
uint8_t reserve; /*!< Reserve */
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
uint8_t custom[CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE]; /*!< Reserve for custom propose */
#endif
uint32_t crc; /*!< Check sum crc32 */
} rtc_retain_mem_t;
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");
#ifdef CONFIG_BOOTLOADER_RESERVE_RTC_MEM
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
/* The custom field must be the penultimate field */
ESP_STATIC_ASSERT(offsetof(rtc_retain_mem_t, custom) == sizeof(rtc_retain_mem_t) - sizeof(uint32_t) - CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE,
"custom field in rtc_retain_mem_t structure must be the field before the CRC one");
#endif
ESP_STATIC_ASSERT(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
#else
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
#endif
ESP_STATIC_ASSERT(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved RTC area must exceed size of rtc_retain_mem_t");
#endif // CONFIG_BOOTLOADER_RESERVE_RTC_MEM
/**
* @brief Verify an app/bootloader image.
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param mode Mode of operation (verify, silent verify, or load).
* @param part Partition to load the app/bootloader from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Get metadata of app/bootloader
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app/bootloader from.
* @param[out] metadata Pointer to the image metadata structure which is be filled in by this function.
* Fields will all be initialised by this function.
*
* @return
* - ESP_OK if filling of metadata was successful
*/
esp_err_t esp_image_get_metadata(const esp_partition_pos_t *part, esp_image_metadata_t *metadata);
/**
* @brief Verify and load an app image (available only in space of bootloader).
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* Image validation checks:
* - Magic byte.
* - Partition smaller than 16MB.
* - All segments & image fit in partition.
* - 8 bit image checksum is valid.
* - SHA-256 of image is valid (if image has this appended).
* - (Signature) if signature verification is enabled.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Load an app image without verification (available only in space of bootloader).
*
* If encryption is enabled, data will be transparently decrypted.
*
* @param part Partition to load the app from.
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
* 'start_addr' member should be set (to the start address of the image.)
* Other fields will all be initialised by this function.
*
* @return
* - ESP_OK if verify or load was successful
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Verify the PRIMARY bootloader image.
*
* @param[out] If result is ESP_OK and this pointer is non-NULL, it
* will be set to the length of the bootloader image.
*
* @return As per esp_image_load_metadata().
*/
esp_err_t esp_image_verify_bootloader(uint32_t *length);
/**
* @brief Verify the PRIMARY bootloader image.
*
* @param[out] Metadata for the image. Only valid if result is ESP_OK.
*
* @return As per esp_image_load_metadata().
*/
esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data);
/**
* @brief Get the flash size of the image
*
* @param app_flash_size The value configured in the image header
* @return Actual size, in bytes.
*/
int esp_image_get_flash_size(esp_image_flash_size_t app_flash_size);
/**
* @brief Get the ota bootloader offset
*
* The esp_image_verify functions use the offset to distinguish between application and bootloader verifications.
* The application must set the OTA bootloader offset before running any verification functions for the OTA bootloader partition.
*
* @return ota Bootloader offset. UINT32_MAX - not set.
*/
uint32_t esp_image_bootloader_offset_get(void);
/**
* @brief Set the ota bootloader offset
*
* The esp_image_verify functions use the offset to distinguish between application and bootloader verifications.
* The application must set the OTA bootloader offset before running any verification functions for the OTA bootloader partition.
*
* @param offset ota Bootloader offset
*/
void esp_image_bootloader_offset_set(const uint32_t offset);
typedef struct {
uint32_t drom_addr;
uint32_t drom_load_addr;
uint32_t drom_size;
uint32_t irom_addr;
uint32_t irom_load_addr;
uint32_t irom_size;
} esp_image_flash_mapping_t;
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,391 @@
/*
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <esp_err.h>
#include "soc/efuse_periph.h"
#include "soc/soc_caps.h"
#include "esp_image_format.h"
#include "esp_rom_efuse.h"
#include "sdkconfig.h"
#include "esp_rom_crc.h"
#include "hal/efuse_ll.h"
#if !CONFIG_IDF_TARGET_LINUX
#include "rom/secure_boot.h"
#endif
#ifdef CONFIG_SECURE_BOOT_V1_ENABLED
#if !defined(CONFIG_SECURE_SIGNED_ON_BOOT) || !defined(CONFIG_SECURE_SIGNED_ON_UPDATE) || !defined(CONFIG_SECURE_SIGNED_APPS)
#error "internal sdkconfig error, secure boot should always enable all signature options"
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Support functions for secure boot features.
Can be compiled as part of app or bootloader code.
*/
#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS
#define ESP_SECURE_BOOT_DIGEST_LEN 48
#else /* !CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */
#define ESP_SECURE_BOOT_DIGEST_LEN 32
#endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */
/* SHA-256 length of the public key digest */
#define ESP_SECURE_BOOT_KEY_DIGEST_SHA_256_LEN 32
/* Length of the public key digest that is stored in efuses */
#if CONFIG_IDF_TARGET_ESP32C2
#define ESP_SECURE_BOOT_KEY_DIGEST_LEN ESP_SECURE_BOOT_KEY_DIGEST_SHA_256_LEN / 2
#else
#define ESP_SECURE_BOOT_KEY_DIGEST_LEN ESP_SECURE_BOOT_KEY_DIGEST_SHA_256_LEN
#endif
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#endif
/**
* @brief Secure Boot Signature Block Version field
*/
typedef enum {
ESP_SECURE_BOOT_V1_ECDSA = 0, /*!< Secure Boot v1 */
ESP_SECURE_BOOT_V2_RSA = 2, /*!< Secure Boot v2 with RSA key */
ESP_SECURE_BOOT_V2_ECDSA = 3, /*!< Secure Boot v2 with ECDSA key */
} esp_secure_boot_sig_scheme_t;
#if CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
#define ESP_SECURE_BOOT_SCHEME ESP_SECURE_BOOT_V1_ECDSA
#elif CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
#define ESP_SECURE_BOOT_SCHEME ESP_SECURE_BOOT_V2_RSA
#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
#define ESP_SECURE_BOOT_SCHEME ESP_SECURE_BOOT_V2_ECDSA
#endif
/* Expected ECDSA curve ID from menuconfig "ECDSA key size" (matches ECDSA_CURVE_P256/P384 in ROM) */
#if CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_256_BITS
#define ESP_SECURE_BOOT_ECDSA_CURVE_ID ECDSA_CURVE_P256
#elif CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS
#define ESP_SECURE_BOOT_ECDSA_CURVE_ID ECDSA_CURVE_P384
#endif
#endif
#if CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
/** @brief Get the selected secure boot scheme key type
*
* @return key type for the selected secure boot scheme
*/
static inline const char* esp_secure_boot_get_scheme_name(esp_secure_boot_sig_scheme_t scheme)
{
switch (scheme) {
case ESP_SECURE_BOOT_V2_RSA:
return "RSA";
case ESP_SECURE_BOOT_V1_ECDSA:
case ESP_SECURE_BOOT_V2_ECDSA:
return "ECDSA";
default:
return "Unknown";
}
}
#endif
/** @brief Is secure boot currently enabled in hardware?
*
* This means that the ROM bootloader code will only boot
* a verified secure bootloader from now on.
*
* @return true if secure boot is enabled.
*/
static inline bool esp_secure_boot_enabled(void)
{
#if CONFIG_IDF_TARGET_ESP32
#ifdef CONFIG_SECURE_BOOT_V1_ENABLED
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
return efuse_ll_get_secure_boot_v1_en();
#else
return esp_efuse_read_field_bit(ESP_EFUSE_ABS_DONE_0);
#endif
#elif CONFIG_SECURE_BOOT_V2_ENABLED
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
return efuse_ll_get_secure_boot_v2_en();
#else
return esp_efuse_read_field_bit(ESP_EFUSE_ABS_DONE_1);
#endif
#endif
#else
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
return efuse_ll_get_secure_boot_v2_en();
#else
return esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
#endif
#endif
return false; /* Secure Boot not enabled in menuconfig */
}
/** @brief Generate secure digest from bootloader image
*
* @important This function is intended to be called from bootloader code only.
*
* This function is only used in the context of the Secure Boot V1 scheme.
*
* If secure boot is not yet enabled for bootloader, this will:
* 1) generate the secure boot key and burn it on EFUSE
* (without enabling R/W protection)
* 2) generate the digest from bootloader and save it
* to flash address 0x0
*
* If first boot gets interrupted after calling this function
* but before esp_secure_boot_permanently_enable() is called, then
* the key burned on EFUSE will not be regenerated, unless manually
* done using espefuse tool
*
* @return ESP_OK if secure boot digest is generated
* successfully or found to be already present
*/
esp_err_t esp_secure_boot_generate_digest(void);
/** @brief Enable secure boot V1 if it is not already enabled.
*
* @important If this function succeeds, secure boot V1 is permanently
* enabled on the chip via efuse.
*
* @important This function is intended to be called from bootloader code only.
*
* @important In case of Secure Boot V1, this will enable r/w protection
* of secure boot key on EFUSE, therefore it is to be ensured that
* esp_secure_boot_generate_digest() is called before this .If secure boot is not
* yet enabled for bootloader, this will
* 1) enable R/W protection of secure boot key on EFUSE
* 2) enable secure boot by blowing the EFUSE_RD_ABS_DONE_0 efuse.
*
* This function does not verify secure boot of the bootloader (the
* ROM bootloader does this.)
*
* Will fail if efuses have been part-burned in a way that indicates
* secure boot should not or could not be correctly enabled.
*
* @return ESP_ERR_INVALID_STATE if efuse state doesn't allow
* secure boot to be enabled cleanly. ESP_OK if secure boot
* is enabled on this chip from now on.
*/
esp_err_t esp_secure_boot_permanently_enable(void);
/** @brief Enables secure boot V2 if it is not already enabled.
*
* @important If this function succeeds, secure boot V2 is permanently
* enabled on the chip via efuse.
*
* @important This function is intended to be called from bootloader code only.
*
* @important In case of Secure Boot V2, this will enable write protection
* of secure boot key on EFUSE in BLK2. .If secure boot is not
* yet enabled for bootloader, this will
* 1) enable W protection of secure boot key on EFUSE
* 2) enable secure boot by blowing the EFUSE_RD_ABS_DONE_1 efuse.
*
* This function does not verify secure boot of the bootloader (the
* ROM bootloader does this.)
*
* @param image_data Image metadata of the application to be loaded.
*
* Will fail if efuses have been part-burned in a way that indicates
* secure boot should not or could not be correctly enabled.
*
* @return ESP_ERR_INVALID_STATE if efuse state doesn't allow
* secure boot to be enabled cleanly. ESP_OK if secure boot
* is enabled on this chip from now on.
*/
esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *image_data);
/** @brief Verify the secure boot signature appended to some binary data in flash.
*
* For ECDSA Scheme (Secure Boot V1) - deterministic ECDSA w/ SHA256 image
* For RSA Scheme (Secure Boot V2) - RSA-PSS Verification of the SHA-256 image digest
* For ECDSA Scheme (Secure Boot V2) - ECDSA Verification of the SHA-256 / SHA-384 (in case of ECDSA-P384 secure boot key) image digest
*
* Public key is compiled into the calling program in the ECDSA Scheme.
* See the apt docs/security/secure-boot-v1.rst or docs/security/secure-boot-v2.rst for details.
*
* @param src_addr Starting offset of the data in flash.
* @param length Length of data in bytes. Signature is appended -after- length bytes.
*
* If flash encryption is enabled, the image will be transparently decrypted while being verified.
*
* @note This function doesn't have any fault injection resistance so should not be called
* during a secure boot itself (but can be called when verifying an update, etc.)
*
* @return ESP_OK if signature is valid, ESP_ERR_INVALID_STATE if
* signature fails, ESP_FAIL for other failures (ie can't read flash).
*/
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length);
/** @brief Secure boot verification block, on-flash data format. */
typedef struct {
uint32_t version;
uint8_t signature[64];
} esp_secure_boot_sig_block_t;
/** @brief Get the size of the secure boot signature block
*
* This is the size of the signature block appended to a signed image.
*
* @return Size of the secure boot signature block in bytes
*/
static inline uint32_t esp_secure_boot_sig_block_size()
{
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
return sizeof(ets_secure_boot_signature_t);
#elif defined(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)
return sizeof(esp_secure_boot_sig_block_t);
#else
return 0;
#endif
}
/** @brief Verify the ECDSA secure boot signature block for Secure Boot V1.
*
* Calculates Deterministic ECDSA w/ SHA256 based on the SHA256 hash of the image. ECDSA signature
* verification must be enabled in project configuration to use this function.
*
* Similar to esp_secure_boot_verify_signature(), but can be used when the digest is precalculated.
* @param sig_block Pointer to ECDSA signature block data
* @param image_digest Pointer to 32 byte buffer holding SHA-256 hash.
* @param verified_digest Pointer to 32 byte buffer that will receive verified digest if verification completes. (Used during bootloader implementation only, result is invalid otherwise.)
*
*/
esp_err_t esp_secure_boot_verify_ecdsa_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest);
#if !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_FULL >= 300
#if CONFIG_SECURE_BOOT_V2_ENABLED || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
/** @brief Verify the secure boot signature block for Secure Boot V2.
*
* Performs RSA-PSS or ECDSA verification of the SHA-256 / SHA-384 image based on the public key
* in the signature block, compared against the public key digest stored in efuse.
*
* Similar to esp_secure_boot_verify_signature(), but can be used when the digest is precalculated.
* @param[in] sig_block Pointer to signature block data
* @param[in] image_digest Pointer to 32/48 byte buffer holding SHA-256/SHA-384 hash.
* @param[out] verified_digest Pointer to 32/48 byte buffer that will receive verified digest if verification completes. (Used during bootloader implementation only, result is invalid otherwise.)
*
*/
esp_err_t esp_secure_boot_verify_sbv2_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, uint8_t *verified_digest);
#endif /* CONFIG_SECURE_BOOT_V2_ENABLED || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT */
/**
* @brief Structure to hold public key digests calculated from the signature blocks of a single image.
*
* Each image can have one or more signature blocks (up to SECURE_BOOT_NUM_BLOCKS). Each signature block includes a public key.
*/
typedef struct {
uint8_t key_digests[SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS][ESP_SECURE_BOOT_KEY_DIGEST_SHA_256_LEN]; /* SHA of the public key components in the signature block */
unsigned num_digests; /* Number of valid digests, starting at index 0 */
} esp_image_sig_public_key_digests_t;
#endif // !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_FULL >= 300
#define FLASH_OFFS_SECURE_BOOT_IV_DIGEST 0
/** @brief Secure boot IV+digest header */
typedef struct {
uint8_t iv[128];
uint8_t digest[64];
} esp_secure_boot_iv_digest_t;
/** @brief Check the secure boot V2 during startup
*
* @note This function is called automatically during app startup,
* it doesn't need to be called from the app.
*
* Verifies the secure boot config during startup:
*
* - Correct any insecure secure boot settings
*/
void esp_secure_boot_init_checks(void);
#if !BOOTLOADER_BUILD && (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME)
/** @brief Scan the current running app for signature blocks
*
* @note This function doesn't verify that the signatures are valid or the
* corresponding public keys are trusted, it only reads the number of signature
* blocks present and optionally calculates the digests of the public keys
* provided in the signature blocks.
*
* @param digest_public_keys If true, the key_digests fields in the
* public_key_digests structure will be filled with the digests of the public
* key provided in each signature block. Note that if Secure Boot V2 is enabled,
* each public key will only be trusted if the same digest is also present in
* eFuse (but this is not checked by this function).
*
* @param public_key_digests[out] Structure is initialized with the num_digests
* field set to the number of signatures found. If digest_public_keys is set,
* the public key digests are also calculated and stored here.
*
* @return
* - ESP_OK - At least one signature was found
* - ESP_ERR_NOT_FOUND - No signatures were found, num_digests value will be zero
* - ESP_FAIL - An error occurred trying to read the signature blocks from flash
*/
esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests);
#endif // !BOOTLOADER_BUILD && (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME)
/** @brief Set all secure eFuse features related to secure_boot
*
* @note
* This API needs to be called in the eFuse batch mode.
* i.e. A call to esp_efuse_batch_write_begin() should be made prior to calling this API to start the batch mode
* After the API has been executed a call to esp_efuse_batch_write_commit()/esp_efuse_batch_write_cancel()
* should be made accordingly.
* @return
* - ESP_OK - Successfully
*/
esp_err_t esp_secure_boot_enable_secure_features(void);
/** @brief Returns the verification status for all physical security features of secure boot in release mode
*
* If the device has secure boot feature configured in the release mode,
* then it is highly recommended to call this API in the application startup code.
* This API verifies the sanity of the eFuse configuration against
* the release (production) mode of the secure boot feature.
*
* @return
* - True - all eFuses are configured correctly
* - False - not all eFuses are configured correctly.
*/
bool esp_secure_boot_cfg_verify_release_mode(void);
#if !defined(BOOTLOADER_BUILD) && SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
/** @brief Returns the verification status of the image pointed by the part_pos argument against the public key digest present at index `efuse_digest_index`
*
* @param index[in] Index of public key digest present in efuse against which the image is to be verified
* @param part_pos[in] It is a pointer to the bootloader/app partition.
*
* @return
* - ESP_OK - if the image can be verified by the key at efuse_index.
* - ESP_FAIL - if the image cannot be verified by the key at efuse_index.
* - ESP_ERR_INVALID_ARG: Error in the passed arguments.
*/
esp_err_t esp_secure_boot_verify_with_efuse_digest_index(int efuse_digest_index, esp_partition_pos_t *part_pos);
#endif // !defined(BOOTLOADER_BUILD) && SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "esp_flash_partitions.h"
#include "esp_image_format.h"
#ifdef __cplusplus
extern "C" {
#endif
// TEE otadata magic is derived from sha256 of "tee_ota" string
#define TEE_OTADATA_MAGIC 0x4337e1e1
/* TEE OTA selection structure (two copies in the TEE OTA data partition) */
typedef struct {
uint32_t magic; // A magic byte for otadata structure
uint8_t version; // OTA image version
uint8_t boot_partition; // Default boot partition
uint8_t ota_state; // OTA_DATA states for checking operability of the app
uint8_t reserved_1; // Reserved field 1
uint32_t reserved_2[5]; // Reserved fields 2
uint32_t crc; // CRC32 of all fields in the structure
} __attribute__((packed)) esp_tee_ota_select_entry_t;
ESP_STATIC_ASSERT(offsetof(esp_tee_ota_select_entry_t, crc) == sizeof(esp_tee_ota_select_entry_t) - sizeof(uint32_t));
// OTA_DATA states for checking operability of the app.
typedef enum {
ESP_TEE_OTA_IMG_NEW = 0x00U, /*!< Monitor the first boot - the bootloader changes the state to PENDING_VERIFY. */
ESP_TEE_OTA_IMG_PENDING_VERIFY = 0x33U, /*!< If encountered during the second boot, the bootloader changes the state to INVALID. */
ESP_TEE_OTA_IMG_INVALID = 0x55U, /*!< App was confirmed as workable - can boot and work without limits. */
ESP_TEE_OTA_IMG_VALID = 0xAAU, /*!< App was confirmed as non-workable - will not selected to boot at all. */
ESP_TEE_OTA_IMG_UNDEFINED = 0xFFU, /*!< Undefined. */
} esp_tee_ota_img_states_t;
#ifdef __cplusplus
}
#endif