Просмотр исходного кода

bootloader_support: Removes old code of SB and FE for esp32h2

KonstantinKondrashov 4 лет назад
Родитель
Сommit
f761cee32e

+ 0 - 346
components/bootloader_support/src/esp32h2/flash_encrypt.c

@@ -1,346 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-
-#include <strings.h>
-#include "bootloader_flash_priv.h"
-#include "bootloader_random.h"
-#include "bootloader_utility.h"
-#include "esp_image_format.h"
-#include "esp_flash_encrypt.h"
-#include "esp_flash_partitions.h"
-#include "esp_secure_boot.h"
-#include "esp_log.h"
-#include "esp32h2/rom/secure_boot.h"
-#include "esp_efuse.h"
-#include "esp_efuse_table.h"
-#include "hal/wdt_hal.h"
-
-static const char *TAG = "flash_encrypt";
-
-/* Static functions for stages of flash encryption */
-static esp_err_t initialise_flash_encryption(void);
-static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis) __attribute__((unused));
-static esp_err_t encrypt_bootloader(void);
-static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions);
-static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition);
-
-esp_err_t esp_flash_encrypt_check_and_update(void)
-{
-    uint8_t flash_crypt_wr_dis = 0;
-    uint32_t flash_crypt_cnt = 0;
-
-    esp_efuse_read_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &flash_crypt_cnt, 3);
-    esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT, &flash_crypt_wr_dis, 1);
-
-    ESP_LOGV(TAG, "SPI_BOOT_CRYPT_CNT 0x%x", flash_crypt_cnt);
-    ESP_LOGV(TAG, "EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT 0x%x", flash_crypt_wr_dis);
-
-    if (__builtin_parity(flash_crypt_cnt) == 1) {
-        /* Flash is already encrypted */
-        int left = (flash_crypt_cnt == 1) ? 1 : 0;
-        if (flash_crypt_wr_dis) {
-            left = 0; /* can't update FLASH_CRYPT_CNT, no more flashes */
-        }
-        ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
-        return ESP_OK;
-    } else {
-#ifndef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
-        /* Flash is not encrypted, so encrypt it! */
-        return encrypt_flash_contents(flash_crypt_cnt, flash_crypt_wr_dis);
-#else
-        ESP_LOGE(TAG, "flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED "
-                      "is set, refusing to boot.");
-        return ESP_ERR_INVALID_STATE;
-#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
-    }
-}
-
-static esp_err_t check_and_generate_encryption_keys(void)
-{
-    esp_efuse_block_t aes_128_key_block;
-
-    bool has_key = esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,   &aes_128_key_block);
-    bool dis_write = false;
-    bool dis_read = false;
-
-    // If there are keys set, they must be write and read protected!
-    if(has_key) {
-        dis_write = esp_efuse_get_key_dis_write(aes_128_key_block);
-        dis_read  = esp_efuse_get_key_dis_read(aes_128_key_block);
-    }
-
-
-    if(has_key && (!dis_read || !dis_write)) {
-        ESP_LOGE(TAG, "Invalid key state, a key was set but not read and write protected.");
-        return ESP_ERR_INVALID_STATE;
-    }
-
-    if(!has_key && !dis_write && !dis_read) {
-        ESP_LOGI(TAG, "Generating new flash encryption key...");
-
-        enum { BLOCKS_NEEDED = 1 };
-        esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
-            ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
-        };
-
-        uint8_t keys[BLOCKS_NEEDED][32] = { 0 };
-        for (int i = 0; i < BLOCKS_NEEDED; ++i) {
-            bootloader_fill_random(keys[i], 32);
-        }
-
-        esp_err_t err = esp_efuse_write_keys(purposes, keys, BLOCKS_NEEDED);
-        if (err != ESP_OK) {
-            if (err == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
-                ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED);
-            } else {
-                ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", err);
-            }
-            return err;
-        }
-        ESP_LOGD(TAG, "Key generation complete");
-        return ESP_OK;
-
-    } else {
-        ESP_LOGI(TAG, "Using pre-existing key in efuse");
-        return ESP_OK;
-    }
-}
-
-
-static esp_err_t initialise_flash_encryption(void)
-{
-    esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
-
-    esp_err_t key_state = check_and_generate_encryption_keys();
-    if(key_state != ESP_OK) {
-        esp_efuse_batch_write_cancel();
-        return key_state;
-    }
-
-#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
-    ESP_LOGI(TAG, "Disable UART bootloader encryption...");
-    esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT);
-#else
-    ESP_LOGW(TAG, "Not disabling UART bootloader encryption");
-#endif
-
-#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
-    ESP_LOGI(TAG, "Disable UART bootloader cache...");
-    esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE);
-#else
-    ESP_LOGW(TAG, "Not disabling UART bootloader cache - SECURITY COMPROMISED");
-#endif
-
-#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
-    ESP_LOGI(TAG, "Disable JTAG...");
-    esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
-    esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
-#else
-    ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
-#endif
-
-    esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
-
-    esp_err_t err = esp_efuse_batch_write_commit();
-    if (err != ESP_OK) {
-        ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
-    }
-
-    return err;
-}
-
-/* Encrypt all flash data that should be encrypted */
-static esp_err_t encrypt_flash_contents(uint32_t spi_boot_crypt_cnt, bool flash_crypt_wr_dis)
-{
-    esp_err_t err;
-    esp_partition_info_t partition_table[ESP_PARTITION_TABLE_MAX_ENTRIES];
-    int num_partitions;
-
-    /* If the last spi_boot_crypt_cnt bit is burned or write-disabled, the
-       device can't re-encrypt itself. */
-    if (flash_crypt_wr_dis || spi_boot_crypt_cnt == EFUSE_SPI_BOOT_CRYPT_CNT) {
-        ESP_LOGE(TAG, "Cannot re-encrypt data SPI_BOOT_CRYPT_CNT 0x%02x write disabled %d", spi_boot_crypt_cnt, flash_crypt_wr_dis);
-        return ESP_FAIL;
-    }
-
-    if (spi_boot_crypt_cnt == 0) {
-        /* Very first flash of encrypted data: generate keys, etc. */
-        err = initialise_flash_encryption();
-        if (err != ESP_OK) {
-            return err;
-        }
-    }
-
-    err = encrypt_bootloader();
-    if (err != ESP_OK) {
-        return err;
-    }
-
-    err = encrypt_and_load_partition_table(partition_table, &num_partitions);
-    if (err != ESP_OK) {
-        return err;
-    }
-
-    /* Now iterate the just-loaded partition table, looking for entries to encrypt
-     */
-
-    /* Go through each partition and encrypt if necessary */
-    for (int i = 0; i < num_partitions; i++) {
-        err = encrypt_partition(i, &partition_table[i]);
-        if (err != ESP_OK) {
-            return err;
-        }
-    }
-
-    ESP_LOGD(TAG, "All flash regions checked for encryption pass");
-
-    /* Set least significant 0-bit in spi_boot_crypt_cnt */
-    int ffs_inv = __builtin_ffs((~spi_boot_crypt_cnt) & 0x7);
-    /* ffs_inv shouldn't be zero, as zero implies spi_boot_crypt_cnt == 0xFF */
-    uint32_t new_spi_boot_crypt_cnt = (1 << (ffs_inv - 1));
-    ESP_LOGD(TAG, "SPI_BOOT_CRYPT_CNT 0x%x -> 0x%x", spi_boot_crypt_cnt, new_spi_boot_crypt_cnt + spi_boot_crypt_cnt);
-
-    esp_efuse_write_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &new_spi_boot_crypt_cnt, 3);
-
-#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
-    //Secure SPI boot cnt after its update if needed.
-    const uint32_t spi_boot_cnt_wr_dis = 1;
-    ESP_LOGI(TAG, "Write protecting SPI_CRYPT_CNT eFuse");
-    esp_efuse_write_field_blob(ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT, &spi_boot_cnt_wr_dis, 1);
-#endif
-    ESP_LOGI(TAG, "Flash encryption completed");
-
-    return ESP_OK;
-}
-
-static esp_err_t encrypt_bootloader(void)
-{
-    esp_err_t err;
-    uint32_t image_length;
-    /* Check for plaintext bootloader (verification will fail if it's already encrypted) */
-    if (esp_image_verify_bootloader(&image_length) == ESP_OK) {
-        ESP_LOGD(TAG, "bootloader is plaintext. Encrypting...");
-
-#if CONFIG_SECURE_BOOT_V2_ENABLED
-        /* The image length obtained from esp_image_verify_bootloader includes the sector boundary padding and the signature block lengths */
-        if (ESP_BOOTLOADER_OFFSET + image_length > ESP_PARTITION_TABLE_OFFSET) {
-            ESP_LOGE(TAG, "Bootloader is too large to fit Secure Boot V2 signature sector and partition table (configured offset 0x%x)", ESP_PARTITION_TABLE_OFFSET);
-            return ESP_ERR_INVALID_SIZE;
-        }
-#endif // CONFIG_SECURE_BOOT_V2_ENABLED
-
-        err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, image_length);
-        if (err != ESP_OK) {
-            ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
-            return err;
-        }
-
-        ESP_LOGI(TAG, "bootloader encrypted successfully");
-        return err;
-    }
-    else {
-        ESP_LOGW(TAG, "no valid bootloader was found");
-        return ESP_ERR_NOT_FOUND;
-    }
-}
-
-static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions)
-{
-    esp_err_t err;
-    /* Check for plaintext partition table */
-    err = bootloader_flash_read(ESP_PARTITION_TABLE_OFFSET, partition_table, ESP_PARTITION_TABLE_MAX_LEN, false);
-    if (err != ESP_OK) {
-        ESP_LOGE(TAG, "Failed to read partition table data");
-        return err;
-    }
-    if (esp_partition_table_verify(partition_table, false, num_partitions) == ESP_OK) {
-        ESP_LOGD(TAG, "partition table is plaintext. Encrypting...");
-        esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET,
-                        FLASH_SECTOR_SIZE);
-        if (err != ESP_OK) {
-            ESP_LOGE(TAG, "Failed to encrypt partition table in place. %x", err);
-            return err;
-        }
-    } else {
-        ESP_LOGE(TAG, "Failed to read partition table data - not plaintext?");
-        return ESP_ERR_INVALID_STATE;
-    }
-
-    /* Valid partition table loaded */
-    ESP_LOGI(TAG, "partition table encrypted and loaded successfully");
-    return ESP_OK;
-}
-
-
-static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition)
-{
-    esp_err_t err;
-    bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED);
-
-    if (partition->type == PART_TYPE_APP) {
-        /* check if the partition holds a valid unencrypted app */
-        esp_image_metadata_t data_ignored;
-        err = esp_image_verify(ESP_IMAGE_VERIFY,
-                               &partition->pos,
-                               &data_ignored);
-        should_encrypt = (err == ESP_OK);
-    } else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) {
-        /* check if we have ota data partition and the partition should be encrypted unconditionally */
-        should_encrypt = true;
-    }
-
-    if (!should_encrypt) {
-        return ESP_OK;
-    } else {
-        /* should_encrypt */
-        ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, partition->pos.size);
-
-        err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size);
-        ESP_LOGI(TAG, "Done encrypting");
-        if (err != ESP_OK) {
-            ESP_LOGE(TAG, "Failed to encrypt partition %d", index);
-        }
-        return err;
-    }
-}
-
-
-esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
-{
-    esp_err_t err;
-    uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)];
-
-    if (src_addr % FLASH_SECTOR_SIZE != 0) {
-        ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x", src_addr);
-        return ESP_FAIL;
-    }
-
-    wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
-    for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
-        wdt_hal_write_protect_disable(&rtc_wdt_ctx);
-        wdt_hal_feed(&rtc_wdt_ctx);
-        wdt_hal_write_protect_enable(&rtc_wdt_ctx);
-
-        uint32_t sec_start = i + src_addr;
-        err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, false);
-        if (err != ESP_OK) {
-            goto flash_failed;
-        }
-        err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE);
-        if (err != ESP_OK) {
-            goto flash_failed;
-        }
-        err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true);
-        if (err != ESP_OK) {
-            goto flash_failed;
-        }
-    }
-    return ESP_OK;
-
-flash_failed:
-    ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
-    return err;
-}

