Merge branch 'master' into feature/esp32s2beta_merge

This commit is contained in:
Angus Gratton
2019-09-16 10:56:48 +10:00
committed by Angus Gratton
361 changed files with 10271 additions and 7062 deletions

View File

@@ -72,3 +72,12 @@ void bootloader_clock_configure(void)
}
#endif
}
#ifdef BOOTLOADER_BUILD
int esp_clk_apb_freq(void)
{
return rtc_clk_apb_freq_get();
}
#endif // BOOTLOADER_BUILD

View File

@@ -277,3 +277,66 @@ void bootloader_common_vddsdio_configure(void)
}
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
}
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)(SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t));
static bool check_rtc_retain_mem(void)
{
return crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc)) == rtc_retain_mem->crc && rtc_retain_mem->crc != UINT32_MAX;
}
static void update_rtc_retain_mem_crc(void)
{
rtc_retain_mem->crc = crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc));
}
void bootloader_common_reset_rtc_retain_mem(void)
{
memset(rtc_retain_mem, 0, sizeof(rtc_retain_mem_t));
}
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void)
{
if (check_rtc_retain_mem()) {
return rtc_retain_mem->reboot_counter;
}
return 0;
}
esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void)
{
if (check_rtc_retain_mem()) {
return &rtc_retain_mem->partition;
}
return NULL;
}
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter)
{
if (reboot_counter) {
if (!check_rtc_retain_mem()) {
bootloader_common_reset_rtc_retain_mem();
}
if (++rtc_retain_mem->reboot_counter == 0) {
// do not allow to overflow. Stop it.
--rtc_retain_mem->reboot_counter;
}
}
if (partition != NULL) {
rtc_retain_mem->partition.offset = partition->offset;
rtc_retain_mem->partition.size = partition->size;
}
update_rtc_retain_mem_crc();
}
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
{
return rtc_retain_mem;
}
#endif

View File

@@ -432,8 +432,31 @@ static void set_actual_ota_seq(const bootloader_state_t *bs, int index)
update_anti_rollback(&bs->ota[index]);
#endif
}
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
esp_partition_pos_t partition = index_to_partition(bs, index);
bootloader_common_update_rtc_retain_mem(&partition, true);
#endif
}
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
void bootloader_utility_load_boot_image_from_deep_sleep(void)
{
if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
esp_partition_pos_t* partition = bootloader_common_get_rtc_retain_mem_partition();
if (partition != NULL) {
esp_image_metadata_t image_data;
if (bootloader_load_image_no_verify(partition, &image_data) == ESP_OK) {
ESP_LOGI(TAG, "Fast booting app from partition at offset 0x%x", partition->offset);
bootloader_common_update_rtc_retain_mem(NULL, true);
load_image(&image_data);
}
}
ESP_LOGE(TAG, "Fast booting is not successful");
ESP_LOGI(TAG, "Try to load an app as usual with all validations");
}
}
#endif
#define TRY_LOG_FORMAT "Trying partition index %d offs 0x%x size 0x%x"
void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index)

View File

@@ -37,7 +37,7 @@ static const char *TAG = "flash_encrypt";
/* Static functions for stages of flash encryption */
static esp_err_t initialise_flash_encryption(void);
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis);
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis) __attribute__((unused));
static esp_err_t encrypt_bootloader(void);
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions);
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition);
@@ -60,8 +60,14 @@ esp_err_t esp_flash_encrypt_check_and_update(void)
return ESP_OK;
}
else {
#ifndef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
/* Flash is not encrypted, so encrypt it! */
return encrypt_flash_contents(flash_crypt_cnt, flash_crypt_wr_dis);
#else
ESP_LOGE(TAG, "flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED "
"is set, refusing to boot.");
return ESP_ERR_INVALID_STATE;
#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
}
}

View File

