]> granicus.if.org Git - esp-idf/commitdiff
bootloader_support: Move secure boot code to bootloader_support
authorAngus Gratton <angus@espressif.com>
Wed, 2 Nov 2016 06:54:47 +0000 (17:54 +1100)
committerAngus Gratton <angus@espressif.com>
Tue, 8 Nov 2016 00:13:54 +0000 (11:13 +1100)
components/bootloader/src/main/bootloader_config.h
components/bootloader/src/main/bootloader_start.c
components/bootloader_support/include/esp_secure_boot.h [moved from components/bootloader_support/include/esp_secureboot.h with 64% similarity]
components/bootloader_support/src/secure_boot.c [moved from components/bootloader/src/main/secure_boot.c with 71% similarity]
components/bootloader_support/src/secureboot.c [deleted file]

index 0823581824630beed4f3f8777bb1aa26a0f6ef85..4559d5f81631cb03745de94d137e1486e59eae39 100644 (file)
@@ -60,7 +60,6 @@ typedef struct {
 } bootloader_state_t;
 
 bool flash_encrypt(bootloader_state_t *bs);
-bool secure_boot_generate_bootloader_digest(void);
 
 #ifdef __cplusplus
 }
index 3bc2696a4b47842d04dad137e84379b770f22839..59b180fd84fbfba38d610fb93acf44acd224b7a8 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "sdkconfig.h"
 #include "esp_image_format.h"
+#include "esp_secure_boot.h"
 #include "bootloader_flash.h"
 
 #include "bootloader_config.h"
@@ -214,6 +215,7 @@ void bootloader_main()
 {
     ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION);
 
+    esp_err_t err;
     esp_image_header_t fhdr;
     bootloader_state_t bs;
     SpiFlashOpResult spiRet1,spiRet2;
@@ -308,8 +310,9 @@ void bootloader_main()
     if(fhdr.secure_boot_flag == 0x01) {
         /* Generate secure digest from this bootloader to protect future
          modifications */
-        if (secure_boot_generate_bootloader_digest() == false){
-            ESP_LOGE(TAG, "Bootloader digest generation failed. SECURE BOOT IS NOT ENABLED.");
+        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...
             */
similarity index 64%
rename from components/bootloader_support/include/esp_secureboot.h
rename to components/bootloader_support/include/esp_secure_boot.h
index b0097df8a63ce068b90b8f0a868811aac441b946..4bf2dc8b23b0e9c849b5dad54cddeb718a7fa080 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <stdbool.h>
 #include <esp_err.h>
+#include "soc/efuse_reg.h"
 
 /* Support functions for secure boot features.
 
  *
  * @return true if secure boot is enabled.
  */
-bool esp_secure_boot_enabled(void);
+static inline bool esp_secure_boot_enabled(void) {
+    return REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_RD_ABS_DONE_0);
+}
 
 
-/** @brief Enable secure boot if it isw not already enabled.
+/** @brief Enable secure boot if it is not already enabled.
  *
- * @important If this function succeeds, secure boot is permanentl
+ * @important If this function succeeds, secure boot is permanently
  * enabled on the chip via efuse.
  *
- * This function is intended to be called from bootloader code.
+ * @important This function is intended to be called from bootloader code only.
+ *
+ * If secure boot is not yet enabled for bootloader, this will
+ * generate the secure boot digest and enable secure boot by blowing
+ * the EFUSE_RD_ABS_DONE_0 efuse.
+ *
+ * This function does not verify secure boot of the bootloader (the
+ * ROM bootloader does this.)
+ *
+ * Will fail if efuses have been part-burned in a way that indicates
+ * secure boot should not or could not be correctly enabled.
+ *
  *
  * @return ESP_ERR_INVALID_STATE if efuse state doesn't allow
  * secure boot to be enabled cleanly. ESP_OK if secure boot
  * is enabled on this chip from now on.
  */
-esp_err_t esp_secure_boot_enable(void);
+esp_err_t esp_secure_boot_permanently_enable(void);
 
 
 
similarity index 71%
rename from components/bootloader/src/main/secure_boot.c
rename to components/bootloader_support/src/secure_boot.c
index 2b1b8573fc2dfffb50dd9378dab0ddba2efc916b..c17aebfbea70cc6f9e5330cc9e66124ea8cfaac4 100644 (file)
 
 #include "sdkconfig.h"
 
-#include "bootloader_config.h"
 #include "bootloader_flash.h"
 #include "esp_image_format.h"
+#include "esp_secure_boot.h"
 
 static const char* TAG = "secure_boot";
 
+#define HASH_BLOCK_SIZE 128
+#define IV_LEN HASH_BLOCK_SIZE
+#define DIGEST_LEN 64
+
 /**
  *  @function :     secure_boot_generate
- *  @description:   generate boot abstract & iv
+ *  @description:   generate boot digest (aka "abstract") & iv
  *
- *  @inputs:        bool
+ *  @inputs:        image_len - length of image to calculate digest for
  */
 static bool secure_boot_generate(uint32_t image_len){
-       SpiFlashOpResult spiRet;
-       uint32_t buf[32];
+    SpiFlashOpResult spiRet;
+    /* buffer is uint32_t not uint8_t to meet ROM SPI API signature */
+    uint32_t buf[IV_LEN / sizeof(uint32_t)];
     const void *image;
 
-       if (image_len % 128 != 0) {
-               image_len = (image_len / 128 + 1) * 128;
-       }
-       ets_secure_boot_start();
-       ets_secure_boot_rd_iv(buf);
-       ets_secure_boot_hash(NULL);
-       Cache_Read_Disable(0);
-       /* iv stored in sec 0 */
-       spiRet = SPIEraseSector(0);
-       if (spiRet != SPI_FLASH_RESULT_OK)
-       {
-               ESP_LOGE(TAG, SPI_ERROR_LOG);
-               return false;
-       }
-       Cache_Read_Enable(0);
-
-       /* write iv to flash, 0x0000, 128 bytes (1024 bits) */
+    /* hardware secure boot engine only takes full blocks, so round up the
+       image length. The additional data should all be 0xFF.
+    */
+    if (image_len % HASH_BLOCK_SIZE != 0) {
+        image_len = (image_len / HASH_BLOCK_SIZE + 1) * HASH_BLOCK_SIZE;
+    }
+    ets_secure_boot_start();
+    ets_secure_boot_rd_iv(buf);
+    ets_secure_boot_hash(NULL);
+    Cache_Read_Disable(0);
+    /* iv stored in sec 0 */
+    spiRet = SPIEraseSector(0);
+    if (spiRet != SPI_FLASH_RESULT_OK)
+    {
+        ESP_LOGE(TAG, "SPI erase failed %d", spiRet);
+        return false;
+    }
+    Cache_Read_Enable(0);
+
+    /* write iv to flash, 0x0000, 128 bytes (1024 bits) */
     ESP_LOGD(TAG, "write iv to flash.");
-       spiRet = SPIWrite(0, buf, 128);
-       if (spiRet != SPI_FLASH_RESULT_OK)
-       {
-               ESP_LOGE(TAG, SPI_ERROR_LOG);
-               return false;
-       }
-
-       /* generate digest from image contents */
+    spiRet = SPIWrite(0, buf, IV_LEN);
+    if (spiRet != SPI_FLASH_RESULT_OK)
+    {
+        ESP_LOGE(TAG, "SPI write failed %d", spiRet);
+        return false;
+    }
+    bzero(buf, sizeof(buf));
+
+    /* generate digest from image contents */
     image = bootloader_mmap(0x1000, image_len);
     if (!image) {
         ESP_LOGE(TAG, "bootloader_mmap(0x1000, 0x%x) failed", image_len);
         return false;
     }
-       for (int i = 0; i < image_len; i+=128) {
-               ets_secure_boot_hash(image + i/sizeof(void *));
-       }
+    for (int i = 0; i < image_len; i+= HASH_BLOCK_SIZE) {
+        ets_secure_boot_hash(image + i/sizeof(void *));
+    }
     bootloader_unmap(image);
 
-       ets_secure_boot_obtain();
-       ets_secure_boot_rd_abstract(buf);
-       ets_secure_boot_finish();
-
-    ESP_LOGD(TAG, "write abstract to flash.");
-       spiRet = SPIWrite(0x80, buf, 64);
-       if (spiRet != SPI_FLASH_RESULT_OK) {
-               ESP_LOGE(TAG, SPI_ERROR_LOG);
-               return false;
-       }
-       ESP_LOGD(TAG, "write abstract to flash.");
-       Cache_Read_Enable(0);
-       return true;
+    ets_secure_boot_obtain();
+    ets_secure_boot_rd_abstract(buf);
+    ets_secure_boot_finish();
+
+    ESP_LOGD(TAG, "write digest to flash.");
+    spiRet = SPIWrite(0x80, buf, DIGEST_LEN);
+    if (spiRet != SPI_FLASH_RESULT_OK) {
+        ESP_LOGE(TAG, "SPI write failed %d", spiRet);
+        return false;
+    }
+    ESP_LOGD(TAG, "write digest to flash.");
+    Cache_Read_Enable(0);
+    return true;
 }
 
 /* Burn values written to the efuse write registers */
@@ -109,34 +118,19 @@ static inline void burn_efuses()
     while (REG_READ(EFUSE_CMD_REG));    /* wait for efuse_read_cmd=0 */
 }
 
