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
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
\ No newline at end of file
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 */
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);
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 */
* @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;
}
/* 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) {
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);
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;
}
}