@@ -103,14 +103,17 @@ static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_ha
static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
bool do_load = (mode == ESP_IMAGE_LOAD);
bool do_load = (mode == ESP_IMAGE_LOAD) || (mode == ESP_IMAGE_LOAD_NO_VALIDATE);
bool do_verify = (mode == ESP_IMAGE_LOAD) || (mode == ESP_IMAGE_VERIFY) || (mode == ESP_IMAGE_VERIFY_SILENT);
#else
bool do_load = false; // Can't load the image in app mode
bool do_load = false; // Can't load the image in app mode
bool do_verify = true; // In app mode is avalible only verify mode
#endif
bool silent = (mode == ESP_IMAGE_VERIFY_SILENT);
bool silent = (mode == ESP_IMAGE_VERIFY_SILENT);
esp_err_t err = ESP_OK;
// checksum the image a word at a time. This shaves 30-40ms per MB of image size
uint32_t checksum_word = ESP_ROM_CHECKSUM_INITIAL;
uint32_t *checksum = NULL;
bootloader_sha256_handle_t sha_handle = NULL;
if (data == NULL || part == NULL) {
@@ -131,41 +134,45 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
goto err;
}
// Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
if (do_verify) {
checksum = &checksum_word;
// Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
#ifdef SECURE_BOOT_CHECK_SIGNATURE
if (1) {
if (1) {
#else
if (data->image.hash_appended) {
if (data->image.hash_appended) {
#endif
sha_handle = bootloader_sha256_start();
if (sha_handle == NULL) {
return ESP_ERR_NO_MEM;
sha_handle = bootloader_sha256_start();
if (sha_handle == NULL) {
return ESP_ERR_NO_MEM;
}
bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t));
}
bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t));
}
ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x",
data->image.magic,
data->image.segment_count,
data->image.spi_mode,
data->image.spi_size,
data->image.entry_addr);
ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x",
data->image.magic,
data->image.segment_count,
data->image.spi_mode,
data->image.spi_size,
data->image.entry_addr);
err = verify_image_header(data->start_addr, &data->image, silent);
if (err != ESP_OK) {
goto err;
}
err = verify_image_header(data->start_addr, &data->image, silent);
if (err != ESP_OK) {
goto err;
}
if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
FAIL_LOAD("image at 0x%x segment count %d exceeds max %d",
data->start_addr, data->image.segment_count, ESP_IMAGE_MAX_SEGMENTS);
}
if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
FAIL_LOAD("image at 0x%x segment count %d exceeds max %d",
data->start_addr, data->image.segment_count, ESP_IMAGE_MAX_SEGMENTS);
}
} // if (do_verify)
uint32_t next_addr = data->start_addr + sizeof(esp_image_header_t);
for (int i = 0; i < data->image.segment_count; i++) {
esp_image_segment_header_t *header = &data->segments[i];
ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
err = process_segment(i, next_addr, header, silent, do_load, sha_handle, &checksum_word);
err = process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum);
if (err != ESP_OK) {
goto err;
}
@@ -174,70 +181,74 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
next_addr += header->data_len;
}
// Segments all loaded, verify length
uint32_t end_addr = next_addr;
if (end_addr < data->start_addr) {
FAIL_LOAD("image offset has wrapped");
}
data->image_len = end_addr - data->start_addr;
ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
if (!esp_cpu_in_ocd_debug_mode()) {
err = verify_checksum(sha_handle, checksum_word, data);
if (err != ESP_OK) {
goto err;
if (do_verify) {
// Segments all loaded, verify length
uint32_t end_addr = next_addr;
if (end_addr < data->start_addr) {
FAIL_LOAD("image offset has wrapped");
}
}
if (data->image_len > part->size) {
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
}
/* For secure boot, we don't verify signature on bootloaders.
data->image_len = end_addr - data->start_addr;
ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
if (NULL != checksum && !esp_cpu_in_ocd_debug_mode()) {
err = verify_checksum(sha_handle, checksum_word, data);
if (err != ESP_OK) {
goto err;
}
}
For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because esptool.py may have
rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.
*/
bool should_verify;
/* For secure boot on ESP32, we don't calculate SHA or verify signautre on bootloaders.
For ESP32S2, we do verify signature on botoloaders which includes the SHA calculation.
(For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because
esptool.py may have rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.)
*/
bool verify_sha;
#if defined(CONFIG_SECURE_BOOT_ENABLED) && defined(CONFIG_IDF_TARGET_ESP32S2BETA)
should_verify = true;
verify_sha = true;
#else // ESP32, or ESP32S2 without secure boot enabled
should_verify = (data->start_addr != ESP_BOOTLOADER_OFFSET);
verify_sha = (data->start_addr != ESP_BOOTLOADER_OFFSET);
#endif
if (should_verify) {
if (verify_sha) {
if (data->image_len > part->size) {
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
}
#ifdef SECURE_BOOT_CHECK_SIGNATURE
// secure boot images have a signature appended
err = verify_secure_boot_signature(sha_handle, data);
// secure boot images have a signature appended
err = verify_secure_boot_signature(sha_handle, data);
#else
// No secure boot, but SHA-256 can be appended for basic corruption detection
if (sha_handle != NULL && !esp_cpu_in_ocd_debug_mode()) {
err = verify_simple_hash(sha_handle, data);
}
// No secure boot, but SHA-256 can be appended for basic corruption detection
if (sha_handle != NULL && !esp_cpu_in_ocd_debug_mode()) {
err = verify_simple_hash(sha_handle, data);
}
#endif // SECURE_BOOT_CHECK_SIGNATURE
} else {
// bootloader may still have a sha256 digest handle open
if (sha_handle != NULL) {
bootloader_sha256_finish(sha_handle, NULL);
}
}
} else { // verify_sha
// bootloader may still have a sha256 digest handle open
if (sha_handle != NULL) {
bootloader_sha256_finish(sha_handle, NULL);
}
if (data->image.hash_appended) {
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
if (hash == NULL) {
err = ESP_FAIL;
goto err;
}
memcpy(data->image_digest, hash, HASH_LEN);
bootloader_munmap(hash);
}
if (data->image.hash_appended) {
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
if (hash == NULL) {
err = ESP_FAIL;
goto err;
}
memcpy(data->image_digest, hash, HASH_LEN);
bootloader_munmap(hash);
}
sha_handle = NULL;
} // verify_sha
} // do_verify
sha_handle = NULL;
if (err != ESP_OK) {
goto err;
}
#ifdef BOOTLOADER_BUILD
if (do_load) { // Need to deobfuscate RAM
if (do_load && ram_obfs_value[0] != 0 && ram_obfs_value[1] != 0) { // Need to deobfuscate RAM
for (int i = 0; i < data->image.segment_count; i++) {
uint32_t load_addr = data->segments[i].load_addr;
if (should_load(load_addr)) {
@@ -264,7 +275,7 @@ err:
// Prevent invalid/incomplete data leaking out
bzero(data, sizeof(esp_image_metadata_t));
return err;
}
}
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
@@ -275,6 +286,15 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad
#endif
}
esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
return image_load(ESP_IMAGE_LOAD_NO_VALIDATE, part, data);
#else
return ESP_FAIL;
#endif
}
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
return image_load(mode, part, data);
@@ -408,6 +428,13 @@ err:
static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
{
// If we are not loading, and the checksum is empty, skip processing this
// segment for data
if(!do_load && checksum == NULL) {
ESP_LOGD(TAG, "skipping checksum for segment");
return ESP_OK;
}
const uint32_t *data = (const uint32_t *)bootloader_mmap(data_addr, data_len);
if (!data) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed",
@@ -415,6 +442,12 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui
return ESP_FAIL;
}
if (checksum == NULL && sha_handle == NULL) {
memcpy((void *)load_addr, data, data_len);
bootloader_munmap(data);
return ESP_OK;
}
#ifdef BOOTLOADER_BUILD
// Set up the obfuscation value to use for loading
while (ram_obfs_value[0] == 0 || ram_obfs_value[1] == 0) {
@@ -428,7 +461,9 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui
for (int i = 0; i < data_len; i += 4) {
int w_i = i / 4; // Word index
uint32_t w = src[w_i];
*checksum ^= w;
if (checksum != NULL) {
*checksum ^= w;
}
#ifdef BOOTLOADER_BUILD
if (do_load) {
dest[w_i] = w ^ ((w_i & 1) ? ram_obfs_value[0] : ram_obfs_value[1]);
@@ -506,15 +541,15 @@ static bool should_load(uint32_t load_addr)
if (!load_rtc_memory) {
if (load_addr >= SOC_RTC_IRAM_LOW && load_addr < SOC_RTC_IRAM_HIGH) {
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x", load_addr);
return false;
}
if (load_addr >= SOC_RTC_DRAM_LOW && load_addr < SOC_RTC_DRAM_HIGH) {
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x", load_addr);
return false;
}
if (load_addr >= SOC_RTC_DATA_LOW && load_addr < SOC_RTC_DATA_HIGH) {
ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08x\n", load_addr);
ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08x", load_addr);
return false;
}
}

View File

@@ -13,9 +13,51 @@
// limitations under the License.
#include <strings.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_flash_encrypt.h"
#include "esp_secure_boot.h"
#ifndef BOOTLOADER_BUILD
static const char *TAG = "flash_encrypt";
void esp_flash_encryption_init_checks()
{
esp_flash_enc_mode_t mode;
// First check is: if Release mode flash encryption & secure boot are enabled then
// FLASH_CRYPT_CNT *must* be write protected. This will have happened automatically
// if bootloader is IDF V4.0 or newer but may not have happened for previous ESP-IDF bootloaders.
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
#ifdef CONFIG_SECURE_BOOT_ENABLED
if (esp_secure_boot_enabled() && esp_flash_encryption_enabled()) {
uint8_t flash_crypt_cnt_wr_dis = 0;
esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
if (!flash_crypt_cnt_wr_dis) {
ESP_EARLY_LOGE(TAG, "Flash encryption & Secure Boot together requires FLASH_CRYPT_CNT efuse to be write protected. Fixing now...");
esp_flash_write_protect_crypt_cnt();
}
}
#endif // CONFIG_SECURE_BOOT_ENABLED
#endif // CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
// Second check is to print a warning or error if the current running flash encryption mode
// doesn't match the expectation from project config (due to mismatched bootloader and app, probably)
mode = esp_get_flash_encryption_mode();
if (mode == ESP_FLASH_ENC_MODE_DEVELOPMENT) {
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
ESP_EARLY_LOGE(TAG, "Flash encryption settings error: app is configured for RELEASE but efuses are set for DEVELOPMENT");
ESP_EARLY_LOGE(TAG, "Mismatch found in security options in bootloader menuconfig and efuse settings. Device is not secure.");
#else
ESP_EARLY_LOGW(TAG, "Flash encryption mode is DEVELOPMENT (not secure)");
#endif
} else if (mode == ESP_FLASH_ENC_MODE_RELEASE) {
ESP_EARLY_LOGI(TAG, "Flash encryption mode is RELEASE");
}
}
#endif
void esp_flash_write_protect_crypt_cnt(void)
{

View File

@@ -56,6 +56,10 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block_t *sig_block, const uint8_t *image_digest)
{
#if !(defined(CONFIG_MBEDTLS_ECDSA_C) && defined(CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED))
ESP_LOGE(TAG, "Signature verification requires ECDSA & SECP256R1 curve enabled");
return ESP_ERR_NOT_SUPPORTED;
#else
ptrdiff_t keylen;
keylen = signature_verification_key_end - signature_verification_key_start;
@@ -117,4 +121,5 @@ cleanup:
mbedtls_mpi_free(&s);
mbedtls_ecdsa_free(&ecdsa_context);
return ret == 0 ? ESP_OK : ESP_ERR_IMAGE_INVALID;
#endif // CONFIG_MBEDTLS_ECDSA_C && CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED
}