secure boot: Enable based on sdkconfig, remove "secure boot flag" from binary image

This commit is contained in:
Angus Gratton 2016-11-07 15:45:26 +11:00
parent ff1b2c6039
commit fe66dd85f0
5 changed files with 73 additions and 17 deletions

View File

@ -28,6 +28,12 @@ config LOG_BOOTLOADER_LEVEL
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
endmenu
menu "Secure boot configuration"
choice SECURE_BOOTLOADER
bool "Secure bootloader"
default SECURE_BOOTLOADER_DISABLED
@ -78,8 +84,35 @@ config SECURE_BOOT_SIGNING_KEY
See docs/security/secure-boot.rst for details.
config SECURE_BOOT_DISABLE_JTAG
bool "First boot: Permanently disable JTAG"
depends on SECURE_BOOTLOADER_ENABLED
default Y
help
Bootloader permanently disable JTAG (across entire chip) when enabling secure boot. This happens on first boot of the bootloader.
It is recommended this option remains set for production environments.
config SECURE_BOOT_DISABLE_UART_BOOTLOADER
bool "First boot: Permanently disable UART bootloader"
depends on SECURE_BOOTLOADER_ENABLED
default Y
help
Bootloader permanently disables UART and other bootloader modes when enabling secure boot. This happens on first boot.
It is recommended this option remains set for production environments.
config SECURE_BOOT_TEST_MODE
bool "Test mode: don't actually enable secure boot"
depends on SECURE_BOOTLOADER_ENABLED
default N
help
If this option is set, all permanent secure boot changes (via Efuse) are disabled.
This option is for testing purposes only - it effectively completely disables secure boot protection.
config SECURE_BOOTLOADER_ENABLED
bool
default SECURE_BOOTLOADER_ONE_TIME_FLASH || SECURE_BOOTLOADER_REFLASHABLE
endmenu
endmenu

View File

@ -316,17 +316,17 @@ void bootloader_main()
ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos);
if(fhdr.secure_boot_flag == 0x01) {
/* Generate secure digest from this bootloader to protect future
modifications */
err = esp_secure_boot_permanently_enable();
if (err != ESP_OK){
ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err);
/* Allow booting to continue, as the failure is probably
due to user-configured EFUSEs for testing...
*/
}
#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
/* Generate secure digest from this bootloader to protect future
modifications */
err = esp_secure_boot_permanently_enable();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err);
/* Allow booting to continue, as the failure is probably
due to user-configured EFUSEs for testing...
*/
}
#endif
if(fhdr.encrypt_flag == 0x01) {
/* encrypt flash */
@ -354,12 +354,16 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err);
return;
}
#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
ESP_LOGI(TAG, "Verifying app signature @ 0x%x (length 0x%x)", partition->offset, image_length);
err = esp_secure_boot_verify_signature(partition->offset, image_length);
if (err != ESP_OK) {
ESP_LOGE(TAG, "App image @ 0x%x failed signature verification (%d)", partition->offset, err);
return;
}
ESP_LOGD(TAG, "App signature is valid");
}
#endif
if (esp_image_load_header(partition->offset, &image_header) != ESP_OK) {
ESP_LOGE(TAG, "Failed to load app image header @ 0x%x", partition->offset);

View File

@ -64,8 +64,7 @@ typedef struct {
uint8_t spi_size: 4; /* flash chip size (esp_image_flash_size_t as uint8_t) */
uint32_t entry_addr;
uint8_t encrypt_flag; /* encrypt flag */
uint8_t secure_boot_flag; /* secure boot flag */
uint8_t extra_header[14]; /* ESP32 additional header, unused by second bootloader */
uint8_t extra_header[15]; /* ESP32 additional header, unused by second bootloader */
} esp_image_header_t;
/* Header of binary image segment */

View File

@ -32,7 +32,7 @@
* @return true if secure boot is enabled.
*/
static inline bool esp_secure_boot_enabled(void) {
return REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_RD_ABS_DONE_0);
return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0;
}

View File

@ -110,12 +110,16 @@ static bool secure_boot_generate(uint32_t image_len){
/* Burn values written to the efuse write registers */
static inline void burn_efuses()
{
#ifdef CONFIG_SECURE_BOOT_TEST_MODE
ESP_LOGE(TAG, "SECURE BOOT TEST MODE. Not really burning any efuses!");
#else
REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */
REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */
REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */
REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */
#endif
}
esp_err_t esp_secure_boot_permanently_enable(void) {
@ -185,10 +189,22 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
return ESP_ERR_INVALID_STATE;
}
ESP_LOGI(TAG, "blowing secure boot efuse & disabling JTAG...");
ESP_LOGI(TAG, "blowing secure boot efuse...");
ESP_LOGD(TAG, "before updating, EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG));
REG_WRITE(EFUSE_BLK0_WDATA6_REG,
EFUSE_RD_ABS_DONE_0 | EFUSE_RD_DISABLE_JTAG);
uint32_t new_wdata6 = EFUSE_RD_ABS_DONE_0;
#ifdef CONFIG_SECURE_BOOT_DISABLE_JTAG
ESP_LOGI(TAG, "disabling JTAG...");
new_wdata6 |= EFUSE_RD_DISABLE_JTAG;
#endif
#ifdef CONFIG_SECURE_BOOT_DISABLE_UART_BOOTLOADER
ESP_LOGI(TAG, "disabling UART bootloader...");
new_wdata6 |= EFUSE_RD_CONSOLE_DEBUG_DISABLE_S;
#endif
REG_WRITE(EFUSE_BLK0_WDATA6_REG, new_wdata6);
burn_efuses();
uint32_t after = REG_READ(EFUSE_BLK0_RDATA6_REG);
ESP_LOGD(TAG, "after updating, EFUSE_BLK0_RDATA6 %x", after);
@ -196,7 +212,11 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
ESP_LOGI(TAG, "secure boot is now enabled for bootloader image");
return ESP_OK;
} else {
#ifdef CONFIG_SECURE_BOOT_TEST_MODE
ESP_LOGE(TAG, "secure boot not enabled due to test mode");
#else
ESP_LOGE(TAG, "secure boot not enabled for bootloader image, EFUSE_RD_ABS_DONE_0 is probably write protected!");
#endif
return ESP_ERR_INVALID_STATE;
}
}