+ 50 - 0
components/bootloader_support/src/esp32h2/flash_encryption_secure_features.c

@@ -0,0 +1,50 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <strings.h>
+#include "esp_flash_encrypt.h"
+#include "esp_secure_boot.h"
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+#include "esp_log.h"
+#include "sdkconfig.h"
+
+static __attribute__((unused)) const char *TAG = "flash_encrypt";
+
+esp_err_t esp_flash_encryption_enable_secure_features(void)
+{
+#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
+    ESP_LOGI(TAG, "Disable UART bootloader encryption...");
+    esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT);
+#else
+    ESP_LOGW(TAG, "Not disabling UART bootloader encryption");
+#endif
+
+#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
+    ESP_LOGI(TAG, "Disable UART bootloader cache...");
+    esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE);
+#else
+    ESP_LOGW(TAG, "Not disabling UART bootloader cache - SECURITY COMPROMISED");
+#endif
+
+#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
+    ESP_LOGI(TAG, "Disable JTAG...");
+    esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
+    esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
+#else
+    ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
+#endif
+
+    esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
+
+#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
+    // This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
+    // otherwise the Flash Encryption key cannot be read protected
+    esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
+#endif
+
+    return ESP_OK;
+}

+ 0 - 301
components/bootloader_support/src/esp32h2/secure_boot.c

