chore: import upstream snapshot with attribution
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user