flash_encrypt.c
1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <strings.h> 16 #include "sdkconfig.h" 17 #include "esp_log.h" 18 #include "esp_efuse.h" 19 #include "esp_efuse_table.h" 20 #include "esp_flash_encrypt.h" 21 #include "esp_secure_boot.h" 22 23 #if CONFIG_IDF_TARGET_ESP32 24 #define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT 25 #define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT 26 #elif CONFIG_IDF_TARGET_ESP32S2 27 #define CRYPT_CNT ESP_EFUSE_SPI_BOOT_CRYPT_CNT 28 #define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT 29 #elif CONFIG_IDF_TARGET_ESP32S3 30 #define CRYPT_CNT ESP_EFUSE_SPI_BOOT_CRYPT_CNT 31 #define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT 32 #endif 33 34 #ifndef BOOTLOADER_BUILD 35 static const char *TAG = "flash_encrypt"; 36 37 void esp_flash_encryption_init_checks() 38 { 39 esp_flash_enc_mode_t mode; 40 41 // First check is: if Release mode flash encryption & secure boot are enabled then 42 // FLASH_CRYPT_CNT *must* be write protected. This will have happened automatically 43 // if bootloader is IDF V4.0 or newer but may not have happened for previous ESP-IDF bootloaders. 44 #ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE 45 #ifdef CONFIG_SECURE_BOOT 46 if (esp_secure_boot_enabled() && esp_flash_encryption_enabled()) { 47 bool flash_crypt_cnt_wr_dis = esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT); 48 if (!flash_crypt_cnt_wr_dis) { 49 uint8_t flash_crypt_cnt = 0; 50 esp_efuse_read_field_blob(CRYPT_CNT, &flash_crypt_cnt, CRYPT_CNT[0]->bit_count); 51 if (flash_crypt_cnt == (1<<(CRYPT_CNT[0]->bit_count))-1) { 52 // If encryption counter is already max, no need to write protect it 53 // (this distinction is important on ESP32 ECO3 where write-procted FLASH_CRYPT_CNT also write-protects UART_DL_DIS) 54 return; 55 } 56 ESP_LOGE(TAG, "Flash encryption & Secure Boot together requires FLASH_CRYPT_CNT efuse to be write protected. Fixing now..."); 57 esp_flash_write_protect_crypt_cnt(); 58 } 59 } 60 #endif // CONFIG_SECURE_BOOT 61 #endif // CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE 62 63 // Second check is to print a warning or error if the current running flash encryption mode 64 // doesn't match the expectation from project config (due to mismatched bootloader and app, probably) 65 mode = esp_get_flash_encryption_mode(); 66 if (mode == ESP_FLASH_ENC_MODE_DEVELOPMENT) { 67 #ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE 68 ESP_LOGE(TAG, "Flash encryption settings error: app is configured for RELEASE but efuses are set for DEVELOPMENT"); 69 ESP_LOGE(TAG, "Mismatch found in security options in bootloader menuconfig and efuse settings. Device is not secure."); 70 #else 71 ESP_LOGW(TAG, "Flash encryption mode is DEVELOPMENT (not secure)"); 72 #endif 73 } else if (mode == ESP_FLASH_ENC_MODE_RELEASE) { 74 ESP_LOGI(TAG, "Flash encryption mode is RELEASE"); 75 } 76 } 77 #endif 78 79 void esp_flash_write_protect_crypt_cnt(void) 80 { 81 esp_efuse_write_field_bit(WR_DIS_CRYPT_CNT); 82 } 83 84 esp_flash_enc_mode_t esp_get_flash_encryption_mode(void) 85 { 86 bool flash_crypt_cnt_wr_dis = false; 87 #if CONFIG_IDF_TARGET_ESP32 88 uint8_t dis_dl_enc = 0, dis_dl_dec = 0, dis_dl_cache = 0; 89 #elif CONFIG_IDF_TARGET_ESP32S2 90 uint8_t dis_dl_enc = 0; 91 uint8_t dis_dl_icache = 0; 92 uint8_t dis_dl_dcache = 0; 93 94 #endif 95 96 esp_flash_enc_mode_t mode = ESP_FLASH_ENC_MODE_DEVELOPMENT; 97 98 if (esp_flash_encryption_enabled()) { 99 /* Check if FLASH CRYPT CNT is write protected */ 100 101 flash_crypt_cnt_wr_dis = esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT); 102 if (!flash_crypt_cnt_wr_dis) { 103 uint8_t flash_crypt_cnt = 0; 104 esp_efuse_read_field_blob(CRYPT_CNT, &flash_crypt_cnt, CRYPT_CNT[0]->bit_count); 105 if (flash_crypt_cnt == (1 << (CRYPT_CNT[0]->bit_count)) - 1) { 106 flash_crypt_cnt_wr_dis = true; 107 } 108 } 109 110 if (flash_crypt_cnt_wr_dis) { 111 112 #if CONFIG_IDF_TARGET_ESP32 113 dis_dl_cache = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_CACHE); 114 dis_dl_enc = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_ENCRYPT); 115 dis_dl_dec = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_DECRYPT); 116 /* Check if DISABLE_DL_DECRYPT, DISABLE_DL_ENCRYPT & DISABLE_DL_CACHE are set */ 117 if ( dis_dl_cache && dis_dl_enc && dis_dl_dec ) { 118 mode = ESP_FLASH_ENC_MODE_RELEASE; 119 } 120 #elif CONFIG_IDF_TARGET_ESP32S2 121 dis_dl_enc = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); 122 dis_dl_icache = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); 123 dis_dl_dcache = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_DCACHE); 124 125 if (dis_dl_enc && dis_dl_icache && dis_dl_dcache) { 126 mode = ESP_FLASH_ENC_MODE_RELEASE; 127 } 128 #endif 129 } 130 } else { 131 mode = ESP_FLASH_ENC_MODE_DISABLED; 132 } 133 134 return mode; 135 }