@@ -1,301 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-#include <string.h>
-
-#include "esp_log.h"
-#include "esp_secure_boot.h"
-#include "soc/efuse_reg.h"
-
-#include "bootloader_flash_priv.h"
-#include "bootloader_sha.h"
-#include "bootloader_utility.h"
-
-#include "esp_rom_crc.h"
-#include "esp_efuse.h"
-#include "esp_efuse_table.h"
-
-#include "esp32h2/rom/efuse.h"
-#include "esp32h2/rom/secure_boot.h"
-
-static const char *TAG = "secure_boot_v2";
-#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
-
-/* A signature block is valid when it has correct magic byte, crc and image digest. */
-static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block, int block_num, const uint8_t *image_digest)
-{
-    uint32_t crc = esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN);
-    if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC) {
-        // All signature blocks have been parsed, no new signature block present.
-        ESP_LOGD(TAG, "Signature block(%d) invalid/absent.", block_num);
-        return ESP_FAIL;
-    }
-    if (block->block_crc != crc) {
-        ESP_LOGE(TAG, "Magic byte correct but incorrect crc.");
-        return ESP_FAIL;
-    }
-    if (memcmp(image_digest, block->image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
-        ESP_LOGE(TAG, "Magic byte & CRC correct but incorrect image digest.");
-        return ESP_FAIL;
-    } else {
-        ESP_LOGD(TAG, "valid signature block(%d) found", block_num);
-        return ESP_OK;
-    }
-
-    return ESP_FAIL;
-}
-
-/* Generates the public key digests of the valid public keys in an image's
-   signature block, verifies each signature, and stores the key digests in the
-   public_key_digests structure.
-
-   @param flash_offset Image offset in flash
-   @param flash_size Image size in flash (not including signature block)
-   @param[out] public_key_digests Pointer to structure to hold the key digests for valid sig blocks
-
-
-   Note that this function doesn't read any eFuses, so it doesn't know if the
-   keys are ultimately trusted by the hardware or not
-
-   @return - ESP_OK if no signatures failed to verify, or if no valid signature blocks are found at all.
-           - ESP_FAIL if there's a valid signature block that doesn't verify using the included public key (unexpected!)
-*/
-static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, esp_image_sig_public_key_digests_t *public_key_digests)
-{
-    esp_err_t ret;
-    uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
-    uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
-    size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
-
-    ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%x (sig block offset 0x%x)", flash_offset, sig_block_addr);
-
-    bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
-
-    ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
-    if (ret != ESP_OK) {
-        ESP_LOGE(TAG, "error generating image digest, %d", ret);
-        return ret;
-    }
-
-    ESP_LOGD(TAG, "reading signatures");
-    const ets_secure_boot_signature_t *signatures = bootloader_mmap(sig_block_addr, sizeof(ets_secure_boot_signature_t));
-    if (signatures == NULL) {
-        ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", sig_block_addr, sizeof(ets_secure_boot_signature_t));
-        return ESP_FAIL;
-    }
-
-    for (int i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
-        const ets_secure_boot_sig_block_t *block = &signatures->block[i];
-
-        ret = validate_signature_block(block, i, image_digest);
-        if (ret != ESP_OK) {
-            ret = ESP_OK;  // past the last valid signature block
-            break;
-        }
-
-        /* Generating the SHA of the public key components in the signature block */
-        bootloader_sha256_handle_t sig_block_sha;
-        sig_block_sha = bootloader_sha256_start();
-        bootloader_sha256_data(sig_block_sha, &block->key, sizeof(block->key));
-        bootloader_sha256_finish(sig_block_sha, key_digest);
-
-        // Check we can verify the image using this signature and this key
-        uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
-        bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
-
-        if (!verified) {
-            /* We don't expect this: the signature blocks before we enable secure boot should all be verifiable or invalid,
-               so this is a fatal error
-            */
-            ret = ESP_FAIL;
-            ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i);
-            break;
-        }
-        ESP_LOGD(TAG, "Signature block (%d) is verified", i);
-        /* Copy the key digest to the buffer provided by the caller */
-        memcpy((void *)public_key_digests->key_digests[i], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
-        public_key_digests->num_digests++;
-    }
-
-    if (ret == ESP_OK && public_key_digests->num_digests > 0) {
-        ESP_LOGI(TAG, "Digests successfully calculated, %d valid signatures (image offset 0x%x)",
-                 public_key_digests->num_digests, flash_offset);
-    }
-
-    bootloader_munmap(signatures);
-    return ret;
-}
-
-static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t *image_data)
-{
-    esp_err_t ret;
-    /* Verify the bootloader */
-    esp_image_metadata_t bootloader_data = { 0 };
-    ret = esp_image_verify_bootloader_data(&bootloader_data);
-    if (ret != ESP_OK) {
-        ESP_LOGE(TAG, "bootloader image appears invalid! error %d", ret);
-        return ret;
-    }
-
-    /* Check if secure boot digests are present */
-    bool has_secure_boot_digest = esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0, NULL);
-    has_secure_boot_digest |= esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1, NULL);
-    has_secure_boot_digest |= esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2, NULL);
-    ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating..");
-
-    if (!has_secure_boot_digest) {
-        esp_image_sig_public_key_digests_t boot_key_digests = {0};
-        esp_image_sig_public_key_digests_t app_key_digests = {0};
-
-        /* Generate the bootloader public key digests */
-        ret = s_calculate_image_public_key_digests(bootloader_data.start_addr, bootloader_data.image_len - SIG_BLOCK_PADDING, &boot_key_digests);
-        if (ret != ESP_OK) {
-            ESP_LOGE(TAG, "Bootloader signature block is invalid");
-            return ret;
-        }
-
-        if (boot_key_digests.num_digests == 0) {
-            ESP_LOGE(TAG, "No valid bootloader signature blocks found.");
-            return ESP_FAIL;
-        }
-        ESP_LOGI(TAG, "%d signature block(s) found appended to the bootloader.", boot_key_digests.num_digests);
-
-        esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
-            ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
-            ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
-            ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
-        };
-
-        ret = esp_efuse_write_keys(secure_boot_key_purpose, boot_key_digests.key_digests, boot_key_digests.num_digests);
-        if (ret) {
-            if (ret == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
-                ESP_LOGE(TAG, "Bootloader signatures(%d) more than available key slots.", boot_key_digests.num_digests);
-            } else {
-                ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", ret);
-            }
-            return ret;
-        }
-
-        /* Generate the application public key digests */
-        ret = s_calculate_image_public_key_digests(image_data->start_addr, image_data->image_len - SIG_BLOCK_PADDING, &app_key_digests);
-        if (ret != ESP_OK) {
-            ESP_LOGE(TAG, "App signature block is invalid.");
-            return ret;
-        }
-
-        if (app_key_digests.num_digests == 0) {
-            ESP_LOGE(TAG, "No valid applications signature blocks found.");
-            return ESP_FAIL;
-        }
-
-        ESP_LOGI(TAG, "%d signature block(s) found appended to the app.", app_key_digests.num_digests);
-        if (app_key_digests.num_digests > boot_key_digests.num_digests) {
-            ESP_LOGW(TAG, "App has %d signature blocks but bootloader only has %d. Some keys missing from bootloader?");
-        }
-
-        /* Confirm if at least one public key from the application matches a public key in the bootloader
-           (Also, ensure if that public revoke bit is not set for the matched key) */
-        bool match = false;
-
-        for (int i = 0; i < boot_key_digests.num_digests; i++) {
-
-            if (esp_efuse_get_digest_revoke(i)) {
-                ESP_LOGI(TAG, "Key block(%d) has been revoked.", i);
-                continue; // skip if the key block is revoked
-            }
-
-            for (int j = 0; j < app_key_digests.num_digests; j++) {
-                if (!memcmp(boot_key_digests.key_digests[i], app_key_digests.key_digests[j], ESP_SECURE_BOOT_DIGEST_LEN)) {
-                    ESP_LOGI(TAG, "Application key(%d) matches with bootloader key(%d).", j, i);
-                    match = true;
-                }
-            }
-        }
-
-        if (match == false) {
-            ESP_LOGE(TAG, "No application key digest matches the bootloader key digest.");
-            return ESP_FAIL;
-        }
-
-        /* Revoke the empty signature blocks */
-        if (boot_key_digests.num_digests < SECURE_BOOT_NUM_BLOCKS) {
-            /* The revocation index can be 0, 1, 2. Bootloader count can be 1,2,3. */
-            for (uint8_t i = boot_key_digests.num_digests; i < SECURE_BOOT_NUM_BLOCKS; i++) {
-                ESP_LOGI(TAG, "Revoking empty key digest slot (%d)...", i);
-                esp_efuse_set_digest_revoke(i);
-            }
-        }
-    }
-    return ESP_OK;
-}
-
-esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *image_data)
-{
-    ESP_LOGI(TAG, "enabling secure boot v2...");
-
-    if (esp_secure_boot_enabled()) {
-        ESP_LOGI(TAG, "secure boot v2 is already enabled, continuing..");
-        return ESP_OK;
-    }
-
-    esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
-
-    esp_err_t key_state = check_and_generate_secure_boot_keys(image_data);
-    if (key_state != ESP_OK) {
-        esp_efuse_batch_write_cancel();
-        return key_state;
-    }
-
-    esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
-
-    esp_err_t err = ESP_FAIL;
-#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
-    ESP_LOGI(TAG, "Enabling Security download mode...");
-    err = esp_efuse_enable_rom_secure_download_mode();
-    if (err != ESP_OK) {
-        ESP_LOGE(TAG, "Could not enable Security download mode...");
-        return err;
-    }
-#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE
-    ESP_LOGI(TAG, "Disable ROM Download mode...");
-    err = esp_efuse_disable_rom_download_mode();
-    if (err != ESP_OK) {
-        ESP_LOGE(TAG, "Could not disable ROM Download mode...");
-        return err;
-    }
-#else
-    ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
-#endif
-
-#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
-    ESP_LOGI(TAG, "Disable hardware & software JTAG...");
-    esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
-    esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
-    esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count);
-#else
-    ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
-#endif
-
-#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
-    esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE);
-#endif
-
-    esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
-
-    err = esp_efuse_batch_write_commit();
-    if (err != ESP_OK) {
-        ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
-        return err;
-    }
-
-#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
-    assert(ets_efuse_secure_boot_aggressive_revoke_enabled());
-#endif
-
-    assert(esp_rom_efuse_is_secure_boot_enabled());
-    ESP_LOGI(TAG, "Secure boot permanently enabled");
-
-    return ESP_OK;
-}

