2021-07-20 14:12:44 +08:00
|
|
|
/*
|
2021-11-13 04:53:18 +08:00
|
|
|
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
2021-07-20 14:12:44 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <bootutil/bootutil.h>
|
2021-11-13 01:21:12 +08:00
|
|
|
#include <bootutil/bootutil_log.h>
|
|
|
|
#include <bootutil/fault_injection_hardening.h>
|
2021-07-20 14:16:03 +08:00
|
|
|
#include <bootutil/image.h>
|
|
|
|
|
2021-11-13 01:21:12 +08:00
|
|
|
#include "bootloader_init.h"
|
2021-11-25 11:45:26 +08:00
|
|
|
#include "bootloader_utility.h"
|
|
|
|
#include "bootloader_random.h"
|
2021-07-20 14:16:03 +08:00
|
|
|
|
2023-03-08 04:56:53 +08:00
|
|
|
#include "esp_assert.h"
|
|
|
|
|
2022-06-13 21:45:39 +08:00
|
|
|
#ifdef CONFIG_MCUBOOT_SERIAL
|
|
|
|
#include "boot_serial/boot_serial.h"
|
|
|
|
#include "serial_adapter/serial_adapter.h"
|
|
|
|
|
|
|
|
const struct boot_uart_funcs boot_funcs = {
|
|
|
|
.read = console_read,
|
|
|
|
.write = console_write
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2021-11-13 04:53:18 +08:00
|
|
|
#if defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH) || defined(CONFIG_SECURE_BOOT)
|
|
|
|
#include "esp_efuse.h"
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_SECURE_BOOT
|
|
|
|
#include "esp_secure_boot.h"
|
|
|
|
#endif
|
2021-11-25 11:45:26 +08:00
|
|
|
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
|
|
|
#include "esp_flash_encrypt.h"
|
|
|
|
#endif
|
2021-11-13 04:53:18 +08:00
|
|
|
|
2021-11-13 01:21:12 +08:00
|
|
|
#include "esp_loader.h"
|
|
|
|
#include "os/os_malloc.h"
|
2021-07-20 14:16:03 +08:00
|
|
|
|
2022-02-22 06:31:46 +08:00
|
|
|
#define IMAGE_INDEX_0 0
|
|
|
|
#define IMAGE_INDEX_1 1
|
|
|
|
|
|
|
|
#define PRIMARY_SLOT 0
|
|
|
|
#define SECONDARY_SLOT 1
|
|
|
|
|
2021-11-13 04:53:18 +08:00
|
|
|
#ifdef CONFIG_SECURE_BOOT
|
|
|
|
extern esp_err_t check_and_generate_secure_boot_keys(void);
|
|
|
|
#endif
|
|
|
|
|
2021-07-20 14:16:03 +08:00
|
|
|
void do_boot(struct boot_rsp *rsp)
|
|
|
|
{
|
2021-11-13 01:21:12 +08:00
|
|
|
BOOT_LOG_INF("br_image_off = 0x%x", rsp->br_image_off);
|
|
|
|
BOOT_LOG_INF("ih_hdr_size = 0x%x", rsp->br_hdr->ih_hdr_size);
|
2022-02-22 06:31:46 +08:00
|
|
|
int slot = (rsp->br_image_off == CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS) ? PRIMARY_SLOT : SECONDARY_SLOT;
|
2022-05-07 01:59:43 +08:00
|
|
|
start_cpu0_image(IMAGE_INDEX_0, slot, rsp->br_hdr->ih_hdr_size);
|
2022-02-22 06:31:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
|
|
|
|
int read_image_header(uint32_t img_index, uint32_t slot, struct image_header *img_header)
|
|
|
|
{
|
|
|
|
const struct flash_area *fap;
|
|
|
|
int area_id;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
area_id = flash_area_id_from_multi_image_slot(img_index, slot);
|
|
|
|
rc = flash_area_open(area_id, &fap);
|
|
|
|
if (rc != 0) {
|
|
|
|
rc = BOOT_EFLASH;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flash_area_read(fap, 0, img_header, sizeof(struct image_header))) {
|
|
|
|
rc = BOOT_EFLASH;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOT_LOG_INF("Image offset = 0x%x", fap->fa_off);
|
|
|
|
BOOT_LOG_INF("Image header size = 0x%x", img_header->ih_hdr_size);
|
|
|
|
|
|
|
|
done:
|
|
|
|
flash_area_close(fap);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void do_boot_appcpu(uint32_t img_index, uint32_t slot)
|
|
|
|
{
|
|
|
|
struct image_header img_header;
|
|
|
|
|
|
|
|
if (read_image_header(img_index, slot, &img_header) != 0) {
|
|
|
|
FIH_PANIC;
|
|
|
|
}
|
|
|
|
|
2022-05-07 01:59:43 +08:00
|
|
|
start_cpu1_image(img_index, slot, img_header.ih_hdr_size);
|
2021-07-20 14:16:03 +08:00
|
|
|
}
|
2022-02-22 06:31:46 +08:00
|
|
|
#endif
|
2021-07-20 14:12:44 +08:00
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
2022-04-19 12:10:30 +08:00
|
|
|
if (bootloader_init() != ESP_OK) {
|
|
|
|
FIH_PANIC;
|
|
|
|
}
|
2021-11-13 04:53:18 +08:00
|
|
|
|
2021-11-25 11:45:26 +08:00
|
|
|
/* Rough steps for a first boot when Secure Boot and/or Flash Encryption are still disabled on device:
|
|
|
|
* Secure Boot:
|
|
|
|
* 1) Calculate the SHA-256 hash digest of the public key and write to EFUSE.
|
|
|
|
* 2) Validate the application images and prepare the booting process.
|
|
|
|
* 3) Burn EFUSE to enable Secure Boot V2 (ABS_DONE_0).
|
|
|
|
* Flash Encryption:
|
|
|
|
* 4) Generate Flash Encryption key and write to EFUSE.
|
|
|
|
* 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
|
|
|
|
* 6) Burn EFUSE to enable Flash Encryption.
|
|
|
|
* 7) Reset system to ensure Flash Encryption cache resets properly.
|
|
|
|
*/
|
|
|
|
|
2021-11-13 04:53:18 +08:00
|
|
|
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
|
|
|
BOOT_LOG_WRN("eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
|
|
|
|
esp_efuse_init_virtual_mode_in_flash(CONFIG_EFUSE_VIRTUAL_OFFSET, CONFIG_EFUSE_VIRTUAL_SIZE);
|
2021-07-20 14:16:03 +08:00
|
|
|
#endif
|
2021-07-20 14:12:44 +08:00
|
|
|
|
2021-11-13 04:53:18 +08:00
|
|
|
#ifdef CONFIG_SECURE_BOOT
|
2021-11-25 11:45:26 +08:00
|
|
|
/* Steps 1 (see above for full description):
|
|
|
|
* 1) Compute digest of the public key.
|
|
|
|
*/
|
|
|
|
|
2021-11-13 04:53:18 +08:00
|
|
|
BOOT_LOG_INF("enabling secure boot v2...");
|
|
|
|
|
|
|
|
bool sb_hw_enabled = esp_secure_boot_enabled();
|
|
|
|
|
|
|
|
if (sb_hw_enabled) {
|
|
|
|
BOOT_LOG_INF("secure boot v2 is already enabled, continuing..");
|
|
|
|
} else {
|
|
|
|
esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
|
|
|
|
|
|
|
|
esp_err_t err;
|
|
|
|
err = check_and_generate_secure_boot_keys();
|
|
|
|
if (err != ESP_OK) {
|
|
|
|
esp_efuse_batch_write_cancel();
|
|
|
|
FIH_PANIC;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-09-08 04:06:35 +08:00
|
|
|
os_heap_init();
|
|
|
|
|
2021-11-13 04:53:18 +08:00
|
|
|
struct boot_rsp rsp;
|
2021-11-25 11:45:26 +08:00
|
|
|
|
2022-11-24 23:49:56 +08:00
|
|
|
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
2021-11-13 04:53:18 +08:00
|
|
|
|
2022-06-13 21:45:39 +08:00
|
|
|
#ifdef CONFIG_MCUBOOT_SERIAL
|
|
|
|
boot_console_init();
|
|
|
|
if (boot_serial_detect_pin()) {
|
|
|
|
BOOT_LOG_INF("Enter the serial recovery mode");
|
|
|
|
boot_serial_start(&boot_funcs);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-11-25 11:45:26 +08:00
|
|
|
/* Step 2 (see above for full description):
|
|
|
|
* 2) MCUboot validates the application images and prepares the booting process.
|
|
|
|
*/
|
|
|
|
|
2022-02-22 06:31:46 +08:00
|
|
|
/* MCUboot's boot_go validates and checks all images for update and returns
|
|
|
|
* the load information for booting the main image
|
|
|
|
*/
|
2021-07-20 14:16:03 +08:00
|
|
|
FIH_CALL(boot_go, fih_rc, &rsp);
|
2022-11-24 23:49:56 +08:00
|
|
|
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
2021-11-13 01:21:12 +08:00
|
|
|
BOOT_LOG_ERR("Unable to find bootable image");
|
2021-11-13 04:53:18 +08:00
|
|
|
#ifdef CONFIG_SECURE_BOOT
|
|
|
|
esp_efuse_batch_write_cancel();
|
|
|
|
#endif
|
2021-07-20 14:16:03 +08:00
|
|
|
FIH_PANIC;
|
2021-07-20 14:12:44 +08:00
|
|
|
}
|
2021-11-13 04:53:18 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_SECURE_BOOT
|
2021-11-25 11:45:26 +08:00
|
|
|
/* Step 3 (see above for full description):
|
|
|
|
* 3) Burn EFUSE to enable Secure Boot V2.
|
|
|
|
*/
|
|
|
|
|
2021-11-13 04:53:18 +08:00
|
|
|
if (!sb_hw_enabled) {
|
|
|
|
BOOT_LOG_INF("blowing secure boot efuse...");
|
|
|
|
esp_err_t err;
|
|
|
|
err = esp_secure_boot_enable_secure_features();
|
|
|
|
if (err != ESP_OK) {
|
|
|
|
esp_efuse_batch_write_cancel();
|
|
|
|
FIH_PANIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = esp_efuse_batch_write_commit();
|
|
|
|
if (err != ESP_OK) {
|
|
|
|
BOOT_LOG_ERR("Error programming security eFuses (err=0x%x).", err);
|
|
|
|
FIH_PANIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
|
|
|
|
assert(esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
assert(esp_secure_boot_enabled());
|
|
|
|
BOOT_LOG_INF("Secure boot permanently enabled");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-11-25 11:45:26 +08:00
|
|
|
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
|
|
|
/* Step 4, 5 & 6 (see above for full description):
|
|
|
|
* 4) Generate Flash Encryption key and write to EFUSE.
|
|
|
|
* 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
|
|
|
|
* 6) Burn EFUSE to enable flash encryption
|
|
|
|
*/
|
|
|
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
BOOT_LOG_INF("Checking flash encryption...");
|
|
|
|
bool flash_encryption_enabled = esp_flash_encryption_enabled();
|
|
|
|
rc = esp_flash_encrypt_check_and_update();
|
|
|
|
if (rc != ESP_OK) {
|
|
|
|
BOOT_LOG_ERR("Flash encryption check failed (%d).", rc);
|
|
|
|
FIH_PANIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Step 7 (see above for full description):
|
|
|
|
* 7) Reset system to ensure flash encryption cache resets properly.
|
|
|
|
*/
|
|
|
|
if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
|
|
|
|
BOOT_LOG_INF("Resetting with flash encryption enabled...");
|
|
|
|
bootloader_reset();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
BOOT_LOG_INF("Disabling RNG early entropy source...");
|
|
|
|
bootloader_random_disable();
|
|
|
|
|
2022-02-22 06:31:46 +08:00
|
|
|
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
|
|
|
|
/* Multi image independent boot
|
|
|
|
* Boot on the second processor happens before the image0 boot
|
|
|
|
*/
|
|
|
|
do_boot_appcpu(IMAGE_INDEX_1, PRIMARY_SLOT);
|
|
|
|
#endif
|
|
|
|
|
2021-07-20 14:16:03 +08:00
|
|
|
do_boot(&rsp);
|
2021-11-13 04:53:18 +08:00
|
|
|
|
2021-07-20 14:12:44 +08:00
|
|
|
while(1);
|
|
|
|
}
|