mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
secure_boot: Checks secure boot efuses
ESP32 V1 and V2 - protection bits. ESP32xx V2: revoke bits, protection bits - refactor efuse component - adds some APIs for esp32 chips as well as for esp32xx chips
This commit is contained in:
parent
b92c290e56
commit
90f2d3199a
@ -692,6 +692,16 @@ menu "Security features"
|
||||
key digest, causing an immediate denial of service and possibly allowing an additional fault
|
||||
injection attack to bypass the signature protection.
|
||||
|
||||
config SECURE_BOOT_ALLOW_UNUSED_DIGEST_SLOTS
|
||||
bool "Leave unused digest slots available (not revoke)"
|
||||
depends on SECURE_BOOT_INSECURE && !IDF_TARGET_ESP32
|
||||
default N
|
||||
help
|
||||
If not set (default), during startup in the app all unused digest slots will be revoked.
|
||||
To revoke unused slot will be called esp_efuse_set_digest_revoke(num_digest) for each digest.
|
||||
Revoking unused digest slots makes ensures that no trusted keys can be added later by an attacker.
|
||||
If set, it means that you have a plan to use unused digests slots later.
|
||||
|
||||
config SECURE_INSECURE_ALLOW_DL_MODE
|
||||
bool "Don't automatically restrict UART download mode"
|
||||
depends on SECURE_BOOT_INSECURE && SECURE_BOOT_V2_ENABLED
|
||||
|
@ -9,6 +9,7 @@ set(srcs
|
||||
"src/bootloader_utility.c"
|
||||
"src/esp_image_format.c"
|
||||
"src/flash_encrypt.c"
|
||||
"src/secure_boot.c"
|
||||
"src/flash_partitions.c"
|
||||
"src/flash_qio_mode.c"
|
||||
"src/bootloader_flash_config_${IDF_TARGET}.c"
|
||||
|
@ -214,6 +214,17 @@ typedef struct {
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
169
components/bootloader_support/src/secure_boot.c
Normal file
169
components/bootloader_support/src/secure_boot.c
Normal file
@ -0,0 +1,169 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// 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_secure_boot.h"
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
static __attribute__((unused)) const char *TAG = "secure_boot";
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT
|
||||
static void efuse_batch_write_begin(bool *need_fix)
|
||||
{
|
||||
if (*need_fix == false) {
|
||||
esp_efuse_batch_write_begin();
|
||||
}
|
||||
*need_fix = true;
|
||||
}
|
||||
|
||||
static void update_efuses(bool need_fix, esp_err_t err)
|
||||
{
|
||||
if (need_fix) {
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Can not be fixed (err=0x%x).", err);
|
||||
esp_efuse_batch_write_cancel();
|
||||
} else {
|
||||
err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming eFuses (err=0x%x)", err);
|
||||
return;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Fixed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_SECURE_BOOT_V1_ENABLED
|
||||
static esp_err_t secure_boot_v1_check(bool *need_fix)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_efuse_block_t block = EFUSE_BLK_SECURE_BOOT;
|
||||
if (!esp_efuse_get_key_dis_read(block)) {
|
||||
efuse_batch_write_begin(need_fix);
|
||||
ESP_LOGW(TAG, "eFuse BLOCK%d should not be readable. Fixing..", block);
|
||||
err = esp_efuse_set_key_dis_read(block);
|
||||
}
|
||||
if (!esp_efuse_get_key_dis_write(block)) {
|
||||
efuse_batch_write_begin(need_fix);
|
||||
ESP_LOGW(TAG, "eFuse BLOCK%d should not be writeable. Fixing..", block);
|
||||
if (err == ESP_OK) {
|
||||
err = esp_efuse_set_key_dis_write(block);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#elif SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS == 1 && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
static esp_err_t secure_boot_v2_check(bool *need_fix)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_efuse_block_t block = EFUSE_BLK_SECURE_BOOT;
|
||||
if (esp_efuse_get_key_dis_read(block)) {
|
||||
ESP_LOGE(TAG, "eFuse BLOCK%d should be readable", block);
|
||||
abort();
|
||||
// This code is not achievable because the bootloader will not boot an app in this state.
|
||||
// But we keep it here just in case (any unexpected behavior).
|
||||
}
|
||||
if (esp_efuse_block_is_empty(block)) {
|
||||
ESP_LOGE(TAG, "eFuse BLOCK%d should not be empty", block);
|
||||
abort();
|
||||
// This code is not achievable because the bootloader will not boot an app in this state.
|
||||
// But we keep it here just in case (any unexpected behavior).
|
||||
}
|
||||
if (!esp_efuse_get_key_dis_write(block)) {
|
||||
efuse_batch_write_begin(need_fix);
|
||||
ESP_LOGW(TAG, "eFuse BLOCK%d should not be writeable. Fixing..", block);
|
||||
err = esp_efuse_set_key_dis_write(block);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#elif SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
static esp_err_t secure_boot_v2_check(bool *need_fix)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_efuse_purpose_t purpose[SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS] = {
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS; ++i) {
|
||||
esp_efuse_block_t block;
|
||||
if (esp_efuse_find_purpose(purpose[i], &block)) {
|
||||
if (!esp_efuse_get_digest_revoke(i)) {
|
||||
if (esp_efuse_get_key_dis_read(block)) {
|
||||
ESP_LOGE(TAG, "eFuse BLOCK%d should be readable", block);
|
||||
abort();
|
||||
// This state is not expected unless the eFuses have been manually misconfigured.
|
||||
}
|
||||
if (esp_efuse_block_is_empty(block)) {
|
||||
ESP_LOGE(TAG, "eFuse BLOCK%d should not be empty", block);
|
||||
abort();
|
||||
// This state is not expected unless the eFuses have been manually misconfigured.
|
||||
}
|
||||
if (!esp_efuse_get_key_dis_write(block)) {
|
||||
efuse_batch_write_begin(need_fix);
|
||||
ESP_LOGW(TAG, "eFuse BLOCK%d should not be writeable. Fixing..", block);
|
||||
if (err == ESP_OK) {
|
||||
err = esp_efuse_set_key_dis_write(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!esp_efuse_get_keypurpose_dis_write(block)) {
|
||||
efuse_batch_write_begin(need_fix);
|
||||
ESP_LOGW(TAG, "The KEY_PURPOSE_SECURE_BOOT_DIGEST%d should be write-protected. Fixing..", block);
|
||||
if (err == ESP_OK) {
|
||||
err = esp_efuse_set_keypurpose_dis_write(block);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!esp_efuse_get_digest_revoke(i)) {
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_UNUSED_DIGEST_SLOTS
|
||||
efuse_batch_write_begin(need_fix);
|
||||
ESP_LOGW(TAG, "Unused SECURE_BOOT_DIGEST%d should be revoked. Fixing..", i);
|
||||
if (err == ESP_OK) {
|
||||
err = esp_efuse_set_digest_revoke(i);
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Unused SECURE_BOOT_DIGEST%d should be revoked. It will not be fixed due to the config", i);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
#endif // CONFIG_SECURE_BOOT
|
||||
|
||||
void esp_secure_boot_init_checks(void)
|
||||
{
|
||||
#ifdef CONFIG_SECURE_BOOT
|
||||
|
||||
if (esp_secure_boot_enabled()) {
|
||||
bool need_fix = false;
|
||||
#ifdef CONFIG_SECURE_BOOT_V1_ENABLED
|
||||
esp_err_t err = secure_boot_v1_check(&need_fix);
|
||||
#else
|
||||
esp_err_t err = secure_boot_v2_check(&need_fix);
|
||||
#endif
|
||||
update_efuses(need_fix, err);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Mismatch in secure boot settings: the app config is enabled but eFuse not");
|
||||
}
|
||||
#endif // CONFIG_SECURE_BOOT
|
||||
}
|
||||
#endif // not BOOTLOADER_BUILD
|
@ -31,7 +31,7 @@
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_hal.h"
|
||||
#include "hal/dma_types.h"
|
||||
#include "esp32c3/esp_efuse_rtc_calib.h"
|
||||
#include "esp_efuse_rtc_calib.h"
|
||||
#include "esp_private/gdma.h"
|
||||
|
||||
#define ADC_CHECK_RET(fun_ret) ({ \
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "driver/rtc_cntl.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/adc.h"
|
||||
#include "esp32s2/esp_efuse_rtc_table.h"
|
||||
#include "esp_efuse_rtc_table.h"
|
||||
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_hal.h"
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "driver/temp_sensor.h"
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp32s2/esp_efuse_rtc_table.h"
|
||||
#include "esp_efuse_rtc_table.h"
|
||||
|
||||
static const char *TAG = "tsens";
|
||||
|
||||
|
@ -4,26 +4,23 @@ if(EXISTS "${COMPONENT_DIR}/${target}")
|
||||
include(${COMPONENT_DIR}/${target}/sources.cmake)
|
||||
spaces2list(EFUSE_SOC_SRCS)
|
||||
set(include_dirs include ${target}/include)
|
||||
set(private_include private_include ${target}/private_include)
|
||||
add_prefix(srcs "${target}/" ${EFUSE_SOC_SRCS})
|
||||
list(APPEND srcs "src/${target}/esp_efuse_api.c"
|
||||
"src/${target}/esp_efuse_fields.c"
|
||||
"src/${target}/esp_efuse_utility.c")
|
||||
if("esp32s2" STREQUAL "${target}")
|
||||
list(APPEND srcs "src/${target}/esp_efuse_rtc_table.c")
|
||||
endif()
|
||||
if("esp32c3" STREQUAL "${target}")
|
||||
list(APPEND srcs "src/${target}/esp_efuse_rtc_calib.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND srcs "src/esp_efuse_api.c"
|
||||
"src/esp_efuse_fields.c"
|
||||
"src/esp_efuse_utility.c")
|
||||
if("esp32" STREQUAL "${target}")
|
||||
list(APPEND srcs "src/esp_efuse_api_key_esp32.c")
|
||||
else()
|
||||
list(APPEND srcs "src/esp_efuse_api_key_esp32xx.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
PRIV_REQUIRES bootloader_support soc spi_flash
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_INCLUDE_DIRS private_include)
|
||||
PRIV_INCLUDE_DIRS "${private_include}")
|
||||
|
||||
if(target)
|
||||
set(TOOL_TARGET -t ${target})
|
||||
|
@ -3,8 +3,12 @@
|
||||
# currently the only SoC supported; to be moved into Kconfig
|
||||
TARGET := $(IDF_TARGET)
|
||||
|
||||
COMPONENT_SRCDIRS := $(TARGET) src src/$(TARGET)
|
||||
COMPONENT_PRIV_INCLUDEDIRS := private_include
|
||||
COMPONENT_ADD_INCLUDEDIRS := $(TARGET)/include include
|
||||
COMPONENT_SRCDIRS := $(TARGET) src
|
||||
ifdef CONFIG_IDF_TARGET_ESP32
|
||||
COMPONENT_OBJEXCLUDE := src/esp_efuse_api_key_esp32xx.o
|
||||
else
|
||||
COMPONENT_OBJEXCLUDE := src/esp_efuse_api_key_esp32.o
|
||||
endif
|
||||
|
||||
-include $(COMPONENT_PATH)/$(TARGET)/component.mk
|
||||
COMPONENT_PRIV_INCLUDEDIRS := private_include $(TARGET)/private_include
|
||||
COMPONENT_ADD_INCLUDEDIRS := include $(TARGET)/include
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
54
components/efuse/esp32/include/esp_efuse.h
Normal file
54
components/efuse/esp32/include/esp_efuse.h
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Type of eFuse blocks for ESP32
|
||||
*/
|
||||
typedef enum {
|
||||
EFUSE_BLK0 = 0, /**< Number of eFuse block. Reserved. */
|
||||
|
||||
EFUSE_BLK1 = 1, /**< Number of eFuse block. Used for Flash Encryption. If not using that Flash Encryption feature, they can be used for another purpose. */
|
||||
EFUSE_BLK_KEY0 = 1, /**< Number of eFuse block. Used for Flash Encryption. If not using that Flash Encryption feature, they can be used for another purpose. */
|
||||
EFUSE_BLK_ENCRYPT_FLASH = 1, /**< Number of eFuse block. Used for Flash Encryption. If not using that Flash Encryption feature, they can be used for another purpose. */
|
||||
|
||||
EFUSE_BLK2 = 2, /**< Number of eFuse block. Used for Secure Boot. If not using that Secure Boot feature, they can be used for another purpose. */
|
||||
EFUSE_BLK_KEY1 = 2, /**< Number of eFuse block. Used for Secure Boot. If not using that Secure Boot feature, they can be used for another purpose. */
|
||||
EFUSE_BLK_SECURE_BOOT = 2, /**< Number of eFuse block. Used for Secure Boot. If not using that Secure Boot feature, they can be used for another purpose. */
|
||||
|
||||
EFUSE_BLK3 = 3, /**< Number of eFuse block. Uses for the purpose of the user. */
|
||||
EFUSE_BLK_KEY2 = 3, /**< Number of eFuse block. Uses for the purpose of the user. */
|
||||
EFUSE_BLK_KEY_MAX = 4,
|
||||
|
||||
EFUSE_BLK_MAX = 4,
|
||||
} esp_efuse_block_t;
|
||||
|
||||
/**
|
||||
* @brief Type of coding scheme
|
||||
*/
|
||||
typedef enum {
|
||||
EFUSE_CODING_SCHEME_NONE = 0, /**< None */
|
||||
EFUSE_CODING_SCHEME_3_4 = 1, /**< 3/4 coding */
|
||||
EFUSE_CODING_SCHEME_REPEAT = 2, /**< Repeat coding */
|
||||
} esp_efuse_coding_scheme_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -1 +1,3 @@
|
||||
set(EFUSE_SOC_SRCS "esp_efuse_table.c")
|
||||
set(EFUSE_SOC_SRCS "esp_efuse_table.c"
|
||||
"esp_efuse_fields.c"
|
||||
"esp_efuse_utility.c")
|
||||
|
@ -1 +1,4 @@
|
||||
set(EFUSE_SOC_SRCS "esp_efuse_table.c")
|
||||
set(EFUSE_SOC_SRCS "esp_efuse_table.c"
|
||||
"esp_efuse_fields.c"
|
||||
"esp_efuse_rtc_calib.c"
|
||||
"esp_efuse_utility.c")
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp32s2/esp_efuse_rtc_table.h"
|
||||
#include "esp_efuse_rtc_table.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_log.h"
|
@ -1 +1,4 @@
|
||||
set(EFUSE_SOC_SRCS "esp_efuse_table.c")
|
||||
set(EFUSE_SOC_SRCS "esp_efuse_table.c"
|
||||
"esp_efuse_fields.c"
|
||||
"esp_efuse_rtc_table.c"
|
||||
"esp_efuse_utility.c")
|
||||
|
@ -1 +1,3 @@
|
||||
set(EFUSE_SOC_SRCS "esp_efuse_table.c")
|
||||
set(EFUSE_SOC_SRCS "esp_efuse_table.c"
|
||||
"esp_efuse_fields.c"
|
||||
"esp_efuse_utility.c")
|
||||
|
@ -1,44 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Type of eFuse blocks for ESP32
|
||||
*/
|
||||
typedef enum {
|
||||
EFUSE_BLK0 = 0, /**< Number of eFuse block. Reserved. */
|
||||
EFUSE_BLK1 = 1, /**< Number of eFuse block. Used for Flash Encryption. If not using that Flash Encryption feature, they can be used for another purpose. */
|
||||
EFUSE_BLK2 = 2, /**< Number of eFuse block. Used for Secure Boot. If not using that Secure Boot feature, they can be used for another purpose. */
|
||||
EFUSE_BLK3 = 3, /**< Number of eFuse block. Uses for the purpose of the user. */
|
||||
EFUSE_BLK_MAX
|
||||
} esp_efuse_block_t;
|
||||
|
||||
/**
|
||||
* @brief Type of coding scheme
|
||||
*/
|
||||
typedef enum {
|
||||
EFUSE_CODING_SCHEME_NONE = 0, /**< None */
|
||||
EFUSE_CODING_SCHEME_3_4 = 1, /**< 3/4 coding */
|
||||
EFUSE_CODING_SCHEME_REPEAT = 2, /**< Repeat coding */
|
||||
} esp_efuse_coding_scheme_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -23,15 +23,7 @@ extern "C" {
|
||||
#include "esp_log.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/esp_efuse.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/esp_efuse.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/esp_efuse.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/esp_efuse.h"
|
||||
#endif
|
||||
#include_next "esp_efuse.h"
|
||||
|
||||
#define ESP_ERR_EFUSE 0x1600 /*!< Base error code for efuse api. */
|
||||
#define ESP_OK_EFUSE_CNT (ESP_ERR_EFUSE + 0x01) /*!< OK the required number of bits is set. */
|
||||
@ -496,48 +488,14 @@ esp_err_t esp_efuse_batch_write_cancel(void);
|
||||
*/
|
||||
esp_err_t esp_efuse_batch_write_commit(void);
|
||||
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
/**
|
||||
* @brief Type of key purpose
|
||||
* @brief Checks that the given block is empty.
|
||||
*
|
||||
* @return
|
||||
* - True: The block is empty.
|
||||
* - False: The block is not empty or was an error.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_EFUSE_KEY_PURPOSE_USER = 0,
|
||||
ESP_EFUSE_KEY_PURPOSE_RESERVED = 1,
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 = 2,
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 = 3,
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY = 4,
|
||||
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL = 5,
|
||||
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG = 6,
|
||||
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE = 7,
|
||||
ESP_EFUSE_KEY_PURPOSE_HMAC_UP = 8,
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0 = 9,
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1 = 10,
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2 = 11,
|
||||
ESP_EFUSE_KEY_PURPOSE_MAX,
|
||||
} esp_efuse_purpose_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to a key purpose for an efuse key block.
|
||||
*
|
||||
* @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
|
||||
*
|
||||
* To get the value of this field use esp_efuse_read_field_blob() or esp_efuse_get_key_purpose().
|
||||
*
|
||||
* @return Pointer: If Successful returns a pointer to the corresponding efuse field otherwise NULL.
|
||||
*/
|
||||
const esp_efuse_desc_t **esp_efuse_get_purpose_field(esp_efuse_block_t block);
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to a key block.
|
||||
*
|
||||
* @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
|
||||
*
|
||||
* @return Pointer: If Successful returns a pointer to the corresponding efuse field otherwise NULL.
|
||||
*/
|
||||
const esp_efuse_desc_t** esp_efuse_get_key(esp_efuse_block_t block);
|
||||
bool esp_efuse_block_is_empty(esp_efuse_block_t block);
|
||||
|
||||
/**
|
||||
* @brief Returns a read protection for the key block.
|
||||
@ -585,6 +543,62 @@ bool esp_efuse_get_key_dis_write(esp_efuse_block_t block);
|
||||
*/
|
||||
esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block);
|
||||
|
||||
/**
|
||||
* @brief Returns true if the key block is unused, false otherwise.
|
||||
*
|
||||
* An unused key block is all zero content, not read or write protected,
|
||||
* and has purpose 0 (ESP_EFUSE_KEY_PURPOSE_USER)
|
||||
*
|
||||
* @param block key block to check.
|
||||
*
|
||||
* @return
|
||||
* - True if key block is unused,
|
||||
* - False if key block is used or the specified block index is not a key block.
|
||||
*/
|
||||
bool esp_efuse_key_block_unused(esp_efuse_block_t block);
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
/**
|
||||
* @brief Type of key purpose
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_EFUSE_KEY_PURPOSE_USER = 0,
|
||||
ESP_EFUSE_KEY_PURPOSE_RESERVED = 1,
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 = 2,
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 = 3,
|
||||
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY = 4,
|
||||
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL = 5,
|
||||
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG = 6,
|
||||
ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE = 7,
|
||||
ESP_EFUSE_KEY_PURPOSE_HMAC_UP = 8,
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0 = 9,
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1 = 10,
|
||||
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2 = 11,
|
||||
ESP_EFUSE_KEY_PURPOSE_MAX,
|
||||
} esp_efuse_purpose_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to a key purpose for an efuse key block.
|
||||
*
|
||||
* @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
|
||||
*
|
||||
* To get the value of this field use esp_efuse_read_field_blob() or esp_efuse_get_key_purpose().
|
||||
*
|
||||
* @return Pointer: If Successful returns a pointer to the corresponding efuse field otherwise NULL.
|
||||
*/
|
||||
const esp_efuse_desc_t **esp_efuse_get_purpose_field(esp_efuse_block_t block);
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to a key block.
|
||||
*
|
||||
* @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
|
||||
*
|
||||
* @return Pointer: If Successful returns a pointer to the corresponding efuse field otherwise NULL.
|
||||
*/
|
||||
const esp_efuse_desc_t** esp_efuse_get_key(esp_efuse_block_t block);
|
||||
|
||||
/**
|
||||
* @brief Returns the current purpose set for an efuse key block.
|
||||
*
|
||||
@ -660,20 +674,6 @@ esp_efuse_block_t esp_efuse_find_unused_key_block(void);
|
||||
*/
|
||||
unsigned esp_efuse_count_unused_key_blocks(void);
|
||||
|
||||
/**
|
||||
* @brief Returns true if the key block is unused, false otherwise.
|
||||
*
|
||||
* An unused key block is all zero content, not read or write protected,
|
||||
* and has purpose 0 (ESP_EFUSE_KEY_PURPOSE_USER)
|
||||
*
|
||||
* @param block key block to check.
|
||||
*
|
||||
* @return
|
||||
* - True if key block is unused,
|
||||
* - False if key block is used or the specified block index is not a key block.
|
||||
*/
|
||||
bool esp_efuse_key_block_unused(esp_efuse_block_t block);
|
||||
|
||||
/**
|
||||
* @brief Returns the status of the Secure Boot public key digest revocation bit.
|
||||
*
|
||||
|
@ -23,15 +23,7 @@ extern "C" {
|
||||
#include "esp_err.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/esp_efuse_utility.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/esp_efuse_utility.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/esp_efuse_utility.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/esp_efuse_utility.h"
|
||||
#endif
|
||||
#include_next "esp_efuse_utility.h"
|
||||
|
||||
/**
|
||||
* @brief Structure range address by blocks
|
||||
|
@ -1,69 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_utility.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "assert.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
const static char *TAG = "efuse";
|
||||
|
||||
// Sets a write protection for the whole block.
|
||||
esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK1) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK1, 1);
|
||||
} else if (blk == EFUSE_BLK2) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK2, 1);
|
||||
} else if (blk == EFUSE_BLK3) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK3, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// read protect for blk.
|
||||
esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK1) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_BLK1, 1);
|
||||
} else if (blk == EFUSE_BLK2) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_BLK2, 1);
|
||||
} else if (blk == EFUSE_BLK3) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_BLK3, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// get efuse coding_scheme.
|
||||
esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)
|
||||
{
|
||||
esp_efuse_coding_scheme_t scheme;
|
||||
if (blk == EFUSE_BLK0) {
|
||||
scheme = EFUSE_CODING_SCHEME_NONE;
|
||||
} else {
|
||||
uint32_t coding_scheme = REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_CODING_SCHEME);
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_VAL_NONE ||
|
||||
coding_scheme == (EFUSE_CODING_SCHEME_VAL_34 | EFUSE_CODING_SCHEME_VAL_REPEAT)) {
|
||||
scheme = EFUSE_CODING_SCHEME_NONE;
|
||||
} else if (coding_scheme == EFUSE_CODING_SCHEME_VAL_34) {
|
||||
scheme = EFUSE_CODING_SCHEME_3_4;
|
||||
} else {
|
||||
scheme = EFUSE_CODING_SCHEME_REPEAT;
|
||||
}
|
||||
}
|
||||
ESP_EARLY_LOGD(TAG, "coding scheme %d", scheme);
|
||||
return scheme;
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_utility.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "assert.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
const static char *TAG = "efuse";
|
||||
|
||||
// Sets a write protection for the whole block.
|
||||
esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK1) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK1, 1);
|
||||
} else if (blk == EFUSE_BLK2) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_SYS_DATA_PART1, 1);
|
||||
} else if (blk == EFUSE_BLK3) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_USER_DATA, 1);
|
||||
} else if (blk == EFUSE_BLK4) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY0, 1);
|
||||
} else if (blk == EFUSE_BLK5) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY1, 1);
|
||||
} else if (blk == EFUSE_BLK6) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY2, 1);
|
||||
} else if (blk == EFUSE_BLK7) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY3, 1);
|
||||
} else if (blk == EFUSE_BLK8) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY4, 1);
|
||||
} else if (blk == EFUSE_BLK9) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY5, 1);
|
||||
} else if (blk == EFUSE_BLK10) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_SYS_DATA_PART2, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// read protect for blk.
|
||||
esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK4) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY0, 1);
|
||||
} else if (blk == EFUSE_BLK5) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY1, 1);
|
||||
} else if (blk == EFUSE_BLK6) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY2, 1);
|
||||
} else if (blk == EFUSE_BLK7) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY3, 1);
|
||||
} else if (blk == EFUSE_BLK8) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY4, 1);
|
||||
} else if (blk == EFUSE_BLK9) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY5, 1);
|
||||
} else if (blk == EFUSE_BLK10) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_SYS_DATA_PART2, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// get efuse coding_scheme.
|
||||
esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)
|
||||
{
|
||||
esp_efuse_coding_scheme_t scheme;
|
||||
if (blk == EFUSE_BLK0) {
|
||||
scheme = EFUSE_CODING_SCHEME_NONE;
|
||||
} else {
|
||||
scheme = EFUSE_CODING_SCHEME_RS;
|
||||
}
|
||||
ESP_LOGD(TAG, "coding scheme %d", scheme);
|
||||
return scheme;
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_utility.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "assert.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
const static char *TAG = "efuse";
|
||||
|
||||
// Sets a write protection for the whole block.
|
||||
esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK1) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK1, 1);
|
||||
} else if (blk == EFUSE_BLK2) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_SYS_DATA_PART1, 1);
|
||||
} else if (blk == EFUSE_BLK3) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_USER_DATA, 1);
|
||||
} else if (blk == EFUSE_BLK4) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY0, 1);
|
||||
} else if (blk == EFUSE_BLK5) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY1, 1);
|
||||
} else if (blk == EFUSE_BLK6) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY2, 1);
|
||||
} else if (blk == EFUSE_BLK7) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY3, 1);
|
||||
} else if (blk == EFUSE_BLK8) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY4, 1);
|
||||
} else if (blk == EFUSE_BLK9) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY5, 1);
|
||||
} else if (blk == EFUSE_BLK10) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_SYS_DATA_PART2, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// read protect for blk.
|
||||
esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK4) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY0, 1);
|
||||
} else if (blk == EFUSE_BLK5) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY1, 1);
|
||||
} else if (blk == EFUSE_BLK6) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY2, 1);
|
||||
} else if (blk == EFUSE_BLK7) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY3, 1);
|
||||
} else if (blk == EFUSE_BLK8) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY4, 1);
|
||||
} else if (blk == EFUSE_BLK9) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY5, 1);
|
||||
} else if (blk == EFUSE_BLK10) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_SYS_DATA_PART2, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// get efuse coding_scheme.
|
||||
esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)
|
||||
{
|
||||
esp_efuse_coding_scheme_t scheme;
|
||||
if (blk == EFUSE_BLK0) {
|
||||
scheme = EFUSE_CODING_SCHEME_NONE;
|
||||
} else {
|
||||
scheme = EFUSE_CODING_SCHEME_RS;
|
||||
}
|
||||
ESP_EARLY_LOGD(TAG, "coding scheme %d", scheme);
|
||||
return scheme;
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_utility.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "assert.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
const static char *TAG = "efuse";
|
||||
|
||||
// Sets a write protection for the whole block.
|
||||
esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK1) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK1, 1);
|
||||
} else if (blk == EFUSE_BLK2) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_SYS_DATA_PART1, 1);
|
||||
} else if (blk == EFUSE_BLK3) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_USER_DATA, 1);
|
||||
} else if (blk == EFUSE_BLK4) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY0, 1);
|
||||
} else if (blk == EFUSE_BLK5) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY1, 1);
|
||||
} else if (blk == EFUSE_BLK6) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY2, 1);
|
||||
} else if (blk == EFUSE_BLK7) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY3, 1);
|
||||
} else if (blk == EFUSE_BLK8) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY4, 1);
|
||||
} else if (blk == EFUSE_BLK9) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_KEY5, 1);
|
||||
} else if (blk == EFUSE_BLK10) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_SYS_DATA_PART2, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// read protect for blk.
|
||||
esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK4) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY0, 1);
|
||||
} else if (blk == EFUSE_BLK5) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY1, 1);
|
||||
} else if (blk == EFUSE_BLK6) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY2, 1);
|
||||
} else if (blk == EFUSE_BLK7) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY3, 1);
|
||||
} else if (blk == EFUSE_BLK8) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY4, 1);
|
||||
} else if (blk == EFUSE_BLK9) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_KEY5, 1);
|
||||
} else if (blk == EFUSE_BLK10) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_SYS_DATA_PART2, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// get efuse coding_scheme.
|
||||
esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)
|
||||
{
|
||||
esp_efuse_coding_scheme_t scheme;
|
||||
if (blk == EFUSE_BLK0) {
|
||||
scheme = EFUSE_CODING_SCHEME_NONE;
|
||||
} else {
|
||||
scheme = EFUSE_CODING_SCHEME_RS;
|
||||
}
|
||||
ESP_EARLY_LOGD(TAG, "coding scheme %d", scheme);
|
||||
return scheme;
|
||||
}
|
@ -282,307 +282,3 @@ esp_err_t esp_efuse_batch_write_commit(void)
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
/**
|
||||
* @brief Keys and their attributes are packed into a structure
|
||||
*/
|
||||
typedef struct {
|
||||
const esp_efuse_desc_t** key; /**< Key */
|
||||
const esp_efuse_desc_t** keypurpose; /**< Key purpose */
|
||||
const esp_efuse_desc_t** key_rd_dis; /**< Read protection of a key */
|
||||
const esp_efuse_desc_t** key_wr_dis; /**< Write protection of a key*/
|
||||
const esp_efuse_desc_t** keypurpose_wr_dis; /**< Write protection of a key purpose*/
|
||||
} esp_efuse_keys_t;
|
||||
|
||||
typedef struct {
|
||||
const esp_efuse_desc_t** revoke;
|
||||
const esp_efuse_desc_t** revoke_wr_dis;
|
||||
} esp_efuse_revokes_t;
|
||||
|
||||
const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
|
||||
{ESP_EFUSE_KEY0, ESP_EFUSE_KEY_PURPOSE_0, ESP_EFUSE_RD_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0_PURPOSE},
|
||||
{ESP_EFUSE_KEY1, ESP_EFUSE_KEY_PURPOSE_1, ESP_EFUSE_RD_DIS_KEY1, ESP_EFUSE_WR_DIS_KEY1, ESP_EFUSE_WR_DIS_KEY1_PURPOSE},
|
||||
{ESP_EFUSE_KEY2, ESP_EFUSE_KEY_PURPOSE_2, ESP_EFUSE_RD_DIS_KEY2, ESP_EFUSE_WR_DIS_KEY2, ESP_EFUSE_WR_DIS_KEY2_PURPOSE},
|
||||
{ESP_EFUSE_KEY3, ESP_EFUSE_KEY_PURPOSE_3, ESP_EFUSE_RD_DIS_KEY3, ESP_EFUSE_WR_DIS_KEY3, ESP_EFUSE_WR_DIS_KEY3_PURPOSE},
|
||||
{ESP_EFUSE_KEY4, ESP_EFUSE_KEY_PURPOSE_4, ESP_EFUSE_RD_DIS_KEY4, ESP_EFUSE_WR_DIS_KEY4, ESP_EFUSE_WR_DIS_KEY4_PURPOSE},
|
||||
{ESP_EFUSE_KEY5, ESP_EFUSE_KEY_PURPOSE_5, ESP_EFUSE_RD_DIS_KEY5, ESP_EFUSE_WR_DIS_KEY5, ESP_EFUSE_WR_DIS_KEY5_PURPOSE},
|
||||
#if 0
|
||||
{ESP_EFUSE_KEY6, ESP_EFUSE_KEY_PURPOSE_6, ESP_EFUSE_RD_DIS_KEY6, ESP_EFUSE_WR_DIS_KEY6, ESP_EFUSE_WR_DIS_KEY6_PURPOSE},
|
||||
#endif
|
||||
};
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
#define ESP_EFUSE_CHK(ret) \
|
||||
do \
|
||||
{ \
|
||||
if( ( err = (ret) ) != ESP_OK ) \
|
||||
goto err_exit; \
|
||||
} while( 0 )
|
||||
|
||||
|
||||
const esp_efuse_desc_t **esp_efuse_get_purpose_field(esp_efuse_block_t block)
|
||||
{
|
||||
switch(block) {
|
||||
case EFUSE_BLK_KEY0:
|
||||
return ESP_EFUSE_KEY_PURPOSE_0;
|
||||
case EFUSE_BLK_KEY1:
|
||||
return ESP_EFUSE_KEY_PURPOSE_1;
|
||||
case EFUSE_BLK_KEY2:
|
||||
return ESP_EFUSE_KEY_PURPOSE_2;
|
||||
case EFUSE_BLK_KEY3:
|
||||
return ESP_EFUSE_KEY_PURPOSE_3;
|
||||
case EFUSE_BLK_KEY4:
|
||||
return ESP_EFUSE_KEY_PURPOSE_4;
|
||||
case EFUSE_BLK_KEY5:
|
||||
return ESP_EFUSE_KEY_PURPOSE_5;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const esp_efuse_desc_t** esp_efuse_get_key(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return s_table[idx].key;
|
||||
}
|
||||
|
||||
bool esp_efuse_get_key_dis_read(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_read_field_bit(s_table[idx].key_rd_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
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);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_key_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_read_field_bit(s_table[idx].key_wr_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
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);
|
||||
}
|
||||
|
||||
esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return ESP_EFUSE_KEY_PURPOSE_MAX;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
uint8_t value = 0;
|
||||
esp_err_t err = esp_efuse_read_field_blob(s_table[idx].keypurpose, &value, s_table[idx].keypurpose[0]->bit_count);
|
||||
if (err != ESP_OK) {
|
||||
return ESP_EFUSE_KEY_PURPOSE_MAX;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t purpose)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_write_field_blob(s_table[idx].keypurpose, &purpose, s_table[idx].keypurpose[0]->bit_count);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_read_field_bit(s_table[idx].keypurpose_wr_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_keypurpose_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
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);
|
||||
}
|
||||
|
||||
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_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 EFUSE_BLK_KEY_MAX; // nothing
|
||||
}
|
||||
|
||||
unsigned esp_efuse_count_unused_key_blocks(void)
|
||||
{
|
||||
unsigned r = 0;
|
||||
for (esp_efuse_block_t b = EFUSE_BLK_KEY0; b < EFUSE_BLK_KEY_MAX; b++) {
|
||||
if (esp_efuse_key_block_unused(b)) {
|
||||
r++;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool esp_efuse_key_block_unused(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return false; // Not a key block
|
||||
}
|
||||
|
||||
if (esp_efuse_get_key_purpose(block) != ESP_EFUSE_KEY_PURPOSE_USER ||
|
||||
esp_efuse_get_keypurpose_dis_write(block) ||
|
||||
esp_efuse_get_key_dis_read(block) ||
|
||||
esp_efuse_get_key_dis_write(block)) {
|
||||
return false; // Block in use!
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (esp_efuse_read_reg(block, i) != 0) {
|
||||
return false; // Block in use!
|
||||
}
|
||||
}
|
||||
|
||||
return true; // Unused
|
||||
}
|
||||
|
||||
bool esp_efuse_get_digest_revoke(unsigned num_digest)
|
||||
{
|
||||
assert(num_digest < sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t));
|
||||
return esp_efuse_read_field_bit(s_revoke_table[num_digest].revoke);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_digest_revoke(unsigned num_digest)
|
||||
{
|
||||
if (num_digest >= sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return esp_efuse_write_field_bit(s_revoke_table[num_digest].revoke);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_write_protect_of_digest_revoke(unsigned num_digest)
|
||||
{
|
||||
assert(num_digest < sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t));
|
||||
return esp_efuse_read_field_bit(s_revoke_table[num_digest].revoke_wr_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest)
|
||||
{
|
||||
if (num_digest >= sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return esp_efuse_write_field_bit(s_revoke_table[num_digest].revoke_wr_dis);
|
||||
}
|
||||
|
||||
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) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_efuse_batch_write_begin();
|
||||
|
||||
if (!esp_efuse_key_block_unused(block)) {
|
||||
err = ESP_ERR_INVALID_STATE;
|
||||
} else {
|
||||
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 ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY ||
|
||||
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 ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_UP) {
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_dis_read(block));
|
||||
}
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_purpose(block, purpose));
|
||||
ESP_EFUSE_CHK(esp_efuse_set_keypurpose_dis_write(block));
|
||||
return esp_efuse_batch_write_commit();
|
||||
}
|
||||
err_exit:
|
||||
esp_efuse_batch_write_cancel();
|
||||
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 err = ESP_OK;
|
||||
if (number_of_keys == 0 || number_of_keys > (EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) || keys == NULL || purposes == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_efuse_purpose_t purpose = 0;
|
||||
esp_efuse_block_t block = EFUSE_BLK_KEY0;
|
||||
|
||||
esp_efuse_batch_write_begin();
|
||||
|
||||
unsigned unused_keys = esp_efuse_count_unused_key_blocks();
|
||||
if (number_of_keys > unused_keys) {
|
||||
ESP_LOGE(TAG, "Not enough unused key blocks available. Required %d, was %d", number_of_keys, unused_keys);
|
||||
err = ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS;
|
||||
} else {
|
||||
for (int i_key = 0; (block < EFUSE_BLK_KEY_MAX) && (i_key < number_of_keys); block++) {
|
||||
if (esp_efuse_key_block_unused(block)) {
|
||||
purpose = purposes[i_key];
|
||||
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], 32));
|
||||
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;
|
||||
}
|
||||
|
||||
#endif // not CONFIG_IDF_TARGET_ESP32
|
||||
|
148
components/efuse/src/esp_efuse_api_key_esp32.c
Normal file
148
components/efuse/src/esp_efuse_api_key_esp32.c
Normal file
@ -0,0 +1,148 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_utility.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "assert.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "efuse";
|
||||
|
||||
/**
|
||||
* @brief Keys and their attributes are packed into a structure
|
||||
*/
|
||||
typedef struct {
|
||||
const esp_efuse_desc_t** key_rd_dis; /**< Read protection of a key */
|
||||
const esp_efuse_desc_t** key_wr_dis; /**< Write protection of a key*/
|
||||
} esp_efuse_keys_t;
|
||||
|
||||
const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
|
||||
{ESP_EFUSE_RD_DIS_BLK1, ESP_EFUSE_WR_DIS_BLK1},
|
||||
{ESP_EFUSE_RD_DIS_BLK2, ESP_EFUSE_WR_DIS_BLK2},
|
||||
{ESP_EFUSE_RD_DIS_BLK3, ESP_EFUSE_WR_DIS_BLK3},
|
||||
};
|
||||
|
||||
|
||||
// Sets a write protection for the whole block.
|
||||
esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK0 || blk >= EFUSE_BLK_MAX) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
unsigned idx = blk - EFUSE_BLK1;
|
||||
return esp_efuse_write_field_cnt(s_table[idx].key_wr_dis, 1);
|
||||
}
|
||||
|
||||
// read protect for blk.
|
||||
esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK0 || blk >= EFUSE_BLK_MAX) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
unsigned idx = blk - EFUSE_BLK1;
|
||||
return esp_efuse_write_field_cnt(s_table[idx].key_rd_dis, 1);
|
||||
}
|
||||
|
||||
// get efuse coding_scheme.
|
||||
esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)
|
||||
{
|
||||
esp_efuse_coding_scheme_t scheme;
|
||||
if (blk == EFUSE_BLK0) {
|
||||
scheme = EFUSE_CODING_SCHEME_NONE;
|
||||
} else {
|
||||
uint32_t coding_scheme = REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_CODING_SCHEME);
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_VAL_NONE ||
|
||||
coding_scheme == (EFUSE_CODING_SCHEME_VAL_34 | EFUSE_CODING_SCHEME_VAL_REPEAT)) {
|
||||
scheme = EFUSE_CODING_SCHEME_NONE;
|
||||
} else if (coding_scheme == EFUSE_CODING_SCHEME_VAL_34) {
|
||||
scheme = EFUSE_CODING_SCHEME_3_4;
|
||||
} else {
|
||||
scheme = EFUSE_CODING_SCHEME_REPEAT;
|
||||
}
|
||||
}
|
||||
return scheme;
|
||||
}
|
||||
|
||||
bool esp_efuse_block_is_empty(esp_efuse_block_t block)
|
||||
{
|
||||
unsigned blk_len_bit = 256;
|
||||
uint32_t key[8];
|
||||
if (esp_efuse_get_coding_scheme(block) == EFUSE_CODING_SCHEME_3_4) {
|
||||
blk_len_bit = 192;
|
||||
}
|
||||
esp_err_t err = esp_efuse_read_block(block, &key, 0, blk_len_bit);
|
||||
if (err != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
unsigned zeros = 0;
|
||||
for (unsigned i = 0; i < blk_len_bit / 32; ++i) {
|
||||
if (key[i] == 0) {
|
||||
++zeros;
|
||||
}
|
||||
}
|
||||
if (zeros == blk_len_bit / 32) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool esp_efuse_get_key_dis_read(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_read_field_bit(s_table[idx].key_rd_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
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);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_key_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_read_field_bit(s_table[idx].key_wr_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
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);
|
||||
}
|
||||
|
||||
bool esp_efuse_key_block_unused(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return false; // Not a key block
|
||||
}
|
||||
|
||||
if (esp_efuse_get_key_dis_read(block) || esp_efuse_get_key_dis_write(block) ||
|
||||
!esp_efuse_block_is_empty(block)) {
|
||||
return false; // Block in use!
|
||||
}
|
||||
|
||||
return true; // Unused
|
||||
}
|
371
components/efuse/src/esp_efuse_api_key_esp32xx.c
Normal file
371
components/efuse/src/esp_efuse_api_key_esp32xx.c
Normal file
@ -0,0 +1,371 @@
|
||||
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_utility.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "assert.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
const static char *TAG = "efuse";
|
||||
|
||||
/**
|
||||
* @brief Keys and their attributes are packed into a structure
|
||||
*/
|
||||
typedef struct {
|
||||
const esp_efuse_desc_t** key; /**< Key */
|
||||
const esp_efuse_desc_t** keypurpose; /**< Key purpose */
|
||||
const esp_efuse_desc_t** key_rd_dis; /**< Read protection of a key */
|
||||
const esp_efuse_desc_t** key_wr_dis; /**< Write protection of a key*/
|
||||
const esp_efuse_desc_t** keypurpose_wr_dis; /**< Write protection of a key purpose*/
|
||||
} esp_efuse_keys_t;
|
||||
|
||||
typedef struct {
|
||||
const esp_efuse_desc_t** revoke;
|
||||
const esp_efuse_desc_t** revoke_wr_dis;
|
||||
} esp_efuse_revokes_t;
|
||||
|
||||
const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
|
||||
{ESP_EFUSE_KEY0, ESP_EFUSE_KEY_PURPOSE_0, ESP_EFUSE_RD_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0, ESP_EFUSE_WR_DIS_KEY0_PURPOSE},
|
||||
{ESP_EFUSE_KEY1, ESP_EFUSE_KEY_PURPOSE_1, ESP_EFUSE_RD_DIS_KEY1, ESP_EFUSE_WR_DIS_KEY1, ESP_EFUSE_WR_DIS_KEY1_PURPOSE},
|
||||
{ESP_EFUSE_KEY2, ESP_EFUSE_KEY_PURPOSE_2, ESP_EFUSE_RD_DIS_KEY2, ESP_EFUSE_WR_DIS_KEY2, ESP_EFUSE_WR_DIS_KEY2_PURPOSE},
|
||||
{ESP_EFUSE_KEY3, ESP_EFUSE_KEY_PURPOSE_3, ESP_EFUSE_RD_DIS_KEY3, ESP_EFUSE_WR_DIS_KEY3, ESP_EFUSE_WR_DIS_KEY3_PURPOSE},
|
||||
{ESP_EFUSE_KEY4, ESP_EFUSE_KEY_PURPOSE_4, ESP_EFUSE_RD_DIS_KEY4, ESP_EFUSE_WR_DIS_KEY4, ESP_EFUSE_WR_DIS_KEY4_PURPOSE},
|
||||
{ESP_EFUSE_KEY5, ESP_EFUSE_KEY_PURPOSE_5, ESP_EFUSE_RD_DIS_KEY5, ESP_EFUSE_WR_DIS_KEY5, ESP_EFUSE_WR_DIS_KEY5_PURPOSE},
|
||||
#if 0
|
||||
{ESP_EFUSE_KEY6, ESP_EFUSE_KEY_PURPOSE_6, ESP_EFUSE_RD_DIS_KEY6, ESP_EFUSE_WR_DIS_KEY6, ESP_EFUSE_WR_DIS_KEY6_PURPOSE},
|
||||
#endif
|
||||
};
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
#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;
|
||||
uint32_t key[8];
|
||||
esp_err_t err = esp_efuse_read_block(block, &key, 0, blk_len_bit);
|
||||
if (err != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
unsigned zeros = 0;
|
||||
for (unsigned i = 0; i < blk_len_bit / 32; ++i) {
|
||||
if (key[i] == 0) {
|
||||
++zeros;
|
||||
}
|
||||
}
|
||||
if (zeros == blk_len_bit / 32) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sets a write protection for the whole block.
|
||||
esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk == EFUSE_BLK1) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_BLK1, 1);
|
||||
} else if (blk == EFUSE_BLK2) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_SYS_DATA_PART1, 1);
|
||||
} else if (blk == EFUSE_BLK3) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_USER_DATA, 1);
|
||||
} else if (blk == EFUSE_BLK10) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_WR_DIS_SYS_DATA_PART2, 1);
|
||||
} else if (blk >= EFUSE_BLK_KEY0 && blk < EFUSE_BLK_KEY_MAX) {
|
||||
unsigned idx = blk - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_write_field_cnt(s_table[idx].key_wr_dis, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// read protect for blk.
|
||||
esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
|
||||
{
|
||||
if (blk >= EFUSE_BLK_KEY0 && blk < EFUSE_BLK_KEY_MAX) {
|
||||
unsigned idx = blk - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_write_field_cnt(s_table[idx].key_rd_dis, 1);
|
||||
} else if (blk == EFUSE_BLK10) {
|
||||
return esp_efuse_write_field_cnt(ESP_EFUSE_RD_DIS_SYS_DATA_PART2, 1);
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
|
||||
}
|
||||
|
||||
// get efuse coding_scheme.
|
||||
esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)
|
||||
{
|
||||
esp_efuse_coding_scheme_t scheme;
|
||||
if (blk == EFUSE_BLK0) {
|
||||
scheme = EFUSE_CODING_SCHEME_NONE;
|
||||
} else {
|
||||
scheme = EFUSE_CODING_SCHEME_RS;
|
||||
}
|
||||
return scheme;
|
||||
}
|
||||
|
||||
const esp_efuse_desc_t **esp_efuse_get_purpose_field(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return s_table[idx].keypurpose;
|
||||
}
|
||||
|
||||
const esp_efuse_desc_t** esp_efuse_get_key(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return s_table[idx].key;
|
||||
}
|
||||
|
||||
bool esp_efuse_get_key_dis_read(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_read_field_bit(s_table[idx].key_rd_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
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);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_key_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_read_field_bit(s_table[idx].key_wr_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
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);
|
||||
}
|
||||
|
||||
esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return ESP_EFUSE_KEY_PURPOSE_MAX;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
uint8_t value = 0;
|
||||
esp_err_t err = esp_efuse_read_field_blob(s_table[idx].keypurpose, &value, s_table[idx].keypurpose[0]->bit_count);
|
||||
if (err != ESP_OK) {
|
||||
return ESP_EFUSE_KEY_PURPOSE_MAX;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t purpose)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_write_field_blob(s_table[idx].keypurpose, &purpose, s_table[idx].keypurpose[0]->bit_count);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
|
||||
unsigned idx = block - EFUSE_BLK_KEY0;
|
||||
return esp_efuse_read_field_bit(s_table[idx].keypurpose_wr_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_keypurpose_dis_write(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
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);
|
||||
}
|
||||
|
||||
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_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 EFUSE_BLK_KEY_MAX; // nothing
|
||||
}
|
||||
|
||||
unsigned esp_efuse_count_unused_key_blocks(void)
|
||||
{
|
||||
unsigned r = 0;
|
||||
for (esp_efuse_block_t b = EFUSE_BLK_KEY0; b < EFUSE_BLK_KEY_MAX; b++) {
|
||||
if (esp_efuse_key_block_unused(b)) {
|
||||
r++;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool esp_efuse_key_block_unused(esp_efuse_block_t block)
|
||||
{
|
||||
if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
|
||||
return false; // Not a key block
|
||||
}
|
||||
|
||||
if (esp_efuse_get_key_purpose(block) != ESP_EFUSE_KEY_PURPOSE_USER ||
|
||||
esp_efuse_get_keypurpose_dis_write(block) ||
|
||||
esp_efuse_get_key_dis_read(block) ||
|
||||
esp_efuse_get_key_dis_write(block)) {
|
||||
return false; // Block in use!
|
||||
}
|
||||
|
||||
if (!esp_efuse_block_is_empty(block)) {
|
||||
return false; // Block in use!
|
||||
}
|
||||
|
||||
return true; // Unused
|
||||
}
|
||||
|
||||
bool esp_efuse_get_digest_revoke(unsigned num_digest)
|
||||
{
|
||||
assert(num_digest < sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t));
|
||||
return esp_efuse_read_field_bit(s_revoke_table[num_digest].revoke);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_digest_revoke(unsigned num_digest)
|
||||
{
|
||||
if (num_digest >= sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return esp_efuse_write_field_bit(s_revoke_table[num_digest].revoke);
|
||||
}
|
||||
|
||||
bool esp_efuse_get_write_protect_of_digest_revoke(unsigned num_digest)
|
||||
{
|
||||
assert(num_digest < sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t));
|
||||
return esp_efuse_read_field_bit(s_revoke_table[num_digest].revoke_wr_dis);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest)
|
||||
{
|
||||
if (num_digest >= sizeof(s_revoke_table) / sizeof(esp_efuse_revokes_t)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return esp_efuse_write_field_bit(s_revoke_table[num_digest].revoke_wr_dis);
|
||||
}
|
||||
|
||||
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) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_efuse_batch_write_begin();
|
||||
|
||||
if (!esp_efuse_key_block_unused(block)) {
|
||||
err = ESP_ERR_INVALID_STATE;
|
||||
} else {
|
||||
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 ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY ||
|
||||
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 ||
|
||||
purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_UP) {
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_dis_read(block));
|
||||
}
|
||||
ESP_EFUSE_CHK(esp_efuse_set_key_purpose(block, purpose));
|
||||
ESP_EFUSE_CHK(esp_efuse_set_keypurpose_dis_write(block));
|
||||
return esp_efuse_batch_write_commit();
|
||||
}
|
||||
err_exit:
|
||||
esp_efuse_batch_write_cancel();
|
||||
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 err = ESP_OK;
|
||||
if (number_of_keys == 0 || number_of_keys > (EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) || keys == NULL || purposes == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_efuse_purpose_t purpose = 0;
|
||||
esp_efuse_block_t block = EFUSE_BLK_KEY0;
|
||||
|
||||
esp_efuse_batch_write_begin();
|
||||
|
||||
unsigned unused_keys = esp_efuse_count_unused_key_blocks();
|
||||
if (number_of_keys > unused_keys) {
|
||||
ESP_LOGE(TAG, "Not enough unused key blocks available. Required %d, was %d", number_of_keys, unused_keys);
|
||||
err = ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS;
|
||||
} else {
|
||||
for (int i_key = 0; (block < EFUSE_BLK_KEY_MAX) && (i_key < number_of_keys); block++) {
|
||||
if (esp_efuse_key_block_unused(block)) {
|
||||
purpose = purposes[i_key];
|
||||
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], 32));
|
||||
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;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "." "include"
|
||||
PRIV_INCLUDE_DIRS "../private_include"
|
||||
PRIV_INCLUDE_DIRS "." "include" "../private_include" ../${target}/private_include
|
||||
PRIV_REQUIRES cmock test_utils efuse bootloader_support
|
||||
)
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "driver/adc.h"
|
||||
#include "hal/adc_ll.h"
|
||||
#include "esp32c3/esp_efuse_rtc_calib.h"
|
||||
#include "esp_efuse_rtc_calib.h"
|
||||
#include "esp_adc_cal.h"
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "esp_adc_cal.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp32s2/esp_efuse_rtc_table.h"
|
||||
#include "esp_efuse_rtc_table.h"
|
||||
#include "hal/adc_hal.h"
|
||||
|
||||
#define ADC_CAL_CHECK(cond, ret) ({ \
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "esp_timer.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_secure_boot.h"
|
||||
|
||||
/***********************************************/
|
||||
// Headers for other components init functions
|
||||
@ -48,7 +49,6 @@
|
||||
#include "esp_core_dump.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_private/dbg_stubs.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_pm.h"
|
||||
#include "esp_private/pm_impl.h"
|
||||
#include "esp_pthread.h"
|
||||
@ -276,6 +276,10 @@ static void do_core_init(void)
|
||||
esp_flash_encryption_init_checks();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT
|
||||
esp_secure_boot_init_checks();
|
||||
#endif
|
||||
|
||||
esp_err_t err;
|
||||
|
||||
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
|
@ -173,6 +173,8 @@ eFuse usage
|
||||
|
||||
- SECURE_BOOT_AGGRESSIVE_REVOKE - Enables aggressive revocation of keys. The key is revoked as soon as verification with this key fails.
|
||||
|
||||
To ensure no trusted keys can be added later by an attacker, each unused key digest slot should be revoked (KEY_REVOKEX). It will be checked during app startup in :cpp:func:`esp_secure_boot_init_checks` and fixed unless :ref:`CONFIG_SECURE_BOOT_ALLOW_UNUSED_DIGEST_SLOTS` is enabled.
|
||||
|
||||
.. _secure-boot-v2-howto:
|
||||
|
||||
How To Enable Secure Boot V2
|
||||
|
@ -92,6 +92,8 @@ components/unity/include/unity_test_runner.h
|
||||
components/cmock/CMock/src/cmock.h
|
||||
components/cmock/CMock/src/cmock_internals.h
|
||||
|
||||
components/efuse/include/esp_efuse.h
|
||||
|
||||
### Here are the files that do not compile for some reason
|
||||
#
|
||||
components/app_trace/include/esp_sysview_trace.h
|
||||
|
Loading…
Reference in New Issue
Block a user