efuse(esp32): Deprecate esp_efuse_burn_new_values() & esp_efuse_write_random_key()
These functions were used only for esp32 in secure_boot and flash encryption. Use idf efuse APIs instead of efuse regs.
This commit is contained in:
committed by
Angus Gratton
parent
eca878b37f
commit
f339b3fc96
@@ -104,8 +104,7 @@ esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
const uint8_t one = 1;
|
||||
return esp_efuse_write_field_blob(s_table[idx].key_rd_dis, &one, 1);
|
||||
return esp_efuse_write_field_bit(s_table[idx].key_rd_dis);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_key_dis_write(esp_efuse_block_t block)
|
||||
@@ -121,8 +120,7 @@ esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
const uint8_t one = 1;
|
||||
return esp_efuse_write_field_blob(s_table[idx].key_wr_dis, &one, 1);
|
||||
return esp_efuse_write_field_bit(s_table[idx].key_wr_dis);
|
||||
}
|
||||
|
||||
bool esp_efuse_key_block_unused(esp_efuse_block_t block)
|
||||
@@ -138,3 +136,110 @@ bool esp_efuse_key_block_unused(esp_efuse_block_t block)
|
||||
|
||||
return true; // Unused
|
||||
}
|
||||
|
||||
esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)
|
||||
{
|
||||
esp_efuse_purpose_t ret_purpose;
|
||||
if (block == EFUSE_BLK0) {
|
||||
ret_purpose = ESP_EFUSE_KEY_PURPOSE_SYSTEM;
|
||||
} else if (block == EFUSE_BLK_ENCRYPT_FLASH) {
|
||||
ret_purpose = ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION;
|
||||
} else if (block == EFUSE_BLK_SECURE_BOOT) {
|
||||
ret_purpose = ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2;
|
||||
} else if (block == EFUSE_BLK3) {
|
||||
ret_purpose = ESP_EFUSE_KEY_PURPOSE_USER;
|
||||
} else {
|
||||
ret_purpose = ESP_EFUSE_KEY_PURPOSE_MAX;
|
||||
}
|
||||
return ret_purpose;
|
||||
}
|
||||
|
||||
bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
(void)block;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool esp_efuse_find_purpose(esp_efuse_purpose_t purpose, esp_efuse_block_t *block)
|
||||
{
|
||||
esp_efuse_block_t dummy;
|
||||
if (block == NULL) {
|
||||
block = &dummy;
|
||||
}
|
||||
|
||||
for (esp_efuse_block_t b = EFUSE_BLK_KEY0; b < EFUSE_BLK_KEY_MAX; b++) {
|
||||
if (esp_efuse_get_key_purpose(b) == purpose) {
|
||||
*block = b;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpose, const void *key, size_t key_size_bytes)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX || key_size_bytes > 32 || purpose >= ESP_EFUSE_KEY_PURPOSE_MAX
|
||||
|| esp_efuse_get_key_purpose(block) != purpose) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_efuse_batch_write_begin();
|
||||
|
||||
if (!esp_efuse_key_block_unused(block)) {
|
||||
err = ESP_ERR_INVALID_STATE;
|
||||
} else {
|
||||
ESP_EFUSE_CHK(esp_efuse_write_block(block, key, 0, key_size_bytes * 8));
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_dis_write(block));
|
||||
if (purpose == ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION) {
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_dis_read(block));
|
||||
}
|
||||
return esp_efuse_batch_write_commit();
|
||||
}
|
||||
err_exit:
|
||||
esp_efuse_batch_write_cancel();
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_write_keys(const esp_efuse_purpose_t purposes[], uint8_t keys[][32], unsigned number_of_keys)
|
||||
{
|
||||
esp_err_t err = ESP_FAIL;
|
||||
if (number_of_keys == 0 || number_of_keys > (EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) || keys == NULL || purposes == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
size_t key_size = 32;
|
||||
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_KEY0);
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
|
||||
key_size = 24;
|
||||
}
|
||||
esp_efuse_purpose_t purpose = 0;
|
||||
esp_efuse_block_t block = EFUSE_BLK_KEY0;
|
||||
|
||||
esp_efuse_batch_write_begin();
|
||||
for (unsigned i_key = 0; (block < EFUSE_BLK_KEY_MAX) && (i_key < number_of_keys); block++) {
|
||||
purpose = purposes[i_key];
|
||||
if (esp_efuse_get_key_purpose(block) == purpose) {
|
||||
ESP_LOGI(TAG, "Writing EFUSE_BLK_KEY%d with purpose %d", block - EFUSE_BLK_KEY0, purpose);
|
||||
ESP_EFUSE_CHK(esp_efuse_write_key(block, purpose, keys[i_key], key_size));
|
||||
i_key++;
|
||||
}
|
||||
}
|
||||
return esp_efuse_batch_write_commit();
|
||||
err_exit:
|
||||
ESP_LOGE(TAG, "Failed to write EFUSE_BLK_KEY%d with purpose %d. Can't continue.", block - EFUSE_BLK_KEY0, purpose);
|
||||
esp_efuse_batch_write_cancel();
|
||||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_ESP32_REV_MIN_3
|
||||
esp_err_t esp_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys)
|
||||
{
|
||||
if (trusted_keys == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
trusted_keys->key_digests[0] = (const void *)esp_efuse_utility_get_read_register_address(EFUSE_BLK_SECURE_BOOT);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_ESP32_REV_MIN_3
|
||||
|
||||
@@ -27,6 +27,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
const esp_efuse_desc_t** revoke;
|
||||
const esp_efuse_desc_t** revoke_wr_dis;
|
||||
const esp_efuse_purpose_t digest_purpose;
|
||||
} esp_efuse_revokes_t;
|
||||
|
||||
const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
|
||||
@@ -42,19 +43,11 @@ const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
|
||||
};
|
||||
|
||||
const esp_efuse_revokes_t s_revoke_table[] = {
|
||||
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE0, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0},
|
||||
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE1, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE1},
|
||||
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE2, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE2},
|
||||
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE0, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE0, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0},
|
||||
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE1, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE1, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1},
|
||||
{ESP_EFUSE_SECURE_BOOT_KEY_REVOKE2, ESP_EFUSE_WR_DIS_SECURE_BOOT_KEY_REVOKE2, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2},
|
||||
};
|
||||
|
||||
#define ESP_EFUSE_CHK(ret) \
|
||||
do \
|
||||
{ \
|
||||
if( ( err = (ret) ) != ESP_OK ) \
|
||||
goto err_exit; \
|
||||
} while( 0 )
|
||||
|
||||
|
||||
bool esp_efuse_block_is_empty(esp_efuse_block_t block)
|
||||
{
|
||||
const unsigned blk_len_bit = 256;
|
||||
@@ -149,8 +142,7 @@ esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
const uint8_t one = 1;
|
||||
return esp_efuse_write_field_blob(s_table[idx].key_rd_dis, &one, 1);
|
||||
return esp_efuse_write_field_bit(s_table[idx].key_rd_dis);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_key_dis_write(esp_efuse_block_t block)
|
||||
@@ -166,8 +158,7 @@ esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
const uint8_t one = 1;
|
||||
return esp_efuse_write_field_blob(s_table[idx].key_wr_dis, &one, 1);
|
||||
return esp_efuse_write_field_bit(s_table[idx].key_wr_dis);
|
||||
}
|
||||
|
||||
esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)
|
||||
@@ -206,8 +197,7 @@ esp_err_t esp_efuse_set_keypurpose_dis_write(esp_efuse_block_t block)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
const uint8_t one = 1;
|
||||
return esp_efuse_write_field_blob(s_table[idx].keypurpose_wr_dis, &one, 1);
|
||||
return esp_efuse_write_field_bit(s_table[idx].keypurpose_wr_dis);
|
||||
}
|
||||
|
||||
bool esp_efuse_find_purpose(esp_efuse_purpose_t purpose, esp_efuse_block_t *block)
|
||||
@@ -231,7 +221,7 @@ esp_efuse_block_t esp_efuse_find_unused_key_block(void)
|
||||
{
|
||||
for (esp_efuse_block_t b = EFUSE_BLK_KEY0; b < EFUSE_BLK_KEY_MAX; b++) {
|
||||
if (esp_efuse_key_block_unused(b)) {
|
||||
return b;
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return EFUSE_BLK_KEY_MAX; // nothing
|
||||
@@ -311,9 +301,11 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
ESP_EFUSE_CHK(esp_efuse_write_field_blob(s_table[idx].key, key, key_size_bytes * 8));
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_dis_write(block));
|
||||
if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 ||
|
||||
if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY ||
|
||||
#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY ||
|
||||
#endif
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE ||
|
||||
@@ -329,7 +321,7 @@ err_exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_write_keys(esp_efuse_purpose_t purposes[], uint8_t keys[][32], unsigned number_of_keys)
|
||||
esp_err_t esp_efuse_write_keys(const esp_efuse_purpose_t purposes[], uint8_t keys[][32], unsigned number_of_keys)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
if (number_of_keys == 0 || number_of_keys > (EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) || keys == NULL || purposes == NULL) {
|
||||
@@ -361,3 +353,37 @@ err_exit:
|
||||
esp_efuse_batch_write_cancel();
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys)
|
||||
{
|
||||
bool found = false;
|
||||
esp_efuse_block_t key_block;
|
||||
|
||||
if (trusted_keys == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < MAX_KEY_DIGESTS; i++) {
|
||||
trusted_keys->key_digests[i] = NULL;
|
||||
if (esp_efuse_get_digest_revoke(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Anti-FI check that this efuse really is not revoked
|
||||
assert(esp_efuse_get_digest_revoke(i) == 0);
|
||||
|
||||
if (!esp_efuse_find_purpose(s_revoke_table[i].digest_purpose, &key_block)) {
|
||||
continue;
|
||||
}
|
||||
trusted_keys->key_digests[i] = (const void *)esp_efuse_utility_get_read_register_address(key_block);
|
||||
found = found || (trusted_keys->key_digests[i] != NULL);
|
||||
}
|
||||
|
||||
trusted_keys->allow_key_revoke = false;
|
||||
|
||||
if (!found) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -19,11 +19,12 @@
|
||||
#include "sys/param.h"
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "efuse";
|
||||
// Permanently update values written to the efuse write registers
|
||||
void esp_efuse_burn_new_values(void)
|
||||
{
|
||||
esp_efuse_utility_burn_efuses();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD
|
||||
#define APP_SEC_VER_SIZE_EFUSE_FIELD CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD
|
||||
#else
|
||||
#define APP_SEC_VER_SIZE_EFUSE_FIELD 16 // smallest possible size for all chips
|
||||
#endif
|
||||
|
||||
// Reset efuse write registers
|
||||
void esp_efuse_reset(void)
|
||||
@@ -31,87 +32,14 @@ void esp_efuse_reset(void)
|
||||
esp_efuse_utility_reset();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
|
||||
|
||||
#include "../include_bootloader/bootloader_flash_priv.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
|
||||
static uint32_t esp_efuse_flash_offset = 0;
|
||||
static uint32_t esp_efuse_flash_size = 0;
|
||||
|
||||
void esp_efuse_init(uint32_t offset, uint32_t size)
|
||||
{
|
||||
esp_efuse_flash_offset = offset;
|
||||
esp_efuse_flash_size = size;
|
||||
}
|
||||
|
||||
static uint32_t emulate_secure_version_read(void)
|
||||
{
|
||||
uint32_t secure_version;
|
||||
uint32_t offset = esp_efuse_flash_offset;
|
||||
if (offset == 0) {
|
||||
ESP_LOGE(TAG, "emulate secure_version can not be used");
|
||||
return 0;
|
||||
}
|
||||
const uint32_t *efuse_place_in_flash = bootloader_mmap(offset, esp_efuse_flash_size);
|
||||
if (!efuse_place_in_flash) {
|
||||
ESP_LOGE(TAG, "secure_version can not be read from (0x%x, 0x%x) flash", offset, esp_efuse_flash_size);
|
||||
return 0;
|
||||
}
|
||||
memcpy(&secure_version, efuse_place_in_flash, sizeof(uint32_t));
|
||||
bootloader_munmap(efuse_place_in_flash);
|
||||
secure_version = ~secure_version;
|
||||
ESP_LOGV(TAG, "Read 0x%08x secure_version from flash", secure_version);
|
||||
return secure_version;
|
||||
}
|
||||
|
||||
static void emulate_secure_version_write(uint32_t secure_version)
|
||||
{
|
||||
uint32_t secure_version_wr = ~secure_version;
|
||||
uint32_t offset = esp_efuse_flash_offset;
|
||||
if (offset == 0) {
|
||||
ESP_LOGE(TAG, "emulate secure_version can not be used");
|
||||
return;
|
||||
}
|
||||
esp_err_t err = bootloader_flash_write(offset, &secure_version_wr, sizeof(secure_version_wr), false);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "secure_version can not be written to flash. err = 0x%x", err);
|
||||
}
|
||||
ESP_LOGV(TAG, "Write 0x%08x secure_version into flash", secure_version);
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
|
||||
|
||||
uint32_t esp_efuse_read_secure_version(void)
|
||||
{
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
uint32_t secure_version = 0;
|
||||
int size = esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION);
|
||||
size = MIN(CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD, size);
|
||||
#ifdef CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
|
||||
secure_version = emulate_secure_version_read();
|
||||
#else
|
||||
size_t size = MIN(APP_SEC_VER_SIZE_EFUSE_FIELD, esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION));
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_SECURE_VERSION, &secure_version, size);
|
||||
#endif // CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
|
||||
|
||||
return __builtin_popcount(secure_version & ((1ULL << size) - 1));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
static void write_anti_rollback(uint32_t new_bits)
|
||||
{
|
||||
int size = esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION);
|
||||
size = MIN(CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD, size);
|
||||
#ifdef CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
|
||||
emulate_secure_version_write(new_bits);
|
||||
#else
|
||||
esp_efuse_write_field_blob(ESP_EFUSE_SECURE_VERSION, &new_bits, size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
bool esp_efuse_check_secure_version(uint32_t secure_version)
|
||||
{
|
||||
uint32_t sec_ver_hw = esp_efuse_read_secure_version();
|
||||
@@ -120,18 +48,16 @@ bool esp_efuse_check_secure_version(uint32_t secure_version)
|
||||
|
||||
esp_err_t esp_efuse_update_secure_version(uint32_t secure_version)
|
||||
{
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
if (CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD < secure_version) {
|
||||
ESP_LOGE(TAG, "Max secure version is %d. Given %d version can not be written.", CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD, secure_version);
|
||||
size_t size = MIN(APP_SEC_VER_SIZE_EFUSE_FIELD, esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION));
|
||||
if (size < secure_version) {
|
||||
ESP_LOGE(TAG, "Max secure version is %d. Given %d version can not be written.", size, secure_version);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
#ifndef CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
|
||||
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(ESP_EFUSE_SECURE_VERSION_NUM_BLOCK);
|
||||
if (coding_scheme != EFUSE_CODING_SCHEME_NONE) {
|
||||
ESP_LOGE(TAG, "Anti rollback is not supported with any coding scheme.");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
uint32_t sec_ver_hw = esp_efuse_read_secure_version();
|
||||
// If secure_version is the same as in eFuse field than it is ok just go out.
|
||||
if (sec_ver_hw < secure_version) {
|
||||
@@ -139,12 +65,11 @@ esp_err_t esp_efuse_update_secure_version(uint32_t secure_version)
|
||||
uint32_t num_bit_app = (1ULL << secure_version) - 1;
|
||||
// Repeated programming of programmed bits is strictly forbidden
|
||||
uint32_t new_bits = num_bit_app - num_bit_hw; // get only new bits
|
||||
write_anti_rollback(new_bits);
|
||||
esp_efuse_write_field_blob(ESP_EFUSE_SECURE_VERSION, &new_bits, size);
|
||||
ESP_LOGI(TAG, "Anti-rollback is set. eFuse field is updated(%d).", secure_version);
|
||||
} else if (sec_ver_hw > secure_version) {
|
||||
ESP_LOGE(TAG, "Anti-rollback is not set. secure_version of app is lower that eFuse field(%d).", sec_ver_hw);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,14 @@ static const char *TAG = "efuse";
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
/* Call the update function to seed virtual efuses during initialization */
|
||||
__attribute__((constructor)) void esp_efuse_utility_update_virt_blocks(void);
|
||||
#endif
|
||||
#endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
#endif // NOT BOOTLOADER_BUILD
|
||||
|
||||
#endif // CONFIG_EFUSE_VIRTUAL
|
||||
|
||||
extern const esp_efuse_range_addr_t range_read_addr_blocks[];
|
||||
extern const esp_efuse_range_addr_t range_write_addr_blocks[];
|
||||
@@ -149,20 +154,32 @@ void esp_efuse_utility_erase_virt_blocks(void)
|
||||
{
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
memset(virt_blocks, 0, sizeof(virt_blocks));
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
esp_efuse_utility_write_efuses_to_flash();
|
||||
#endif
|
||||
#endif // CONFIG_EFUSE_VIRTUAL
|
||||
}
|
||||
|
||||
// Fills the virt_blocks array by values from efuse_Rdata.
|
||||
void esp_efuse_utility_update_virt_blocks(void)
|
||||
{
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
ESP_EARLY_LOGI(TAG, "Loading virtual efuse blocks from real efuses");
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
int subblock = 0;
|
||||
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4) {
|
||||
virt_blocks[num_block][subblock++] = REG_READ(addr_rd_block);
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
if (!esp_efuse_utility_load_efuses_from_flash()) {
|
||||
#else
|
||||
if (1) {
|
||||
#endif
|
||||
ESP_EARLY_LOGW(TAG, "Loading virtual efuse blocks from real efuses");
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
int subblock = 0;
|
||||
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4) {
|
||||
virt_blocks[num_block][subblock++] = REG_READ(addr_rd_block);
|
||||
}
|
||||
ESP_EARLY_LOGD(TAG, "virt_blocks[%d] is filled by EFUSE_BLOCK%d", num_block, num_block);
|
||||
}
|
||||
ESP_EARLY_LOGD(TAG, "virt_blocks[%d] is filled by EFUSE_BLOCK%d", num_block, num_block);
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
esp_efuse_utility_write_efuses_to_flash();
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
ESP_EARLY_LOGI(TAG, "Emulate efuse is disabled");
|
||||
@@ -170,31 +187,29 @@ void esp_efuse_utility_update_virt_blocks(void)
|
||||
}
|
||||
|
||||
// Prints efuse values for all registers.
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
void esp_efuse_utility_debug_dump_blocks(void)
|
||||
{
|
||||
printf("EFUSE_BLKx:\n");
|
||||
esp_rom_printf("EFUSE_BLKx:\n");
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
int num_reg = 0;
|
||||
printf("%d) ", num_block);
|
||||
esp_rom_printf("%d) ", num_block);
|
||||
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4, num_reg++) {
|
||||
printf("0x%08x ", virt_blocks[num_block][num_reg]);
|
||||
esp_rom_printf("0x%08x ", virt_blocks[num_block][num_reg]);
|
||||
}
|
||||
printf("\n");
|
||||
esp_rom_printf("\n");
|
||||
}
|
||||
#else
|
||||
for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
|
||||
printf("%d) ", num_block);
|
||||
esp_rom_printf("%d) ", num_block);
|
||||
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4) {
|
||||
printf("0x%08x ", REG_READ(addr_rd_block));
|
||||
esp_rom_printf("0x%08x ", REG_READ(addr_rd_block));
|
||||
}
|
||||
printf("\n");
|
||||
esp_rom_printf("\n");
|
||||
}
|
||||
#endif
|
||||
printf("\n");
|
||||
esp_rom_printf("\n");
|
||||
}
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
// returns the number of array elements for placing these bits in an array with the length of each element equal to size_of_base.
|
||||
int esp_efuse_utility_get_number_of_items(int bits, int size_of_base)
|
||||
@@ -345,3 +360,94 @@ static bool check_range_of_bits(esp_efuse_block_t blk, int offset_in_bits, int s
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t esp_efuse_utility_get_read_register_address(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block < EFUSE_BLK_MAX);
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
return (uint32_t)&virt_blocks[block][0];
|
||||
#else
|
||||
return range_read_addr_blocks[block].start;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if defined(BOOTLOADER_BUILD) && defined(CONFIG_EFUSE_VIRTUAL) && !defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH)
|
||||
void esp_efuse_init_virtual_mode_in_ram(void)
|
||||
{
|
||||
esp_efuse_utility_update_virt_blocks();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
|
||||
#include "../include_bootloader/bootloader_flash_priv.h"
|
||||
|
||||
static uint32_t esp_efuse_flash_offset = 0;
|
||||
static uint32_t esp_efuse_flash_size = 0;
|
||||
|
||||
void esp_efuse_init_virtual_mode_in_flash(uint32_t offset, uint32_t size)
|
||||
{
|
||||
esp_efuse_flash_offset = offset;
|
||||
esp_efuse_flash_size = size;
|
||||
esp_efuse_utility_update_virt_blocks();
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
}
|
||||
|
||||
void esp_efuse_utility_erase_efuses_in_flash(void)
|
||||
{
|
||||
if (esp_efuse_flash_offset == 0) {
|
||||
ESP_EARLY_LOGE(TAG, "no efuse partition in partition_table? (Flash is not updated)");
|
||||
abort();
|
||||
}
|
||||
esp_err_t err = bootloader_flash_erase_range(esp_efuse_flash_offset, esp_efuse_flash_size);
|
||||
if (err != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to erase flash. err = 0x%x", err);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
bool esp_efuse_utility_load_efuses_from_flash(void)
|
||||
{
|
||||
if (esp_efuse_flash_offset == 0) {
|
||||
ESP_EARLY_LOGE(TAG, "no efuse partition in partition_table? (Flash is not updated)");
|
||||
abort();
|
||||
}
|
||||
uint32_t efuses_in_flash[sizeof(virt_blocks)];
|
||||
|
||||
esp_err_t err = bootloader_flash_read(esp_efuse_flash_offset, &efuses_in_flash, sizeof(efuses_in_flash), true);
|
||||
if (err != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Can not read eFuse partition from flash (err=0x%x)", err);
|
||||
abort();
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sizeof(virt_blocks); ++i) {
|
||||
if (efuses_in_flash[i] != 0xFFFFFFFF) {
|
||||
ESP_EARLY_LOGW(TAG, "Loading virtual efuse blocks from flash");
|
||||
memcpy(virt_blocks, efuses_in_flash, sizeof(virt_blocks));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void esp_efuse_utility_write_efuses_to_flash(void)
|
||||
{
|
||||
if (esp_efuse_flash_offset == 0) {
|
||||
ESP_EARLY_LOGE(TAG, "no efuse partition in partition_table? (Flash is not updated)");
|
||||
abort();
|
||||
}
|
||||
|
||||
esp_err_t err = bootloader_flash_erase_range(esp_efuse_flash_offset, esp_efuse_flash_size);
|
||||
if (err != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to erase flash. err = 0x%x", err);
|
||||
abort();
|
||||
}
|
||||
|
||||
err = bootloader_flash_write(esp_efuse_flash_offset, &virt_blocks, sizeof(virt_blocks), false);
|
||||
if (err != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "secure_version can not be written to flash. err = 0x%x", err);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
|
||||
Reference in New Issue
Block a user