]> granicus.if.org Git - esp-idf/commitdiff
efuse/flash encryption: Reduce FLASH_CRYPT_CNT to a 7 bit efuse field
authorAngus Gratton <angus@espressif.com>
Thu, 28 Mar 2019 23:28:42 +0000 (10:28 +1100)
committerbot <bot@espressif.com>
Fri, 12 Apr 2019 07:28:57 +0000 (07:28 +0000)
8th bit is not used by hardware.

As reported https://esp32.com/viewtopic.php?f=2&t=7800&p=40895#p40894

components/bootloader_support/src/flash_encrypt.c
components/soc/esp32/include/soc/efuse_reg.h
docs/en/security/flash-encryption.rst

index 814bb39259e7ed82c9108beb94cd9dfec603860f..8d5955eff74a5f715cfdd0e0877fb6bbd8e5b589 100644 (file)
@@ -163,7 +163,7 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
 
     /* If the last flash_crypt_cnt bit is burned or write-disabled, the
        device can't re-encrypt itself. */
-    if (flash_crypt_wr_dis || flash_crypt_cnt == 0xFF) {
+    if (flash_crypt_wr_dis) {
         ESP_LOGE(TAG, "Cannot re-encrypt data (FLASH_CRYPT_CNT 0x%02x write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
         return ESP_FAIL;
     }
@@ -200,8 +200,8 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
     ESP_LOGD(TAG, "All flash regions checked for encryption pass");
 
     /* Set least significant 0-bit in flash_crypt_cnt */
-    int ffs_inv = __builtin_ffs((~flash_crypt_cnt) & 0xFF);
-    /* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == 0xFF */
+    int ffs_inv = __builtin_ffs((~flash_crypt_cnt) & EFUSE_RD_FLASH_CRYPT_CNT);
+    /* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == EFUSE_RD_FLASH_CRYPT_CNT (0x7F) */
     uint32_t new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
     ESP_LOGD(TAG, "FLASH_CRYPT_CNT 0x%x -> 0x%x", flash_crypt_cnt, new_flash_crypt_cnt);
     REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, new_flash_crypt_cnt);
index 6c3f45c542d01cb4d28a6c39deb5c2b24f4ff9e3..a2ee03d31428afaef7e41af29713f788e8d85ff2 100644 (file)
 
 #include "soc.h"
 #define EFUSE_BLK0_RDATA0_REG          (DR_REG_EFUSE_BASE + 0x000)
-/* EFUSE_RD_FLASH_CRYPT_CNT : RO ;bitpos:[27:20] ;default: 8'b0 ; */
+/* EFUSE_RD_FLASH_CRYPT_CNT : RO ;bitpos:[26:20] ;default: 7'b0 ; */
 /*description: read for flash_crypt_cnt*/
-#define EFUSE_RD_FLASH_CRYPT_CNT  0x000000FF
+#define EFUSE_RD_FLASH_CRYPT_CNT  0x0000007F
 #define EFUSE_RD_FLASH_CRYPT_CNT_M  ((EFUSE_RD_FLASH_CRYPT_CNT_V)<<(EFUSE_RD_FLASH_CRYPT_CNT_S))
-#define EFUSE_RD_FLASH_CRYPT_CNT_V  0xFF
+#define EFUSE_RD_FLASH_CRYPT_CNT_V  0x7F
 #define EFUSE_RD_FLASH_CRYPT_CNT_S  20
 /* EFUSE_RD_EFUSE_RD_DIS : RO ;bitpos:[19:16] ;default: 4'b0 ; */
 /*description: read for efuse_rd_disable*/
 #define EFUSE_CODING_SCHEME_VAL_34   0x1
 
 #define EFUSE_BLK0_WDATA0_REG          (DR_REG_EFUSE_BASE + 0x01c)
-/* EFUSE_FLASH_CRYPT_CNT : R/W ;bitpos:[27:20] ;default: 8'b0 ; */
+/* EFUSE_FLASH_CRYPT_CNT : R/W ;bitpos:[26:20] ;default: 7'b0 ; */
 /*description: program for flash_crypt_cnt*/
-#define EFUSE_FLASH_CRYPT_CNT  0x000000FF
+#define EFUSE_FLASH_CRYPT_CNT  0x0000007F
 #define EFUSE_FLASH_CRYPT_CNT_M  ((EFUSE_FLASH_CRYPT_CNT_V)<<(EFUSE_FLASH_CRYPT_CNT_S))
-#define EFUSE_FLASH_CRYPT_CNT_V  0xFF
+#define EFUSE_FLASH_CRYPT_CNT_V  0x7F
 #define EFUSE_FLASH_CRYPT_CNT_S  20
 /* EFUSE_RD_DIS : R/W ;bitpos:[19:16] ;default: 4'b0 ; */
 /*description: program for efuse_rd_disable*/
index 82e6fb379ccdd77f90afd8835ea76ada294843cf..136d18822264ba912fe8b815fe2eb8edcbba11ed 100644 (file)
@@ -146,7 +146,7 @@ Limited Updates
 
 Only 4 plaintext serial update cycles of this kind are possible, including the initial encrypted flash.
 
-After the fourth time encryption is enabled, :ref:`FLASH_CRYPT_CNT` has the maximum value ``0x7F`` (7 bits set) and encryption is permanently enabled. Flashing :ref:`FLASH_CRYPT_CNT` to ``0xFF`` (8 bits set) does not re-disable encryption, the eighth bit is ignored.
+After the fourth time encryption is enabled, :ref:`FLASH_CRYPT_CNT` has the maximum value ``0x7F`` (7 bits set) and encryption is permanently enabled. 
 
 Using :ref:`updating-encrypted-flash-ota` or :ref:`pregenerated-flash-encryption-key` allows you to exceed this limit.
 
@@ -381,9 +381,9 @@ The following sections provide some reference information about the operation of
 FLASH_CRYPT_CNT efuse
 ^^^^^^^^^^^^^^^^^^^^^
 
-``FLASH_CRYPT_CNT`` is an 8-bit efuse field which controls flash encryption. Flash encryption enables or disables based on the number of bits in this efuse which are set to "1":
+``FLASH_CRYPT_CNT`` is a 7-bit efuse field which controls flash encryption. Flash encryption enables or disables based on the number of bits in this efuse which are set to "1":
 
-- When an even number of bits (0,2,4,6,8) are set: Flash encryption is disabled, any encrypted data cannot be decrypted.
+- When an even number of bits (0,2,4,6) are set: Flash encryption is disabled, any encrypted data cannot be decrypted.
 
   - If the bootloader was built with "Enable flash encryption on boot" then it will see this situation and immediately re-encrypt the flash wherever it finds unencrypted data. Once done, it sets another bit in the efuse to '1' meaning an odd number of bits are now set.
 
@@ -394,7 +394,7 @@ FLASH_CRYPT_CNT efuse
 
 - When an odd number of bits (1,3,5,7) are set: Transparent reading of encrypted flash is enabled.
 
-- After all 8 bits are set (efuse value 0xFF): Transparent reading of encrypted flash is disabled, any encrypted data is permanently inaccessible. Bootloader will normally detect this condition and halt. To avoid use of this state to load unauthorised code, secure boot must be used or :ref:`FLASH_CRYPT_CNT` must be write-protected.
+- To avoid use of :ref:`FLASH_CRYPT_CNT` state to disable flash encryption, load unauthorised code, then re-enabled flash encryption, secure boot must be used or :ref:`FLASH_CRYPT_CNT` must be write-protected.
 
 
 .. _flash-encryption-algorithm: