espressif: ESP32, ESP32S2 and ESP32C3 native flash encryption

Native flash encryption was added as option for Espressif chips and
added to the initialization process before MCUboot workflow.

Signed-off-by: Almir Okato <almir.okato@espressif.com>
diff --git a/boot/espressif/main.c b/boot/espressif/main.c
index bd1d04d..083efc5 100644
--- a/boot/espressif/main.c
+++ b/boot/espressif/main.c
@@ -10,6 +10,8 @@
 #include <bootutil/image.h>
 
 #include "bootloader_init.h"
+#include "bootloader_utility.h"
+#include "bootloader_random.h"
 
 #if defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH) || defined(CONFIG_SECURE_BOOT)
 #include "esp_efuse.h"
@@ -17,6 +19,9 @@
 #ifdef CONFIG_SECURE_BOOT
 #include "esp_secure_boot.h"
 #endif
+#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
+#include "esp_flash_encrypt.h"
+#endif
 
 #include "esp_loader.h"
 #include "os/os_malloc.h"
@@ -37,12 +42,31 @@
 {
     bootloader_init();
 
+    BOOT_LOG_INF("Enabling RNG early entropy source...");
+    bootloader_random_enable();
+
+    /* 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.
+     */
+
 #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);
 #endif
 
 #ifdef CONFIG_SECURE_BOOT
+    /* Steps 1 (see above for full description):
+     *   1) Compute digest of the public key.
+     */
+
     BOOT_LOG_INF("enabling secure boot v2...");
 
     bool sb_hw_enabled = esp_secure_boot_enabled();
@@ -66,8 +90,13 @@
     os_heap_init();
 
     struct boot_rsp rsp;
+
     fih_int fih_rc = FIH_FAILURE;
 
+    /* Step 2 (see above for full description):
+     *   2) MCUboot validates the application images and prepares the booting process.
+     */
+
     FIH_CALL(boot_go, fih_rc, &rsp);
 
     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
@@ -79,6 +108,10 @@
     }
 
 #ifdef CONFIG_SECURE_BOOT
+    /* Step 3 (see above for full description):
+     *   3) Burn EFUSE to enable Secure Boot V2.
+     */
+
     if (!sb_hw_enabled) {
         BOOT_LOG_INF("blowing secure boot efuse...");
         esp_err_t err;
@@ -103,6 +136,35 @@
     }
 #endif
 
+#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();
+
     do_boot(&rsp);
 
     while(1);