-/**
- *  @brief Enable secure boot if it is not already enabled.
- *
- *  Called if the secure boot flag is set on the
- *  bootloader image in flash. If secure boot is not yet enabled for
- *  bootloader, this will generate the secure boot digest and enable
- *  secure boot by blowing the EFUSE_RD_ABS_DONE_0 efuse.
- *
- *  This function does not verify secure boot of the bootloader (the
- *  ROM bootloader does this.)
- *
- *  @return true if secure boot is enabled (either was already enabled,
- *  or is freshly enabled as a result of calling this function.) false
- *  implies an error occured (possibly secure boot is part-enabled.)
- */
-bool secure_boot_generate_bootloader_digest(void) {
+esp_err_t esp_secure_boot_permanently_enable(void) {
     esp_err_t err;
     uint32_t image_len = 0;
-    if (REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0)
+    if (esp_secure_boot_enabled())
     {
         ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing..");
-        return true;
+        return ESP_OK;
     }
 
     err = esp_image_basic_verify(0x1000, &image_len);
     if (err != ESP_OK) {
         ESP_LOGE(TAG, "bootloader image appears invalid! error %d", err);
-        return false;
+        return err;
     }
 
     uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
@@ -178,17 +172,17 @@ bool secure_boot_generate_bootloader_digest(void) {
     ESP_LOGI(TAG, "Generating secure boot digest...");
     if (false == secure_boot_generate(image_len)){
         ESP_LOGE(TAG, "secure boot generation failed");
-        return false;
+        return ESP_FAIL;
     }
     ESP_LOGI(TAG, "Digest generation complete.");
 
     if (!efuse_key_read_protected) {
         ESP_LOGE(TAG, "Pre-loaded key is not read protected. Refusing to blow secure boot efuse.");
-        return false;
+        return ESP_ERR_INVALID_STATE;
     }
     if (!efuse_key_write_protected) {
         ESP_LOGE(TAG, "Pre-loaded key is not write protected. Refusing to blow secure boot efuse.");
-        return false;
+        return ESP_ERR_INVALID_STATE;
     }
 
     ESP_LOGI(TAG, "blowing secure boot efuse & disabling JTAG...");
@@ -200,9 +194,9 @@ bool secure_boot_generate_bootloader_digest(void) {
     ESP_LOGD(TAG, "after updating, EFUSE_BLK0_RDATA6 %x", after);
     if (after & EFUSE_RD_ABS_DONE_0) {
         ESP_LOGI(TAG, "secure boot is now enabled for bootloader image");
-        return true;
+        return ESP_OK;
     } else {
         ESP_LOGE(TAG, "secure boot not enabled for bootloader image, EFUSE_RD_ABS_DONE_0 is probably write protected!");
-        return false;
+        return ESP_ERR_INVALID_STATE;
     }
 }
diff --git a/components/bootloader_support/src/secureboot.c b/components/bootloader_support/src/secureboot.c
deleted file mode 100644 (file)
index e55c1f3..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdint.h>
-#include <limits.h>
-
-#include "esp_log.h"
-
-
-