+ 70 - 0
components/bootloader_support/src/esp32h2/secure_boot_secure_features.c

@@ -0,0 +1,70 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <strings.h>
+#include "esp_flash_encrypt.h"
+#include "esp_secure_boot.h"
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+#include "esp_log.h"
+#include "sdkconfig.h"
+
+static __attribute__((unused)) const char *TAG = "secure_boot";
+
+esp_err_t esp_secure_boot_enable_secure_features(void)
+{
+    esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
+
+#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
+    ESP_LOGI(TAG, "Enabling Security download mode...");
+    esp_err_t err = esp_efuse_enable_rom_secure_download_mode();
+    if (err != ESP_OK) {
+        ESP_LOGE(TAG, "Could not enable Security download mode...");
+        return err;
+    }
+#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE
+    ESP_LOGI(TAG, "Disable ROM Download mode...");
+    esp_err_t err = esp_efuse_disable_rom_download_mode();
+    if (err != ESP_OK) {
+        ESP_LOGE(TAG, "Could not disable ROM Download mode...");
+        return err;
+    }
+#else
+    ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
+#endif
+
+#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
+    ESP_LOGI(TAG, "Disable hardware & software JTAG...");
+    esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
+    esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
+    esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count);
+#else
+    ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
+#endif
+
+#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
+    esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE);
+#endif
+
+    esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
+
+#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
+    bool rd_dis_now = true;
+#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
+    /* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot
+       when Flash Encryption is being enabled */
+    rd_dis_now = esp_flash_encryption_enabled();
+#endif
+    if (rd_dis_now) {
+        ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
+        esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
+    }
+#else
+    ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
+#endif
+
+    return ESP_OK;
+}