From e5672e5d7f560b9ad038d51f03edd0d1cf546728 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 29 Mar 2019 10:28:42 +1100 Subject: [PATCH] efuse/flash encryption: Reduce FLASH_CRYPT_CNT to a 7 bit efuse field 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 | 6 +++--- components/efuse/esp32/esp_efuse_table.c | 4 ++-- components/efuse/esp32/esp_efuse_table.csv | 2 +- components/efuse/esp32/include/esp_efuse_table.h | 2 +- components/soc/esp32/include/soc/efuse_reg.h | 12 ++++++------ docs/en/api-reference/system/efuse.rst | 4 ++-- docs/en/security/flash-encryption.rst | 8 ++++---- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index 814bb39259..8d5955eff7 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -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); diff --git a/components/efuse/esp32/esp_efuse_table.c b/components/efuse/esp32/esp_efuse_table.c index 0e390c6d13..36b54b50ba 100644 --- a/components/efuse/esp32/esp_efuse_table.c +++ b/components/efuse/esp32/esp_efuse_table.c @@ -17,7 +17,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table 840523b9e1313240e6102615e3a497a5 +// md5_digest_table 544d434da010ce22f7db1b14d38e1d66 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -96,7 +96,7 @@ static const esp_efuse_desc_t CONSOLE_DEBUG_DISABLE[] = { }; static const esp_efuse_desc_t FLASH_CRYPT_CNT[] = { - {EFUSE_BLK0, 20, 8}, // Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT., + {EFUSE_BLK0, 20, 7}, // Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT., }; static const esp_efuse_desc_t WR_DIS_FLASH_CRYPT_CNT[] = { diff --git a/components/efuse/esp32/esp_efuse_table.csv b/components/efuse/esp32/esp_efuse_table.csv index 9d8381413b..23b28ec47d 100644 --- a/components/efuse/esp32/esp_efuse_table.csv +++ b/components/efuse/esp32/esp_efuse_table.csv @@ -41,7 +41,7 @@ DISABLE_DL_DECRYPT, EFUSE_BLK0, 200, 1, Flash encrypt. Disable UART DISABLE_DL_CACHE, EFUSE_BLK0, 201, 1, Flash encrypt. Disable UART bootloader MMU cache. EFUSE_DISABLE_DL_CACHE. DISABLE_JTAG, EFUSE_BLK0, 198, 1, Flash encrypt. Disable JTAG. EFUSE_RD_DISABLE_JTAG. CONSOLE_DEBUG_DISABLE, EFUSE_BLK0, 194, 1, Flash encrypt. Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE. -FLASH_CRYPT_CNT, EFUSE_BLK0, 20, 8, Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT. +FLASH_CRYPT_CNT, EFUSE_BLK0, 20, 7, Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT. # Write protection # #################### diff --git a/components/efuse/esp32/include/esp_efuse_table.h b/components/efuse/esp32/include/esp_efuse_table.h index ad67ae2216..807fb08882 100644 --- a/components/efuse/esp32/include/esp_efuse_table.h +++ b/components/efuse/esp32/include/esp_efuse_table.h @@ -17,7 +17,7 @@ extern "C" { #endif -// md5_digest_table 840523b9e1313240e6102615e3a497a5 +// md5_digest_table 544d434da010ce22f7db1b14d38e1d66 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. diff --git a/components/soc/esp32/include/soc/efuse_reg.h b/components/soc/esp32/include/soc/efuse_reg.h index e3f660496e..bbe9677137 100644 --- a/components/soc/esp32/include/soc/efuse_reg.h +++ b/components/soc/esp32/include/soc/efuse_reg.h @@ -17,11 +17,11 @@ #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*/ @@ -319,11 +319,11 @@ #define EFUSE_CODING_SCHEME_VAL_REPEAT 0x2 #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*/ diff --git a/docs/en/api-reference/system/efuse.rst b/docs/en/api-reference/system/efuse.rst index 44d4df812d..dd8c6bd993 100644 --- a/docs/en/api-reference/system/efuse.rst +++ b/docs/en/api-reference/system/efuse.rst @@ -184,7 +184,7 @@ How add a new field 5 RD_DIS_BLK1 EFUSE_BLK0 16 1 6 RD_DIS_BLK2 EFUSE_BLK0 17 1 7 RD_DIS_BLK3 EFUSE_BLK0 18 1 - 8 FLASH_CRYPT_CNT EFUSE_BLK0 20 8 + 8 FLASH_CRYPT_CNT EFUSE_BLK0 20 7 9 MAC_FACTORY EFUSE_BLK0 32 8 10 MAC_FACTORY EFUSE_BLK0 40 8 11 MAC_FACTORY EFUSE_BLK0 48 8 @@ -334,4 +334,4 @@ To get a dump for all eFuse registers. 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 -.. include:: /_build/inc/esp_efuse.inc \ No newline at end of file +.. include:: /_build/inc/esp_efuse.inc diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index 82e6fb379c..136d188222 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -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: